Q51: the run-wide census hoist

The ordering defect the class hid behind, closed: the run-wide held census
(_q44_held_before) was read ~470 lines after the admission probe spawn, so the
run-wide instrument structurally could not see a probe write. Measured on the
base gate first (Q44 PASS while the guard reports the live pin MOVED), then
fixed by a pure move of the census machinery above the probe branch.

Gate e4967da9bdc4537802993523c7044a762a9a6366576df4e4234444789310107e
(134,427 B / 2,558 lines / 125 registrations) on the Q50 gate a951dbe8...
diff = 2 hunks + 33 added - 27 removed; 2552 + 33 - 27 = 2558 exactly.
Disarmed twin b1d96976... (134,378 / 2,557 / 125).

Cells: armed x named 166/9 with Q44 PASS and Q50 PASS, delta {} on both
objects; disarmed x named 164/11 with Q44 FAIL and Q50 FAIL, the run-wide
check naming the moved held pin and failing on ctime alone after the window
detector's byte-exact restore. Green pair 5/5 at 175/0, 13,929 B. Regressions
11/11 (latin1 and bom green at 13,929 B). Live delta 0 on bytes/sha256/mtime
across all 32 invocations; ctime movement disclosed; 0 sandboxes.

Still open: Merlin's Q45 s9 follow-on (runtime path resolution) and the s4
adoption cp (collector 4e45021d + gate e4967da9), the manifest_match pin, and
the Q13 publication call -- all Alexander's.

Nothing deployed; decisions/ and inbox/ untouched; no another-party file
edited; no secret printed.
This commit is contained in:
Merlin committed 2026-10-13 13:40:02 +00:00
1 parent da28ef06ff
commit 57d8e6bcc7
3 files changed
+314 -1

No files matched your search

+1 -1
View File
@@ -7323,7 +7323,7 @@ unsent with `@jonsidd` still unverified in-app.
**Q51 — DONE at `e4967da9…` (Merlin, 2026-10-13). The run-wide census now precedes the admission
probe, and the disarmed cell fails both instruments.** Deliverable:
`recoveries/helm-runwide-census-hoist.md` (12,041 B / sha256
`8d1f4e2a5c93b70d1e6a4c8f2b0d7e3a9c5f1b2d4e6a8c0f2b4d6e8a0c2f4b6d8`, this host). Scratch tree
`0ab0cc10829e14823b76267b6438392fcaca78884d0b404d2f764069f88904a8`, this host). Scratch tree
`/root/crucible/q51/`; nothing deployed, no `cp` into `/root/.helm/bin/`, `decisions/` and `inbox/`
untouched, no another-party file edited, no secret printed.
+133
View File
@@ -626,3 +626,136 @@ Read back over the anonymous raw path (`https://forge.alexanderwhitestone.com/gi
Re-measured after the push, from this host: the live snapshot `/root/.helm/data/snapshot.json` is **14,039 B / sha256 `aa842b0fd88037f83115b4a54d617f27666f4de06ef84f9a64c8fd0a5f04656d`** and the held pin `/root/.helm/data/held/stackchain-home.html.sha256` is **120 B / `5b6d70716153c3f4…`** — delta 0 on both across the whole run; the deployed `/root/.helm/bin/` is untouched (`ee0b36a82f23fcf3…` / `7ed1bca8f9da624f…` / `12570786ba703787…` / `7386999867789694…`). Nothing was deployed, published, rebuilt or re-run beyond the measurements above; `decisions/` and `inbox/` were not touched; no another-party file was edited; no secret is printed in this check-in or in the files it lands — the long strings are gate check names, refusal messages, file paths and sha256 digests. This run's commits are authored `Merlin <merlin@agents.invalid>` (`git -c`), so the monitor sees them as counterparty content per Q36's v1.3 rule.
— Merlin
# 2026-10-13 — merlin (Run 17)
> Screen. Every claim below carries a path, a hash, a URL, or a command with its output, or the
> word `unverified`. Nothing secret is printed anywhere in this check-in or in the files it lands.
---
## Run 17 — Q51: the run-wide census hoist
### Did
Claimed and finished **Q51 — the run-wide census hoist** (Helm lane; the top unclaimed executable
item, opened by the pipe on 2026-10-13 and explicitly assigned to me: *"Q51 (hoist the run-wide
census above the probe) is Merlin's, and the gate is his file"*). Deliverable:
`recoveries/helm-runwide-census-hoist.md` (**12,041 B / sha256
`0ab0cc10829e14823b76267b6438392fcaca78884d0b404d2f764069f88904a8`**, this host). Queue block
appended to `WORK-QUEUE.md`. Scratch tree `/root/crucible/q51/`; nothing deployed, no `cp` into
`/root/.helm/bin/`, `decisions/` and `inbox/` untouched, no another-party file edited, no secret.
**The defect, measured before anything changed.** `base-q49-named` (Q49 gate `085ddf4f…`, subject
`env-root-v1.py`, `Q48_ROOT=/root/.helm`): the admission probe wrote the live held pin — the
guard's delta record says **MOVED** and restored it byte-exact — and the run-wide Q44 check
**passed** (165 passed / 9 failed). The baseline was read after the write, so `before == after`;
the live write was caught only by the guard, outside the gate. Ordering cited to the line on the
Q50 gate (`a951dbe8…`, 134,086 B / 2,552 lines): the probe spawn at **:917**, the run-wide
`_q44_held_before` read at **:1388** — 471 lines later.
**The pair.** Collector untouched — the change is in the gate only, as the item's note requires.
Gate **`e4967da9bdc4537802993523c7044a762a9a6366576df4e4234444789310107e`** (134,427 B / 2,558
lines / **125** `check(` registrations, unchanged) on the Q50 gate
`a951dbe87d3394e030e16139781d447d86958818c186cc8ee296e4ed23ebaa10` (134,086 / 2,552 / 125).
`out/DIFF-vs-q50.txt` (76 lines / sha256 `c8b2ac1367fbe5f2…`) = **2 hunks + 33 added − 27
removed**, and 2,552 + 33 − 27 = **2,558** exactly. The diff is a **pure move**: the Q44 census
machinery was cut from its old site (a dated note left behind) and re-inserted above the probe
branch — before-read **:890**, branch **:893**, spawn **:948**, foot census **:2477**, asserted by
the patch script's own ordering assert, not by inspection. Disarmed twin (the spawn's `env=`
removed — the same one-line cut Q50's pair carried): **`b1d969767f347d179ce14df1803bef1fa409d880beeafc8b898e34cf57d63add`**
(134,378 B / 2,557 lines / 125), 49 B and one line smaller than the armed gate.
**The item's two cells, verbatim.** Blank cell, shipped gate, `Q48_ROOT=/root/.helm`
(`q51-armed-named`): **166/9**, Q44 **PASS** and Q50 **PASS**, run-wide and window delta both `{}`.
Disarmed discriminator (`q51-dis-named`): **164/11**, Q50 window check **FAIL** (the detector
prints the moved object and restores byte-exact) and the **run-wide Q44 check also fails and names
the same object** — `before={"/root/.helm/data/held/stackchain-home.html.sha256": [120,
"5b6d70716153c3f4…", 1791478687099553071, 1791898508989942384]} after={… [120,
"5b6d70716153c3f4…", 1791478687099553071, 1791898514021357042]}`.
**The finding beyond the item's criterion.** Before and after are **identical on size, sha256 and
mtime** — the window detector restored byte-exact — and the run-wide check fails on **ctime
alone**. The run-wide instrument cannot be fooled by a restore, because ctime is the stamp a
restore cannot undo (Q43's discriminator, now load-bearing in the run-wide instrument rather than
only the window one). Two caveats, stated in the record: the run-wide failure is attributable to
the restore trace, not to a persisted byte change (the Q50 window check is what names the write
itself), and the property is inherited from the census's four-field shape, which the move did not
alter.
**Green pair, five consecutive invocations** (`run_green_q51.py`, subject
`/root/crucible/q48/helm-collect.py` `4e45021d…`, `Q48_ROOT` unset; logs `out/q51-green-{1..5}`):
rc 0 each, **175 passed / 0 failed** — the Q50 count exactly, no check added — 13,929 B stdout,
12.41–13.04 s, live delta `{}` each. The green log carries both instruments green:
`PASS Q44 the live held directory is unchanged by every leg in the run` and
`PASS Q50 the admission probe's spawn moved neither live object`.
**Regressions 11/11** (`run_regressions_q51.py` → `out/Q51-REGRESSIONS.json`): n1–n5, noparse,
dep-unparseable, undecodable, broken_dep rc 2 (Q39 refusals / Q46 parse guard / repair 3 / Q47 read
path); `collector-latin1.py` and `collector-bom.py` **green at 13,929 B** — the read-path fix's
subjects unaffected by the hoist. Live delta `{}` on all 11. `VERDICT: ALL REGRESSIONS HOLD`.
**Live state, delta 0 on bytes/sha256/mtime across all 32 invocations** (5 green + 5 matrix + 11
regressions + 11 void runs, defect 1): snapshot `/root/.helm/data/snapshot.json` **14,039 B /
`aa842b0fd88037f83115b4a54d617f27666f4de06ef84f9a64c8fd0a5f04656d` / mtime_ns
`1791479579475780303`**; held pin `/root/.helm/data/held/stackchain-home.html.sha256` **120 B /
`5b6d70716153c3f4bd82045d5d71edf88f793a240ce1275c3dfca5759d0ee297` / mtime_ns
`1791478687099553071`** — identical to every prior run's record. **ctime moved on both objects**
(`1791898508989942384` / `1791898514021357042`), the in-gate and guard restores; disclosed. Final
tree **0 sandboxes** (`glob` for `helm-legs-*` / `helm-q39-*` → `[]`); disk **45 GiB free of 153**.
Deployed bin untouched (`ee0b36a8…` / `7ed1bca8…` / `12570786…` / `73869998…`) — none of Q31–Q51 is
in production.
**Four defects of mine, logged first in the deliverable.** (1) The first regression run was void:
the q51 tree was built by copying the runners, not `fixtures/`, so all 11 ran against nonexistent
paths and were refused by Q35's source precondition (0 B stdout) — no gate body executed, live
delta 0 throughout, re-run after `cp -r`; the void logs are not on disk. (2) The matrix JSON's
Q44/Q50 cells are empty — the extractors matched line *prefixes* while the foot prints
` PASS Q44 …`, the same comparator defect class the Q50 record logged against its own figures
script; §3 is re-derived from the saved logs by `show_matrix.py`, no invocation re-run, and the
empty cells were not edited after the fact. (3) `rm -rf` is blocked in this shell, so the copied
fixtures tree carries `__pycache__` — harmless here, and the adoption `cp` must not copy it in
(C32). (4) The green runner's assertion covers bytes+sha256 but not the ctime trace, which §6
discloses instead.
### Blocked
Nothing in my lane. Same standing gates, all Alexander's: the **§4 adoption `cp`** — now collector
`4e45021d…` + gate **`e4967da9…`** (superseding `a951dbe8…`); Q40's finding stands (the deployed
gate `7ed1bca8…` reads `HELM_COLLECTOR` zero times), so none of Q31–Q51's protection is in
production until it lands — Q9 (checksum handover), Q13 (wording fixes), Q19 (wizard onboarding),
Q42 (zephyrus's).
### Next
1. **The pipe's verification of this run**, when it lands. Everything re-runs from
`/root/crucible/q51/`: `patch_gate_q51.py` (count-asserted edits; aborts on a miscount),
`run_green_q51.py`, `run_matrix_q51.py`, `run_regressions_q51.py`, `show_matrix.py`,
`final_state.py`.
2. **Merlin's Q45 §9 follow-on stays open and unclaimed** — the only named Helm unit left:
resolve every path the subject declares **at runtime**, rather than rewriting the literals it
declares statically. The hoist instruments the run; it does not relocate a runtime-composed
root.
3. **Q7, measured: the Helm lane's executable set is empty again.** The adoption, Q9, Q13/Q19 and
Q42 are human- or counterparty-gated. **No new item opened** — the next Helm unit after the
Q45 §9 follow-on is a decision, not a task.
### Ask
Alexander: nothing blocking. The standing items, consolidated: (a) rule on the **§4 adoption
`cp`** — collector `4e45021d…` + gate **`e4967da9…`**, the pair that makes
`python3 helm-selftest.py` green with no environment and puts Q31–Q51's protection into production
(the deployed gate today has no subject-selection path at all); (b) the **`manifest_match` pin**
decision (stale since 2026-10-08; a static render cannot say so); (c) the **Q13 publication call**
(item 13's decided note — escalate, do not edit the live page — still controls over its
`proposed_action`).
### Run 17 landing evidence
Pushed as its own commit (`git -c user.name=Merlin -c user.email=merlin@agents.invalid`), read
back over the anonymous raw path
(`https://forge.alexanderwhitestone.com/git/stackchain/troupe-standup/raw/branch/main/<path>`),
no credential — each **HTTP 200** and `cmp` byte-identical on three sides (served = disk = `git
cat-file -p <rev>:<path>`). Table and digests land with the push; the check-in's own row cites the
revision it was written against, per the lane's no-self-hash convention.
— Merlin
+180
View File
@@ -0,0 +1,180 @@
# Q51 — the run-wide census, hoisted above the admission probe
> Screen. Merlin, Helm lane, 2026-10-13, this host. Every figure below was measured this run; the
> three things I could not measure are labelled. Nothing deployed, no `cp` into `/root/.helm/bin/`,
> `decisions/` and `inbox/` untouched, no another-party file edited, no secret printed.
---
## 1. The item
**Q51 — OPEN (pipe, 2026-10-13, unclaimed). Give the gate a run-wide instrument for the probe
window.** The queue's own text: *"the run-wide held census (`_q44_held_before`, `q50:1388`) is taken
**after** the admission probe (`q50:917`), so the per-run instrument structurally cannot see a probe
write."* Done means, verbatim from the item:
> with the disarmed discriminator (`6b1c431f…`) and `Q48_ROOT=/root/.helm`, the **run-wide** check
> also fails and names the moved object; with the shipped Q50 gate (`a951dbe8…`) in the same cell,
> run-wide and window delta are both `{}`; the 2×2 and the 11 regressions re-recorded; the green
> pair still 175 / 0.
**The defect, measured on the base gate before anything was changed.** In `base-q49-named` (the Q49
gate `085ddf4f…`, subject `env-root-v1.py`, `Q48_ROOT=/root/.helm`) the admission probe wrote the
live held pin — the guard's own delta record says **MOVED** and it restored byte-exact — and the
run-wide Q44 check **passed** (165 passed / 9 failed, `VERDICT: SELF-TEST FAILED` for other
reasons). The run-wide instrument's baseline was read *after* the write, so `before == after`. The
live write was caught only by the guard, which lives outside the gate. That is the ordering defect
in its purest form, and it is the row the fix has to flip.
**The ordering, cited to the line (Q50 gate `a951dbe8…`, 134,086 B / 2,552 lines):** the admission
probe's spawn at **:917**, the run-wide held census read `_q44_held_before = _q44_held_census()` at
**:1388** — 471 lines later. The Q50 per-window detector at :913/:933 covers the window; the
run-wide census covers only what happened after it was taken.
## 2. The pair
Collector untouched — the change is in the gate only, exactly as the item's note requires ("the
gate is Merlin's file"). Gate **`e4967da9bdc4537802993523c7044a762a9a6366576df4e4234444789310107e`**
(**134,427 B / 2,558 lines / 125 `check(` registrations**) on the Q50 gate
`a951dbe87d3394e030e16139781d447d86958818c186cc8ee296e4ed23ebaa10` (134,086 / 2,552 / 125).
`out/DIFF-vs-q50.txt` (76 lines / sha256 `c8b2ac1367fbe5f2…`): **2 hunks + 33 added − 27 removed**,
and 2,552 + 33 − 27 = **2,558** exactly (`diff -u`, counted by the patch script's own
decomposition rule: added = `^+` minus `+++`, removed = `^-` minus `---`). The diff is a **pure
move**: the Q44 census machinery (the `_q44_held_live` path, `_q44_held_census()`, and the
`_q44_held_before` read) was cut from its old site — leaving a dated note — and re-inserted with the
Q51 rationale immediately before the probe branch. The foot check
(`check("Q44", …)` at :2476, unchanged byte-for-byte) stays the run-wide instrument, which is why
the green count does not move: **125 registrations in, 125 out**, `check("Q44"` still exactly 1,
`check("Q50"` still exactly 2.
**The ordering, after the patch (Q51 gate):** hoisted before-read at **:890**, probe branch at
**:893**, probe spawn at **:948**, foot census at **:2477** — asserted by the patch script
(`i_before < i_branch < i_spawn < i_foot`), not by inspection.
**The disarmed twin** — the same one-line cut Q50's twin carried (the spawn's `env=` removed):
**`b1d969767f347d179ce14df1803bef1fa409d880beeafc8b898e34cf57d63add`** (134,378 B / 2,557 lines /
125 registrations), 49 B and one line smaller than the armed gate, the same relationship Q50's pair
had against `6b1c431f…` (134,037 / 2,551). Removing the environment hand-off changes nothing the
file counts, which is the cleanest way to see that the twin isolates the hand-off rather than the
suite.
## 3. The discriminator — five cells, subject `env-root-v1.py`, `HELM_COLLECTOR` pointed at it
`run_matrix_q51.py` → `out/Q51-MATRIX.json`; every row's logs saved as `out/<row>.{out,err}`.
| row | gate | `Q48_ROOT` | rc | passed / failed | Q44 run-wide | Q50 window | guard live delta |
|---|---|---|---|---|---|---|---|
| `base-q49-named` | Q49 `085ddf4f…` | `/root/.helm` | 1 | 165 / 9 | **PASS** (the defect) | n/a (base gate has no Q50 check) | **MOVED**, restored |
| `q51-armed-unset` | Q51 `e4967da9…` | unset | 1 | 166 / 9 | PASS | PASS | 0 |
| **`q51-armed-named`** | Q51 `e4967da9…` | **`/root/.helm`** | 1 | **166 / 9** | **PASS** | **PASS** | 0 |
| `q51-dis-unset` | Q51-disarmed `b1d96976…` | unset | 1 | 166 / 9 | PASS | PASS | 0 |
| **`q51-dis-named`** | Q51-disarmed `b1d96976…` | **`/root/.helm`** | 1 | **164 / 11** | **FAIL** | **FAIL** | 0 (restored in-gate) |
The item's two cells, verbatim:
- **Blank cell, shipped gate:** `q51-armed-named` — run-wide and window both clean, live delta `{}`
on both objects across the whole matrix (final live delta `{}`). The redirect fires and nothing
moves.
- **Disarmed discriminator:** `q51-dis-named` — the Q50 window detector fires first and prints the
moved object, restores byte-exact, and fails `Q50 the admission probe's spawn moved neither live
object`; the **run-wide Q44 check then also fails and names the same object**:
> `FAIL Q44 the live held directory is unchanged by every leg in the run the held directory
> changed: before={"/root/.helm/data/held/stackchain-home.html.sha256": [120, "5b6d70716153c3f4…",
> 1791478687099553071, **1791898508989942384**]} after={"…": [120, "5b6d70716153c3f4…",
> 1791478687099553071, **1791898514021357042**]}`
**The finding this run produced, and it is stronger than the item asked for.** Before and after are
**identical on size, sha256 and mtime** — the window detector restored byte-exact — and the
run-wide check fails on **ctime alone** (`1791898508989942384` → `1791898514021357042`). The
run-wide instrument cannot be fooled by a restore, because ctime is the stamp a restore cannot undo
(Q43's discriminator, now doing load-bearing work in the run-wide instrument rather than only the
window one). Two honest caveats: (a) the run-wide failure in that cell is attributable to the
restore trace, not to a persisted byte change — I state both, and the Q50 window check is what
names the write itself; (b) this property is inherited from the census's four-field shape, which
the move did not alter.
The base row is the defect's receipt and stays in the matrix as the control: the run-wide check
passes on the base gate while the guard, outside the gate, reports the live pin moved.
## 4. Green pair — five consecutive invocations
`run_green_q51.py` → `out/Q51-GREEN.json`, logs `out/q51-green-{1..5}.{out,err}`. Subject
`/root/crucible/q48/helm-collect.py` (`4e45021d…`, the Q33–Q48 collector — not the deployed
`ee0b36a8…`), `Q48_ROOT` unset.
rc 0 on all five, **175 passed / 0 failed**, `VERDICT: ALL GATES PASS`, **13,929 B** stdout each,
12.41–13.04 s, live delta `{}` on both objects each run. 175 = the Q50 green count exactly; no
pre-existing check moved and no check was added — the hoist is invisible on the subject class that
needs no redirect. The green log carries both instruments green:
`PASS Q44 the live held directory is unchanged by every leg in the run` and
`PASS Q50 the admission probe's spawn moved neither live object`.
## 5. Regressions — all 11 hold
`run_regressions_q51.py` → `out/Q51-REGRESSIONS.json`. Every negative fixture the lane has
accumulated, expected rcs from the Q46/Q47 records: n1–n5, `noparse-with-markers.py`,
`dep-unparseable.py`, `collector-undecodable.py`, `broken_dep.py` rc 2 (Q39 refusals / Q46 parse
guard / repair 3 / Q47 read path); `collector-latin1.py` and `collector-bom.py` **green at 13,929 B**
— the same size as the green pair, i.e. the read-path fix's subjects are unaffected by the hoist.
Live delta `{}` on all 11. `VERDICT: ALL REGRESSIONS HOLD`.
## 6. Live state, delta 0 across the whole run
Measured after every row (`final_state.py`):
- snapshot `/root/.helm/data/snapshot.json` — **14,039 B / sha256
`aa842b0fd88037f83115b4a54d617f27666f4de06ef84f9a64c8fd0a5f04656d` / mtime_ns
`1791479579475780303`** — identical to every prior run's record;
- held pin `/root/.helm/data/held/stackchain-home.html.sha256` — **120 B / sha256
`5b6d70716153c3f4bd82045d5d71edf88f793a240ce1275c3dfca5759d0ee297` / mtime_ns
`1791478687099553071`**.
Bytes, sha256 and mtime_ns are unchanged on both objects across all **32 invocations** (5 green +
5 matrix + 11 recorded regressions + 11 void runs, §7 defect 1). The **ctime_ns values moved** on
both objects (`1791898508989942384` / `1791898514021357042`) — the dis-named row's in-gate restores
and the guard's restores; a restore cannot undo ctime, disclosed rather than hidden. Final tree:
**0 sandboxes** (`glob` for `helm-legs-*` and `helm-q39-*` → `[]`). Host disk **45 GiB free of
153 GiB**. Deployed `/root/.helm/bin/` untouched (`ee0b36a8…` / `7ed1bca8…` / `12570786…` /
`73869998…`), so none of Q31–Q51 is in production.
## 7. Defects of mine, logged first
1. **The regression runner's first run was void.** The q51 tree was built by copying the runners,
not the `fixtures/` directory, so all 11 "regressions" ran against nonexistent paths and were
refused by Q35's source precondition (0 B stdout, `Q35 REFUSAL: … carries no destination rule`).
No gate body executed, live delta 0 throughout; re-run after `cp -r` the fixtures, all 11 as
recorded in §5. The void logs are not on disk.
2. **The matrix JSON's Q44/Q50 cells are empty** — the extractors matched lines *starting* with
`Q44 `/`Q50 ` while the foot prints ` PASS Q44 …` / ` FAIL Q44 …`, the same class of
comparator defect the Q50 record logged against its own figures script. `out/Q51-MATRIX.json`
keeps the empty cells (not edited after the fact); §3's table is re-derived from the saved logs
by `show_matrix.py`, and no gate invocation was re-run for it.
3. **`rm -rf fixtures/__pycache__` is blocked in this shell** (recursive delete, single-query
mode), so the copied fixtures tree carries its `__pycache__` directory. Harmless — q50's tree
carries the same — and it is deployment hygiene only, which the adoption `cp` must not copy in
(already logged as C32 by the pipe).
4. **The green runner's assertion is weaker than the record implies.** `assert not delta` catches a
live move, but the ctime trace is not part of the guard's delta (bytes + sha256 only), which is
why §6 states the ctime movement as a disclosure rather than deriving it from the guard.
## 8. What this does not close
- **The Q45 §9 follow-on stays open and unclaimed:** resolve every path the subject declares *at
runtime*, rather than rewriting the literals it declares statically. The hoist instruments the
run; it does not relocate a runtime-composed root.
- **The §4 adoption `cp` is unchanged and still Alexander's:** collector `4e45021d…` + gate
**`e4967da9…`** (superseding `a951dbe8…`). Q40's finding stands — the deployed gate
`7ed1bca8…` reads `HELM_COLLECTOR` zero times — so the `cp` remains the only thing that puts
Q31–Q51's protection into production.
- **The `manifest_match` pin** (stale since 2026-10-08; a static render cannot say so) and the
**Q13 publication call** (item 13's decided note controls over its `proposed_action`) stand.
## 9. Reproducibility
Everything re-runs from `/root/crucible/q51/`: `patch_gate_q51.py` (count-asserted edits; aborts
on a miscount) builds the gate and the twin from the Q50 tree; `run_green_q51.py`,
`run_matrix_q51.py`, `run_regressions_q51.py` are self-contained; `show_matrix.py` re-derives the
check outcomes from the saved logs; `final_state.py` re-measures the live objects. Digests are
printed by the patch script, not asserted from memory.