§22 S1: thread collection_id through backend + update tests (N=1 unchanged, 454 green)

- collections.py resolution helpers (default_collection_id, type, initial_state)
- registry mirror writes project grouping fields + default-collection corpus fields
- auth.project_of_rfc joins collections; project_member_role reads memberships
- cache/api_*/funder writers+readers re-keyed to collection_id (cached_prs + denormalised
  project_id tags unchanged); api_deployment reads type/initial_state from the default collection
- projects.py restamp detects bootstrap via collections; initial_state via collection
- tests updated to the three-tier schema; test_migration_028 retired (superseded by 029)
- add @S1 acceptance test (collection grain + N=1 serving)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ben Stull
2026-06-05 08:26:14 -07:00
parent 867f2504d6
commit 9ca07a3f81
27 changed files with 475 additions and 301 deletions
+14 -6
View File
@@ -74,13 +74,20 @@ def test_parse_rejects_invalid(bad, msg):
def test_apply_upserts_projects_and_deployment():
_db()
doc = registry.parse_registry(VALID)
registry.apply_registry(doc, registry_sha="regsha1")
registry.apply_registry(doc, registry_sha="regsha1", default_id="default")
# §22 three-tier: the project carries the grouping-tier fields; the
# per-corpus type/initial_state live on its default collection.
prow = db.conn().execute(
"SELECT name, type, content_repo, visibility, initial_state, registry_sha FROM projects WHERE id='default'"
"SELECT name, content_repo, visibility, registry_sha FROM projects WHERE id='default'"
).fetchone()
assert prow["name"] == "Open Human Model"
assert prow["content_repo"] == "meta"
assert prow["registry_sha"] == "regsha1"
crow = db.conn().execute(
"SELECT type, initial_state FROM collections WHERE id='default'"
).fetchone()
assert crow["type"] == "document"
assert crow["initial_state"] == "super-draft"
drow = db.conn().execute("SELECT name, tagline FROM deployment WHERE id=1").fetchone()
assert drow["name"] == "Open Human Model"
assert drow["tagline"] == "A model of human flourishing"
@@ -88,11 +95,12 @@ def test_apply_upserts_projects_and_deployment():
def test_apply_rejects_type_change_on_existing_project():
_db()
registry.apply_registry(registry.parse_registry(VALID), "s1")
registry.apply_registry(registry.parse_registry(VALID), "s1", default_id="default")
changed = VALID.replace("type: document", "type: specification")
registry.apply_registry(registry.parse_registry(changed), "s2") # logged + skipped, no raise
t = db.conn().execute("SELECT type FROM projects WHERE id='default'").fetchone()["type"]
registry.apply_registry(registry.parse_registry(changed), "s2", default_id="default") # skipped
# §22.4a immutable type — now enforced on the collection.
t = db.conn().execute("SELECT type FROM collections WHERE id='default'").fetchone()["type"]
assert t == "document" # immutable — unchanged
# The deployment row IS still advanced even though the project upsert was skipped.
# The deployment row IS still advanced even though the type change was skipped.
drow = db.conn().execute("SELECT registry_sha FROM deployment WHERE id=1").fetchone()
assert drow["registry_sha"] == "s2"