Skip to main content

Context

After ADR-0010 split the original monorepo into eigenoid/core and eigenoid/studio (renamed app-studio per ADR-0011), Studio still lives as a single repo containing both the React/Vite frontend and the FastAPI backend in one tree. The implementation plan in app-studio/SAAS_PLAN.md (v3) recommended keeping the monorepo with a "future split path documented".

ADR-0015 commits Studio to the same hosting topology and operational model as svc-access + app-access-admin: Pages frontend, Cloud Run backend, CF Workers gateway, dev → main branch model. The rest of the org already follows the app- / svc- / iac- naming convention from ADR-0011 with one repo per category, per surface:

SurfaceRepo
Access control backendsvc-access
Access control admin frontendapp-access-admin
Foundation infra (org-level)iac-foundation

Keeping Studio frontend + backend in one repo diverges from this pattern and creates concrete costs as the project grows:

  • CODEOWNERS and CI secrets blast-radius: a backend deploy secret is reachable from the frontend pipeline and vice versa.
  • Coupled release cadence: a frontend revert requires coordinating with any in-flight backend work in the same branch.
  • Path-filter fragility in CI: every workflow has to remember which subdirectory it's scoped to; one missing filter and a frontend PR triggers backend tests (or worse, the deploy).
  • Cross-stack PRs become hard to review: frontend and backend changes mixed in one branch.
  • Infra (Terraform) does not belong in either: when iac-studio Terraform lands, putting it in the same repo as the backend couples deploys of infra to deploys of code.

The cost of splitting now is one bounded refactor with git filter-repo (history preserved). The cost of splitting later, after the repo grows further, only goes up.

Decision

Split Studio into three repos, following ADR-0011 naming:

RepoSurfaceHostingBranches
eigenoid/app-studioReact/Vite/TS/Tailwind frontendCloudflare Pages → studio.eigenoid.comdevmain
eigenoid/svc-studioFastAPI backendCloud Run in eigenoid-prd, behind CF Workers gateway per ADR-0014devmain
eigenoid/iac-studioTerraform for Studio's GCP/CF resources, OpenAPI contract, Studio-specific docs that don't belong in docs-internaln/a (CI applies via WIF per ADR-0009)devmain

The current eigenoid/app-studio repo is not archived — it is reused for the frontend (already named correctly per ADR-0011 since Studio's user-facing surface is an "app", and its dev branch already holds the recent frontend + plan work). The backend code is extracted out of it into the new eigenoid/svc-studio repo.

Migration plan

  1. svc-studio initialization: from the current app-studio dev branch (which already contains the merged backend Dockerfile, OPENAI_API_KEY validation, and frontend VITE_BACKEND_URL work — PRs #8/#9/#10), run git filter-repo --subdirectory backend. History of backend/ is preserved with full blame. Push as eigenoid/svc-studio. Repository creation goes through the standard "Request new repository" issue template per ADR-0007 so safe-settings and suborg config apply automatically.
  2. app-studio cleanup: in app-studio's dev branch, remove the backend/ directory (the code now lives in svc-studio). Update start.sh so the local dev loop pulls/runs the backend from the sibling svc-studio checkout (auto-detection like ADR-0010's EIGENOID_CORE_ROOT pattern, with EIGENOID_STUDIO_BACKEND_ROOT).
  3. iac-studio initialization: created fresh (no historical Terraform or OpenAPI worth preserving yet).
  4. CI bootstrap: each repo gets its own pr-title.yml (Conventional Commits enforcement, copied from platform-actions) and ci.yml (frontend: npm ci && npm run build; backend: import smoke test + planned pytest scaffold; iac: terraform fmt -check && terraform validate).
  5. Cutover: only after svc-studio has its first green CI build and the local dev loop works end-to-end against the sibling layout, the backend directory is removed from app-studio main. Until then, both copies coexist on dev.

Why this naming and not studio-frontend / studio-backend

The earlier draft of this ADR used studio-frontend / studio-backend. That violates ADR-0011's category-prefix convention. app-, svc-, and iac- prefixes are required so safe-settings suborg globs (app-*, svc-*, iac-*) and CODEOWNERS patterns work cleanly. Following the convention is mandatory; the convention determines the structure.

Consequences

  • Aligned with org convention: app-/svc-/iac- prefixes per ADR-0011; one repo per category per surface, like svc-access + app-access-admin.
  • CODEOWNERS, CI secrets, and branch protection are per surface. Blast-radius of credentials is reduced; a frontend repo cannot leak a backend Cloud Run deploy key.
  • Independent release cadence between frontend, backend, and infra.
  • Per-repo CI is simpler — fewer path filters, less workflow coordination.
  • History is preserved for the backend (filter-repo on backend/ subdirectory). Blame survives.
  • Each cross-stack feature is now two PRs (and three when infra is touched). Accepted as the price of the other gains.
  • OpenAPI contract drift becomes a real concern: the contract lives in iac-studio, is generated and published by svc-studio CI, and consumed by app-studio for typed TS clients. Discipline + a CI check that the published contract matches the backend's generated one is required. Versioning by SHA or release tag.
  • Three new CI workflow setups (one per repo) instead of one. Manageable via copy/adapt from platform-actions templates.
  • safe-settings suborg routing happens automatically because the prefixes match existing globs in platform-settings.
  • Existing Studio open PRs (#6 UI accessibility on feat/ui-non-tech-accessibility, #7 SAAS_PLAN on docs/saas-plan) need to land before the backend extraction starts, or be rebased after. Coordinate with @andylow92.

Alternatives considered

  • Keep monorepo with documented future-split path (the SAAS_PLAN v3 recommendation): rejected. The repo only grows; the cost of the split is monotonically increasing. Today is the cheapest moment to do it.
  • Two repos only — app-studio (frontend) + svc-studio (backend), no iac-studio: rejected. Terraform doesn't naturally live in either; folding it into svc-studio couples infra deploys to code deploys, and folding into iac-org-shared mixes Studio-specific resources with org-wide ones. A dedicated iac-studio keeps the boundaries clean.
  • Use app-studio for backend and rename frontend to something else: rejected. The user-facing surface is the "app" by convention; the backend is the supporting service ("svc-").
  • Names like studio-frontend / studio-backend / studio-infra (the earlier draft): rejected for violating ADR-0011's category-prefix rule. Suborg globs (app-*, svc-*, iac-*) would not match.
  • Monorepo with Turborepo / Nx: rejected as overengineering for the team size and as further divergence from the rest of the org.

References