Three top-level folders. One CI lane today (split per layer when scale demands). Ownership cohorts via CODEOWNERS — every folder routes to its owning team. The boundaries map to who's allowed to write what.
Why administrative/ instead of engineering/ for the obs app: the obs app watches the platform on behalf of every operator. It's admin/ops tooling, not engineering-specific. engineering/ stays as a placeholder for actual engineering-vibe-scripter cartridges. Why chatbot is under global/: the chatbot is cross-cutting — every department will use it. Apps that genuinely belong to one department go under that department's folder; cross-cutting apps live under global/ with their consumption gated at the Cognito-group level (the Cartridges tab's "Access" config controls this declaratively).
# Substrate — platform team only
/substrate/ @platform-team
# Console — engineering owns functional; UI team owns visual
/console/sdk/v1/css/ @ui-team
/console/sdk/v1/components.css @ui-team
/console/sdk/v1/design-tokens.css @ui-team
/console/sdk/v1/ @engineering-team
/console/_platform/ @engineering-team
# Cartridges — department-scoped vibe scripters
/cartridges/global/ @platform-team
/cartridges/administrative/ @admin-ops-team
/cartridges/engineering/ @engineering-vibe-scripters
/cartridges/sales/ @sales-vibe-scripters
/cartridges/marketing/ @marketing-vibe-scripters
/cartridges/hr/ @hr-vibe-scripters
/cartridges/finance/ @finance-vibe-scripters
/cartridges/labs/ @engineering-team # lower review bar; loose oversight
# Catch-all
* @platform-team
For Phase A (single human in all roles), every line is one person. The structure is right from day one. When external contributors arrive, role groups expand to include them without restructuring.
cartridge/<app-name>cp -r cartridges/_template cartridges/<department>/<app-name>cartridge-plan.yml — Terraform plan against the substrate's statecartridge-apply.yml with confirm = APPLYai-sandbox-app-registry DDB (immutable; append-only per §22)| From | To | Allowed? | Mechanism |
|---|---|---|---|
| cartridges/* | console/sdk/v1/ | Yes | Imports / link from app's HTML; Terraform consumes SDK module outputs |
| cartridges/* | substrate/ | No (direct) | All substrate access goes through SDK helpers; cartridges read substrate's output values via remote-state data sources only when the SDK doesn't suffice (rare) |
| console/sdk/ | substrate/ | Yes | SDK Terraform modules consume substrate outputs (CMK ARNs, role ARNs, etc.) via remote-state data sources |
| console/_platform/ | substrate/ | Yes | Same as SDK |
| substrate/ | console/ or cartridges/ | No (one-way) | Substrate must not depend on anything above it in the stack |
Stay monorepo until at least one of these is true:
The monorepo's folder structure mirrors what the three-repo split would be. Migration is git filter-branch + tfstate migration + CI workflow split. ~1 day of platform-team work.
The cartridge folders mirror the same departmental axis the data governance grid (Step 4.5.a) uses for CMKs:
| Cartridge folder | Native governance cells (Phase 1) | Future cells |
|---|---|---|
cartridges/global/ | uses platform's chosen cell (Phase 1: eng-low-risk backend, ceo-office-low-risk frontend) | per-cartridge override |
cartridges/administrative/ | eng-low-risk (built; obs app) | admin-confidential (audit-grade) |
cartridges/engineering/ | eng-low-risk (built) | eng-confidential, eng-high-risk |
cartridges/ceo-office/ | ceo-office-low-risk (built) | ceo-office-confidential, ceo-office-high-risk |
cartridges/sales/ | sales-low-risk (build when needed) | sales-high-risk (PII customer data) |
cartridges/marketing/ | marketing-low-risk | — |
cartridges/hr/ | (skip low; HR almost always confidential) | hr-confidential (employee data) |
cartridges/finance/ | finance-low-risk | finance-high-risk, finance-confidential |
cartridges/labs/ | labs-low-risk (sandbox; ephemeral) | — |
The departmental axis is the right organizing principle for both data classification (CMKs) and app ownership (cartridges). The substrate and the cartridges share the same vocabulary.
Folder = ownership. Group-claim = access. Cross-department apps still live under the owner department's folder; visibility is controlled at the AppMenu / Cognito group level.
The repo's folder structure encodes who can write what — that's authority. Who consumes an app is determined at run time via Cognito groups — that's consumption. Conflating the two leads to either over-permissive write access or under-discoverable apps. Separating them lets the same app be owned by one department and consumed by many.