docs(specs): the M2 trust-boundary table — measured, and three boundaries CLOSED (PR-7, H-7)

formation/ declares its trust boundary explicitly (forge.py's five ordered
rules + hashing.py's content-addressing, no-floats, no-pickle, self-sealing).
ingest/gate.py — the PRODUCTION boundary, the only point where raw data enters
the versor manifold, facing untrusted user text every turn — had no comparable
table. H-7: asymmetric rigor invites the assumption that the un-tabled boundary
is the less important one, when it is the opposite.

Written per H-7's authority: documentation first, evidence decides whether code
follows. Every row measured against the code at edf6c2a4, not assumed — and the
measurement reframes the entry.

  ALREADY MET (2)   no floats in hashed payloads — _stable_digest hashes
                    salt + name, both UTF-8 strings, no float reaches a digest
                    no pickle — absent from all of ingest/

  CATEGORY          content-addressed artifacts, self-sealing, source
  DIFFERENCE (3)    allow-list. All three presuppose a PERSISTED ARTIFACT WITH
                    CITATIONS. formation validates artifacts it will store; the
                    gate transforms text it will not. Recording these as owed
                    obligations would have manufactured three hardening tasks
                    that cannot be done, and sent a future reader to do them.
                    Closing them is the load-bearing half of this table.

  REAL DELTA (1)    no audit record per rejection. The gate refuses with typed
                    exceptions (KeyError :235/:286, RuntimeError :318/:424) and
                    records nothing about what it refused;
                    vocab.record_unknown_token :331 records OOV observation,
                    which is not a rejection record.

On the delta, stated so it is not over-read: it is NOT a containment hole —
refusal is fail-closed and nothing unvalidated crosses into the manifold. It
costs forensics. It is the same failure class as H-11, which PR-9 closed on the
turn spine hours ago: a guard that works correctly and leaves no trace of having
worked. And it has a named downstream consumer — a widening program (G-3) must
be able to ask "what shapes is this boundary refusing, and how often", which
today it cannot.

Hardening for B6 is a separate PR per this entry's own authority, sized against
whether anything consumes gate-rejection telemetry today.

AGENTS.md §Security-and-trust-boundaries defaults also checked row by row for
completeness: four are n/a to a component that executes nothing, touches no
filesystem, and mutates nothing; the display/log default is met.

Docs only. Registers: H-7 CLOSED, PR-7 marked LANDED.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wcw2pnMBwyvmNyQg4uPEt4
This commit is contained in:
Claude 2026-07-28 04:30:00 +00:00
parent edf6c2a454
commit 39331dbce1
No known key found for this signature in database
3 changed files with 72 additions and 1 deletions

View file

@ -59,6 +59,15 @@ Ranked by leverage (cognitive/structural load removed ÷ effort), per the AGENTS
**Why it hinders:** asymmetric rigor invites the assumption that the un-tabled boundary is the less important one; it is the opposite.
**Better home:** an M2 trust-boundary table in `runtime_contracts.md`, formation-style; hardening PRs only where the table exposes real deltas.
**Authority:** documentation first; evidence decides whether code follows.
**Status (2026-07-28): CLOSED — table written, and the measurement reframes the entry.** `docs/specs/runtime_contracts.md` §"M2 trust-boundary table" measures `ingest/gate.py` against all six of formation's declared boundaries at `edf6c2a4`. The result is not "five of six missing":
| | |
|---|---|
| **Already met** | no floats in hashed payloads (`_stable_digest` hashes strings only); no pickle anywhere under `ingest/` |
| **Category differences — closed, not owed** | content-addressing, self-sealing, and the source allow-list all presuppose a *persisted artifact with citations*. Formation validates artifacts it will store; the gate transforms text it will not. Writing these as obligations would have manufactured three gaps and sent someone to close them |
| **REAL DELTA (one)** | **no audit record per rejection.** The gate refuses with typed exceptions and records nothing about what it refused |
The surviving delta is **not a containment hole** — refusal is fail-closed and nothing unvalidated crosses. It costs forensics, and it is the *same failure class as H-11*: a guard that works correctly and leaves no trace of having worked. It also has a downstream consumer worth naming — a widening program (G-3) must be able to ask "what shapes is the boundary refusing, and how often?", which today it cannot. Hardening is a separate PR per this entry's own authority.
## H-8 · The record contradicts the code at three load-bearing points
**Verdict:** `wrong-solution` as *record-keeping* — divergence that reasoners inherit · **Layers:** governance

View file

@ -221,9 +221,11 @@ The assessment directory's own corrections (N-1…N-7 applied to `30-gap-registe
**Landed, and the verification pass this item mandated is why the three came out differently.** (a) was the real gap and worse than the register stated: the only import ban covered a single physics module, while `generate/realize/recall.py` — the actual recall path — asserted the law in its docstring with nothing enforcing it. Now scanned across five roots for banned ANN libraries *and* hand-rolled `cosine*` definitions. (b) is now exact: no function may construct `TurnVerdicts` without invoking `safety_check.check`, and every call must pass `self.safety_pack` (substituting the pack is a bypass that skipping-detection would miss). (c) was already well pinned — its gap was **reach**: a fail-closed safety contract running in no curated suite, verified only after merge. Promoted onto the gate. **Four sabotages, each observed red**, each caught by its own pin.
### PR-7 · The M2 trust-boundary table · **M** · H-7
### PR-7 · The M2 trust-boundary table · **M** · H-7 — **LANDED 2026-07-28**
Formation's six-boundary standard written for `ingest/gate.py` in `runtime_contracts.md`. **Documentation first** — the table's job is to expose real deltas at the surface facing untrusted user text; hardening PRs follow only where deltas are real, and are separate PRs.
**Landed, and the table's value turned out to be as much in what it closes as in what it opens.** Measured at `edf6c2a4`: two boundaries **already met** (no floats in hashed payloads, no pickle), three are **category differences** (content-addressing, self-sealing, source allow-list all presuppose a persisted artifact with citations — formation validates what it stores, the gate transforms what it does not), and **one is a real delta**: no audit record per rejection. Recording the three as closed is the load-bearing half; as owed obligations they would have generated three fake hardening tasks. The surviving delta is forensic, not containment (refusal is fail-closed), and is the same failure class PR-9 just closed on the turn spine.
### PR-8 · Materialise the typed refusal · **M** · H-3/G-20 — *needs a small ADR (the ADR-0024 chain reserved the seam)*
`InnerLoopExhaustion`'s reason/region/rejected-attempt evidence reaches `ChatResponse.refusal_reason` and a minimal honest served surface, instead of `""`. **Verification:** a refusing turn serves a non-empty, typed, replayable refusal, and `trace_hash` behavior is unchanged for non-refusing turns.

View file

@ -1087,3 +1087,63 @@ under complete provenance:
Enforcement pin: `tests/test_observed_he_morph_constraint_v0.py` (four-arm
ablation).
---
## M2 trust-boundary table — `ingest/gate.py` (PR-7, H-7)
**Why this table exists.** `formation/` declares its trust boundary explicitly:
the Forge's five ordered validation rules (`formation/forge.py`) plus the
hashing contract (`formation/hashing.py` — content-addressed artifacts, no
floats in hashed payloads, no pickle, self-sealing SHAs). `ingest/gate.py` is
the *production* boundary — the only point where raw data enters the versor
manifold, facing untrusted user text on every turn — and it had no comparable
declared table. H-7's charge: asymmetric rigor invites the assumption that the
un-tabled boundary is the less important one, when it is the opposite.
**Method: measured, not assumed.** Each row states what formation declares,
what the gate actually does at `edf6c2a4`, and a verdict. Three of the six
turn out **not to transfer at all**, and saying so is the point — formation
validates *artifacts it will persist*; the gate transforms *text it will not*.
Writing those three as owed obligations would have manufactured four gaps that
do not exist and sent someone to close them.
| # | Formation's boundary | `ingest/gate.py` at `edf6c2a4` | Verdict |
|---|---|---|---|
| B1 | **Content-addressed artifacts** — canonical JSON + SHA over every artifact | Produces a `FieldState` in memory; persists no artifact | **Category difference** — nothing is stored, so there is nothing to address |
| B2 | **No floats in hashed payloads** (`canonical_json` rejects them; float repr is platform-dependent) | `_stable_digest` (`:135`) hashes `salt + "\0" + name`, both UTF-8 strings. No float reaches a digest | **Already met** |
| B3 | **No pickle anywhere** (code-execution surface; defeats replay determinism) | No `pickle` import anywhere under `ingest/` | **Already met** |
| B4 | **Self-sealing** — SHA computed over the payload with its own `sha` field blanked | No persisted artifact to seal | **Category difference** |
| B5 | **Source allow-list** (Forge R3 — every cited source SHA must be allow-listed) | Input is live user text, not mined corpus with citations | **Category difference** |
| B6 | **An audit record per rejection** — quarantine is recorded, not merely refused | Refuses with typed exceptions (`KeyError` `:235`/`:286`, `RuntimeError` `:318`/`:424`). `vocab.record_unknown_token` (`:331`) records OOV *observation*, which is not a rejection record | **REAL DELTA — the only one** |
### The one real delta, stated precisely
The production boundary facing untrusted text **refuses correctly and records
nothing about what it refused.** Formation quarantines with a record; the gate
raises and the fact is gone unless a caller happens to log it. Two consequences
worth separating:
- **Not a safety hole.** The refusal is typed and fail-closed — nothing
unvalidated crosses into the manifold. B6's absence costs *forensics*, not
containment.
- **It is the same failure class as H-11**, which PR-9 closed on the turn
spine: a guard that works correctly and leaves no trace of having worked.
A boundary that cannot say what it rejected cannot answer "is this input
shape common enough to support?" — which is exactly the question a widening
program (G-3) has to ask of its own refusals.
### What this table does not do
Per H-7's authority — *"documentation first; evidence decides whether code
follows"* — this is the evidence, not the fix. B6 is a hardening candidate for
a separate PR, sized against whether anything actually consumes gate-rejection
telemetry today. B1/B4/B5 are **closed as category differences** and should not
be re-derived as gaps by a future reader; that is what this table is for.
**AGENTS.md §"Security and trust boundaries" defaults**, checked against the
gate for completeness: explicit opt-in for arbitrary execution (n/a — the gate
executes nothing), reject unsafe paths before filesystem access (n/a — no
filesystem access), centralize safe display/log handling (met — the gate emits
no user-controlled text to logs), no hidden background execution (met), no
broad filesystem mutation (met — the gate mutates nothing).