From 5c1e8d290e0a4124abce6a7280c8443d894ee61a Mon Sep 17 00:00:00 2001 From: fred Date: Wed, 26 Aug 2026 19:02:11 -0500 Subject: [PATCH] =?UTF-8?q?docs:=20hierarchy=20contract=20revision=206=20?= =?UTF-8?q?=E2=80=94=20three-prong=20wording,=20allowlist=20composition=20?= =?UTF-8?q?rules,=20honest=20detection=20scope=20(terra=20r5=20F7/F8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/requirements/hierarchy-schema.md | 43 +++++++++++++++++++-------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/docs/requirements/hierarchy-schema.md b/docs/requirements/hierarchy-schema.md index a1332b30..3df5015d 100644 --- a/docs/requirements/hierarchy-schema.md +++ b/docs/requirements/hierarchy-schema.md @@ -42,6 +42,14 @@ dynamically constructed table name carries neither a schema symbol nor a class-table literal. The detection claim is now coextensive with what the three prongs statically see. +Revision 6 (terra r5 residual F7 + new F8): the "two prongs" wording +corrected to three (F8); §6.3(b) gains the allowlist composition rules +(no generic raw-SQL helper is allowlisted; an allowlisted module may +not export caller-supplied-SQL execution) and fails outright on +runtime code-construction primitives; the detection claim is scoped +honestly to the stated syntactic forms, with evasions beyond static +reach assigned to §5.1 review/audit rather than claimed for CI. + 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 @@ -244,8 +252,8 @@ 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 - with two prongs, both bound to one explicitly enumerated allowlist of - hierarchy command/repository modules. (i) Symbol prong: write + with three prongs, each 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 @@ -257,16 +265,27 @@ Binding on the implementing PRs (extends A1 §8.3): constructed — the call site is statically detectable even when a dynamically assembled table name is not, so a raw writer with a runtime-built identifier is caught by its primitive, not its - payload. 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, or a legitimate raw query elsewhere in the - codebase) is resolved by extending the allowlist in the same PR, - never by weakening the assertion. The allowlist is closed: a symbol - writer fails prong (i), a raw writer naming a class table fails - prong (ii), and any raw execution at all outside the allowlist fails - prong (iii), so every new writer — ORM, raw-literal, or - dynamically constructed — fails CI until the allowlist names it and - the write path is surfaced in review rather than passing unnoticed. + payload. Two composition rules keep prong (iii) meaningful: the + allowlist names hierarchy command/repository modules only — a + generic raw-SQL helper or database-utility module is never + allowlisted; and an allowlisted module MUST NOT export a function + that executes caller-supplied SQL (such an export is itself a + raw-execution primitive, and the exporting module is treated as + unallowlisted for prong (iii) if it does). Runtime code-construction + primitives (`eval`, `new Function`) anywhere in the scanned sources + fail the assertion outright, allowlist or not. 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, or a + legitimate raw query elsewhere in the codebase) is resolved by + extending the allowlist in the same PR, never by weakening the + assertion. The allowlist is closed, and the assertion's detection + claim is exactly its prongs: it statically surfaces every writer + expressed as a schema-symbol reference, a class-table SQL literal, a + raw-execution call site, or runtime code construction. An evasion + engineered outside those syntactic forms is a §5.1 violation that + review and audit own — the witness does not claim to catch what + static analysis cannot see, and any such evasion found later is + corrected as a conformance defect, not grandfathered. 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