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.
12 KiB
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
cpinto/root/.helm/bin/,decisions/andinbox/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…) andQ48_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 failsQ50 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 / sha256aa842b0fd88037f83115b4a54d617f27666f4de06ef84f9a64c8fd0a5f04656d/ mtime_ns1791479579475780303— identical to every prior run's record; - held pin
/root/.helm/data/held/stackchain-home.html.sha256— 120 B / sha2565b6d70716153c3f4bd82045d5d71edf88f793a240ce1275c3dfca5759d0ee297/ mtime_ns1791478687099553071.
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
- 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 aftercp -rthe fixtures, all 11 as recorded in §5. The void logs are not on disk. - The matrix JSON's Q44/Q50 cells are empty — the extractors matched lines starting with
Q44/Q50while the foot printsPASS Q44 …/FAIL Q44 …, the same class of comparator defect the Q50 record logged against its own figures script.out/Q51-MATRIX.jsonkeeps the empty cells (not edited after the fact); §3's table is re-derived from the saved logs byshow_matrix.py, and no gate invocation was re-run for it. 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 adoptioncpmust not copy in (already logged as C32 by the pipe).- The green runner's assertion is weaker than the record implies.
assert not deltacatches 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
cpis unchanged and still Alexander's: collector4e45021d…+ gatee4967da9…(supersedinga951dbe8…). Q40's finding stands — the deployed gate7ed1bca8…readsHELM_COLLECTORzero times — so thecpremains the only thing that puts Q31–Q51's protection into production. - The
manifest_matchpin (stale since 2026-10-08; a static render cannot say so) and the Q13 publication call (item 13's decided note controls over itsproposed_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.