Commit Graph
93 Commits
Author SHA1 Message Date
Merlin e1fbb14065 queue+record+checkin: G11 -- the pin pill that outlived its reading
The held pin f27326e8b13d1dec (pinned 2026-10-08T16:58:07.100Z) no longer
matches the live body (200 / 217,163 B / c34ae2c245117ca7), yet the
renderer's pill reads the frozen manifest_match field and prints a green
'match' beside 'not re-checked since' in a page whose own verdict pill
reads '0 green / 6 not green'. One renderer edit conditions the pill on
the reading's freshness (stale -> amber 'match (unverified)'; the fresh
branch is byte-identical), and gate G11 adds four checks on Q45S10+G10:
161,122 B / 3,053 lines / 135 registrations. Prediction stated before the
run and met: shipped 184/1 (G10's deployed-page row), twin 183/2.
Live delta 0 on bytes/sha256/mtime_ns/ctime_ns across all four objects;
sandboxes 0/0; HELM_COLLECTOR still 0, so nothing is in production.
Nothing deployed, no another-party file edited, no secret printed.
2026-10-14 16:13:15 +00:00
Merlin 8c3c7d58a6 queue+record, landing: Run 28's readback over the anonymous raw commit path -- all three rows 200, served = disk = git at 7af50b5
Readback by /root/crucible/q58/readback_r28.py, artifact out/R28-READBACK.json,
read_at 2026-10-14T13:28:12Z, revision 7af50b5, head_at_read 7af50b5, author
Merlin <merlin@agents.invalid>. All three rows HTTP 200, served = disk =
git cat-file -p 7af50b5:<path>:

  recoveries/helm-deployed-page-generation.md   9,953 B  bdd5fa1c03586c28...
  WORK-QUEUE.md                              1,067,607 B  a78cc8dff36908a5...
  checkins/2026-10-14-merlin.md                65,984 B  0af2ecd2aaaee0f0...

The landing delta is measured from git, not from the append script:
git diff --numstat 7af50b5^ 7af50b5 = 72/0 on the queue, 124/0 on the check-in,
149/0 on the record = 345 insertions, 0 deletions. The queue's byte delta is
1,062,291 -> 1,067,607 B = +5,316 against a block of 5,322 B; the 6-byte
difference is the block's leading newline-dash-dash-dash separator aligning with
the separator the parent already carried, which is also why git counts 72 added
lines rather than the block's own 74. Reconstruction verified byte-exact:
parent[:1060132] + block + parent[1060138:] == rev is True, so the pipe's
"Erratum, mine: the 13:09Z tick" block is intact and keeps its own separator. No
another-party content was clobbered.

ONE DEFECT OF MINE, logged in the check-in's landing block rather than smoothed:
the append script's printed before figure for the queue was 1,060,143 B against a
shared prefix of 1,060,132 B -- 11 bytes stale, because sha(QUEUE) and the later
QUEUE.read_bytes() are two separate reads and the pipe was writing the file
between them (its erratum is stamped 2026-10-14T13:26:06Z, after my 13:25:50Z
append and before my 13:27:05Z commit). The file content is correct and every
assertion that mattered was on bytes read once and written once; only the printed
diagnostic is stale. The git figures are the authoritative ones, and the check-in
was unaffected -- parent is a prefix of rev: True, residual 0 B, 124 lines =
numstat 124/0 -- because the pipe does not write my check-in. This is the
concurrent-writer form of Run 24's logged defect, not its unit form: the units
were bytes throughout.

Live state at the landing, unchanged: deployed page 9,865 B /
427b7b54c69b18d270288910fc810732463129f48ec4bdd7dbc75cdb22997ce4 / mtime_ns
1791709034017837233; snapshot 14,039 B / aa842b0fd880... / mtime_ns
1791479579475780303; held pin 120 B / 5b6d70716153c3f4... / mtime_ns
1791478687099553071. Deployed /root/.helm/bin/ untouched (ee0b36a82f23... /
5c67473d8928... / 7ed1bca8f9da... / 12570786ba70... / 738699986778...),
grep -c HELM_COLLECTOR = 0, so Q40 stands and G10 is not in production. Sandboxes
0/0 both ways. Disk 45 G avail of 154.

Append-only, trailing newline asserted on the written file: check-in 65,984 ->
69,697 B (+3,713, sha256 d1d616878ecbd269...). No another-party file edited,
decisions/ and inbox/ untouched, no secret printed.
2026-10-14 13:36:19 +00:00
Merlin 7af50b5bcd queue+record: G10 -- the deployed Helm page is a stale generation of the renderer, and the self-test cannot see it
The Helm's pinned site now reads HTTP 200 / 217,163 B / sha256 c34ae2c245117ca7...
while the held pin is f27326e8b13d1dec... pinned 2026-10-08T16:58:07.100Z, so
pin_matches_live_now is false. The deployed page /var/www/alexander-whitestone/helm/index.html
is 9,865 B / sha256 427b7b54c69b18d270288910fc810732463129f48ec4bdd7dbc75cdb22997ce4 / mtime
2026-10-11T08:57:14.017Z and renders a green "match" with no "as of" and no "not re-checked
since". The renderer carrying that fix is mtime 2026-10-11T11:12:43.756Z, 8,129.7 s later, and
the real snapshot through it (--out scratch --as-of 2026-10-14T00:00:00.000Z, rc 0) renders
11,798 B / sha256 f32191223931e74b... carrying "as of 2026-10-08T17:12:59.458Z . 5d 6h 47m ago
. not re-checked since". The fix exists, works, and was never deployed.

Why the self-test was green: helm-selftest.py:420-421 runs the qualifier check on a synthetic
fixture at a pinned clock (hr.SNAPSHOT = fp), and :422-425's "build_page() writes nothing"
only proves build_page did not overwrite production. Neither reads the deployed artifact --
the Q34/Q40 law in a new place: a gate that tests the producer cannot vouch for the artifact
in the document root.

The fix is gate G10, four checks, on Q45S10's c56230e5a075... (147,151 / 2,798 / 127):
helm-selftest-q58.py 153,469 B / sha256 3b98b62fa5c7ea626091f6d0f63566de79818ae414bcffe323dd1ddd53956158
/ 2,916 lines / 131 check(" registrations. Shipped (reads the live page): rc 1, 180 passed /
1 failed, stdout 15,055 B / e8304379529c4c83..., the one FAIL being "the deployed page carries
the manifest qualifier". Twin (the same gate with _g10_deployed repointed at a scratch
current-generation render, ast-asserted): rc 0, 181 passed / 0 failed, ALL GATES PASS, stdout
14,824 B / fe8c8c72825962d9.... Prediction stated before the run and met exactly -- a red row
that cannot go green would prove nothing.

Live state delta 0 across all four invocations on bytes + sha256 + mtime_ns: page 9,865 B /
427b7b54c69b18d2... / 1791709034017837233; snapshot 14,039 B / aa842b0fd880... /
1791479579475780303; held pin 120 B / 5b6d7071... / 1791478687099553071. Sandboxes 0/0 both
ways (shallow glob and recursive rglob). No --deploy anywhere in the G10 block. Deployed bin
unchanged, five digests re-read, grep -c HELM_COLLECTOR = 0 so Q40 stands and G10 is not in
production.

Two shipped runs are both 180/1 at 15,055 B while byte_stable_stdout reads false; the
difference is mkdtemp suffixes in the sandbox path the gate prints. The four G10 rows are
byte-identical across both runs, and normalising the four path patterns gives stdout sha256
1958d8212fa60e44... on both with residual differing lines 0.

Six defects of mine are logged first in the record: two claims in one cell (the first G10
check 3 asserted both the predicate's soundness and the finding, which would have made the
twin 180/1 and hidden the discriminator); a report filter written from memory
(startswith("PASS") never matches the two-space rendering -- the lane's own logged class
reproduced on a fresh artifact); a live-path assertion that fired on G5's read-only check and
then on G10's own comment; byte_stable_stdout: false reported as found with the cause
measured; ast.unparse's single quotes; and pathlib.Path in a gate that imports
from pathlib import Path.

No queue item was opened: the Helm executable set was empty at the start of the run (Q49's
"Status: open and unclaimed" at :6847 is stale -- this file's own hygiene ledger at :8026
records Q49 CLOSED), so the unit taken was the one defect the lane had measured and labelled
but never fixed. Owed to Alexander, both decisions rather than tasks: re-render and re-deploy
the Helm page, and the section-4 adoption cp of collector 4e45021d... + gate 3b98b62fa5c7ea62....

Append-only, prefix asserted on bytes before each write, trailing newline asserted on the
written files: queue 1,060,143 -> 1,065,465 B (+5,322, sha256 9f0a02b429eb7ed5...), check-in
58,536 -> 65,984 B (+7,448, sha256 0af2ecd2aaaee0f0...), record 9,953 B / sha256
bdd5fa1c03586c28.... No another-party file edited, decisions/ and inbox/ untouched, no secret
printed.
2026-10-14 13:27:05 +00:00
Merlin 3606d5f1b8 check-in: Run 27 readback -- both files re-fetched anonymously from the forge (no credential) and byte-identical to disk: checkins/2026-10-14-merlin.md 200 / 57806 B / sha256 7944230ef257922daa6e9b181ff300a6713c183d1638590780992d7c425be90f, replies/2026-10-14-to-merlin-52.md 200 / 5949 B / sha256 ab71ca7b76d4390d43d40a503967ad1371ae1404447fd97bdca3a95746223a2c; check-in 57806 -> 58536 B / +730, append-only with the prefix asserted on bytes before the write. Nothing deployed, no another-party file edited, no secret printed. Merlin <merlin@agents.invalid>. 2026-10-14 10:55:25 +00:00
Merlin 8efe67626b reply 52 (merlin) + check-in Run 27: reply 51's three open rows closed, the C2 coefficient corrected 72 -> 16 -- the rewritten tree path /root/crucible/q57/q56-plus-twelve is 34 chars against the baselines' 18, so the per-occurrence delta is 16 not 12; six occurrences per cell, 16 x 6 = 96 = the measured growth on both (shipped 14044 -> 14140, armed 14254 -> 14350, growth/occurrences = 16.0000, substitution LONG -> each cell's own root gives len(replaced)-len(orig) = 0 on both, so the tree path explains the growth completely); four fields fixed one value each in q57/fix_c2_r27.py, out/R25-C2-BYTES.json 1735 B 887578d0a2bf -> 1735 B 9fd5f1d23016 (predicted_growth per cell) and out/R25-C2.json 1274 B 366593fd8149 -> 1274 B 0c0b2cb65187 (shipped/armed_predicted), both 0 bytes across the edit because 72 and 16 are the same width so the digests are the evidence; growth 96/96, delta_orig/delta_long_tree 210/210, delta_portable true, gate digests cd43284ff009/c56230e5a075 and every byte count unchanged. The hyphenated check-ins/ subject has two loci, e388225 and 121da2f, both verified from git log. The 2b834d4 subject size restated (18527 at that commit, 13218 at its parent, blobs 4e3cca9cff / 4f53c93a70), the row reply 50 dropped. The :688 sentence scoped as an append (append-only): no Run-25 byte or digest was wrong -- only the paths and one coefficient; the record's :293 parenthetical survives. Two defects of mine logged first: the coefficient was a wrong figure that two replies quoted while grading harmless, and my first diagnostic grepped /root/crucible/q56 for the shipped cell whose root is /root/crucible/q55 (miscount; the diff_c2_bytes count of 6 was right). Attribution: commits carry -c user.name=Merlin -c user.email=merlin@agents.invalid per reply 47 section 4; author=merlin 87 at HEAD before this run. Live state re-measured unchanged: snapshot 14039 / aa842b0fd880 / mtime_ns 1791479579475780303 / ctime_ns 1791957230760646867; held pin 120 / 5b6d70716153c3 / mtime_ns 1791478687099553071 / ctime_ns 1791957230761646950 (both ctimes still the Run-24 guard-restore pair); deployed bin 5 files with HELM_COLLECTOR 0 so Q40 stands; disk 45 G avail of 154 (72 percent). Check-in append 52937 -> 57806 B / +4869, append-only with the prefix asserted on bytes before the write. No new item opened -- the Helm executable set is empty and the section 4 cp (collector 4e45021d + gate c56230e5a075) is Alexander's decision. Nothing deployed, no another-party file edited, decisions/ and inbox/ untouched, no secret printed. 2026-10-14 10:53:15 +00:00
Merlin ae25f89604 reply 52 (merlin) + check-in Run 27: reply 51's three open rows closed, the C2 coefficient corrected 72 -> 16 -- the rewritten tree path /root/crucible/q57/q56-plus-twelve is 34 chars against the baselines' 18, so the per-occurrence delta is 16 not 12; six occurrences per cell, 16 x 6 = 96 = the measured growth on both (shipped 14044 -> 14140, armed 14254 -> 14350, growth/occurrences = 16.0000, substitution LONG -> each cell's own root gives len(replaced)-len(orig) = 0 on both, so the tree path explains the growth completely); four fields fixed one value each in q57/fix_c2_r27.py, out/R25-C2-BYTES.json 1735 B 887578d0a2bf -> 1735 B 9fd5f1d23016 (predicted_growth per cell) and out/R25-C2.json 1274 B 366593fd8149 -> 1274 B 0c0b2cb65187 (shipped/armed_predicted), both 0 bytes across the edit because 72 and 16 are the same width so the digests are the evidence; growth 96/96, delta_orig/delta_long_tree 210/210, delta_portable true, gate digests cd43284ff009/c56230e5a075 and every byte count unchanged. The hyphenated check-ins/ subject has two loci, e388225 and 121da2f, both verified from git log. The 2b834d4 subject size restated (18527 at that commit, 13218 at its parent, blobs 4e3cca9cff / 4f53c93a70), the row reply 50 dropped. The :688 sentence scoped as an append (append-only): no Run-25 byte or digest was wrong -- only the paths and one coefficient; the record's :293 parenthetical survives. Two defects of mine logged first: the coefficient was a wrong figure that two replies quoted while grading harmless, and my first diagnostic grepped /root/crucible/q56 for the shipped cell whose root is /root/crucible/q55 (miscount; the diff_c2_bytes count of 6 was right). Attribution: commits carry -c user.name=Merlin -c user.email=merlin@agents.invalid per reply 47 section 4; author=merlin 87 at HEAD before this run. Live state re-measured unchanged: snapshot 14039 / aa842b0fd880 / mtime_ns 1791479579475780303 / ctime_ns 1791957230760646867; held pin 120 / 5b6d70716153c3 / mtime_ns 1791478687099553071 / ctime_ns 1791957230761646950 (both ctimes still the Run-24 guard-restore pair); deployed bin 5 files with HELM_COLLECTOR 0 so Q40 stands; disk 45 G avail of 154 (72 percent). Check-in append 52937 -> 57806 B / +4869, append-only with the prefix asserted on bytes before the write. No new item opened -- the Helm executable set is empty and the section 4 cp (collector 4e45021d + gate c56230e5a075) is Alexander's decision. Nothing deployed, no another-party file edited, decisions/ and inbox/ untouched, no secret printed. 2026-10-14 10:52:57 +00:00
Merlin e388225a9d helm: Run 26 landing evidence -- the anonymous raw-commit readback at 121da2ffad (check-ins/2026-10-14-merlin.md 50668 -> 52937 B). Both rows HTTP 200, served = disk = git cat-file -p 121da2ffad: recoveries/helm-discovery-channel-seed.md 22650 B / 35bdeec27f617cf1d6c50c94b902b0f944d1e32e32c1a99f5a498ece9bdb9ce8, check-ins/2026-10-14-merlin.md 50668 B / c35ffc5d808b5ab446c97a256f6de83884463ea18df8b0e75bcc6d5e3b8f1133 at 121da2ffad before this append; artifact out/R26-READBACK.json 674 B / 5613b686dbaa4d981f5b058fe9e1e16360fef5fe8460c8ade694e3a29dad7fab with its .sha256 beside it, host-local (0 paths under out/ in the tree). The check-in's own row defers to the next revision's read. Landing deltas git diff --numstat 2fe5d17 121da2ffad: 82 0 checkins/2026-10-14-merlin.md 56 0 recoveries/helm-discovery-channel-seed.md -- append-only, 0 deletions. The remote had advanced to 2fe5d17 (the pipe's Run-25 verification block) between bc95796 and this push; no conflict, no merge. Live state unchanged (snapshot 14039 / aa842b0f / mtime_ns 1791479579475780303 / ctime_ns 1791957230760646867; held pin 120 / 5b6d7071 / mtime_ns 1791478687099553071 / ctime_ns 1791957230761646950, the Run-24 guard-restore pair), deployed /root/.helm/bin/ untouched with HELM_COLLECTOR count 0 so Q40 stands, sandboxes 0, disk 45 G of 154. Nothing deployed, no another-party file edited, decisions/ and inbox/ untouched, no secret printed. 2026-10-14 08:40:32 +00:00
Merlin 121da2ffad helm: Run 26 -- reply 48's four citation corrections discharged (recoveries/helm-discovery-channel-seed.md 18527 -> 22650 B + section 9, check-ins/2026-10-14-merlin.md 45119 -> 50668 B + Run 26). The pipe's verification of Run 25 confirmed all four discharges on its own instrument and returned four citation corrections; each verified and fixed by measurement, none a figure and none moving a conclusion. C1: the lengthened test tree holds three files not two -- helm-selftest-q55.py 143389 / cd43284ff009, helm-selftest-q56.py 147151 / c56230e5a075, and Q34-NULL-EVIDENCE.txt 694 B / sha256 f46b2f3b677552d5f1417b9e3d848bba235cda4711cb1f0447efcde160fb788f, mtime 2026-10-14T08:13:32Z, written between the two re-run cells; the writer is the gate itself at helm-selftest-q56.py:2551 (_q34_dump = Path(__file__).resolve().parent / "Q34-NULL-EVIDENCE.txt"), which is the mechanical explanation for the artifact the pipe observed following the lane across q49/q55/q56; the 0-sandbox census is unaffected. C2: every out/ citation was one level off because Run 25's scripts wrote to the tree root while the prose kept Run 24's out/ form -- fixed by moving all eleven artifact files into out/ with every digest asserted unchanged by the move (out/R26-MANIFEST.json), so out/R25-MEASUREMENTS.json 2405 B / 111b949ffb8c, out/R25-C2.json 1274 / 366593fd8149, out/R25-C2-BYTES.json 1735 / 887578d0a2bf, out/R25-READBACK.json 1126 / 39803e50e668 and out/R25-READBACK-FINAL.json 869 B all resolve; no Run-25 figure was wrong, only the paths. C3: the landing block's read clocks are the artifacts' own fields -- 2026-10-14T08:23:20Z at revision 2b834d4 and 2026-10-14T08:31:19Z at 0c8aef5. C4: the one-byte landing figure is the bc95796 erratum, independently confirmed by reply 48's addendum. Live state unchanged and re-measured: snapshot 14039 / aa842b0fd88037f83115b4a54d617f27666f4de06ef84f9a64c8fd0a5f04656d / mtime_ns 1791479579475780303 / ctime_ns 1791957230760646867; held pin 120 / 5b6d70716153c3f4bd82045d5d71edf88f793a240ce1275c3dfca5759d0ee297 / mtime_ns 1791478687099553071 / ctime_ns 1791957230761646950, both ctime values the Run-24 guard-restore pair so nothing has written either object since; deployed /root/.helm/bin/ untouched with HELM_COLLECTOR count 0 so Q40 stands; sandboxes 0; disk 45 G of 154. Defects of mine logged first: the out/ citation regression, the unlisted "nothing else" sentence, and the clock approximation -- none touches a figure, digest, mechanism or verdict, and the section 4 adoption pair (collector 4e45021d + gate c56230e5a075) is untouched. No new item opened -- the Helm executable set is empty and the next unit is the cp decision, not a task. Nothing deployed, no another-party file edited, decisions/ and inbox/ untouched, no secret printed. Merlin <merlin@agents.invalid>, author=merlin = 86. 2026-10-14 08:39:19 +00:00
Merlin bc95796428 helm: Run 25 erratum -- the 0c8aef5 landing commit subject's byte figure is one byte wrong (checkins/2026-10-14-merlin.md 43636 -> 45119 B). The commit subject reads "41168 -> 43635 B"; the measured figures are 41168 -> 43636 B (+2468, sha256 7c054d2a652deca466a5bc4719654da03edd6ef999ad0da11712996457153556). A commit message cannot be edited, so the correction lives in the file. The one-byte figure is the only wrong number in this run's artifacts; every in-file figure reproduces from git and the scratch tree (the three landing digests decd3350585dd169 / 27cddb8dada786a3 / f1ceb4194839a90f, the byte sizes 18527 / 986844 / 41168, the numstat splits 11/0 + 105/0 + 71/0 = 187 insertions 0 deletions, the record's pre-append 13218 B / 83acffe0222d, and the C1/C2/C3 tables). Final readback at 0c8aef5 over the anonymous raw commit path (artifact out/R25-READBACK-FINAL.json sha256 4e9263a4039bb731c23a9e7679b9a6556c37f2943faef9a3ac4bbfcdd1b1d068, host-local, 0 paths under out/ in the tree): all three rows HTTP 200, served = disk = git cat-file. Live state unchanged (snapshot 14039 / aa842b0f / mtime_ns 1791479579475780303; held pin 120 / 5b6d7071 / mtime_ns 1791478687099553071), deployed /root/.helm/bin/ untouched with HELM_COLLECTOR count 0 so Q40 stands, sandboxes 0 in the q57 tree, disk 45 G of 154. Nothing deployed, no another-party file edited, decisions/ and inbox/ untouched, no secret printed. 2026-10-14 08:31:19 +00:00
Merlin 0c8aef5ae5 helm: Run 25 landing evidence -- the anonymous raw-commit readback at 2b834d4 (checkins/2026-10-14-merlin.md 41168 -> 43635 B). Read by /root/crucible/q57/readback_r25.py over https://forge.alexanderwhitestone.com/git/stackchain/troupe-standup/raw/commit/2b834d4/<path>, no credential; artifact out/R25-READBACK.json (1126 B / sha256 39803e50e6687939abaa86d26442ea3f9ba41f717afaa7a91263c90842a9a14b) with its .sha256 beside it, host-local (0 paths under out/ in the tree, E13's rule). All three rows HTTP 200, served = disk = git cat-file -p 2b834d4:<path>: recoveries/helm-discovery-channel-seed.md 18527 B / decd3350585dd169d78995fd08f4d1120394c884b764198bd419a4bb1cf4a265, WORK-QUEUE.md 986844 B / 27cddb8dada786a32e5b49275b05b96c303a9d35ce2fa642fcfd9606ba4572f6, checkins/2026-10-14-merlin.md 41168 B / f1ceb4194839a90f092517692062adb83da72cf091a6ccb4e2ae352b0ee2e048 at 2b834d4 before this append. The check-in's own row defers to the next revision's read (a file cannot cite its own post-append digest); the landing deltas are git diff --numstat a87745a 2b834d4 = 11/0 queue, 105/0 check-in, 71/0 record, 187 insertions 0 deletions, append-only asserted before the push. Provenance: this commit and 2b834d4 are authored Merlin <merlin@agents.invalid>, git log --author=merlin = 83 before this push asserted by the append script; 32ad55b and 50bf350 remain Timmy-authored and are not rewritten. Live state unchanged (snapshot 14039 / aa842b0f / mtime_ns 1791479579475780303; held pin 120 / 5b6d7071 / mtime_ns 1791478687099553071; ctime the disclosed guard-restore trace), deployed /root/.helm/bin/ untouched with HELM_COLLECTOR count 0 so Q40 stands, sandboxes 0 in the q57 tree, disk 45 G of 154. Nothing deployed, no another-party file edited, decisions/ and inbox/ untouched, no secret printed. 2026-10-14 08:29:36 +00:00
Merlin 2b834d4ce9 helm: Run 25 -- reply 47's corrections discharged by measurement (recoveries/helm-discovery-channel-seed.md 13218 B + record section 8, check-ins/2026-10-14-merlin.md + Run 25, WORK-QUEUE.md + Run 25 block). The pipe's Run-24 verification (a87745a) returned three corrections and one provenance defect; each re-measured from the git blobs and the scratch tree (/root/crucible/q57/), none accepted from the reply, all four confirmed. C1: the landing correction's character/byte pair is mispaired -- the queue at 8ba7c8e is 970138 B / 959834 chars (delta 10304) and at 32ad55b 978022 B / 967603 chars (delta 10419), so "978022 bytes = 959834 characters" pairs 32ad55b's bytes with 8ba7c8e's chars; the printed +7769 is the character delta, the byte delta is +7884; the named cause (len() of a decoded string) is right and the check-in's second pair (29217 B = 28840 chars) is correct as written. C2: stdout byte figures are a function of the gate's own directory length, coefficient measured not assumed -- both gates copied byte-identically into a tree whose full path is +16 per occurrence, the two green cells re-run rc 0 with 176/0 and 177/0 and live delta {}, each stdout grown exactly 96 B = 6 x 16, and len(replaced) - len(orig) = 0 after replacing every occurrence, so the tree path fully explains the growth; portable citations are the verdict, rc, suite counts, digest pair and the +210 B armed-vs-shipped delta (210 in both trees); tree-scoped are the raw 14044/14254; "byte-stable across all five" stands as written. C3: the 406212 B reclaimed has no derivation in its artifact -- out/Q56-CENSUS.json records one removed path with no byte count beside "reclaimed_bytes": 406212, so the sum of recorded per-path bytes is 0; restated, the removal is recorded and the figure is Testimony only. P: both Run-24 commits (32ad55b, 50bf350) are authored Timmy <timmy@stackchain.ai>, the clone's configured identity, because Run 24's append scripts carry no commit step; fixed prospectively -- this commit and every later one carries the Merlin identity, asserted by git log --author=merlin = 83 before the push; published history is not rewritten because both revisions are cited by the queue's Run-24 block and reply 47. Live delta 0 on bytes/sha256/mtime_ns/ctime_ns for both live objects (snapshot 14039 / aa842b0f / mtime_ns 1791479579475780303; held pin 120 / 5b6d7071 / mtime_ns 1791478687099553071); deployed /root/.helm/bin/ untouched with HELM_COLLECTOR count 0 so Q40 stands and none of Q31-Q45S10 is in production; sandboxes 0 in the q57 tree; disk 45 G of 154. No mechanism, digest, line count or verdict moves under any of the four corrections; the section 4 adoption pair (collector 4e45021d + gate c56230e5a075) is untouched. Two defects of mine logged first: the C2 coefficient (12 assumed, 16 measured -- the test tree was nested under q57/) and nothing else. No new item opened -- the Helm executable set is empty and the next Helm unit is the cp decision, not a task. Nothing deployed, no another-party file edited, decisions/ and inbox/ untouched, no secret printed. 2026-10-14 08:22:26 +00:00
Merlin 619a953f86 helm: Run 23 landing evidence -- readback at eec3ff3 over the raw COMMIT path, three rows served = disk = git (record 20820 / 8d67248f, WORK-QUEUE.md 962664 / 972efe4a, check-in 18265 / 45223797), artifact out/R23-READBACK.json 1229 B / sha256 9846ea9050802ca24d67a869e4facae7c750ee6a0bdbe3c8a9b07bd808372c18. The check-in's own row defers to the artifact because appending this block changes its digest; the artifact's revision field dates each row. Live state unchanged (snapshot 14039 / aa842b0f / mtime_ns 1791479579475780303; held pin 120 / 5b6d7071 / 1791478687099553071; ctime unmoved this run), deployed /root/.helm/bin/ untouched with HELM_COLLECTOR count 0 so Q40 stands, sandbox census 0 in the q55 tree, nothing deployed, decisions/ and inbox/ untouched, no another-party file edited, no secret printed. 2026-10-14 03:39:04 +00:00
Merlin eec3ff38e7 helm: Run 23 -- the record's four numbers corrected and the digests re-verified on disk (armed gate 143385 -> 143389 B, twin 143416 -> 143422 B, twin-armed 31 -> 33 B, insertion block +3020 -> +3024 B / +58 lines, and the differing line's identifier _q45S9_pwd_sites -> _q55_pwd_sites at :435/:442/:451 armed and :435/:451 twin; cause: the Q55 -> Q45S9 rename moved the bytes after the figures were taken and before the digests were computed, so the record paired a post-rename digest with pre-rename bytes). Both digests are unchanged -- armed cd43284ff009d1cceb3aaa6a65b701d1076eaf801e32b705672601b4122b746a, twin 8adad99bdc872ecd09ddea88ae55b5fc55a3886571ffaa5f49a053b52430586d, both 2735 lines / 126 registrations -- so the section 4 adoption cp pair (collector 4e45021d + gate cd43284f) is sound and needs no re-cite. Gate re-run once on the real collector: rc 0, 176 passed / 0 failed, ALL GATES PASS, 14044 B stdout / sha256 585e0e4b0508b565a18ca52cde3c464b9f92673b8fad538a12a33fd8a07131c1 / 1216 B stderr / 12.2 s, PASS Q52 present, live delta {} on bytes/sha256/mtime_ns/ctime_ns for both live objects. Reply 45 section 5.1 closed: the c4addca readback is now durable because readback_r23.py reads /raw/commit/<rev>/<path> -- 6 rows across c4addca and b31c727, all 6 served = git, the record byte-identical at both revisions (14808 / d4c381f7). Deliverables append-only with the anchor count and the trailing newline asserted on the written file: recoveries/helm-pwdir-channel-refusal.md 14808 / d4c381f7 -> 20820 / 8d67248f (+6012 B), checkins/2026-10-14-merlin.md 10499 / eae1c6b2 -> 18265 / 45223797 (+7766 B), WORK-QUEUE.md 957453 / d60d6dee -> 962664 / 972efe4a (+5211 B). One defect of mine logged: run23_verify.py's first Q52 filter used startswith("PASS Q52") and never matched the two-space rendering -- the lane's own logged defect, reproduced on a fresh artifact and fixed before the run was recorded. No new item opened (Q42 zephyrus's, Q52 Mercury's, Q53 Alexander's; the Helm executable set is empty by both this lane's and the pipe's measurement). Nothing deployed -- HELM_COLLECTOR count 0 in /root/.helm/bin/helm-selftest.py, so Q40 stands; decisions/ and inbox/ untouched, no another-party file edited, no secret printed. 2026-10-14 03:38:35 +00:00
Merlin 8d105e9dab helm: Run 22 landing fill -- the c4addca readback, three rows served = disk = git, check-in 9,279 B / 2d815c65... at that revision 2026-10-14 01:31:51 +00:00
Merlin c4addca3ce helm: Run 22 -- the Q45 s9 pwd channel closed (a home-database read the redirect cannot reach, refused at admission)
Deliverable recoveries/helm-pwdir-channel-refusal.md (14,808 B / sha256
d4c381f713e9fe95beefbd14a93220ab4049625f280c116e656419f3e11b7b89) plus the queue block at the foot
of WORK-QUEUE.md (+5,419 B / 63 lines, 951,756 B / d8f54086edbcbbc96e39533d7b6dcf0e9effff108b596ed18685b03d1045e1db)
and checkins/2026-10-14-merlin.md (Run 22). Scratch tree /root/crucible/q55/; nothing deployed, no cp
into /root/.helm/bin/, decisions/ and inbox/ untouched, no another-party file edited, no secret printed.

The class, measured on the shipped Q52 gate before the change: a subject whose root is composed from
the user database (ROOT = Path(pwd.getpwuid(os.getuid()).pw_dir) / ".helm") resolves the live root
under a scratch HOME (rc 0, both fixtures), passes the Q52 home-channel check (the check asserts the
legs' HOME is redirected; pwd.getpwuid never reads HOME), and writes the LIVE held pin through the
gate's own --q52-witness flag (5b6d7071... -> fdd45f74..., restored byte-exact by the guard). A foot
check reports after the legs; only a precondition refuses before them.

The fix: gate cd43284ff009d1cceb3aaa6a65b701d1076eaf801e32b705672601b4122b746a (143,385 B / 2,735
lines / 126 registrations -- unchanged; +3,020 B / +58 lines on the Q52 gate 78b290ec...) -- a
precondition after Q46's parse guard, before the Q39 sandbox, the admission probe and any leg: a
subject whose AST reads the pwd module is refused (exit 2, dated, naming every pwd site with its
line). Disarmed twin 8adad99bdc872ecd09ddea88ae55b5fc55a3886571ffaa5f49a053b52430586d.

25 guarded cells: armed x pwr/pwr-witness/pwn rc 2 refusal (stdout 0 B, live delta {}); disarmed x
pwr-witness reproduces the escape (live pin 5b6d7071... -> ced810a9..., restored byte-exact);
disarmed x pwr 175/1 with Q52 PASS and Q45 FAIL (the shipped behaviour); green pair x5 176/0 at
14,044 B; regressions 11/11. Covered shapes are not over-refused: the witness pin lands inside the
sandbox, and the covered fixtures fail Q43 identically under the shipped gate (measured side by side).

Live delta 0 on bytes/sha256/mtime across all 25 cells (snapshot aa842b0f... / 14,039, pin
5b6d7071... / 120); ctime moved on the pin across the deliberately-live witness cells (guard restores)
-- disclosed. Sandboxes: q55 tree 0/0; the E14 leak re-measured at 26 across /root/crucible and all
26 removed (842,401 B reclaimed) with the q55 __pycache__. Deployed /root/.helm/bin/ untouched,
HELM_COLLECTOR count 0 -- Q40 stands. Disk 45 G avail of 154.

Adoption, Alexander's: the s4 cp is collector 4e45021d... + gate cd43284ff009..., superseding
78b290ec... / e4967da9... / a951dbe8.... Five defects of mine are logged first in the deliverable
(part 1's void d/e rows, its prefix-vs-full restored comparison, its broken Q45 filter, my assumed
d/e expectation, and the gate's first-written Q55 label). No new item opened -- the Helm lane's
executable set is empty; the next unit is a decision, not a task.
2026-10-14 01:31:30 +00:00
Merlin a41f0b97ec helm: Run 21 landing evidence -- three-way readback at 258e3ad, and the clock correction the run's own Screen line needed
The fill for Run 21 (content at 258e3ad). Read back over the anonymous raw path at
revision 258e3ad by /root/crucible/q54/readback_q54.py (artifact out/Q54-READBACK.txt,
398 B, mtime 2026-10-13 23:04:19.489552154Z, host-local): record 200 / 34,311 /
4ba00ce427b85079adedf34524c8334a92e949b205efcc682c8cdd47a99a1cd7, queue 200 / 935,526 /
c5316986a532ce2ba4c479e89b0a4839c7bcd6e6c613d859511616b9fb7323e0, check-in 200 / 94,099 /
1da711a046950f73979bfaa52fe04479c76cbd573ba1421c937d3f53dd8d4ba7 -- all three
served = disk = git, all newline-terminated, ALL ROWS EQUAL.

Clock correction, appended not edited in place: the Run-21 blocks cite "~21:2xZ",
which no instrument supports. The Run-21 content commit 258e3ad was made at
2026-10-13T23:03:50Z (git log -1 --format=%cI) and the readback artifact at
23:04:19.489552154Z. The cite was assumed from reply 42's 21:07Z timestamp rather than
measured -- the same defect class as reply 42 section 1, reproduced by this run's own
Screen line and corrected here.

Live and deployed unchanged across the whole run: snapshot 14,039 B / aa842b0fd880 /
mtime_ns 1791479579475780303; held pin 120 B / 5b6d70716153 / mtime_ns
1791478687099553071; deployed bin ee0b36a8 / 5c67473d / 7ed1bca8 / 12570786 / 73869998
with grep -c HELM_COLLECTOR = 0 on the gate (Q40 stands, nothing of Q31-Q45s9 in
production); disk 45 G avail of 154; worktree clean.

Read-only run: no gate invocation, no live write, no deployment, no edit to another
party's file, decisions/ and inbox/ untouched, no secret printed.
2026-10-13 23:05:10 +00:00
Merlin 258e3ad121 helm: Run 21 -- reply 42's three sentences discharged against my own records
The three sentences replies/2026-10-13-to-merlin-42.md (1b16385) returned against
Run 20's closing note, each re-measured from git with a non-stripping reader
(measure2.py) and cross-checked with sha256sum:

1. Both readback clocks were wrong: readback.py ran at 20:45:43.513552892Z (not
   ~21:0xZ) and readback_final.py at 20:52:18.142200548Z (not ~21:2xZ); cfae76a
   was committed 20:51:49Z, 29.1 s before readback_final.py existed, so the
   closing note cites a readback that postdates its commit. The note's table is
   sound (cf07003 digests); the clock sentences and the readback description are
   the defect.
2. Row 3's equality: the per-revision census shows record and queue byte-identical
   across cf07003->cfae76a (34,311 / 4ba00ce4, 927,009 / 7754184c, both 0x0a);
   the check-in is 83,854 / 4306bc50 at cf07003 and 85,869 / a1f3ad72 at cfae76a,
   which is what disk and branch/main serve. The table row is right; the sentence
   above it needs the per-row revision.
3. Three of three, confirmed: at 7673477 all three files end 0x29 (31,219 /
   925,786 / 82,262); dc3c2f7 terminated queue+check-in, cf07003 the record
   (+22/-1 on the record alone), cfae76a the check-in's closing note (+33).
4. The queue close block's undated 927,009 is cf07003's reading; the queue at HEAD
   1b16385 is 933,092 / 114d937e.

Own defect logged first: the take-1 instrument (measure_r42.py) .strip()ed its
captures, so its digests were computed over stripped content; measure2.py is the
authority and the record is sound.

Queue hygiene appended: four "open and unclaimed" status lines name closed items
(Q21, the Q13 fix pack, Q49, Q51); the DONE blocks below them govern.

Read-only run: no gate invocation, no live write, no deployment, no edit to
another party's file, decisions/ and inbox/ untouched, no secret printed.
Live and deployed unchanged: snapshot aa842b0f / 14,039, pin 5b6d7071 / 120,
HELM_COLLECTOR 0 in every deployed file, disk 45 G of 154.
2026-10-13 23:03:50 +00:00
Merlin cfae76ac47 helm: Run 20 closing note -- the final revision is cf07003, read back three ways
Names the three commits that carry this unit (7673477 corrections +307/-0, dc3c2f7
landing evidence and E17 +76/-2, cf07003 E18 +22/-1) and the final readback at
cf07003: all three rows HTTP 200 and served = disk = git cat-file -p cf07003:<path>,
each newline-terminated -- record 34,311 B / 4ba00ce427b85079..., queue 927,009 B /
7754184c5368..., check-in 83,854 B / 4306bc5035ed... The record's digest is the same
value E18 carries, so the two rows agree rather than one chasing the other; the check-in's
own row is dated at cf07003, the revision before this append, and is not restated.

out/ artifacts (Q53-MEASUREMENTS.json, Q53-READBACK.txt, Q53-READBACK-FINAL.txt) are
host-local and not forge-verifiable -- 0 paths under out/ in the tree, raw path 404 --
E13's rule applied to this run's own artifacts.

Nothing deployed, no cp into /root/.helm/bin/, decisions/ and inbox/ untouched, no
another-party file edited, no secret printed. Live state delta 0 across every measurement:
snapshot 14,039 B / aa842b0fd88037f8... / mtime_ns 1791479579475780303 / ctime_ns
1791907371554631194; held pin 120 B / 5b6d70716153c3f4... / mtime_ns
1791478687099553071 / ctime_ns 1791907371554631194. Deployed bin untouched
(ee0b36a82f23, 5c67473d8928, 7ed1bca8f9da, 12570786ba70, 738699986778), HELM_COLLECTOR
count 0 -- Q40 stands, so none of Q31-Q45s9 is in production. df -h / -> 46 G avail of
154, 71 % used. Sandbox census in the q53 tree 0; E14 records the 26 elsewhere under
/root/crucible.
2026-10-13 20:51:49 +00:00
Merlin cf07003903 helm: Run 20 E18 -- the E17 append reproduced the very defect E17 describes
Found by readback_final.py's per-row trailing-newline flag, not by inspection: at
dc3c2f7 the queue and the check-in both read True and the record read False, because
fix_newline.py's own E17 literal ends with the signature and no newline -- so the append
written to log the defect re-introduced it on the record. Fixed by writing one newline
byte; no line of content moved. Record 33,064 B / cfb71db33761... -> 34,311 B /
4ba00ce427b85079adedf34524c8334a92e949b205efcc682c8cdd47a99a1cd7, +22/-1 (the -1 is the
newline E17 itself dropped).

The lesson is stronger than E17's rule and is stated in E18: a trailing newline is not a
property you get from writing head + sep + tail + addition, because the ADDITION has to
end with one. The assertion belongs on the written file -- assert the bytes end with a
newline after every append, or print the flag per readback row -- not on the helper's
intent. Both instances are measured in E18 and neither is deleted.

Nothing deployed, no cp into /root/.helm/bin/, decisions/ and inbox/ untouched, no
another-party file edited, no secret printed. Live state unchanged: snapshot 14,039 B /
aa842b0fd88037f8... / mtime_ns 1791479579475780303, held pin 120 B / 5b6d70716153c3f4...
/ mtime_ns 1791478687099553071, ctime_ns 1791907371554631194 on both; deployed bin
untouched, HELM_COLLECTOR count 0.
2026-10-13 20:50:05 +00:00
Merlin dc3c2f7548 helm: Run 20 landing evidence + E17, the newline defect my append helper introduced
Landing evidence for Run 20, read back over the anonymous raw path at ~21:0xZ,
instrument /root/crucible/q53/readback.py. All three rows HTTP 200, served = disk =
git cat-file -p 7673477:<path>:
  recoveries/helm-home-channel-guard.md  31,219 B / 0f8b7f1617a67f5e8308e85b837e3256d74949080750dbabacc0f09f106464fa
  WORK-QUEUE.md                         925,786 B / 78feb8441d8f01183c5f57c7248366400d7f5d5720bf3b8a10d12c37b73a2c11
  checkins/2026-10-13-merlin.md          82,262 B / 9db0834471415e3a6a4d1844910a8f21d3a558305b9a69ea08785b8ec0bcda94
The check-in row is that file at 7673477, before this append -- a file cannot cite its
own post-append digest, so the row is dated rather than chased. out/Q53-MEASUREMENTS.json
and out/Q53-READBACK.txt are host-local and not forge-verifiable: 0 paths under out/ in
the tree at 7673477, raw path 404 -- E13's own rule applied to this run's artifacts.

E17, found on my own tool before this commit: q53/append.py's append_last() wrote
head + sep + addition and never wrote tail back, and tail was the file's single trailing
newline, so the record, the queue and the check-in each lost it. Measured by
git diff --numstat: the Run-20 append read 16/0 on the queue and 159/0 on the record
(clean), then 19/1 and 28/1 once the landing appends ran -- the 1 in each being the
dropped newline, not a content edit. Restored by writing one newline byte to each file
(WORK-QUEUE.md 927,008 -> 927,009 B; the check-in 83,853 -> 83,854 B); no line of
content moved. It matters beyond hygiene because this lane's readback discipline compares
served = disk = git cat-file byte for byte, so a lost trailing newline is a real delta an
outside reader would have to explain. The rule: write head + sep + tail + addition, and
assert tail is whitespace-only before dropping it -- the count(anchor) == 1 discipline
extended to the tail.

Nothing deployed, no cp into /root/.helm/bin/, decisions/ and inbox/ untouched, no
another-party file edited, no secret printed. Live state unchanged: snapshot 14,039 B /
aa842b0fd88037f8... / mtime_ns 1791479579475780303, held pin 120 B / 5b6d70716153c3f4...
/ mtime_ns 1791478687099553071, ctime_ns 1791907371554631194 on both; deployed bin
untouched, HELM_COLLECTOR count 0 -- Q40 stands, so none of Q31-Q45s9 is in production.
2026-10-13 20:47:42 +00:00
Merlin 7673477003 helm: Run 20 -- the four corrections replies 38/39/40 returned are discharged
Append-only: E10-E16 in recoveries/helm-home-channel-guard.md (21,230 B /
953ea1a14c5fa49b... -> 31,219 B / 0f8b7f1617a67f5e..., +159/-0) and a Run-20 block in
WORK-QUEUE.md (919,333 B / c5fa27ea61cf43de... -> 925,786 B / 78feb8441d8f01183...,
+16/-0). Scratch tree /root/crucible/q53/; read-only, no gate invocation, no live write,
nothing deployed, no cp into /root/.helm/bin/, decisions/ and inbox/ untouched, no
another-party file edited, no secret printed.

Measured this run, not accepted:
- E10 (reply 38 s1, upheld): E4's legs-caller row said :1160; grep -n
  '_q50_rebuild_env(' helm-selftest-q52.py gives :815 def, :977 probe caller, :1162 legs
  caller. :1160/:1161 are the two comment lines above it -- a comment read as code. The
  record's own s2 cite was right; the erratum's cell was the defect.
- E11 (reply 38 s2 / reply 39 s0, restated scoped and dated): the command as written,
  grep -rn 'caff1f504855264a' /root/crucible/q52/, returns 9 lines in 8 files at 20:5xZ
  (run19_append_record.py 2, the other seven 1 each); out/ returns 0 (rc 1); the repo
  tree at HEAD returns 15 lines in 6 files. The 3 is a Run-18-era reading of the three
  scratch prose files it names, 1 each, stale because Run 19's own five scripts quote the
  string. Finding unchanged: the figure stays unverified; direction Corroborated by
  out/Q52-MATRIX.json's two guard_restored rows with final_live_delta {}.
- E12 (reply 40 s2): the landing block's readback clock is 18:30:31Z, not 18:31:0xZ.
  out/Q45S9-RUN19-READBACK.json (1,686 B / ccec083ce40f...) records read_at
  2026-10-13T18:30:31.084749+00:00, revision 068ac5f, epoch 1791916231.084749. A +/-360 s
  band census reproduces the pipe's supporting measurement to the millisecond: next
  write after the read is run19_append_landing.py at +160.699 s = 18:33:11.78Z.
- E13 (reply 40 s3): the readback artifact is host-local, not forge-verifiable --
  git ls-tree -r --name-only HEAD gives 244 paths, 0 under out/, no worktree out/, and
  the anonymous raw path returns HTTP 404 (11 bytes). Stated as a property of the lane:
  every out/*.json across Q31-Q45s9 is host-local.

Two findings of my own, from re-reading rather than from being told:
- E14: the sandbox census is tree-scoped. E7's "both ways -> [] / []" is true of the q52
  tree; the recursive census over /root/crucible is 26 -- 19 helm-legs-* (q43 x1,
  q43/variants x2, q43z/variants x1, q44 x2, q45/variants x13) and 7 helm-q39-* (q48).
  The skill's own logged lesson applied to my own record.
- A sixth line-citation defect: E4's --q52-witness row puts the section comment at
  :1261; grep -n gives :1262 (comment) and :1270 (flag test).

E15 re-derives, measured not accepted: gate 78b290ecf2d93e0c... 140,365 B / 2,677 lines
/ 126 check(; disarmed twin be7b306a... 140,390 B; _q52_home_sites :758;
_q50_rebuild_env :815; probe caller :977; check("Q52", ...) :1205;
out/Q52-MATRIX.json 12,308 B / 75bd624e... at 2026-10-13T16:02:51+0000;
out/q52-dis-check.out 191 lines, 174 passed / 2 failed, FAILs at :186 (Q52
home-redirect) and :187 (Q45 module-constant, HELM_HOME /root/.helm and HELD_DIR
/root/.helm/data/held escaping the cut redirect) -- E3 re-derives exactly.

Live delta 0 on bytes/sha256/mtime_ns across every measurement: snapshot 14,039 B /
aa842b0fd88037f8... / mtime_ns 1791479579475780303 / ctime_ns 1791907371554631194; held
pin 120 B / 5b6d70716153c3f4... / mtime_ns 1791478687099553071 / ctime_ns
1791907371554631194, still Run 18's restore trace. Deployed /root/.helm/bin/ untouched
(ee0b36a82f23, 5c67473d8928, 7ed1bca8f9da, 12570786ba70, 738699986778), HELM_COLLECTOR
count 0 -- Q40 stands, so none of Q31-Q45s9 is in production. df -h / -> 46 G avail of
154, 71 % used.

Standing and still human-gated, unchanged: the s4 adoption cp of collector 4e45021d... +
gate 78b290ecf2d93e0cc3087e5ede8baef5c10ca52986706d5da69a13a619dbdd9f; the manifest_match
pin stale since 2026-10-08; Q13's publication call; Q9's checksum handover; Q19's
onboarding. No new item opened: Q42 is zephyrus's, Q52 is Mercury's, Q53 is Alexander's,
so the Helm lane's executable set is empty again and its next unit is a decision, not a
task.
2026-10-13 20:45:32 +00:00
Merlin b4524a2893 helm: Q45s9 Run 19 -- landing evidence over the anonymous raw path
Readback of the three landed files at 068ac5f, as its own commit: all three HTTP 200,
served = disk = git cat-file -p HEAD:<path>.

- recoveries/helm-home-channel-guard.md 21,230 B / 953ea1a14c5fa49b6d2d8e0d8324a8ac9d739ca4c39695646a5c05ae9cbf37fb
- WORK-QUEUE.md 909,662 B / 83b62e9d55180c38a12d9c26b8abea2661f033b448745599250fcba8a181a6fc
- checkins/2026-10-13-merlin.md 73,547 B / 43fb28e1fe92f587ce5cfa24fda8461a800b10239f63bd699672c35b21f1b19d

Instrument /root/crucible/q52/run19_readback.py, artifact out/Q45S9-RUN19-READBACK.json
(1,686 B / ccec083ce40f53242ab469f96529d9047eb525047891bedd4b492256fa45b39d), which names
the revision it was read at. This block was written against the queue at 909,662 B /
83b62e9d... and does not cite its own post-append digest.

Live state at readback time: snapshot 14,039 B / aa842b0fd88037f8... / mtime_ns
1791479579475780303, held pin 120 B / 5b6d70716153c3f4... / mtime_ns 1791478687099553071,
ctime 1791907371554631194 on both; deployed /root/.helm/bin/ untouched, HELM_COLLECTOR
count 0. Nothing deployed, no another-party file edited, no secret printed.
2026-10-13 18:34:22 +00:00
Merlin 068ac5fe7d helm: Q45s9 Run 19 -- corrections to the home-channel record landed
Taken on replies/2026-10-13-to-merlin-37.md section 2, which left five corrections open
on this lane's own file. Nothing above the appended sections was edited; three appends
only, 312 insertions / 0 deletions.

- The label collision is closed by renaming in prose: the item is Q45s9 (the queue's own
  section id, and the wording the c559d33 commit subject already carries), not Q52, which
  is Mercury's item at WORK-QUEUE.md:7167. The gate's internal check("Q52") registration
  and _q52_* helpers are deliberately not renamed -- renaming changes the gate's digest
  and would invalidate the byte-level verification reply 37 performed against it.
- The gate digest, measured in full: sha256sum /root/crucible/q52/helm-selftest-q52.py ->
  78b290ecf2d93e0cc3087e5ede8baef5c10ca52986706d5da69a13a619dbdd9f (64 hex, 140,365 B /
  2,677 lines / 126 registrations). The c559d33 commit subject carries a 63-character
  value, one c dropped at index 16; a commit message cannot be edited, so the correction
  lives in the record and the queue. The section-4 adoption cite is the 64-character value.
- The disarmed row's transient pin figure is unverified: grep -rn 'caff1f504855264a'
  over the scratch tree returns 3 hits, all this lane's prose, 0 in out/; the same for
  1791907100434371499. out/Q52-MATRIX.json (12,308 B / 75bd624ef25c5667...) records
  10d12a7d20c5f0ac... / 1791907358370548372 for that row and 576a47723957844e... /
  1791907371509627497 for the raw row, both guard_restored true. Direction Corroborated,
  cited figure unverified.
- The readback pairing is stated: out/Q52-READBACK.json carries revision 6954cc6 and its
  check-in row 67,347 B / 912985e3..., against the record's landing table's 65,145 B /
  d89b2189... at c559d33 -- both true, the revision field is the pairing.
- Four line citations corrected by grep -n in the shipped gate (_q52_home_sites :786 -> :758,
  legs' _q50_rebuild_env caller :1162 -> :1160, check("Q52") :1204 -> :1205, --q52-witness
  flag test :1270), and the q52-dis-check row's second failing check named
  (out/q52-dis-check.out:187, FAIL Q45 ... HELM_HOME: /root/.helm).
- "Delta 0 across all 21 invocations" is restated as net zero with two disclosed
  transient movements: exactly two of five matrix rows carry a non-empty guard_live_delta
  with guard_restored true, and final_live_delta is {}.

Artifacts: recoveries/helm-home-channel-guard.md 21,230 B / 953ea1a14c5fa49b6d2d8e0d8324a8ac9d739ca4c39695646a5c05ae9cbf37fb;
WORK-QUEUE.md 909,662 B / 83b62e9d55180c38a12d9c26b8abea2661f033b448745599250fcba8a181a6fc;
checkins/2026-10-13-merlin.md 73,547 B / 43fb28e1fe92f587ce5cfa24fda8461a800b10239f63bd699672c35b21f1b19d.

Live state re-measured 2026-10-13T18:18:06Z, delta 0: snapshot 14,039 B / aa842b0fd88037f8...
/ mtime_ns 1791479579475780303; held pin 120 B / 5b6d70716153c3f4... / mtime_ns
1791478687099553071; ctime 1791907371554631194 on both, unmoved since Run 18. Deployed
/root/.helm/bin/ untouched (ee0b36a8 / 7ed1bca8 / 5c67473d / 12570786 / 73869998),
grep -c HELM_COLLECTOR = 0 -- Q40 stands. No gate invocation, no live write, no cp, no
another-party file edited, decisions/ and inbox/ untouched, no secret printed.
2026-10-13 18:29:05 +00:00
Merlin 6954cc6e1f helm: run 18 landing evidence -- three-way byte-identical readback of recoveries/helm-home-channel-guard.md (13,173 B / 3f813ca2), WORK-QUEUE.md (897,771 B / e8da72cf) and the check-in's c559d33 revision over the anonymous raw path; live state delta 0 on bytes/sha256/mtime; deployed bin untouched; no secret printed 2026-10-13 16:08:55 +00:00
Merlin c559d33131 helm: the Q45 s9 follow-on closed -- the home-directory channel (collector 4e45021d unchanged; gate 78b290ecf2d93e0c3087e5ede8baef5c10ca52986706d5da69a13a619dbdd9f, 140,365 B / 2,677 lines / 126 registrations, on the Q51 gate e4967da9, diff 6 hunks + 122 - 3 = 2,677 lines; disarmed twin be7b306a one line different)
The last runtime-resolution route in Q45 s7-limit-1's family with neither a literal nor an ast-visible env read: HELM_HOME = Path.home() / ".helm" composes the live root because CPython's posixpath.expanduser reads HOME itself. The channel is live in the shipped subject -- the real collector calls Path.home() twice (its himalaya search). Mechanism: an ast inventory of home-database reads (_q52_home_sites, :786) and, inside Q50's one rebuild function (two callers, probe :977 / legs :1162), a redirect of HOME + USERPROFILE to <target>/q52-home -- a redirect, not a refusal -- with a conditional Q52 NOTE and one new check("Q52", :1204). A --q52-witness extra flag (:1261) runs the copy with --deploy --pin --skip-tests --out <sandbox dest>, the pin shape the suite itself refuses (Q44's rule), because the class's write path is unreachable from the green run.

Measured: green 5/5 at 176 passed / 0 failed (= 175 + 1), 14,044 B stdout, live delta {}; the real collector's own .home() read makes the check non-vacuous. Discriminator, five cells under the digest-verified guard: armed x collector-home.py (d62888c4) -- the copy resolves inside the sandbox and the pin lands at q52-home/.helm/data/held/stackchain-home.html.sha256 in the sandbox, live delta 0; armed x collector-expanduser.py (99c49d39) -- same; disarmed x home -- HOME stays /root, the copy resolves HELM_HOME=/root/.helm and the live pin moves to sha256 caff1f504855264a / mtime_ns 1791907100434371499, restored byte-exact; disarmed without the witness flag -- the foot's own check fails (FAIL Q52, home_reads=['.home()'] HOME='/root', 174 passed / 2 failed); direct invocation, ambient env -- the live pin moves (the class's floor). Regressions 11/11 hold; live delta 0 on bytes/sha256/mtime across all 21 invocations (snapshot 14,039 B / aa842b0f, held pin 120 B / 5b6d7071); ctime moved on both objects (1791907371554631194), the guard restores of the two deliberately-live rows -- disclosed. Final tree 0 sandboxes; deployed /root/.helm/bin untouched (7ed1bca8, grep -c HELM_COLLECTOR = 0 -- Q40 stands, so none of Q31-Q52 is in production); disk 46 GiB free of 154.

Five defects of mine logged first in the deliverable: the witness's missing local subprocess import; the witness anchored before the leg copy was written; the witness's live census reading the held directory (IsADirectoryError); the NOTE claiming a redirect that had not fired (the disarmed twin's own FAIL contradicted it -- the NOTE is now derived from the actual env); and the first matrix measuring nothing because the real collector pins only under --pin, which the suite refuses. Limits stated as the item's own: the original-subject legs inherit the ambient environment (Q48's residual); pwd.getpwuid().pw_dir bypasses HOME (the inventory names it, the redirect cannot relocate it); the inventory is static (Q46's limit).

Files: recoveries/helm-home-channel-guard.md (13,173 B / sha256 3f813ca23202590c675f7ac7587f0d5e7d8b0ff9ee9f4f0711996530a2d6d7db), WORK-QUEUE.md (897,771 B), checkins/2026-10-13-merlin.md (Run 18). Scratch tree /root/crucible/q52/ not committed. No deployment, decisions/ and inbox/ untouched, no another-party file edited, no secret printed. The Helm lane's executable set is empty again; the adoption cp (collector 4e45021d + gate 78b290ec, superseding e4967da9) remains Alexander's.
2026-10-13 16:08:17 +00:00
Merlin 7794c89577 checkin 2026-10-13-merlin.md run 17 landing evidence (Q51 readback: 3 files HTTP 200, three-way byte-identical at 57d8e6b) 2026-10-13 13:41:00 +00:00
Merlin 57d8e6bcc7 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.
2026-10-13 13:40:02 +00:00
Merlin 36f8e9fb4a Q50 landing evidence: three files read back HTTP 200 over the anonymous raw path, byte-identical on three sides (served = disk = git cat-file -p 4c6cd50); live objects delta 0, deployed bin untouched 2026-10-13 11:27:38 +00:00
Merlin 4c6cd50baf Q50 closed: the admission probe's environment -- one rule, one function, two callers
Taken on the pipe's own offer (reply 34, asks 1). The Q48 value-redirect and Q49
default-redirect are factored into _q50_rebuild_env(_target) and called twice: at the
rule's original site for the legs (target the legs' sandbox) and above the admission
probe's spawn for the probe (target the probe's own tree, which exists before the
spawn -- the legs' sandbox does not). The spawn now carries env=, and a per-window
census of both live objects around the spawn is the class's detector: a move is
restored byte-exact in-gate, recorded, printed as a dated Q50 DETECTOR note, and
fails the named check "Q50 the admission probe's spawn moved neither live object".

Measured, all five matrix cells under a digest-verified guard (subject env-root-v1.py):
  base-q49 x named  MOVED  held pin 120 B / 5b6d7071... -> 14 B / 784b9bde..., guard-restored
  q50-armed x unset  delta 0  0 value + 1 default redirect
  q50-armed x named  delta 0  1 value redirect  -- the blank cell, filled
  q50-dis   x unset  delta 0  the probe copy's own Q45 literal relocation covers the
                              default shape; the redirect is load-bearing only in the named cell
  q50-dis   x named  delta 0  the DETECTOR fires: pin moves inside the gate, restored
                              byte-exact, foot prints FAIL Q50 (165/10 vs armed 166/9)
Green 5 x rc 0 / 175 passed / 0 failed (174 + 1) / 13,929 B / live delta 0.
Regressions 11/11 hold (n1-n5, noparse, dep-unparseable, undecodable, broken_dep rc 2;
latin1 and bom green 175/0). Live objects byte-identical to session start on
(bytes, sha256, mtime_ns); deployed bin untouched (ee0b36a8... / 7ed1bca8...,
HELM_COLLECTOR count 0 -- Q40's finding stands). Named follow-on, not fixed here:
hoist the run-wide held census above the probe. Three harness defects of mine logged
first in the record. Nothing deployed; no another-party file edited; no secret.
2026-10-13 11:26:36 +00:00
Merlin 26d4020ce2 Q49 landing evidence: the three post-push digests, read back from main
The record's deferred table and the check-in's deferred line are filled from the
anonymous raw read at main, taken after the push (a pre-push readback returns 404
for a new file), so the figures are stable for any outsider. All three HTTP 200
and byte-identical to disk.
2026-10-13 09:07:12 +00:00
Merlin de74527209 Q49 closed: the Q48 live-held invocation named and reproduced; the class closed
- (a) ATTRIBUTION, measured not withdrawn. env-root-v1.py = q48/env-root.py with its
  two default literals returned to /root/.helm (asserted count 2). Under a
  digest-verified guard: the fixture run --dry-run / bare / --deploy --out <scratch>
  with Q48_ROOT UNSET each moved the live held pin, and
  HELM_COLLECTOR=<that fixture> Q48_ROOT unset python3 q48/helm-selftest.py moved it
  too. All three Q48_ROOT=<scratch> controls: no move. Written bytes measured by a
  5 ms watcher: 14 B / sha 784b9bded20e9e22... / 'q48-env-pin\n'. Q48's 6.2
  attribution is upheld as a measurement; the pipe's negative reproduces exactly.
  The writing leg is named verbatim by the per-leg census: the G8 --dry-run
  original-subject leg, whose own source comment asserts "it writes nothing".

- (b) THE CLASS IS CLOSED, green 5/5. helm-selftest-q49.py (128,948 B / 2,445 lines /
  085ddf4f42ae80ea...): the DEFAULT redirect (every os.environ.get("X","<default>")
  pair inventoried by ast; a default literal resolving inside the live data root is
  redirected to the per-invocation sandbox), a per-leg census of BOTH live objects as
  detection, and a guard on the in-process --deploy leg. Checks 120 -> 123
  (+3 check("Q49"), nothing else moved). Five green runs: rc 0, 174 passed /
  0 failed, 13,863 B stdout, digests 13cf5cf7 / d4666b9f / 0abd28cd / 5ed81c37 /
  bbbd1901, live delta 0 on both objects.

- TWO FINDINGS BEYOND THE ITEM. (i) G8's --deploy branch calls hcg.main() IN-PROCESS
  with only SNAPSHOT_PATH patched, so a subject that resolved its root at import time
  wrote the LIVE SNAPSHOT (14,039 B -> 137 B) -- reproduced, restored, and now
  guarded. (ii) In the fully disarmed configuration the live pin still moves and no
  spawn the traced instrument can attribute it: one fixture main() per run, banner
  naming the sandbox, both censuses silent, watcher still seeing 120 B -> 14 B at
  t+280 ms. The write is real, the mechanism is UNATTRIBUTED, and it is named as the
  Helm lane's next unit rather than guessed at.

- Six live writes under guard, every one restored from a digest-verified backup that
  refuses to restore unless the backup digest matches. Both live objects byte-identical
  at session end: snapshot aa842b0fd88037f8... / 14,039 B and held pin
  5b6d70716153c3f4... / 120 B. Nothing deployed: /root/.helm/bin/helm-selftest.py is
  still 7ed1bca8... and reads HELM_COLLECTOR 0 times, so none of Q31-Q49 is in
  production and the cp of collector 4e45021d... + gate 085ddf4f... stays Alexander's.

Deliverable: recoveries/helm-resolved-root-live-path.md (15,220 B).
Scratch tree /root/crucible/q49/. Record, check-in Run 15 and queue block.
2026-10-13 09:06:35 +00:00
Merlin abe1f0b8c8 Run 14 landing evidence: all three files HTTP 200 over the anonymous raw path and three-way identical (served = disk = git cat-file -p 20623b6) at the revision the push created; the check-in row cites its pre-append revision per the no-self-hash convention 2026-10-13 06:45:12 +00:00
Merlin 20623b66fd Q48 queue block + check-in Run 14: the pair (collector 4e45021d + gate a590170f, diff 186 = 2 file + 3 hunk + 143 added + 0 removed + 18 context, 2124+143-0=2287); green 171/0 x5; witness armed-live redirected /root/.helm -> sandbox with the pin in the sandbox, disarmed-live wrote live and the guard restored byte-exact; three live-held writes disclosed with final live_delta 0 2026-10-13 06:44:25 +00:00
Merlin 0b0b591cc7 Q48 CLOSED (Merlin): the runtime-resolution redirect — an env- or argv-resolved live root is relocated into the sandbox; 169 -> 171 green 5/5; the class measured with prevention separated from detection; the live-held incident caused, restored and disclosed 2026-10-13 06:44:11 +00:00
Merlin 1b3d7a44da check-in: Run 13 landing evidence — the post-push readback measured rather than promised: all three files HTTP 200 over the anonymous raw path and byte-identical on three sides (served, disk, git cat-file -p 8cb941f) at the revision the push created 2026-10-13 03:54:27 +00:00
Merlin 8cb941fc26 Q47 CLOSED (Merlin): the read path — a subject the interpreter can run neither crashes the gate nor is falsely refused
The subject's source is now read the way CPython reads it: bytes through
tokenize.detect_encoding (BOM stripped, PEP 263 cookie honoured), with a
dated exit-2 refusal for a file that cannot be read that way, at Q46's
guard point — after Q35's precondition, before the admission probe,
before any leg, before any sandbox. All four subject-source reads route
through the one reader; one stderr NOTE when the encoding is not plain
utf-8; the Q46 parse guard, the Q45 redirect, every check() and the 169
count untouched.

Deliverable recoveries/helm-read-path-guard.md (12,821 B), scratch tree
/root/crucible/q47/, evidence out/Q47-NEGATIVES.json (21 rows),
out/Q47-VERDICT.json, out/Q47-GREEN.json, out/DIFF-vs-q46.txt.

Measured, not asserted: latin-1 cookie subject rc 0 / 169 passed / ALL
GATES PASS under the shipped gate (Q39-Q45 crash with UnicodeDecodeError);
BOM'd collector rc 0 / 169 passed (Q43/Q45 SyntaxError at the sandbox
copy, Q44 AttributeError, sandboxes left); genuinely undecodable subject
rc 2 with the dated Q47 REFUSAL and no sandbox. Q39 runs the BOM subject
green with 164 passed — the read-path class is the text-compiling gates
(Q43-Q46), not subject handling generally. Green pair 5x rc 0, 169/0,
13,312 B stdout / 425 B stderr, live and held delta 0 on all 26
invocations. Adoption pair moves to collector 4e45021d + gate 76f2292b.

Nothing deployed, no cp into /root/.helm/bin/, decisions/ and inbox/
untouched, no another-party file edited, no secret. Run 13 in the
check-in; queue block appended.
2026-10-13 03:53:48 +00:00
Merlin 29cea300a1 Q46 landing evidence: the readback table filled from the measured read (three files HTTP 200 and byte-identical on three sides at a6b1ae3; the check-in row cites the committed revision, per the no-self-hash convention) 2026-10-13 01:38:51 +00:00
Merlin a6b1ae3434 Q46 closed: the parse guard
An unparseable subject is refused with exit 2 and a dated message naming the
parse failure, not admitted-then-crashed. Discriminator on all five gates,
digest-identical to the revision history: Q39 rc 1 SyntaxError at the legs
import of the original subject, Q43 rc 1 SyntaxError at the sandbox-copy
import, Q44 rc 1 AttributeError at the unguarded _q39_tree.body, Q45 rc 1
SyntaxError at the sandbox-copy import, Q46 rc 2 dated refusal with stdout 0
B and no sandbox created. dep-unparseable refused by Q39 repair 3 on all five
gates. C2 reproduced: the ROOT glob sees no leftover while the recursive
census sees legacy/q4X/helm-legs-*. Green pair 5x rc 0, 169 passed, 13,312 B,
live delta 0; atexit sandbox cleanup closes the n5 leak measured before and
after. Live snapshot aa842b0f 14,039 B and held pin 5b6d7071 delta 0 across
27 invocations. Adoption pair is now collector 4e45021d + gate ae69d5dd.
2026-10-13 01:38:23 +00:00
Merlin d5a14d4386 Run 11 landing evidence, final fill: the post-push readback measured rather than promised -- the fill landed as 00df4e6, the same anonymous raw path re-read the check-in at HTTP 200 / 103,128 B, cmp byte-identical to disk, sha256 4a17e8ee17a65dce20898ae16e562a8aea22490ef31c40c3e8d8467c2bb6479e reproducing from git cat-file -p 00df4e6, so served/disk/committed agree on three sides at the revision that now exists and the pre-append row stands at 57895b2 (100,376 B / 87c275a1) 2026-10-12 23:22:47 +00:00
Merlin 00df4e6e5b Run 11 landing evidence: the three files read back 200 and byte-identical on three sides (served, disk, git cat-file 57895b2) over the anonymous raw path; live snapshot and held pin re-measured delta 0, the held pin's ctime named as this run's restore trace 2026-10-12 23:22:07 +00:00
Merlin 57895b2e7c Q45 CLOSED: the redirect keys on the resolved value, not on a name (Helm lane, Merlin)
One rule replaces Q44's two: every absolute path literal in the subject that
resolves inside the live data root is relocated to the same relative path inside
the per-invocation sandbox, on the parsed node's own span, wherever in the module
it sits and whatever the constant holding it is called. Q44's HELM_HOME =
assignment rewrite is subsumed, not removed; the SNAPSHOT_PATH rewrite (Q39/Q43's
mechanism) is kept. Q39's literal refusal is retired for this class and its reason
printed where the refusal stood -- the refusal's own text said the rewrite "cannot
redirect a path that is not the module constant the rule keys on", which is the
statement Q45 makes false.

Gate 2bbca218871bc5613e1fe3c4d3a84fe2e6da05ffc526e51b2865a8c8ad00ee5e (105,477 B /
1,942 lines) against Q44's 18580c102ddb1c3f (94,819 / 1,731); diff = 426 lines =
2 file headers + 7 hunk headers + 284 added + 73 removed + 60 context, sums exactly;
1,731 + 284 - 73 = 1,942. Collector byte-identical to Q44's 4e45021d80395d3f
(measured by sha256 comparison, not asserted).

Green pair 5 consecutive: rc 0, 13,312 B stdout each, 169 passed / 0 failed,
VERDICT: ALL GATES PASS. 169 = 166 + 3, unchanged from Q44 -- two new Q45 checks
plus Q44's held-directory check carried verbatim and still labelled Q44.

The five Q39 negatives still refused under both gates (all ten rc 2, live delta 0).
n5 is the class change: Q44 refuses it (stdout 0 B), Q45 admits it and lets its legs
run (stdout 575 B), still rc 2 with live delta 0.

Discriminator on a scratch protected root, rule (3) disarmed, two subjects (a
differently-named root constant; the held directory built at call time from a
literal, with HELD_DIR left in place as a decoy) x three variants (redirect armed /
disarmed / the Q44 gate blind):
  armed    rc 0, 169/0, the only held write in the run's own sandbox, protected delta 0
  disarmed rc 1, 165/4, the held write in the protected root, protected NONZERO
  q44blind rc 0, 169/0, VERDICT: ALL GATES PASS, and the held write in the protected root
Prevention separated from detection by measurement, on both shapes.

INCIDENT, disclosed in full: the first discriminator run wrote the LIVE held
directory. The subject's root literal was /root/.helm while the variant's own live
root was the scratch protected root, so the literal sat outside the gate's live
root, was never in the redirect's inventory, and the copy the legs ran still named
live. Restored byte-exact from /root/crucible/q43z/backup/held.bak by
restore_held.py, verified against the recorded digest 5b6d70716153c3f4 (120 B,
mtime_ns 1791478687099553071). ctime_ns moved to 1791846636217687791 -- the trace
of the restore, which a restore cannot undo. Three mechanical fixes followed in
this tree: make_subjects.py retargets the root literal with an asserted count;
run_negatives.py's guard() refuses any discriminator subject whose code names the
live data root (it fired during this build); abort_if_live_moved() stops the whole
run the moment a live object moves.

Four instrument defects of mine, each caught by its own measurement: the span list
visited each AST node once per ancestor (ast.walk nested inside _q39_iter_nodes),
which produced Path('<sandbox>'le/<sandbox>'le/<sandbox>'le/<sandbox>') on the
HELM_HOME line; the subject header swap stripped the original docstring's opening
triple quote; make_subjects.py's truthiness and its HELM_HOME expectation; and the
q44blind variant's PIN block reading the wrong environment variable.

Two defects in others' code, found here and not fixed here: the Q44 gate accesses
_q39_tree.body with no None guard (unexercised, so reported rather than repaired);
and Q39's _q39_live_literals list appends once per ancestor yielded, so one literal
site printed 12 times (deduped for display where Q45 reads it; Q39's list unchanged).

Live state delta 0 on all 21 rows: snapshot 14,039 B / aa842b0fd88037f8 /
mtime_ns 1791479579475780303 / ctime_ns 1791789490146606356; held pin 120 B /
5b6d70716153c3f4 / mtime_ns 1791478687099553071 / ctime_ns 1791846636217687791
(that ctime is the restore trace). Deployed /root/.helm/bin/ untouched
(ee0b36a82f23fcf3 / 7ed1bca8f9da624f / 5c67473d89283c3d). Nothing deployed, no cp,
decisions/ and inbox/ untouched, no another-party file edited, no secret.
2026-10-12 23:21:35 +00:00
Merlin 9e6fe7ca93 Q44 landing evidence fill: the Run 10 table's measured digests, read back after 534be9e
python3 /root/crucible/q44/readback.py, exit 0, VERDICT: ALL READBACKS IDENTICAL,
run after the push of 534be9e. Anonymous raw path, no credential, all three HTTP 200:

  recoveries/helm-root-redirect.md  200 / 12,811   e68be4cdd5a535e22eae87f5ffbf9cb6841ea3d8a044ae34c13e74f86460568b
  WORK-QUEUE.md                     200 / 709,179  f2d6c923212c633618aa1a9624b33b0459bb1190a148489222f57e45a6803bff
  checkins/2026-10-12-merlin.md     200 / 84,760   06573214c798bd8e878b84b4157e01b67c20ea3e43a294d59bc716f622f485b2

Each byte-identical on three sides: the bytes the server served, the bytes on disk,
and git cat-file -p 534be9e:<path>. The check-in row cites 534be9e, which is the
revision the readback verified; this fill's own revision is this commit and is
verified over the same path by the same script, its digest recorded here rather
than inside the file.

Nothing else changed: /root/.helm/bin/ untouched (ee0b36a82f23fcf3... /
7ed1bca8f9da624f... / 5c67473d89283c3d...), live snapshot 14,039 B /
aa842b0fd88037f83115b4a54d617f27666f4de06ef84f9a64c8fd0a5f04656d / mtime
2026-10-08 17:12:59.475780303 +0000, held pin 120 B /
5b6d70716153c3f4bd82045d5d71edf88f793a240ce1275c3dfca5759d0ee297 / mtime
2026-10-08 16:58:07.099553071 +0000 -- delta 0 across the run. decisions/ and
inbox/ untouched, no another-party file edited, no secret.
2026-10-12 20:53:38 +00:00
Merlin 534be9e32c Q44 CLOSED: the pin class is closed by construction, not by argv rule (Helm lane, Merlin)
Deliverable recoveries/helm-root-redirect.md (12,811 B / sha256
e68be4cdd5a535e22eae87f5ffbf9cb6841ea3d8a044ae34c13e74f86460568b). Scratch tree
/root/crucible/q44/; harness run_negatives.py -> out/Q44-NEGATIVES.json
(66,881 B / 611ab1e06e172be535ae5f19e21b4e1a6667a0f1b7542d130fc9d72298c5b895,
generated_at 2026-10-12T20:49:04Z), 17 invocations. Nothing deployed, no cp into
/root/.helm/bin/, decisions/ and inbox/ untouched, no another-party file edited,
no secret.

The pair: subject collector 4e45021d80395d3f... (29,954 B / 720 lines) byte-identical
to Q43's -- every change is in the gate. Gate 18580c102ddb1c3f...
(94,716 B / 1,731 lines) against Q43's c22601ecea4192d9... (88,468 / 1,612);
diff -u = 195 lines = 3 header + 133 added + 14 removed + 45 context, and
1,612 + 133 - 14 = 1,731 exactly.

What changed: the copy builder rewrites the HELM_HOME = assignment ITSELF to the
per-invocation sandbox, so every constant composed from it follows by construction;
the composed set is found by ast on the subject's own source (module-level Assign
nodes whose value references HELM_HOME) and is [SNAPSHOT_PATH, HELD_DIR]. The
SNAPSHOT_PATH rewrite is kept as defence in depth. Rule (3)'s --pin refusal is kept
but reclassified as defence in depth. Q39's admission, its behavioural probe and its
per-leg watch are untouched; no check's meaning changed. Three new checks, so the
green count is Q43's 166 + 3 = 169 passed / 0 failed: (1) the root constant is
redirected; (2) every constant composed from the root resolves inside the sandbox,
measured by a subprocess that imports the copy and prints the live values (not a
source marker); (3) the live held directory is unchanged by every leg, censused on
bytes, sha256, mtime_ns and ctime_ns before any leg and again at the foot.

Green pair, 5 consecutive invocations: rc 0 each, 12,966 B stdout, "helm-selftest:
169 passed, 0 failed" / VERDICT: ALL GATES PASS, 12.00-12.14 s; log digests
5c519157eaec4a40... / 97916ab27b8521c0... / 6f5553364b7a0d09... / ad57bad15689dfc5...
/ 00a1ae6dc2519efc... . Q43's counters unchanged (4 legs redirected, 3 --dry-run legs
original, 0 refusals, sandbox holds 3 paths with no data/snapshot.json).

The five Q39 negatives, still refused -- each run under the Q44 gate and, as the
pre-Q44 comparator, under the Q43 gate: all ten rc 2, stdout 0 B
(e3b0c44298fc1c149...), no report block, live delta 0, live held delta 0, 0.14-0.21 s.

The discriminator, on a scratch protected root (never live), rule (3) disarmed and a
--pin --deploy leg appended at the foot so it runs through the same leg wrapper.
pinleg (redirect armed): rc 0 / 169 passed, the pin lands in the sandbox
("pinned e40308e573d046d7d503acecbfbde82b8ccd10758a345b0440d55b796e2d821e ->
<sandbox>/data/held/stackchain-home.html.sha256"), protected held file delta 0
(114 B / b58d2d0eb9f45862b... / mtime_ns 1791478687000000000 / ctime_ns
1791838054542473495 before and after). pinleg-noredirect (redirect disarmed, live root
stood in for the scratch root): rc 1 / 166 passed / 3 failed, the same shape lands in
the protected root's held file (120 B / f98215b460bf89764924096c6fc657e62173e4c26f99bc4a2e5c489f3ed0f416 /
mtime_ns 1791838143983952745 / ctime_ns 1791838143991953414 -- NONZERO). Prevention
separated from detection by measurement. The live-path write was NOT re-measured: it
would clobber /root/.helm/data/held, Q43 already measured it (pinned 5e5cd6d26a70...)
and this run's pinleg reproduces the same body digest e40308e5... from the same code
path, so the class is the same one.

Live state, delta 0 across all 17 invocations: snapshot 14,039 B /
aa842b0fd88037f83115b4a54d617f27666f4de06ef84f9a64c8fd0a5f04656d / mtime_ns
1791479579475780303 / ctime_ns 1791789490146606356; held pin 120 B /
5b6d70716153c3f4bd82045d5d71edf88f793a240ce1275c3dfca5759d0ee297 / mtime_ns
1791478687099553071 / ctime_ns 1791478687102553111. Deployed bin untouched
(ee0b36a82f23fcf3... / 7ed1bca8f9da624f... / 5c67473d89283c3d...).

Limits and this run's own defects, logged first in the deliverable: the redirect keys
on the HELM_HOME = assignment, so a differently-named root or a call-time path is not
covered by the substitution (Q39's literal scan and the per-leg watch remain the
backstop); the shipped gate never exercises the redirect on a --pin leg, so that
shape's evidence is the variant; my first green run read 168 passed / 1 failed because
my own comparator excluded the sandbox root itself (startswith(dir + "/") is false for
HELM_HOME, whose value IS the root) -- fixed in patch_gate2.py and the only reason the
count is 169; the Q43 resolution-leg check false-fails under the variants and was fixed
in the variant only (patch_variants.py), the shipped gate untouched by that edit; and
one unexplained observation -- in pinleg-noredirect the sandbox census holds 5 paths
including data/snapshot.json, i.e. a leg wrote a snapshot inside the sandbox, which is
the sandbox doing its job and rides on nothing, recorded rather than explained.

Q7, measured: after this item the Helm lane's executable set is empty again (Q9 blocked
on the audio handover, Q13/Q19 gated on Alexander, Q42 open and zephyrus's). No new item
opened. The section 4 adoption is now a three-file ask: collector 4e45021d... + gate
18580c1..., with Q40's finding unchanged -- the deployed gate 7ed1bca8... has no
subject-selection path at all.
2026-10-12 20:52:12 +00:00
Merlin 2ddbe68f9f checkins: Run 9 landing evidence -- the three landed files read back over the
anonymous raw path (200 / cmp byte-identical, readback.py exit 0, VERDICT: ALL
READBACKS IDENTICAL) and the table filled with the measured digests

The table cites the committed revision 0fb8b20 for this check-in's own row
(200 / 75,361 B / fc4e750b392d2099c11703b8ea0f4e26036ea3a86b0123a8e2a5c1a6a53393ff,
reproduced locally by `git cat-file -p 0fb8b20:checkins/2026-10-12-merlin.md |
sha256sum`), not a transient local revision -- Run 8's row cited one and the pipe
returned that as D1. The check-in's own digest after this fill is deliberately
not printed: a file cannot cite its own final digest, and chasing that regress is
what moved Run 8's row through six revisions.

The other two rows are stable and carry their read-back digests:
recoveries/helm-leg-sandbox.md 200 / 13,561 B /
7c5111aa064e85247007a8ce1ca7a20e0d82d64db45eae0edcef62b9e78eec28 and
WORK-QUEUE.md 200 / 691,024 B /
90399c0f1586952a20e9a229db277aabdf2d062da2eddd30f79159d9033644e4, each cmp
byte-identical to disk.

Read-back at 2026-10-12T18:34:33Z, no credential. Nothing deployed, no another
party's file edited, no secret printed.
2026-10-12 18:35:43 +00:00
Merlin 0fb8b2096c Q43: the legs run the rewritten subject -- prevention, not detect-and-restore
Q39's repair 5 is a net, not a fence: live bytes and mtime are read around every
subprocess and around the subject's in-process import, a change restores the
bytes and refuses the run, so the write has already happened when the watch
fires. Q39's own record names the residual and the Q39 closure asks for "the
stronger form (the legs against a rewritten copy)". This is that form, and it is
the Helm lane's next unit rather than a new invention.

Three rules in the one choke point the gate already has -- the leg wrapper
installed on subprocess.run, so every future leg inherits them:

  1. a subject leg carrying --dry-run runs AS THE ORIGINAL, watched: it writes
     nothing by the collector's own rule (helm-collect.py:698), and running the
     original is what lets the resolution leg read the subject's own destination
     out of its banner;
  2. every other subject leg, and the in-process import, runs the REWRITTEN COPY
     -- every SNAPSHOT_PATH = assignment pointing at a per-invocation sandbox
     built after admission and removed at the end of the run -- so module-level
     code can write at most into the sandbox;
  3. a subject leg is REFUSED (exit 2, the leg never runs) if its argv names the
     live snapshot or passes --pin.

Rule 3 is load-bearing, not decoration: the collector refuses only when --out
resolves to its OWN SNAPSHOT_PATH (helm-collect.py:702), so a copy whose
destination is the sandbox would write the live path if a leg named it. The
gate's own "explicit live --out is refused" leg therefore now names the copy's
own destination -- the Q30 discipline applied to the collector. The rule under
test is unchanged; it is measured on a path that is not live, and the semantic
change is stated in the gate and the record rather than left implicit.

Measured, 20 gate invocations, live delta 0 on every one (snapshot 14,039 B /
aa842b0f... / mtime_ns 1791479579475780303; held pin 120 B / 5b6d7071... /
mtime_ns 1791478687099553071):

  - green pair, 5 consecutive runs: rc 0, 166 passed / 0 failed, ALL GATES PASS,
    12,248 B stdout; 4 subject legs redirected, 3 --dry-run legs run as the
    original, 0 refusals; the sandbox holds 3 paths (the copy and its bytecode
    cache, no data/snapshot.json); 18 legs watched, delta 0 on each;
  - the five Q39 negatives refuse under BOTH gates (rc 2, stdout 0 B, no report
    block, live delta 0) -- but they are refused at Q39's admission, before the
    Q43 sandbox exists, so they are a regression control and nothing in the
    five-fixture suite exercises the redirect. Stated, not hidden;
  - the discriminator, on a scratch protected path: argvlive (the gate's own
    pre-Q43 leg shape, rule 3 armed) -> rc 2, the refusal naming the leg's argv,
    the copy's destination and the rule at :702, and the protected file's sha,
    mtime AND ctime unchanged -- the leg never ran. argvlive-norule3 (rule 3
    disarmed) -> rc 2 via Q39's watch, protected ctime MOVED while sha and mtime
    were restored -- the leg ran, the copy wrote a real snapshot over the
    protected file, and only the restore put it back. ctime_ns is the
    discriminator: the stamp a restore cannot undo;
  - the --pin residual: pin_stackchain() writes HELD_DIR, composed from HELM_HOME
    and untouched by the rewrite, so a --pin leg is refused (rc 2, naming --pin
    and /root/.helm/data/held); a copy with HELD_DIR also redirected to scratch,
    run --pin --deploy, writes the scratch held file, so the path is real; bare
    --pin is refused by the destination gate before `if args.pin`, so it is one
    flag combination away, not on the default path;
  - the rewrite is behaviour-preserving: original vs copy, both --dry-run, both
    20,570 B, scrubbed over the gate's full clock set -> diff_keys [].

Three defects of mine, logged first in the record: the redirect keyed on argv[0],
which is the interpreter (the subject is an argv element, and the first run
measured 0 redirects while its legs ran the original -- the Q40 shape); the
behaviour-preservation scrub omitted generated_at and duration_seconds; and the
first --pin measurement ran bare, so the held path was never reached.

Limits stated in the record: prevention is total for the SNAPSHOT_PATH class, not
for every class; the legs still execute the subject's code, and damage to
anything other than the snapshot is out of this gate's scope; the five-fixture
suite no longer reaches Q43's machinery, so the two variants and the pin residual
are the coverage.

Nothing deployed: no cp into /root/.helm/bin/, the deployed bin is unmoved
(ee0b36a8... / 7ed1bca8... / 5c67473d...), decisions/ and inbox/ untouched, no
another-party file edited, no secret printed. Adoption stays Alexander's, and Q40
measured that the deployed gate has no subject-selection path at all, so the cp
is the only thing that puts any of Q31-Q43's protection into production.
2026-10-12 18:33:44 +00:00
Merlin fbb2562c35 checkins: Run 8 landing evidence appended -- the Q41 erratum's three landed files read back over the anonymous raw path (200 / cmp byte-identical); the check-in's own row cites its pre-append revision, as Run 4 and Run 7 do, because a file cannot hash itself. 2026-10-12 16:10:38 +00:00
Merlin ff32a440e2 recoveries: Q41 erratum applied -- literal rows' offsets re-measured in the space their row names (s3e.py:81 returned an S0 offset under an S1 label; fraction was a mixed-space ratio). 6 of 42 measured rows move at 4dp, class mean 0.229448 -> 0.229590 (0.2294 -> 0.2296); the magazine contrast (0.4735) and the fifths split (21/10/9/1/1) are unchanged. Second defect of mine found while applying: s3e.py:105 counted the raw excerpt against the S1 body, so 16 occurrence counts were under-counts and the multi-occurrence aggregate moves 8 -> 9. Also applied: the anchor-census label fix (46 anchored + 4 no-anchor = 50), the 25 -> 35 anchor revision logged (Q41 35 = 25 unique + 10 shared with the magazine 91; union 116 = Q21's census figure), and the fifths bucketing rule printed (min(int(f*5),4)). Verified from the patched markdown itself: 50 rows / 0 malformed, class counts 30/5/7/4/4 summing to 50, Q21 join 42 bound / 4 mis-bound / 4 unanchored, 50/50 rows agreeing with the S1-measured set. Scratch /root/crucible/q41/; no page re-fetched; decisions/ and inbox/ untouched; nothing deployed. 2026-10-12 16:08:56 +00:00
Merlin e9cd99f280 checkins: Run 7 landing evidence -- anonymous readback of all three files 200 / cmp-identical (readback.py exit 0, VERDICT ALL READBACKS IDENTICAL) 2026-10-12 13:58:09 +00:00
Merlin 6abf898bd1 queue: Q41 excerpt fidelity class and placement, the 30 non-magazine entries DONE (Merlin) -- deliverable recoveries/excerpt-placement-nonmagazine.md (33645 B / sha256 d16761a827dfe5de9868dc0e1e513153d6acaa802983000959172d873de98c84); population 30 entries / 50 excerpts / 35 distinct anchors all HTTP 200 (index 200 / 34488 B / 4f764ef4, 2026-10-12T13:46:28Z); tally 30 literal / 5 normalised-literal / 7 elided / 4 paraphrase / 4 unreadable; placement n=42 over 26 of 30 entries, mean 0.2294 vs the magazine class 0.4735, fifths 21/10/9/1/1; Q21 join exact 42 bound / 4 mis-bound / 4 unanchored = 42/4/4; two of my own defects logged first (source-type unreadable rule on 23 non-article rows; three URL-tokenisation failures fixed, witness event-2022-08-21-...-1414 seq 1); scratch /root/crucible/q41/; no new item opened, Q37 pipe's, Q9/Q13/Q19 and Helm adoption gated 2026-10-12 13:57:38 +00:00
Merlin 5d71c855fb Q40: the deployed gate admits all five negatives, and has no admission path at all
Reproduces the Q39 closure's C26 from this host and states the mechanism:
`grep -c HELM_COLLECTOR /root/.helm/bin/helm-selftest.py` -> 0; the deployed gate
imports its subject at module scope from a hard-coded path (`:39`), so the five
fixtures are never loaded -- the shipped gate has no subject-selection path at
all, which is why Q34-Q39's admission machinery has nothing in production to
guard. Measured: deployed gate x5 fixtures -> rc 0 / 7,488 B stdout /
`119 passed, 0 failed` / `VERDICT: ALL GATES PASS`, stderr 0 B, live snapshot
`aa842b0f...` delta 0 across all 15 invocations plus the green control; Q38
admits n1 and n2 (its C22/C23 holes); Q39 `9b09f328...` refuses all five
(rc 2 / stdout 0 B / no fixture file touched / live delta 0) and runs the pair
green (164 passed / 0 failed, `Q39 OK`, 17 legs watched, delta 0 on each).
Nothing deployed, no `cp`, `/root/.helm/bin/`, `decisions/` and `inbox/`
untouched. Deliverable `recoveries/helm-deployed-gate-admission.md` (5,633 B /
sha256 5bdd2e7503cced8eee5b31a0256500aaa8eda9f8e3adbb80d3702eeb5e8df61a).
2026-10-12 11:43:08 +00:00
Merlin 9af42d2115 Q40: the deployed gate admits all five negatives, and has no admission path at all
Reproduces the Q39 closure's C26 from this host and states the mechanism:
`grep -c HELM_COLLECTOR /root/.helm/bin/helm-selftest.py` -> 0; the deployed gate
imports its subject at module scope from a hard-coded path (`:39`), so the five
fixtures are never loaded -- the shipped gate has no subject-selection path at
all, which is why Q34-Q39's admission machinery has nothing in production to
guard. Measured: deployed gate x5 fixtures -> rc 0 / 7,488 B stdout /
`119 passed, 0 failed` / `VERDICT: ALL GATES PASS`, stderr 0 B, live snapshot
`aa842b0f...` delta 0 across all 15 invocations plus the green control; Q38
admits n1 and n2 (its C22/C23 holes); Q39 `9b09f328...` refuses all five
(rc 2 / stdout 0 B / no fixture file touched / live delta 0) and runs the pair
green (164 passed / 0 failed, `Q39 OK`, 17 legs watched, delta 0 on each).
Nothing deployed, no `cp`, `/root/.helm/bin/`, `decisions/` and `inbox/`
untouched. Deliverable `recoveries/helm-deployed-gate-admission.md` (5,633 B /
sha256 5bdd2e7503cced8eee5b31a0256500aaa8eda9f8e3adbb80d3702eeb5e8df61a).
2026-10-12 11:42:47 +00:00
Merlin e56f959246 Q40: the deployed gate admits all five negatives, and has no admission path at all
Reproduces the Q39 closure's C26 from this host and states the mechanism:
`grep -c HELM_COLLECTOR /root/.helm/bin/helm-selftest.py` -> 0; the deployed gate
imports its subject at module scope from a hard-coded path (`:39`), so the five
fixtures are never loaded -- the shipped gate has no subject-selection path at
all, which is why Q34-Q39's admission machinery has nothing in production to
guard. Measured: deployed gate x5 fixtures -> rc 0 / 7,488 B stdout /
`119 passed, 0 failed` / `VERDICT: ALL GATES PASS`, stderr 0 B, live snapshot
`aa842b0f...` delta 0 across all 15 invocations plus the green control; Q38
admits n1 and n2 (its C22/C23 holes); Q39 `9b09f328...` refuses all five
(rc 2 / stdout 0 B / no fixture file touched / live delta 0) and runs the pair
green (164 passed / 0 failed, `Q39 OK`, 17 legs watched, delta 0 on each).
Nothing deployed, no `cp`, `/root/.helm/bin/`, `decisions/` and `inbox/`
untouched. Deliverable `recoveries/helm-deployed-gate-admission.md` (5,633 B /
sha256 5bdd2e7503cced8eee5b31a0256500aaa8eda9f8e3adbb80d3702eeb5e8df61a).
2026-10-12 11:42:14 +00:00
Merlin 4e87c8fee5 Q39 landing evidence: the three files read back 200 and cmp byte-identical over the anonymous raw path (record 12,253 / 56e25f16, queue 587,985 / 3884ebf8, check-in pre-append 38,651 / d16b8ef2); live snapshot aa842b0f delta 0 and deployed bin untouched after the push 2026-10-12 09:32:59 +00:00
Merlin fad802c0f5 Q39: the destination guard's admission is keyed on the subject's own destination, and every leg is watched (Helm lane)
Five repairs to the Q38 gate (74aba348 -> 9b09f328, +309/-38): the probe injects
from pathlib import Path so the rewritten line cannot NameError; EVERY SNAPSHOT_PATH
assignment is rewritten; a probe that dies with a traceback is refused; an ast scan
refuses an absolute path literal resolving inside /root/.helm/data/; and live bytes
and mtime are read around every subprocess and around the subject's in-process
import, a change dying the run and restoring the bytes it read.

Negative controls (q39-negatives.py, Q39-NEGATIVES.json): five fixtures, each run
under BOTH gates. n1 (the incident's shape) and n2 (a probe that dies with a
traceback) are ADMITTED by the Q38 gate - n1's in-process import writes the
fixture's destination inside the gate's own run - and refused by the Q39 gate.
Green pair: 5 consecutive invocations, rc 0, 164 passed / 0 failed, 17 legs
watched, live delta 0 on every run. Live snapshot aa842b0f delta 0 throughout;
nothing deployed, decisions/ and inbox/ untouched.
2026-10-12 09:32:18 +00:00
Merlin 4ed1da96ae Q38 landing evidence: the three files read back 200 and cmp byte-identical over the anonymous raw path (guard 10,232 / 69e72474, queue 570,365 / c18ffd4c, check-in pre-append 30,506 / 35a7ad50); live snapshot aa842b0f delta 0 and deployed bin untouched after the push 2026-10-12 07:07:13 +00:00
Merlin 0776480b51 Q38: the destination guard is behavioural, not documented (Helm lane, Q36 candidate 2)
Q35's precondition reads a source marker (--deploy and SNAPSHOT_PATH.resolve() in the subject's
source), so a subject that documents the rule in a comment without implementing it is admitted —
the pipe measured exactly that at 02:4xZ today. The gate now, at helm-selftest.py:117-211, after
the Q35 check and before the subject import (:784) and G8's bare-refusal leg (:1079-1081, the Q34
incident's leg), runs a copy of the subject's source with its SNAPSHOT_PATH = assignment rewritten
to a sentinel path as a subprocess bare, and refuses the subject (exit 2, no leg runs) unless that
run exits non-zero, writes nothing, and leaves the live snapshot delta 0. The probe never imports
the subject into the gate's process.

Measured this run (scratch tree /root/crucible/q38/, nothing deployed):
- 7 consecutive green invocations, exit 0 each, 164 passed / 0 failed and ALL GATES PASS in every
  log, the Q38 OK line present in all seven, live snapshot sha256+mtime read around every
  invocation with delta 0 throughout.
- Discriminator on both sides: fake-documented-no-rule.py (both markers in its docstring, so the
  Q35 predicate over its source is true) exits 2 with the refusal naming probe rc=0 and the
  sentinel written (74 B / 817e3830...); fake-marker-only.py (the pipe's measured shape) exits 2 at
  the assignment step; the deployed collector exits 2 at the Q35 source check with zero Q38 lines —
  the ordering. The admission control: fake-marker-only.py under the Q35 gate runs G7 and dies at
  the subject import (AttributeError, helm-selftest.py:688) — the admission measured end to end.
- Gate 1,044 -> 1,141 lines (+97/-0; DIFF.txt 108 lines / ac8e52bb...), sha256 643e5387... ->
  74aba348...; collector byte-identical to the Q34/Q35 pair (4e45021d..., 720 lines).
- Live snapshot /root/.helm/data/snapshot.json 14,039 B / aa842b0f... / mtime_ns
  1791479579475780303, delta 0 across every leg; deployed bin untouched (ee0b36a8 / 7ed1bca8 /
  5c67473d); decisions/ and inbox/ untouched; no another-party file edited.

Section 4 consequence: the adoption pair is now collector 4e45021d... + gate 74aba348...
(superseding 643e5387...); the cp into /root/.helm/bin/ remains Alexander's.
2026-10-12 07:06:41 +00:00
Merlin f19243d3e6 Q35: Run 2 landing evidence appended to the check-in (readback table: helm-precondition-gate.md 200/8261 sha a5d3ad6a, WORK-QUEUE.md 200/537076 sha 28c7250b, check-in 200/12471 sha 814cda6e pre-append, all cmp byte-identical over the anonymous raw path; live snapshot aa842b0f/14039/mtime_ns 1791479579475780303 delta 0 across the whole Run 2; deployed bin untouched ee0b36a8/7ed1bca8/5c67473d; nothing deployed) 2026-10-12 02:37:49 +00:00
Merlin dd0bc69061 Q35 DONE: the destination-rule guard is a precondition, not a report (recoveries/helm-precondition-gate.md, scratch /root/crucible/q35/).
The subject collector named by HELM_COLLECTOR is checked for the rule (--deploy and SNAPSHOT_PATH.resolve() in its source) at helm-selftest.py:96-114 BEFORE the subject is imported (:679) and before G1, and refused with exit 2, a stderr message naming the subject and the missing rule, and the live snapshot read before/after the refusal. Gate +61/-2 (985 -> 1044 lines, 45e53187 -> 643e5387); collector byte-identical to the Q34 pair (4e45021d); the precondition registers no check() so the suite count is unchanged at 164 and the old foot-of-suite source check is kept at :1032.

Seven consecutive green invocations (164 passed / 0 failed each, log digests in the deliverable), live snapshot delta 0 across every leg (aa842b0f / 14039 B / mtime_ns 1791479579475780303). Discriminator both sides in one run pair: deployed pre-gate collector as subject -> exit 2, stdout 0 bytes (e3b0c442, no summary and no PASS line, which is how "no leg executed" is measured), live delta 0; missing subject refused the same way, not crashed. Mechanism probe from this tree (q35-mechanism.py, mech-probe.log): default destination rebound to scratch, bare main() -- deployed ee0b36a8 rc=0 no refusal, 18523 B written (9331b218, schema helm.snapshot/1); pair 4e45021d rc=2, refusal naming the path and --deploy, nothing written.

Limits stated: the gate run bare now refuses itself (default subject is the pre-gate deployed collector; the section-4 cp is what makes the shipped gate green, Alexander's); the precondition reads a source marker, not behavioral proof; the rule protects the gate's legs, not a direct CLI run. Nothing deployed; decisions/ and inbox/ untouched.
2026-10-12 02:37:25 +00:00
Merlin ac98bfb53c Q34: landing evidence appended to the check-in (readback table: helm-null-gate.md 200/9924 sha 84b1e714, WORK-QUEUE.md 200/521480 sha 602746a5, check-in 200/6442 sha 08afa919, all cmp byte-identical over the anonymous raw path; live snapshot aa842b0f/14039/mtime_ns 1791479579475780303 delta 0; deployed bin untouched ee0b36a8/7ed1bca8/5c67473d; nothing deployed, the §4 cp is a three-file ask now) 2026-10-12 00:29:31 +00:00
Merlin a16d9e45be Q34 DONE: the pointer's null case is gated (recoveries/helm-null-gate.md, scratch /root/crucible/q34/). Four checks planted in the gate's own scratch tree between two collects on a profile with sessions/ and logs/ and no files: latest_active_path null, source_path still the profile directory, the key present with value null rather than absent, and a follow-up collect where a planted file sets the pointer while the citation holds; the member analogue stated unreachable by construction. Seven consecutive green gate invocations (exit 0, 164 passed 0 failed each, the Q33 160 plus these four), log digests in the deliverable. Red on both comparators: Q33-before collector under the full gate exit 1 / 153 passed 11 failed (the Q33 nine plus Q34 checks 3 and 4); pre-Q33 collector 2 passed 2 failed on the four checks by module import with no subprocess leg; checks 1-2 pass vacuously on both comparators and are reported as vacuous. The collector did not move (byte-identical to the Q33 pair, 4e45021d, 720 lines); the gate moved +56/-0 (929 -> 985 lines, 45e53187), so the §4 adoption ask is now a three-file ask. One incident logged first: the first red leg ran the full gate against the pre-Q33 collector, which has no destination gate, so the bare --skip-tests leg wrote the live snapshot (aa842b0f -> e4d1ad5, 14039 -> 18524 B, mtime_ns 1791479579475780303 -> 1791764761933369921 at 00:26:01Z); restored byte-exact from /root/crucible/q31/snap-before.json with the mtime re-stamped and the comparator re-run by import only; live snapshot delta 0 across every leg after the restore. Deployed bin untouched. Limits: a live empty profile is unobserved; checks 1-2 vacuous on the comparators; the null value is not schema-constrained. 2026-10-12 00:28:38 +00:00
Merlin dded721159 Q33: landing evidence appended (readback table, untouched-file re-verification) 2026-10-11 22:21:13 +00:00
Merlin 8bb88da1d3 Q33 DONE: the newest-file pointer is its own named field (evidence.latest_active_path / newest_checkin_file), source_path is a stable citation everywhere, the Q32 pointer carve-out is deleted from the gate; 6 consecutive green gate invocations (160/160 each), 8 paired runs with zero differing leaf paths without the carve-out, the gate red on the pre-Q33 collector (8 behavioural checks), consumer walk done; C5 appended to helm-g8-scrub.md Limits; collector 4e45021d + selftest 4a442f62 scratch-local, adoption is Alexander's 2026-10-11 22:20:43 +00:00
Merlin 83e92530d6 Q32: landing evidence appended (readback table, untouched-file re-verification) 2026-10-11 20:00:06 +00:00
Merlin 7e12c82506 Q32 DONE: the G8 two-run agreement check is deterministic — declared scrub set covers every clock-derived field (age_seconds, last_active_at, last_checkin_at, the newest-file pointer), 6 consecutive green gate invocations, 8 paired runs with zero differing leaf paths; collector 8a477376 unchanged, adoption identity is now collector 8a477376 + selftest 9ce6a4e9 2026-10-11 19:59:42 +00:00
Merlin ebf5226451 Q31: append final landing-evidence figures (Merlin) 2026-10-11 13:32:41 +00:00
Merlin bf5028732e Q31: landing evidence block for run 6 (Merlin) 2026-10-11 13:32:13 +00:00
Merlin 300228b44c Q31: collector's entry point executed, destination gated, G8 gate (Merlin run 6) 2026-10-11 13:31:39 +00:00
Merlin e2a8246785 check-in: Run 5 landing evidence (adfff7a) — all three files 200 and byte-identical over the anonymous raw path; live Helm page re-verified unchanged at 9,865 B / 427b7b54…; selftest 119/119 2026-10-11 11:16:48 +00:00
Merlin adfff7a39a Q30 DONE: the renderer's entry point runs, and it refuses production by default
- reproduced the defect first: python3 helm-render.py exits 1 with
  NameError: name 'build_page' is not defined (guard at :90-91 above
  def build_page at :232), same with --out, no file written
- moved the __main__ guard to the end of helm-render.py (:495 of 495);
  --out/--as-of semantics unchanged; fixed renderer 21,766 B sha256
  5c67473d89283c3d4434928dc96d45ff48a41d8f443ecc3c98e9236be8b597f9
- destination gate per the 09:21Z control-plane addendum: OUT_DEFAULT is
  production, so main() resolves the destination and refuses without
  --deploy (exit 2, message naming the path and flag); parse_args now
  returns (out, now, explicit_out, deploy)
- gate G7: the CLI executed in a subprocess, asserting emitted bytes
  (exit 0, file exists, bytes equal build_page()'s at the pinned clock,
  byte count matches, --as-of honoured, live root untouched); production
  destination refused by default and by explicit --out at the prod path
  (resolve(), not string equality); --deploy branch exercised against a
  patched OUT_DEFAULT; source-order guard so the defect cannot return
- gates re-run: 119 passed, 0 failed (102 before; G7 adds 17); the gate
  discriminates - the same command against the pre-fix file exits 1
- CONTRACT.md appended append-only: transcripts, digests, gate, and a
  revision note on :213-214 (deploy is now --deploy)
- nothing deployed: live page 9,865 B / 427b7b54c69b18d2... and snapshot
  aa842b0fd88037f8... unchanged before and after every run; --deploy
  alone never executed
2026-10-11 11:16:20 +00:00
Merlin 577d476f9c check-in: Run 2 landing evidence (ca48895) — all three files 200 and byte-identical over the anonymous raw path; live Helm page re-verified unchanged at 9,865 B / 427b7b54c69b18d2… and still serving the five false FRESH badges 2026-10-11 09:09:35 +00:00
Merlin ca4889584e Helm run 2: the page aged and it lied about it
recoveries/helm-render-aging.md — the served Helm page (9,865 B / sha256
427b7b54c69b18d270288910fc810732463129f48ec4bdd7dbc75cdb22997ce4, read
2026-10-11T08:53:51Z) carried five false FRESH badges and a "5 green" pill on a
snapshot 2d 15h 40m old, against its own rule "green = measured OK and fresh".
The honest reading was 0 green / 6 not green. The same page served
manifest_match: true while a fresh collect returns False (live
5e5cd6d26a700423... vs held f27326e8b13d1dec...). No Helm cron job exists.

helm-render.py now re-derives every badge from each source's own observed_at
against the collector's threshold table (imported, not copied), recomputes the
verdict, and stamps the page with its snapshot age, a STALE READING/CURRENT
banner naming the stalest source and its ratio, and a per-card evidence line
carrying the limit each reading aged past. --as-of pins the render clock.

Roster identity was filename_body.split("-")[0], which registers
zephyrus-sparkborn as two members; it is now the longest roster prefix, with
unrecognised bodies reported in troupe_standup.unrecognised_bodies rather than
silently attributed. Fresh collect: 4 members, unrecognised_bodies: [].

The site digest was unreproducible from outside: run() uses text=True, so
live_body_sha256 is over the CRLF->LF-normalised body. 217,162 wire bytes /
9a5ee1328d4a3fedd... vs 217,149 normalised / 5e5cd6d26a700423..., delta 13 = the
13 CRLF pairs, lone CR 0, raw.replace(CRLF,LF) == normalised. The snapshot now
records live_body_sha256_wire and names the rule; both reproduce via
curl | sha256sum and curl | tr -d '\r' | sha256sum.

helm-selftest: 102 passed, 0 failed, six gates. Three defects of mine are logged
first in the deliverable: (1) the first renderer ran at module scope, so
importing it overwrote the production page — reverted byte-exact from a pre-run
copy and re-verified; (2) build_page() referenced an undefined SNAPSHOT and
78/78 passed because nothing called it; (3) card() was passed the evidence
sub-dict instead of the source block, so no card printed its limit. A gate that
does not execute the path it protects is not a gate — G5 renders real HTML at a
pinned clock and asserts on the emitted bytes.

Nothing deployed: /var/www/alexander-whitestone/helm/index.html unchanged at
9,865 B / 427b7b54c69b18d2... throughout; staged pages live in
/root/crucible/helm/. Deploy is one command and Alexander's under section 4.
/root/.helm/data/snapshot.json not clobbered (aa842b0fd88037f8... before and
after). No secret printed; decisions/ and inbox/ untouched; no other party's
file edited; no X page fetched.
2026-10-11 09:08:58 +00:00
Merlin 1a58ae487d landing evidence for Q29 (cf3547c): anonymous raw readback, 200 + cmp-identical on all three files 2026-10-11 06:50:46 +00:00
Merlin cf3547cd1a Q29 DONE: render-site-guards.md - the guards that are not the walk (22 fixtures + control, second guarantee stated, one finding: unguarded int(sats) leaves a partial tree) 2026-10-11 06:50:32 +00:00
Merlin 71da58427a check-in: Q28 landing evidence (Merlin) - 7ce4ea0 pushed, all three files 200 and byte-identical over the anonymous raw path; shared tree untouched, live index unchanged 2026-10-11 04:40:48 +00:00
Merlin 7ce4ea0a4b queue: Q28 render-site channels DONE (Merlin) - 20 channels, 13 by fixture (19 fixtures, every negative exit 1 with 0 writes), 7 measured exclusions; the walk is the guarantee restated in one sentence; the no-token control byte-identical at 91ecf6bf with 125 files; two corrections in prose (36 esc call lines / 43 occurrences, not 28; Q27's fixture breakdown sums to 41-42 against its own 35-row log); shared tree untouched at 97fedb5d / 63c9cee6, live index 200 / 34,488 B / 4f764ef4dfb9; nothing executed 2026-10-11 04:40:31 +00:00
Merlin f494bcd051 check-in: Q27 landing evidence (Merlin) - 08013ba pushed, all three files 200 and byte-identical over the anonymous raw path (readback 8ab0221e / 34716145492bd265 / 0b19045f3c961830); shared tree untouched, live index unchanged 2026-10-11 02:33:13 +00:00
Merlin 08013ba55a queue: Q27 render-site coverage DONE (Merlin)
32 emit sites in build_blocks.py enumerated from the source (28 esc calls plus the 4
prose panels): 28 covered by fixture, 4 stated structural exclusions. 35 fixtures,
every negative exit 1 with 0 files written (4 valid-panel builds expand, 12
malformed-panel dies, 4 uncited dies, 10 non-panel field dies, 2 URL-field dies, 3
class-field dies, head/index/pager/gap/genesis, 1 no-token control).

URL-field scope decided: a token in a URL must die - safe_url rejects the non-https
body_source_url value, the pre-write sentinel scan catches the https-with-token and
excerpt cases, all exit 1 with 0 files.

The queue's scope clause closed with option (a): check_uncited() runs above OUT.mkdir
so all four token classes are pre-write (the uncited fixture wrote 20 files before the
patch, 0 after, same message).

No-token build still byte-identical at 91ecf6bf (125 files, diff -rq vs the shared
site-ledger silent). Shared tree untouched at 97fedb5d with blocks.json 63c9cee6; live
index 200 / 34,488 B / 4f764ef4dfb9. Patched builder c4127c6c is scratch-local,
nothing staged; decisions/ and inbox/ untouched.
2026-10-11 02:32:48 +00:00
Merlin 6724816681 check-in: Q26 landing evidence (Merlin) - f05179e pushed, all three files 200 and byte-identical over the anonymous raw path 2026-10-11 00:25:21 +00:00
Merlin f05179e89e queue: Q26 hardening DONE (Merlin) - the two silent token classes now die at build time (pre-write sentinel scan, per-entry panel set so the quote branch is caught by construction, render_genesis panels routed through expand_prose), all five Q25 legs re-run green on the hardened prototype (no-token build byte-identical at 91ecf6bf, 125 files, diff -rq vs live tree silent, registry still 8, uncited-handle negative still exit 1, H1-H4 demo still 3 of 125 files), 12 negative fixtures all exit 1 with their own message (7 malformed incl. open brace/empty handle/whitespace/wrong namespace/over-15-chars/lone close/close-then-open, 5 outside-panel incl. quote branch, title, excerpt, display_name, coverage gap) plus a cited-token positive control expanding on the entry page AND the genesis page; contributor.display_name fifth slot measured without building it - G2 and I2 take the handle-only fix, G1 needs display_name as a fifth panel to anchor @AnthonyDessauer beside the single handle slot (a build change, Alexander's); hardened convention carries 4 of Q24's 31 deltas as links (H1-H4); shared build tree untouched at 97fedb5d with site-ledger byte-identical and nothing modified since 2026-10-10 18:00Z, live index 200/34,488 B/4f764ef4dfb9, blocks.json read-only, decisions/ and inbox/ untouched, nothing executed 2026-10-11 00:25:06 +00:00
Merlin 0c48152341 check-in: Q25 landing evidence (Merlin) - a9f23a6 pushed, all three files byte-identical over the anonymous raw path 2026-10-10 22:17:41 +00:00
Merlin a9f23a69a4 queue: Q25 prose-anchor convention DONE (Merlin) - {{x:HANDLE}} token prototyped in scratch, no-token build byte-identical (tree digest 91ecf6bf, 125 files), validator negative-tested, census 46 rows/23 handles (20 resolve/1 moved/2 404), 4 of 24 Q24 clauses upgraded (H1-H4); shared build tree untouched 2026-10-10 22:17:19 +00:00
Merlin a57df4ab7b check-in: Q24 landing evidence (Merlin) - commit 3c8623f pushed, all four files read back byte-identical over the anonymous raw path 2026-10-10 20:08:21 +00:00
Merlin 3c8623fda4 queue: Q24 the Q13 fix pack DONE (Merlin) - 25 clauses / 31 deltas staged unrun, 1 decided + 24 undecided, blast radius 20 of 125 emitted files; the finding is that the ledger build has no anchor mechanism for the prose panels, so every 'anchor it' clause naming a source in body/plain_summary cannot be staged as a link by any blocks.json field; Q25 proposed per Q7 (a prose-anchor convention, implemented in the build tree and left unpublished) 2026-10-10 20:07:48 +00:00
Merlin 8b56abe688 queue: Q23 named-unlinked source liveness DONE (Merlin) - 4 sources, 3 resolve / 1 404 2026-10-10 17:53:09 +00:00
Merlin f0d684e66d check-in: append Q22 landing evidence 2026-10-10 15:46:18 +00:00
Merlin 5c7a75fd9b queue: Q22 named-source liveness DONE (Merlin) — 28 fetches, 27 sources, 6 entries with a dead name 2026-10-10 15:46:04 +00:00
Merlin 8c1aea3f1a check-in: Q21 landing evidence read back over the forge (deliverable 200/110,696 B, sha256 47ff51b0..., byte-identical; queue 200/304,736 B; check-in 200/20,789 B) 2026-10-10 13:36:09 +00:00
Merlin e3b2f4ba18 queue: Q21 excerpt-binding census DONE (Merlin) - 121/121 entries, 319 excerpts, 116 anchors all 200: 311 bound (300 verbatim / 7 marked-elision / 4 URL-tokenised), 4 mis-bound, 4 unanchored, 0 unreadable; the four mis-bound are one defect (block-25/88/89/90 attach the Skinner Stacking corroboration quote to the bare site root, which detags to 5,009 chars with Skinner x0 while the passage is verbatim at /a-conversation-with-burnchainers/, the publication's only ?s=Skinner article result); the four unanchored are the The-block testimony quotes on the same pages (correct for Testimony only); 38 named-source rows with Q12's StackchainQuant (handle 404) and @a_koby findings reproduced; zero anchors with empty excerpts, zero internal bindings; two comparator defects of mine logged (</a> as block closer + single unescape vs double-escaped entry pages; spaced-only ellipsis splitter); Q22 proposed (named-source handle liveness) as the queue fell to one executable item (Q20) 2026-10-10 13:35:36 +00:00
Merlin 0d1e8d5393 check-in 2026-10-10 (Q12 landing evidence: push aab23e5..67b892d, anonymous raw GET of recoveries/evidence-tier-audit.md 200 / 19,516 B / sha256 625bfb1e9afd9ba byte-identical to disk) 2026-10-10 09:09:03 +00:00
Merlin 67b892d7bb Q12 DONE: are the evidence tiers earned? (recoveries/evidence-tier-audit.md) - 18/18 justified, 0 too strong / 0 too weak / 0 indeterminate, no badge in the sample misstates its evidence; sample rule stated before any fetch (every non-documented entry = all 6: 5 testimony_only + 1 corroborated + 0 unrecovered, plus every 9th documented entry in index order = 12, total 18 of 121); census reproduced from the live index (200 / 34,488 B / sha256 4f764ef4dfb9, grep 'badge documented' 115 / testimony 5 / corroborated 1 / unrecovered 0 = 121 <li id=); all 18 entry pages and 17 cited sources fetched live this run, 33 of 37 quoted excerpts >=25 chars verbatim in a source the entry cites, and 8 of 12 sampled magazine entries carry a displayed date equal to the cited article's own article:published_time to the day; five named findings, none a badge overstatement - (1) block-25/88/89/90 quote the 'Skinner Stacking' passage and link the bare site root which contains 'Skinner' 0 times while the passage is verbatim at /a-conversation-with-burnchainers/ (200 / 155,217 B / sha 50a2e57e3ba6), the publication's only ?s=Skinner result; (2) event-2022-08-18 names StackchainQuant's October account twice, links it nowhere, and x.com/StackchainQuant returns 404 'User Profile Not Found', its badge still earned by the post text verbatim x3 and tx ae63c499 confirmed at height 749999 / 2022-08-18T17:45:12Z / 851,979 sats; (3) magazine-026 names @a_koby with no anchor; (4) the legend's Unrecovered tier is defined and applied 0/121 times while material fitting it sits in lower-tier Uncertainty panels; (5) Documented on the 91 magazine entries is a liveness claim not a held-artifact claim (Receipt panel says 'No receipt is held', and bitcoinmagazine.com answered 403 to a Chrome UA and 200 / 341,802 B to a bare curl UA in the same minute); limits: 18 of 121 is a sample, the 6 non-documented are a complete census of their tiers and the 12 documented license no rate for the other 103, all byte counts and hashes are dated readings from this host ~09:0x UTC, nothing live edited; check-in 2026-10-10-merlin.md; Q12 status block appended; Q20 next, Q9 blocked on the audio handover, Q13/Q19 gated on Alexander, depth not thin so no new item opened 2026-10-10 09:08:47 +00:00
Merlin b378277f46 check-in: landing evidence for Q6 (commit 8bd0b09 pushed aeac3ea..8bd0b09; anonymous raw read 200 / 15,239 B / sha256 1f5cc9ba..., cmp byte-identical) 2026-10-08 17:29:05 +00:00
Merlin 8bd0b09928 Q6: public guide to checking the archive (docs/how-to-check-this-archive.md) — every command run before submission; badge census 115/5/1 and 121=91+22+8 reproduced, magazine-040 worked example: sourcing holds, 'a nod to the last block he mined' unsupported (mined/last block/mining = 0 occurrences); check-in for 2026-10-08 merlin (Crucible run 2) 2026-10-08 17:28:47 +00:00
Merlin 1f84d252e3 check-in 2026-10-08 (first check-in; Helm P0 shipped) 2026-10-08 17:19:41 +00:00