docs(amd1213-d): D1 confirmed by existing controls; correct my own survey error

D1 is confirmed, not assumed. The controls exist and are strong: all ten
mutation seams table-driven with byte-for-byte restoration of six artifacts,
new-seat rollback leaving no residue, and ROLLBACK_INTEGRITY escalation across
three parent-substitution attacks with recovery evidence written.

This corrects a wrong finding of mine. I reported that eleven injectFailure
seams existed in production and zero tests used any of them, and that D1's
rollback path had never executed. The grep behind that searched for the
identifier `injectFailure` in the specs; the specs pass the injector as an
inline lambda, so the controls were present and the search could not see them.
I was one step from writing a duplicate spec. Recorded with the method note --
grep the production seam names, not the parameter name.

One narrow gap left standing rather than papered over: nothing asserts the
in-memory restoration of plan.managedLinks.links to manifestLinksBefore. The
filesystem is checked, the plan object is not. It matters only if a caller
reuses a plan after catching a failure, which nothing does today, so it is
defence-in-depth and is noted for when D2/D4/D6 are confirmed.

Remaining amendment item is now D2/D4/D6 confirmation; D3 and D5 are closed.

Commit-only per scrappy's controlling packet (comms 20260813T212447Z dc43de):
not pushed, PR #1213 not updated, nothing re-authored.
This commit is contained in:
2026-08-15 15:16:17 -05:00
parent be2d14fb6c
commit 5cce40ff8b
@@ -13,13 +13,42 @@ which understated progress by roughly two defects. Branch head `3667a7a7`.
| Defect | State | Evidence |
|---|---|---|
| D1 transactional rollback | Substantially implemented | `fleet-launch-command.ts` snapshots links before mutating, prepares the manifest, and has `injectFailure` seams at `prepare-manifest`, `write-manifest`, `close-manifest`, `rename-manifest`; restores `manifestLinksBefore` on failure |
| D1 transactional rollback | **Confirmed** — controls exist and are strong | see below; one narrow gap (in-memory link restoration unasserted) |
| D2 exact managed-link classes | Substantially implemented | classifier at `fleet-launch-command.ts:598-663`: exact resolved credential, direct one-component plugin/skill only, symlink target and ancestor rejected, `realpath` containment, duplicates rejected |
| D3 ambient-PATH executable resolution | **Closed** — executables `585dac7a`, environment `3667a7a7` | see below; one deliberate residual (HOME) |
| D4 config check/apply safety | Substantially implemented | `secure_dir` ancestor checks, `read_private` with `O_NOFOLLOW` + fstat, apply via mkstemp + fchmod 0600 + fsync + dev/ino re-check before `os.replace`, compatibility path separated |
| D5 bounded test seam | **Closed this pass** (commit `b91b702a`) | see below |
| D6 validate-by-path then exec-by-path | Substantially implemented | helper runs as a verified snapshot piped to `bash -s`, not executed by pathname; the same binding applied to the runtime in D3 |
### D1 — confirmed, and a correction to my own survey
I first reported that eleven `injectFailure` seams existed in production and **zero tests used
any of them**, and that D1's rollback path had never been executed. That was wrong. The grep
behind it searched for the identifier `injectFailure` in the specs; the specs supply the injector
as an inline lambda, so the controls were there and the search could not see them. Method note
for the next survey: grep the production seam names, not the parameter name.
The controls that exist, all in `fleet-launch-command.spec.ts`:
- **All ten mutation seams**, table-driven — `mkdir-seat`, `prepare-manifest`, `write-settings`,
`write-snapshot`, `credential-link`, `prune-link`, `install-link`, `write-manifest`,
`close-manifest`, `rename-manifest`. Each asserts byte-for-byte restoration of six artifacts
(settings bytes, settings mode, generated snapshot, manifest, credential symlink target, plugin
symlink target) plus the absence of the `.tmp` manifest.
- **New-seat rollback** — a failure on a seat the transaction itself created leaves no directory
and no residue.
- **`ROLLBACK_INTEGRITY` escalation** — three parent-substitution attacks (symlink swap, inode
replacement, rename away) each produce a typed refusal, leave an external sentinel untouched,
and write `.mosaic-fleet-launch-recovery.json`. A replacement of the transaction-created seat
is likewise refused rather than deleted.
That is a real RED→GREEN matrix, not an implementation read as done.
**Gap, narrow:** nothing asserts the in-memory restoration of `plan.managedLinks.links` to
`manifestLinksBefore` — the filesystem is checked, the plan object is not. It matters only if a
caller reuses a plan after catching a failure, which nothing currently does, so this is
defence-in-depth rather than a live defect. Worth one assertion when D2/D4/D6 are confirmed.
### D2 — one thing worth recording so it is not "fixed" later
The alias concern in the packet (`duplicates/normalization aliases`) is closed by strictness, not
@@ -156,9 +185,9 @@ skip. Falsified by inverting the guard's default to `!leaseEnforcementActivatabl
## Still open
- **D1/D2/D4/D6 need confirmation, not assumption.** They read as substantially implemented but I
have not run the packet's full RED→GREEN control matrix against each seam. This is now the
largest remaining item in the amendment.
- **D2/D4/D6 need confirmation, not assumption.** They read as substantially implemented but I
have not run the packet's full RED→GREEN control matrix against each seam. D1 is now confirmed
(see above), D3 and D5 are closed; these three are the remaining item.
- **D3's HOME residual** is routed to harness-homes (see above). It is stated, not engineered
around, and it does not belong to this branch.
- Required next evidence per the packet: all D1D6 observed RED→GREEN controls, framework-shell,