From f9435c2a03f6bcbabd91883458c1b1fee24578a7 Mon Sep 17 00:00:00 2001 From: mos-dt-0 Date: Fri, 31 Jul 2026 19:20:05 -0500 Subject: [PATCH] =?UTF-8?q?docs(remediation):=20bank=20D-19=20=E2=80=94=20?= =?UTF-8?q?an=20integrity=20property=20that=20cannot=20exist=20at=20its=20?= =?UTF-8?q?specified=20layer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implementing the D-18 manifest hit CWE-345: manifest and marker share one same-UID writable tree, so that actor can regenerate both and pass. No local construction fixes self-authentication without a key outside its authority. The seat escalated rather than calling it tamper-resistant — the charter corollary working on its first real test. Ruling: Option A, scope AC2 to accidental/independent/stale mutation, retain the design. The undefendable boundary is not the weak link (same-UID write already owns the source, the tests, preflight.mjs and .husky); AC2 exists for the D-5 staleness class, against which the design works; and a real anchor arrives with the choke-point executor and PG spine, which verify outside the worktree's authority. Acceptable only with honest labelling: threat model verbatim in code and PR, the words tamper-proof/tamper-evident/secure barred there, scope carried in AC2's restatement, residual risk named as backlog, all controls kept RED-first. Generalizable: when a property cannot exist at the layer it was specified, implement what the layer can guarantee, state the boundary precisely, and record where the real guarantee comes from. A known gap written down is acceptable; a gap implied fixed is not. Co-Authored-By: Claude Opus 5 (1M context) --- docs/remediation/TASKS.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/docs/remediation/TASKS.md b/docs/remediation/TASKS.md index 1f7d5dd1..5d8d3c82 100644 --- a/docs/remediation/TASKS.md +++ b/docs/remediation/TASKS.md @@ -93,6 +93,45 @@ and must not be cited as merge evidence. Rely on reviewer clearance + real CI. Three independent live instances in a single session — format gate, agent context reset, queue guard — is the class confirmed, not anecdote. +### D-19 — an integrity property that cannot exist at the layer it was specified + +Implementing D-18's manifest, the seat + a Codex security review reached **CWE-345**: the symlink +manifest and the source-hash marker both live in the **same same-UID writable generated tree**, so an +actor with that UID can plant a rogue link, regenerate _both_, retain the fingerprint, and pass. **No +local cryptographic construction fixes self-authentication** without a key outside that actor's +authority; relocating the marker changes the path, not the authority. + +The seat **escalated rather than describing self-authentication as tamper-resistant** — the explicit +failure mode the charter corollary demands. That is the corollary working, on its first real test. + +**Ruling — Option A: scope AC2 to accidental / independent / stale mutation; retain the design.** +Rationale, recorded so it can be challenged: + +1. **The undefendable boundary is not the weak link.** An actor with same-UID write can already edit the + source, the tests, `scripts/preflight.mjs` itself, and `.husky/*`. If they have that, _nothing_ in the + local checkout is trustworthy — hardening the manifest buys no real security while **implying + protection that does not exist**, which is worse than the gap. +2. **What AC2 is actually for.** These checks exist because a five-month-stale `.next` produced 19 + phantom `TS2307` errors indistinguishable from real ones (**D-5**). That is staleness, drift and + foreign residue — and against that class the design demonstrably works. +3. **A real trust anchor arrives later, from this mission's own architecture.** An anchor must live + outside the actor's authority; for a fleet running as one user that means a separate service — + precisely the **choke-point executor + PG spine** of Builds 1–2, which verify outside the worktree's + authority. Hand-rolling key distribution for a local preflight now would duplicate that work badly. +4. Option C (structural policy, no manifest) is strictly worse — it cannot detect a **removed** expected link. + +**Option A is acceptable only with honest labelling**, or it becomes the disease it is meant to cure: +the threat model stated verbatim in the code _and_ the PR ("does **not** defend against same-UID write; +no local construction can"), the words _tamper-proof / tamper-evident / secure_ barred from that +context, the scope carried in AC2's restatement, the residual risk named as a backlog item pointing at +the spine work, and every existing control kept RED-first. + +**The generalizable rule.** When a required property **cannot exist at the layer where it was +specified**, the honest moves are: implement what the layer _can_ guarantee, **state the boundary +precisely**, and record where the real guarantee will come from. **A known gap that is written down is +acceptable; a gap that is implied fixed is not.** Silence here would have shipped a verification +artifact that verifies nothing — with a green to prove it. + ### D-18 — two pre-registered criteria were mutually unsatisfiable, discoverable only at implementation Implementing D-17's fix surfaced a conflict **between** pre-registered criteria: