S2 contract 1 of 9 (webui-audit, T10 targeted-update ruling). One new file: docs/requirements/hierarchy-schema.md.
Turns PRD D2/D9/D13 (Part I §4) and native-kanban SOT Amendment A1 (§8) into the concrete schema contract for the tenancy/authorization structure record class:
companies → estates → platform_projects → workspaces, NOT NULL RESTRICT parent FKs — exactly-one chain by construction, no edge tables, no detached states
platform_projects named to avoid the ratified collision with the workspace-internal projects planning table (A1 §8.1.4)
hierarchy_grants attachment shape (exactly-one-of subject and target, CHECK-enforced); role vocabulary and evaluation deferred to contract 2
transfer = single audited parent-FK update, both-sides authority, zero business-row mutation (A1 chain maintenance)
no owner columns: ownership is the grant structure (embedded ruling for Jason)
verification matrix incl. real-Postgres constraint witnesses (ci-postgres service in the test step)
Independent review (gate 16) to follow before merge. No self-merge without review.
S2 contract 1 of 9 (webui-audit, T10 targeted-update ruling). One new file: docs/requirements/hierarchy-schema.md.
Turns PRD D2/D9/D13 (Part I §4) and native-kanban SOT Amendment A1 (§8) into the concrete schema contract for the tenancy/authorization structure record class:
- companies → estates → platform_projects → workspaces, NOT NULL RESTRICT parent FKs — exactly-one chain by construction, no edge tables, no detached states
- platform_projects named to avoid the ratified collision with the workspace-internal projects planning table (A1 §8.1.4)
- hierarchy_grants attachment shape (exactly-one-of subject and target, CHECK-enforced); role vocabulary and evaluation deferred to contract 2
- transfer = single audited parent-FK update, both-sides authority, zero business-row mutation (A1 chain maintenance)
- no owner columns: ownership is the grant structure (embedded ruling for Jason)
- Gateway-only mutation path, semantic audit, fail-closed bottom-up deletion
- verification matrix incl. real-Postgres constraint witnesses (ci-postgres service in the test step)
Independent review (gate 16) to follow before merge. No self-merge without review.
Turns PRD D2/D13 and kanban-SOT Amendment A1 into a concrete schema
contract: companies/estates/platform_projects/workspaces with NOT NULL
RESTRICT parent chains (chain uniqueness by construction), per-parent slug
scoping, hierarchy_grants attachment shape (vocabulary deferred to
contract 2), transfer as single audited parent-FK update requiring
both-sides authority, no owner columns (ownership = grants), fail-closed
bottom-up deletion, Gateway-only mutation path, and a verification matrix
with real-Postgres constraint witnesses.
- tenancy-FK exemption: canonical workspace_id is the one permitted
business->class reference; all other forms forbidden with control test
- record class = 4 node tables + hierarchy_grants per A1 8.1.2
- grant uniqueness via UNIQUE NULLS NOT DISTINCT (or 6 partial indexes);
NOT NULL on role/granted_by/name/slug
- grant FK delete actions split: target cascade, principal RESTRICT
- audit parity: REQ-AUD-001 guarantees, same-transaction outbox,
deletion-safe snapshot linkage, cascade coverage, rollback witness
- roll-up never-a-write restored to full A1 strength (no canonical writes)
- ownership invariant completed via contract 2; both-sides transfer rule
marked new policy; legacy premise corrected
- corrected cardinality witness (one-parent-per-child + sibling control)
- provenance fixes: REQ-MIG-001 attribution dropped, projects table
described accurately, D8-rank-1 claim removed
The 'one live importer' claim was false: the measured production importer
set of the db migration runner has four members (Gateway database module
via the barrel, storage Postgres adapter, fleet-backlog and gateway-verify
CLI commands via literal dynamic import). The enumeration example now
names all four, the import analysis resolves literal dynamic import()
routes, and a non-literal dynamic import of the db package fails the
assertion. Injection-only consumers (schema-check) have no import edge.
APPROVED — rev-code-01, pinned to head e3b0375211d7e09d2dff03b83c31ae56f57e29fc (re-verified unmoved immediately before posting).
Scope: doc-only, single file docs/requirements/hierarchy-schema.md (+380 lines vs merge-base 49b79434, nine revisions). This contract is the anchor the rest of the S2 set cites; verified independently of the terra r1-r9 chain, with my own measurement of every load-bearing claim:
Rev-9 importer enumeration (the r9 delta) re-measured by me. My own migration-symbol sweep (runMigrations|runPgliteMigrations|getMigrationStatus|readJournalTags|applyMigrationsByHash over production sources, tests excluded) finds exactly the four named members: apps/gateway/src/database/database.module.ts (barrel static), packages/storage/src/adapters/postgres.ts (barrel static), packages/mosaic/src/commands/fleet-backlog.ts (literal dynamic await import('@mosaicstack/db'), destructuring both migration runners), packages/mosaic/src/commands/gateway/verify.ts (literal dynamic import at :101). Exhaustiveness control: the wider @mosaicstack/db importer list minus symbol users leaves only schema-symbol consumers and string mentions. schema-check.ts is injection-only as claimed (SchemaCheckDeps interface, its only @mosaicstack/db hits are remediation-message strings). No nonliteral dynamic import of the db package exists in code (only .md docs). The four-member claim is exact.
A1 citations verbatim: §8.1.2 record class (tenancy/authorization structure records incl. hierarchy-level access grants; §3 invariant 10 and REQ-TEN-001 not applying to the class), §8.1.4 naming (platform-project vs the workspace-internal planning projects; MUST NOT merge), §8.2.2/§8.2.3/§8.3 acceptance rows — all match native-kanban-sot.md lines 388-458. REQ-AUD-001 (line 193) and REQ-API-001 (line 206) exist as cited.
Codebase facts: planning projects table carries no workspace_id and sits under the ─── Brain ─── section comment ("so labeled" accurate); legacy teams.owner_id/manager_id + team_members.role exist exactly as §4.4 disparages (schema.ts:127-151); none of the five contract tables exist today (0 hits — clean implementation slate); pinned drizzle-orm 0.45.1 exposes nullsNotDistinct() (unique-constraint.d.ts:10), so §3.2's mechanism is real.
The §6.3(b) writer-coverage apparatus is internally coherent across its nine-revision history: three prongs + composition rules (no generic raw-SQL helper allowlisted; allowlisted modules may not export caller-supplied-SQL execution), infrastructure register exempt from prong (iii) only, re-export-aware + literal-dynamic-import-resolving analysis, nonliteral db dynamic import failing outright, runtime code-construction primitives failing outright, and the honest detection-scope statement (static prongs exactly; beyond-syntax evasions owned by §5.1 review/audit — not claimed for CI). The rev-8→9 fix (one-live-importer → four-member measured set) is the kind of measured-not-asserted completeness the register itself demands.
Cross-contract consistency with contract 2 (my review id 324) re-confirmed at this head: §3.1 grant shape + role-vocabulary ownership, §4.2 both-sides new-policy flag, §4.4 initial-owner naming, §6.5 transfer tests citing back — no contradictions.
Gates run by me in a fresh worktree at this head: format:check rc=0 (pinned prettier; rev-8 file also clean — no style delta in rev 9); typecheck rc=0 (45/45); lint rc=0 (25/25). (Docs-only PR; web-deps build not needed for typecheck here, but typecheck ran the full 45-task matrix.)
Non-blocking notes:
[S1] §6.3(b) is now a ~700-word single paragraph inside one bullet; the writer-allowlist / infrastructure-register / importer-enumeration triple would be easier to implement-and-audit split into lettered sub-items in a future editorial pass. No semantic change requested.
CI note: 2838 running on this head at review time (as fred noted; prior #1435 pipelines all killed/canceled under queue load). Merge waits on 2838 terminal green. First in the S2 merge order — landing it unblocks the #1436/#1438/#1439 refs their contracts already cite.
**APPROVED — rev-code-01, pinned to head `e3b0375211d7e09d2dff03b83c31ae56f57e29fc`** (re-verified unmoved immediately before posting).
Scope: doc-only, single file `docs/requirements/hierarchy-schema.md` (+380 lines vs merge-base 49b79434, nine revisions). This contract is the anchor the rest of the S2 set cites; verified independently of the terra r1-r9 chain, with my own measurement of every load-bearing claim:
1. **Rev-9 importer enumeration (the r9 delta) re-measured by me.** My own migration-symbol sweep (`runMigrations|runPgliteMigrations|getMigrationStatus|readJournalTags|applyMigrationsByHash` over production sources, tests excluded) finds exactly the four named members: `apps/gateway/src/database/database.module.ts` (barrel static), `packages/storage/src/adapters/postgres.ts` (barrel static), `packages/mosaic/src/commands/fleet-backlog.ts` (literal dynamic `await import('@mosaicstack/db')`, destructuring both migration runners), `packages/mosaic/src/commands/gateway/verify.ts` (literal dynamic import at :101). Exhaustiveness control: the wider `@mosaicstack/db` importer list minus symbol users leaves only schema-symbol consumers and string mentions. schema-check.ts is injection-only as claimed (`SchemaCheckDeps` interface, its only `@mosaicstack/db` hits are remediation-message strings). No nonliteral dynamic import of the db package exists in code (only .md docs). The four-member claim is exact.
2. **A1 citations verbatim:** §8.1.2 record class (tenancy/authorization structure records incl. hierarchy-level access grants; §3 invariant 10 and REQ-TEN-001 not applying to the class), §8.1.4 naming (platform-project vs the workspace-internal planning `projects`; MUST NOT merge), §8.2.2/§8.2.3/§8.3 acceptance rows — all match `native-kanban-sot.md` lines 388-458. REQ-AUD-001 (line 193) and REQ-API-001 (line 206) exist as cited.
3. **Codebase facts:** planning `projects` table carries no `workspace_id` and sits under the `─── Brain ───` section comment ("so labeled" accurate); legacy `teams.owner_id`/`manager_id` + `team_members.role` exist exactly as §4.4 disparages (schema.ts:127-151); none of the five contract tables exist today (0 hits — clean implementation slate); pinned drizzle-orm 0.45.1 exposes `nullsNotDistinct()` (unique-constraint.d.ts:10), so §3.2's mechanism is real.
4. **The §6.3(b) writer-coverage apparatus is internally coherent** across its nine-revision history: three prongs + composition rules (no generic raw-SQL helper allowlisted; allowlisted modules may not export caller-supplied-SQL execution), infrastructure register exempt from prong (iii) only, re-export-aware + literal-dynamic-import-resolving analysis, nonliteral db dynamic import failing outright, runtime code-construction primitives failing outright, and the honest detection-scope statement (static prongs exactly; beyond-syntax evasions owned by §5.1 review/audit — not claimed for CI). The rev-8→9 fix (one-live-importer → four-member measured set) is the kind of measured-not-asserted completeness the register itself demands.
5. **Cross-contract consistency** with contract 2 (my review id 324) re-confirmed at this head: §3.1 grant shape + role-vocabulary ownership, §4.2 both-sides new-policy flag, §4.4 initial-owner naming, §6.5 transfer tests citing back — no contradictions.
Gates run by me in a fresh worktree at this head: `format:check` rc=0 (pinned prettier; rev-8 file also clean — no style delta in rev 9); `typecheck` rc=0 (45/45); `lint` rc=0 (25/25). (Docs-only PR; web-deps build not needed for typecheck here, but typecheck ran the full 45-task matrix.)
Non-blocking notes:
- [S1] §6.3(b) is now a ~700-word single paragraph inside one bullet; the writer-allowlist / infrastructure-register / importer-enumeration triple would be easier to implement-and-audit split into lettered sub-items in a future editorial pass. No semantic change requested.
CI note: 2838 running on this head at review time (as fred noted; prior #1435 pipelines all killed/canceled under queue load). Merge waits on 2838 terminal green. First in the S2 merge order — landing it unblocks the #1436/#1438/#1439 refs their contracts already cite.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
S2 contract 1 of 9 (webui-audit, T10 targeted-update ruling). One new file: docs/requirements/hierarchy-schema.md.
Turns PRD D2/D9/D13 (Part I §4) and native-kanban SOT Amendment A1 (§8) into the concrete schema contract for the tenancy/authorization structure record class:
Independent review (gate 16) to follow before merge. No self-merge without review.
APPROVED — rev-code-01, pinned to head
e3b0375211d7e09d2dff03b83c31ae56f57e29fc(re-verified unmoved immediately before posting).Scope: doc-only, single file
docs/requirements/hierarchy-schema.md(+380 lines vs merge-base49b79434, nine revisions). This contract is the anchor the rest of the S2 set cites; verified independently of the terra r1-r9 chain, with my own measurement of every load-bearing claim:runMigrations|runPgliteMigrations|getMigrationStatus|readJournalTags|applyMigrationsByHashover production sources, tests excluded) finds exactly the four named members:apps/gateway/src/database/database.module.ts(barrel static),packages/storage/src/adapters/postgres.ts(barrel static),packages/mosaic/src/commands/fleet-backlog.ts(literal dynamicawait import('@mosaicstack/db'), destructuring both migration runners),packages/mosaic/src/commands/gateway/verify.ts(literal dynamic import at :101). Exhaustiveness control: the wider@mosaicstack/dbimporter list minus symbol users leaves only schema-symbol consumers and string mentions. schema-check.ts is injection-only as claimed (SchemaCheckDepsinterface, its only@mosaicstack/dbhits are remediation-message strings). No nonliteral dynamic import of the db package exists in code (only .md docs). The four-member claim is exact.projects; MUST NOT merge), §8.2.2/§8.2.3/§8.3 acceptance rows — all matchnative-kanban-sot.mdlines 388-458. REQ-AUD-001 (line 193) and REQ-API-001 (line 206) exist as cited.projectstable carries noworkspace_idand sits under the─── Brain ───section comment ("so labeled" accurate); legacyteams.owner_id/manager_id+team_members.roleexist exactly as §4.4 disparages (schema.ts:127-151); none of the five contract tables exist today (0 hits — clean implementation slate); pinned drizzle-orm 0.45.1 exposesnullsNotDistinct()(unique-constraint.d.ts:10), so §3.2's mechanism is real.Gates run by me in a fresh worktree at this head:
format:checkrc=0 (pinned prettier; rev-8 file also clean — no style delta in rev 9);typecheckrc=0 (45/45);lintrc=0 (25/25). (Docs-only PR; web-deps build not needed for typecheck here, but typecheck ran the full 45-task matrix.)Non-blocking notes:
CI note: 2838 running on this head at review time (as fred noted; prior #1435 pipelines all killed/canceled under queue load). Merge waits on 2838 terminal green. First in the S2 merge order — landing it unblocks the #1436/#1438/#1439 refs their contracts already cite.