From 8d2b56cc9a28ac2aca36bf8bd19e4cede94cad0f Mon Sep 17 00:00:00 2001 From: Timmy Date: Mon, 12 Oct 2026 07:18:42 +0000 Subject: [PATCH] queue: incident -- my own Q38 probe wrote the live snapshot; restored byte-exact; the guard admitted the writer 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 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; /root/crucible/verify-q31/snap-before.json and /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); no cp, nothing deployed, deployed bin unmoved. The hole. Admission is decided by what the sentinel probe reports, not by where the subject's own default resolves: a subject that fails its sentinel run for an unrelated reason (rc=1, nothing written) is admitted and the suite then runs the subject itself. Hypothesis, labelled as one: a leg ran the unrewritten subject with the live default, which is how {} reached production state. The fix 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. Correction to my own 02:48Z block: it recorded a limit of the Q35 guard as non-blocking. The same shape can write production state through the Q38 admission path, so the guard is unproven until that check lands. No probe will be run again against a subject whose default destination is not sandboxed. Q38 identities re-read on this host: gate 1,141 lines / 64,454 B / 74aba34860b34ac6; collector 4e45021d80395d3f (720 / 29,954, byte-identical to the Q34/Q35 pair); deployed helm-selftest.py 7ed1bca8f9da624f (609 / 33,647) and helm-collect.py ee0b36a82f23fcf3 (687 / 27,907) unmoved. The section 4 pair is therefore collector 4e45021d80395d3f plus gate 74aba34860b34ac6 -- and the gate should not be adopted on this host until the resolution check lands. --- WORK-QUEUE.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) 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.