From dcf42208232ffc905fc4e633e0470ad8189b561c Mon Sep 17 00:00:00 2001 From: fred Date: Wed, 26 Aug 2026 18:48:13 -0500 Subject: [PATCH] docs: hierarchy schema contract revision 4 (terra r3 residual F7: raw-SQL literal prong) --- docs/requirements/hierarchy-schema.md | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/docs/requirements/hierarchy-schema.md b/docs/requirements/hierarchy-schema.md index 6d5e54b5..e18a817a 100644 --- a/docs/requirements/hierarchy-schema.md +++ b/docs/requirements/hierarchy-schema.md @@ -30,6 +30,11 @@ to contract 1 §6.2 — was already fixed in contract 2 revision 2, which cites §6.5; measured against `origin/contract/rbac-grants` head `501112d2`.) +Revision 4 (terra r3 residual F7): the §6.3(b) writer-coverage assertion +extended to raw SQL — it now also fails on class-table name literals +inside SQL strings or tagged SQL templates outside the allowlist, so a +raw-SQL writer that touches no schema symbol is still caught. + Scope: the tenancy/authorization structure record class — companies, estates, platform-projects, workspaces, hierarchy grants, their parentage, and constraints. Out of scope: the RBAC grant vocabulary and evaluation @@ -232,12 +237,19 @@ Binding on the implementing PRs (extends A1 §8.3): declared hierarchy command family — no generic CRUD endpoint. (b) Writer coverage — the closed allowlist a route inventory cannot provide: a static CI assertion over the Gateway and package sources - that write references to the class-table schema symbols (insert, - update, delete) occur only in an explicitly enumerated allowlist of - hierarchy command/repository modules. The allowlist is closed: a new - writer anywhere else fails the assertion until the allowlist is - extended in the same PR, so an unregistered internal or raw-SQL write - path is surfaced in CI and review rather than passing unnoticed. + with two prongs, both bound to one explicitly enumerated allowlist of + hierarchy command/repository modules. (i) Symbol prong: write + references to the class-table schema symbols (insert, update, delete) + occur only in allowlisted modules. (ii) Literal prong: a class-table + name appearing inside a SQL string or tagged SQL template outside the + allowlist fails the assertion — this is what catches a raw-SQL writer + that references no schema symbol. Schema definitions and generated + migrations are excluded from the literal prong; a false positive + (e.g. a table name in a non-write query string) is resolved by + extending the allowlist in the same PR, never by weakening the + assertion. The allowlist is closed: any new writer, ORM or raw, + fails CI until the allowlist names it, so the write path is surfaced + in review rather than passing unnoticed. 4. Audit witnesses: for each mutation class (create, rename, transfer, grant create/change/revoke, delete) — the event exists after commit with actor/verb/target and same-transaction atomicity; a rolled-back