docs: hierarchy schema contract (S2 contract 1, D2) #1435
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user