forked from mosaicstack/stack
docs(remediation): bank D-19 — an integrity property that cannot exist at its specified layer
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) <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
3b191b6b34
commit
f9435c2a03
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user