diff --git a/WORK-QUEUE.md b/WORK-QUEUE.md index 5492ddc..6134d24 100644 --- a/WORK-QUEUE.md +++ b/WORK-QUEUE.md @@ -5066,3 +5066,31 @@ Scratch tree `/root/crucible/q38/`; nothing deployed, nothing published; the sha guard protects the gate's legs, not a direct CLI run of a pre-gate collector (the Q35 limit, unchanged). - **Q7, measured:** the unclaimed executable set is unchanged and not empty — **Q37** (pipe tooling) is open. Nothing opened this tick beyond this item, which discharges Q36's candidate 2 on Alexander's direction. + +**Incident — my own Q38 probe wrote the live snapshot (restored byte-exact), and the behavioural guard admitted the +writer. 2026-10-12 07:18Z (control plane).** Logged and fixed in the same tick; the content came back from three +independent copies of the original digest. + +- **What happened.** My probe (`/tmp/hermes-probe/probe2.py`) ran the Q38 gate with a fake subject whose + `SNAPSHOT_PATH` is the live path, which writes `{}` there and exits 0. The gate returned **exit 0** with + `Q38 OK: the subject refused its sentinel destination (probe rc=1, sentinel written=False, live delta 0)` — and the + live snapshot became **2 B / `44136fa355b3678a…`** (the sha256 of `{}`), mtime_ns `1791789464458475582`. A subject + that writes the live default was therefore **admitted**, and the write landed inside the gate's own run while its + summary reported `live delta 0`. +- **Restore.** `/root/.helm/data/snapshot.json` is back to `aa842b0fd88037f83115b4a54d617f27666f4de06ef84f9a64c8fd0a5f04656d` + / 14,039 B / mtime_ns `1791479579475780303`, copied from `/root/crucible/q31/snap-before.json`; two further copies + (`/root/crucible/verify-q31/snap-before.json`, `/root/troupe-verify/q35/snap-before.json`) carry the identical + digest, so the restored bytes are not a single-point assumption. `os.utime` set both stamps to the original. The + public page was never touched (9,865 B, mtime `2026-10-11T08:57:14Z`), and no `cp` was made, nothing deployed, the + deployed bin unmoved. +- **The guard's hole, stated as observed plus one labelled hypothesis.** Admission is decided by what the *sentinel* + probe reports, not by where the subject's own default resolves. Observed: a subject that fails its sentinel run for + an unrelated reason (`rc=1`, nothing written to the sentinel) is admitted, and the suite then runs the subject + itself. Hypothesis, labelled: a leg ran the unrewritten subject with the live default, which is how `{}` reached + production state. The fix that closes it is the resolution check — refuse any subject whose default destination + resolves inside `/root/.helm/data/` — with the live snapshot's bytes **and** mtime re-read after every leg rather + than summarised once at the end. +- **Correction to my own 02:48Z block.** That block recorded a *limit* of the Q35 guard ("a comment defeats it") as a + non-blocking observation. This tick shows the same shape can write production state through the Q38 guard's own + admission path, so the limit is not cosmetic: the guard must be treated as unproven until the resolution check + lands. No probe should be run again against any subject whose default destination is not sandboxed.