Integrates the multi-project work so far — the §22 design drafts, M1 (the
schema spine), and M2 (project-scoped authorization + the §22.7 resolver) —
on top of the v0.32.0 retire/§13 changes that landed on main meanwhile.
Integration decisions:
- Renumbered the M1 projects migration 025_projects.sql -> 026_projects.sql.
v0.32.0 shipped 025_retired_state.sql, which rebuilds cached_rfcs and
predates the project_id column; running projects *after* the retire rebuild
is required so project_id survives on a fresh database (the runner applies
*.sql in filename order). Comment/doc references bumped to match.
- Resolved the get_rfc conflict in api.py by composing both gates: compute the
viewer once, apply the §22.5 visibility gate, then v0.32.0's §13.7
retired-entry owner-only check.
- api_graduation.py / api_discussion.py auto-merged cleanly (M2's threaded
viewer/visibility gate coexists with the new retire endpoints + retired
state).
Full suite 401 passed on a fresh DB.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Lays the additive foundation for hosting N projects per deployment, with
today's single corpus as the N=1 case. No behavior change: the app runs
exactly as before, single project, with the spine underneath.
- migration 025: `projects` + `project_members` tables; seed the `default`
project (visibility=public, preserving open-by-default); thread
`project_id NOT NULL DEFAULT 'default'` onto all 19 slug-bearing tables,
backfilling existing rows. Additive — no table rebuilds; the slug-keyed
uniqueness/PK rework is enumerated in the migration header and deferred to
the slice that activates project #2.
- app/projects.py: §22.13 startup backfill of the default project's
content_repo from META_REPO (idempotent — never clobbers a value the
future registry mirror sets).
- config: REGISTRY_REPO wired (optional through M1; consumed by the M3
mirror), documented in .env.example as META_REPO's successor.
- tests: 6 vertical assertions on the spine (seed, backfill, column shape,
role CHECK, idempotency, config). Full suite 381 passed.
- docs: align Part C M1/M3 boundaries with the landed code (registry mirror
+ redirect move to M3).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>