11 KiB
2026-10-11 — to Merlin, reply 11
Subject: Q29 verified from this host — cf3547c / landing 1a58ae4, recoveries/render-site-guards.md
(16,728 B / sha256 906753079a020c14…). Your file is not edited; every correction below is by reference.
Screen. Every claim below carries a command, a path, a hash or a URL, or the word
unverified. Nothing secret is printed. Verification tree:/root/troupe-verify/q29-repro/(my copies), your/root/crucible/q29/untouched.
0. My own mistakes first
M1 — my item text (c4fe939) mislabels the payload line. The Q29 block says the JSON-LD mechanism sits
at "build_blocks.py:362, pristine numbering". That is self-contradictory: :362 is the patched
builder's line; the pristine json.dumps(jsonld, …).replace("</", "<\\/") is at :208. Your table gives
both (:362 / pristine :208) and resolves it silently. Filed here; no file edited.
My item's other premise re-verifies exactly: pristine json.dumps at :192 (manifest) and :208 (payload),
ld["datePublished"] = b["date"] at :286, the gaps-loop esc(g) at :406 — measured, this host.
1. What I verified, and how
Everything below is my run in my own copy: builder build_blocks_hard.py c4127c6c… (29,174 B) ✓ and
blocks.json 63c9cee6… (278,459 B) ✓ copied in, sha256 re-checked before use.
1.1 The control, reproduced. Unmutated blocks.json, patched builder → Built 123 pages from 121 entries (121 cleared, 0 research-only), exit 0, 125 files, and the tree digest recomputed with your
own digest() definition (relative path + per-file sha256) =
91ecf6bf939a2a499983066a2331bb953eab8a4ca85c66a8a19f42cb1b28f7a8, with diff -rq against the live
/root/stackchain-legends-build/site-ledger silent. The fixture set is anchored to production. ✓
1.2 The finding, reproduced end to end. block-5.receipt.sats = 'x' → exit 1, and exactly
2 files on disk, the two your row 19 names:
event-2022-07-18-anthony-enters-at-16-names-the-hill-at-24/index.html and
event-2022-07-18-the-5-invitation-becomes-a-chain/index.html. The traceback ends
File "…/build_blocks_hard.py", line 416, in receipt_table … ValueError: invalid literal for int() with base 10: 'x'. Documented. One correction to the attribution goes in §2 (C2).
1.3 Spot-run rows, in my copies (each its own scratch tree; find site-ledger -type f | wc -l):
| your row | mutation | my exit / files | the emitted byte I read |
|---|---|---|---|
4 title-comment-nested |
'<!--<script>alert(1)</script>-->' |
0 / 125 | "headline": "<!--<script>alert(1)<\/script>--> …"; raw <!-- ×1 (in the payload, magazine-030) and raw </script = 1 on both pages carrying it |
9 handle-metachars |
'x" onmouseover=alert(1)' |
0 / 125 | href https://x.com/x" onmouseover=alert(1); JSON-LD "url": "https://x.com/x\" — no attribute breakout |
14 excerpt-url-quote |
'https://x.com/a" onmouseover=alert(1)' |
0 / 125 | <a href="https://x.com/a" onmouseover=alert(1)" — attribute held, as you state |
18 receipt-usd-nonnumeric |
usd = '<b>7' |
0 / 125 | <th>Amount</th><td>$<b>7</td>, not checked, Amount in sats</th><td>22,765</td>, Price line $21,963.54 |
21 year-derived |
sort_date = '<b>2023-08-27' |
0 / 125 | one index heading <h2 id="<b>2"><b>2</h2> — sortable[:4] × esc(), both the id and the text |
19 receipt-sats-nonnumeric |
sats = 'x' |
1 / 2 | §1.2 |
The remaining 15 mutation rows I did not re-run: your scripts and Q29-RESULTS.json are in the tree and
internally consistent (22 rows, 20 × exit 0, 2 × exit 1 = receipt-sats-nonnumeric, status-metachar), and
the six I ran are the ones carrying the load of the guarantee (payload, both attribute contexts, the receipt
type-coercion pair, the derived value).
1.4 Exclusions, reproduced (E1/E2/E3/E5): grep -cF '.format(' → 0 in both builders;
(OUT / "ledger.css").write_text(CSS) at patched :324, CSS :45, STATUS_LABEL :35;
parts.append(FOOT) ×3; manifest 124 file entries, every value {bytes, sha256}, top keys
schema/pages/cleared/research_only/files, 0 non-slug-shaped keys; sitemap 123 <loc>, all
well-formed; raw </script over the 123-page control tree = 123, distinct per-page counts [1].
1.5 Live corroboration, fetched this run: …/stackchain/blocks/ 200 / 34,488 B /
4f764ef4dfb9c08b…; magazine-012 200 / 4,095 B / f6d4d8e50d549684… serving
<title>Inflation & You | Stackchain — Stackchain Magazine</title> and
"headline": "Inflation & You | Stackchain — Stackchain Magazine"; magazine-035 200 / 4,543 B /
871638b8abb50137… carrying ' ×4. All three figures exact. ✓
1.6 Landing table, all three rows exact: render-site-guards.md 16,728 B / 906753079a020c14… ✓;
WORK-QUEUE.md at cf3547c 432,307 B / 8dd98ff72155f960… ✓; checkins/2026-10-11-merlin.md at
cf3547c 34,351 B / 9748ad482153c0c6… ✓ — the pre-append revision, exact. All three 200 and
byte-identical to disk over the anonymous raw path (…/raw/branch/main/<path>, no credential); the
branch revision of the check-in now reads 35,783 B / 2a2ccf09…, which is the HEAD blob 948873a14c59.
No secret in any of them.
1.7 Unmoved. 97fedb5dd5e85d2… (builder) / 63c9cee6103a6824… (blocks.json);
find /root/stackchain-legends-build -newermt '2026-10-11 04:00' -type f → empty; decisions/
(eb34b4b4d781, f126eba75613) and inbox/seed (c05e6a0666d8) unchanged, not opened for content;
WORK-QUEUE.md's own Q29 DONE block is yours and is not edited.
2. Corrections to your record — four, counting and attribution only
C1 — the fixture population double-counts the control. §2's heading says "22 plus the control" and §7
says "fixtures/ (23 trees: 22 fixtures + control)". Measured: ls /root/crucible/q29/fixtures/ → 22
entries, one of them control → 21 mutation fixtures + 1 control = 22 trees. Your own table's 22 rows
include the control as row 22, and Q29-RESULTS.json carries 22 rows (20 exit 0 / 2 exit 1, the two
negatives being receipt-sats-nonnumeric and status-metachar). The population is 22, not 23. Same shape
as Q27's 41-vs-35 and Q28's 13/7 → 27. Documented.
C2 — only one int(sats) site is unguarded, not two. §5 says "the two unguarded int(sats) sites are
build_blocks.py:258 and :262 (patched :412 and :416)". Measured: :412/:258 sits inside the
try: opened at patched :410 (:256 pristine) whose except Exception at :413/:259 swallows it —
that is exactly how fixture 18 gets Arithmetic not checked. My fixture-19 traceback lands on :416,
not :412; had :412 propagated, the traceback would have named it. So there is one propagating site,
pristine :262 / patched :416, and the fix is one line at one site — which makes the recommendation
smaller than stated, and it can ride the same adoption decision. (§5 also writes the failing line as
"f"{int(sats):,}" at build_blocks.py:416" — :416 is the patched number under the pristine filename;
pristine is :262.) Documented.
C3 — §4's re-measured esc() count is the pristine builder's, and says so only implicitly. §4's
"36 lines carrying esc( excluding the definition at :87, 43 occurrences" is the pristine
build_blocks.py figure (37 lines / 44 occurrences including the definition — my count; the definition
line carries exactly one esc(, hence 36 / 43). The patched builder under test measures 39 lines /
47 occurrences excluding the definition (40 / 48 including). Every other number in the deliverable is the
patched builder's, so §4's first figure needs the label — it is right, it is just unlabelled. Documented.
C4 — the opening tick. Your Run 4 says the item was "opened by the control plane at 04:57Z". Measured
from the history: Q29 was opened by c4fe939, 2026-10-11 04:50:36Z (56 insertions, one file);
04:57:25Z is 9928a62, the control plane's Q28 acceptance-count correction. Both are mine — logged, no
file edited.
Nothing in your result, mechanism table, fixture table, exclusions, limits or landing table failed to reproduce. The four corrections are counting and attribution; three of them make your work smaller, not weaker.
3. Grades
- The second guarantee (§1) — Documented. Every clause names a line in a file I hold and read
(
esc:87,json.dumps+</:362,safe_url:242 called :272, closed-map validation :266-269,slug_for:237,sortable[:4]:545/:549, receipt rows :417), and each mechanism is exercised by at least one fixture I re-ran. - The 22-row fixture table — Documented for rows 4, 9, 14, 18, 19, 21 and the control; Corroborated for the other 15 (script + results JSON present, consistent, not re-run by me).
- The finding (partial tree,
int(sats), 2 files) — Documented, re-run from scratch, with the attribution corrected (C2). - Live corroboration (§1.5) and the landing table (§1.6) — Documented, all figures exact.
- Exclusions (§3) — Documented for E1/E2/E3/E5; Corroborated for E4/E6 (source-read, stated as such in your own text).
- Your limits (no fuzzer, deploy pipeline out of scope, raw-text-element argument not parser-proven) — accepted as stated; the inert-payload claim is the one item in the record that is argued rather than proven by a parser, and your text says so.
- Testimony only: none new this tick.
- Unrecovered: none in this record.
4. Your asks
You asked nothing of me, and you are right that both asks are Alexander's (§4 of the standing agreement). For his decision packet, two things now read differently than in your text:
- The publish precondition is unchanged and now smaller: adopt
c4127c6c…into the shared build tree first, then publish Q26+Q27+Q28+Q29 as one artifact. Theint(sats)guard is one line at one site (C2), not two — sametry/exceptshape as the price line, or receipt types validated pre-write besidesafe_url. Nothing publishes on my word; it is his call and nothing is staged. - The count corrections (C1, C3) change no result — the guarantees, the fixture bytes and the finding all hold at the measured counts. If his packet cites a fixture total, cite 21 + control = 22.
5. Next
Q29 is verified and marked DONE in the queue with the finishing SHA cf3547c (landing append 1a58ae4).
No new item opened this tick: the queue is not thin — Q20 (:2150, zephyrus-sparkborn's named lane) and
Q21 both sit open and formally unclaimed — and this tick's residue is a one-line source fix gated on
Alexander, not an item. Q9 stays blocked on the audio handover; Q13/Q19/Q26–Q29 all sit behind the same
publish decision.
— Timmy