diff --git a/WORK-QUEUE.md b/WORK-QUEUE.md index 8779863..47a81ad 100644 --- a/WORK-QUEUE.md +++ b/WORK-QUEUE.md @@ -3234,3 +3234,12 @@ where it is. This is a scope clause on Q27 — not a new item, and not a reopeni silent classes die loudly, with the fixture set and both negative classes proving it) is met and verified. To be carried in the next reply to Merlin. +**Status: DONE 2026-10-11 — `recoveries/render-site-coverage.md` (Merlin). 32 sites: 28 covered by fixture, 4 structural exclusions; 35 fixtures, every negative writes 0 files; the scope clause closed with option (a), all four token classes now pre-write; no-token build still byte-identical at `91ecf6bf`.** +- **Site inventory, enumerated from the source not the data:** 32 named sites — 28 `esc()` calls that render a `blocks.json` value plus the 4 prose panels — each with its `build_blocks.py` line number, field and landing. One row per site in the deliverable's row table: fixture (class), exit code, files-written-at-failure, first stderr line. +- **Fixtures (35):** 4 valid-panel builds (`{{x:arizonanhodl}}` cited, expands — 4 anchors on `magazine-001`, leg 4), 12 malformed-panel dies, 4 uncited dies, 10 non-panel field dies (`title`, `date`, `date_display`, `date_basis`, `contributor.display_name`, `excerpts[0].text`, `receipt.reuse_status`, …), 2 URL-field dies, 3 class-field dies (`status`/`ledger` die at entry validation: `unknown status '{{x:'`; `variant` at the sentinel scan), head-block JSON-LD author, index label/date, pager `n`, coverage gap, genesis body, 1 no-token control. **Every negative fixture exits 1 with 0 files written.** +- **URL-field scope decision — a token in a URL field must die**, measured both ways (`URL-CHECK.txt`): `body_source_url` non-https → `safe_url` fires (`must be https, got '{{x:'`); https-with-token → sentinel scan fires (`token sentinel {{ in a field that is not a prose panel`); `excerpts[].url` (no `safe_url`) → sentinel scan. All exit 1, 0 files. +- **Scope clause closed with option (a).** New `check_uncited()` (plus shared `panels_for()`), same `TOKEN_RE` scan and same message as `expand_prose`'s `die()`, runs **above `OUT.mkdir`**; `expand_prose` keeps the check as a backstop behind `pre_checked=True`. Measured: the `{{x:NotACitedHandle}}`-in-`uncertainty` fixture wrote **20 files** before the patch and **0** after — same message both times. All four token classes (sentinel, malformed, uncited, gap) are now pre-write. +- **Control:** unmodified `blocks.json` (`63c9cee6…`) through the patched builder → exit 0, **125 files, tree digest `91ecf6bf939a2a499983066a2331bb953eab8a4ca85c66a8a19f42cb1b28f7a8`** (the Q26 baseline), `diff -rq` against the shared `site-ledger` silent. Shared tree untouched: `build_blocks.py` still `97fedb5dd5e85d2…`, `blocks.json` `63c9cee6…`, nothing modified since 2026-10-10 18:00Z. Live index `200 / 34,488 B / 4f764ef4dfb9c08b…`. +- **Scratch only, not staged.** Patched builder `build_blocks_hard.py` sha256 `c4127c6c9325ed9f8cab03b80b454cccde0f9f1e768289ff216d2fb79e78dbf2` (29,174 B, diff `DIFF-SCOPE.txt` +65/−12) lives in `/root/crucible/q27/`; publishing it is Alexander's, the same gate Q26/Q13 state. +- **Testimony only:** none — every figure in this record came from a command in this run; the live index was fetched this run. +- **Q7, measured:** Q20 active (zephyrus-sparkborn's); Q9 blocked on the audio handover; Q13/Q19 gated on Alexander. The unclaimed executable set is empty again, so a successor is owed; this record does not open one. diff --git a/checkins/2026-10-11-merlin.md b/checkins/2026-10-11-merlin.md index 2e7e93a..6673b3d 100644 --- a/checkins/2026-10-11-merlin.md +++ b/checkins/2026-10-11-merlin.md @@ -156,3 +156,83 @@ Re-verified in the same breath: the shared build tree's `build_blocks.py` is sti `https://alexanderwhitestone.com/stackchain/blocks/` is 200 / 34,488 B / `4f764ef4dfb9c08b…`. `blocks.json` was read-only throughout; `decisions/` and `inbox/` were not touched and nothing was executed. + +--- + +## Run 2 — Q27: render-site coverage, and the scope clause closed (Merlin, 2026-10-11 ≈02:30 UTC) + +### Did + +Claimed and finished **Q27 — a fixture at every render site** (the top unclaimed item; Q20 is +zephyrus-sparkborn's, Q9 blocked on the audio handover, Q13/Q19 gated on Alexander). The item is +Q26 §9 limit 2's honest answer: Q26 proved 12 token classes die, not that every emit site is +watched. + +Deliverable: `recoveries/render-site-coverage.md` (**20,865 B / sha256 +`34716145492bd265cceb9cded8363f0a59a057862e1c90f74625e93b39d51ac1`**, this host). Scratch tree +`/root/crucible/q27/` (35 fixture trees under `fixtures/`, verify trees under `verify/`, re-runnable +with `python3 q27-fixtures.py` then `python3 q27-verify.py`). + +**32 sites, enumerated from the source, not the data:** 28 `esc()` calls that render a `blocks.json` +value plus the 4 prose panels, each with its `build_blocks.py` line number, field and landing. +One row per site in the deliverable — fixture class, exit code, files-written-at-failure, first +stderr line. **28 covered by fixture, 4 structural exclusions** (`slug`/canonical: `slug_for()` +sanitises `{{` out; `year`: a 4-char slice; sitemap `loc`: same sanitised slug; `contributor.handle`: +an account name interpolated into a URL by construction — and it still carries a die-fixture). +Every exclusion is a stated reason, not "no entry does". + +**35 fixtures, every negative writes 0 files.** 4 valid-panel builds (`{{x:arizonanhodl}}` cited → +expands; 4 anchors on `magazine-001`, moves nothing else), 12 malformed-panel dies, 4 uncited dies, +10 non-panel field dies (`title`, `date`, `date_display`, `date_basis`, `contributor.display_name`, +`excerpts[0].text`, `receipt.reuse_status`, …), 2 URL-field dies, 3 class-field dies (`status`/`ledger` +die at entry validation — `unknown status '{{x:'`; `variant` at the sentinel scan), head-block +JSON-LD author, index label/date, pager `n`, coverage gap, genesis body, 1 no-token control. + +**URL-field scope decision — a token in a URL field must die**, measured both ways (`URL-CHECK.txt`): +`body_source_url` non-https → `safe_url` fires (`must be https, got '{{x:'`); https-with-token → +sentinel scan fires; `excerpts[].url` (never passed through `safe_url`) → sentinel scan. All exit 1, +0 files. + +**The scope clause closed with option (a).** New `check_uncited()` beside a shared `panels_for()`, +running the same `TOKEN_RE` scan and the same message as `expand_prose`'s `die()`, **above +`OUT.mkdir`**; `expand_prose` keeps the check as a backstop behind `pre_checked=True`. Measured: the +`{{x:NotACitedHandle}}`-in-`uncertainty` fixture wrote **20 files** before the patch and **0** after — +same message both times (`BUILD FAILED: magazine-001:uncertainty: prose-anchor token names handle +@NotACitedHandle which no entry cites`). **All four token classes are now pre-write**, so the +partial-tree state the clause reproduced cannot arise from any of them. Patched builder +`build_blocks_hard.py` sha256 `c4127c6c9325ed9f8cab03b80b454cccde0f9f1e768289ff216d2fb79e78dbf2` +(29,174 B; diff `DIFF-SCOPE.txt`, +65/−12 over the Q26 prototype `d45cc28f…`). + +**Control:** unmodified `blocks.json` (`63c9cee6…`) through the patched builder → exit 0, **125 files, +tree digest `91ecf6bf939a2a499983066a2331bb953eab8a4ca85c66a8a19f42cb1b28f7a8`** (the Q26 baseline), +`diff -rq` against the shared `site-ledger` silent (leg 8). Leg 3: an uncited token in a +quote-branch `body` dies at `check_tokens` first (correct ordering — the sentinel class is the wider +net). Leg 7: the `pre_checked=False` backstop still dies on the same fixture. + +**Nothing touched.** Shared tree at `97fedb5dd5e85d2…` / `blocks.json` `63c9cee6…`, nothing modified +since 2026-10-10 18:00Z (leg 9). Live archive unchanged: `https://alexanderwhitestone.com/stackchain/blocks/` +**200 / 34,488 B / sha256 `4f764ef4dfb9c08b2654ff0783550d20ad1bb7a31cb0c32070974a5fe451557e`** at +2026-10-11 ≈02:31 UTC. `blocks.json` read-only throughout; `decisions/` and `inbox/` untouched, +nothing executed, no another-party file edited. Patched builder is scratch-local and stays there. + +### Blocked + +Nothing blocked the run. Deliberately unverified, recorded as such: the 4 structural exclusions are +**reasoned from the source, not fuzzed** — no random-token fuzzer ran against the builder, so "no +`{{` can survive `slug_for()`" is a code-reading claim backed by the sanitising regex +(`[^a-z0-9-]+` → `-`, build_blocks.py:93) and the 4-char slice (`sortable[:4]`), not by a fixture. + +### Next + +- **Alexander's call, not mine:** whether to publish the patched builder (the scope-clause close is + a real behavioural change: uncited-handle failures can no longer leave a partial tree). Scratch + until he says so — the same gate Q26/Q13 state. +- **Q7, measured:** Q20 active (zephyrus's); Q9 blocked on the audio handover; Q13/Q19 gated on + Alexander. The unclaimed executable set is empty again, so a successor is owed; this record opens + none — the successor should come from a fresh measurement, not from this run's own finding. + +### Ask + +1. **Alexander — publish, hold, or decline the scope-clause close.** It is the difference between + "20 files written on an uncited-token failure" and "0", on a prototype that is not in production. +2. **Nothing asked of zephyrus-sparkborn this tick.** His lane is Q20. diff --git a/recoveries/render-site-coverage.md b/recoveries/render-site-coverage.md new file mode 100644 index 0000000..a3810ec --- /dev/null +++ b/recoveries/render-site-coverage.md @@ -0,0 +1,206 @@ +# Q27 — render-site coverage: every emit site in build_blocks.py, one fixture each + +Author: Merlin. Run: 2026-10-11, scratch tree `/root/crucible/q27/` (all 35 fixture trees under +`fixtures/`, verify trees under `verify/`; re-runnable with `python3 q27-fixtures.py` then +`python3 q27-verify.py`). Nothing published, no `blocks.json` edit, nothing staged. + +Builder under test: `/root/crucible/q27/build_blocks_hard.py` — the Q26 prototype +(`d45cc28f7d69afcdab4eccb16e9e0cc264e4317e059e17f1ba53eb23f792cb60`, 27,878 B) plus this item's +scope-clause patch: **sha256 `c4127c6c9325ed9f8cab03b80b454cccde0f9f1e768289ff216d2fb79e78dbf2`**, +**29,174 B**. Diff `DIFF-SCOPE.txt` (77 lines, +65/-12). Pristine shared-tree builder +`97fedb5dd5e85d2b10071e8e4904b3a9b1573072149e722fbece93eaf0774672` — untouched (leg 9). + +## Method + +Every string the build emits comes from one of **32 named sites**: 28 `esc()` calls that render a +`blocks.json` value, plus the 4 prose panels (whose pristine `esc()` calls the Q26 prototype +routes through `expand_prose`). Sites are enumerated from the source with line numbers, not from +today's data, which is the difference between this item and Q26's §9 limit 2. Each site gets +either a fixture — a valid `{{x:}}` and/or a malformed `{{x:` token placed in that +field, with the raw exit code and first stderr line — or a stated structural reason no entry can +carry one there today. + +Fixture tokens: valid `{{x:arizonanhodl}}` (a cited handle), malformed `{{x:`, uncited +`{{x:NotACitedHandle}}`. Fixtures apply to `magazine-001` (a summary-branch magazine entry with +contributor, 3 excerpts, receipt-less), `magazine-002` (pager neighbour), entry `n=5` (block-5, +genesis, `body_kind` null → quote branch) and entry `n=6` (block-6, `body_kind: quote`). + +## Row table — one row per render site + +| site | build_blocks.py line | field | fixture (class) | exit · files | first stderr line | +|---|---|---|---|---|---| +| S01 | 215 | `title` | nonpanel:title | 1·0 | BUILD FAILED: magazine-001:title: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plain_sum | +| S02 | 216 | `title (as desc)` | nonpanel:title | 1·0 | BUILD FAILED: magazine-001:title: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plain_sum | +| S03 | 217 | `slug (via slug_for)` | **structural exclusion** — no entry field reaches it | — | see below | +| S04 | 208 | `ld object` | head:jsonld-author | 1·0 | BUILD FAILED: magazine-001:contributor.display_name: token sentinel {{ in a field that is not a prose panel (panels: body, body_pr | +| S05 | 238 | `status` | class:status | 1·0 | BUILD FAILED: block[30] unknown status '{{x:' | +| S06 | 239 | `ledger` | class:ledger | 1·0 | BUILD FAILED: block[30] unknown ledger '{{x:' | +| S07 | 241 | `variant` | class:variant | 1·0 | BUILD FAILED: magazine-001:variant: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plain_s | +| S08 | 263 | `receipt (k,v)` | nonpanel:receipt.reuse_status | 1·0 | BUILD FAILED: block-5:receipt.reuse_status: token sentinel {{ in a field that is not a prose panel (panels: body_provenance, plain | +| S09 | 266 | `receipt.reuse_status` | nonpanel:receipt.reuse_status | 1·0 | BUILD FAILED: block-5:receipt.reuse_status: token sentinel {{ in a field that is not a prose panel (panels: body_provenance, plain | +| S10 | 297 | `title / n` | nonpanel:title | 1·0 | BUILD FAILED: magazine-001:title: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plain_sum | +| S11 | 299 | `title` | nonpanel:title | 1·0 | BUILD FAILED: magazine-001:title: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plain_sum | +| S12 | 303 | `date_display / date` | nonpanel:date_display | 1·0 | BUILD FAILED: magazine-001:date_display: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, pl | +| S13 | 303 | `date_basis` | nonpanel:date_basis | 1·0 | BUILD FAILED: magazine-001:date_basis: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plai | +| S14 | 286 | `date` | nonpanel:date | 1·0 | BUILD FAILED: magazine-001:date: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plain_summ | +| S15 | 308 | `contributor.display_name` | nonpanel:contributor.display_name | 1·0 | BUILD FAILED: magazine-001:contributor.display_name: token sentinel {{ in a field that is not a prose panel (panels: body, body_pr | +| S16 | 310 | `contributor.handle` | **structural exclusion** (fixture `excl:contributor.handle` still dies) | exit 1 · 0 | see below | +| S17 | 325 | `body (quote branch)` | genesis:body | 1·0 | BUILD FAILED: block-5:body: token sentinel {{ in a field that is not a prose panel (panels: body_provenance, plain_summary.text, u | +| S18 | 323 | `body_source_url` | url-field:body_source_url | 1·0 | BUILD FAILED: magazine-001:body_source_url: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, | +| S19 | 333 | `excerpts[].url` | url-field:excerpts[0].url | 1·0 | BUILD FAILED: magazine-001:excerpts[0].url: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, | +| S20 | 335 | `excerpts[].text` | nonpanel:excerpts.0.text | 1·0 | BUILD FAILED: magazine-001:excerpts[0].text: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance | +| S21 | 351 | `n (prev)` | pager:n | 1·0 | BUILD FAILED: magazine-002:n: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plain_summary | +| S22 | 356 | `n (next)` | pager:n | 1·0 | BUILD FAILED: magazine-002:n: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plain_summary | +| S23 | 384 | `title` | index:label | 1·0 | BUILD FAILED: magazine-001:title: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plain_sum | +| S24 | 395 | `date/sort_date[:4]` | **structural exclusion** — no entry field reaches it | — | see below | +| S25 | 398 | `date_display / date` | index:date | 1·0 | BUILD FAILED: magazine-001:date_display: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, pl | +| S26 | 405 | `coverage.gaps[]` | index:coverage.gaps | 1·0 | BUILD FAILED: coverage.gaps[4]: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plain_summa | +| S27 | 325 | `body (genesis)` | genesis:body | 1·0 | BUILD FAILED: block-5:body: token sentinel {{ in a field that is not a prose panel (panels: body_provenance, plain_summary.text, u | +| S28 | 182 | `slug` | **structural exclusion** — no entry field reaches it | — | see below | +| S29 | 317 | `body (summary)` | panel-malformed:body | 1·0 / 1·0 | BUILD FAILED: magazine-001:body: malformed prose-anchor token — sentinel {{ left after token expansion; tokens must read exactly { | +| S30 | 340 | `plain_summary.text` | panel-malformed:plain_summary.text | 1·0 / 1·0 | BUILD FAILED: magazine-001:plain_summary.text: malformed prose-anchor token — sentinel {{ left after token expansion; tokens must | +| S31 | 342 | `body_provenance` | panel-malformed:body_provenance | 1·0 / 1·0 | BUILD FAILED: magazine-001:body_provenance: malformed prose-anchor token — sentinel {{ left after token expansion; tokens must rea | +| S32 | 344 | `uncertainty` | panel-malformed:uncertainty | 1·0 / 1·0 | BUILD FAILED: magazine-001:uncertainty: malformed prose-anchor token — sentinel {{ left after token expansion; tokens must read ex | + +**Totals: 32 sites — 28 covered by fixture, 4 structural exclusions** +(S03 `slug`/canonical, S16 `contributor.handle`, S24 `year`, S28 sitemap `loc`; S16 also carries a +die-fixture). 35 fixtures total: 4 valid-panel builds, 12 malformed-panel dies, 4 uncited dies, +10 non-panel field dies, 2 URL-field dies, 3 class-field dies, 1 head-block, 1 index, 1 pager, +1 gap, 1 genesis, 1 scope-clause measurement, 1 no-token control. Every negative fixture writes +**0 files** except the pre-patch scope-clause measurement (20 files, below). + +### The four structural exclusions, stated + +- **S16** — `contributor.handle` is an account name interpolated into a URL by construction (`https://x.com/{esc(handle)}`, line 310); a token there is a URL-value error, not a prose token. Fixture `excl:contributor.handle` proves it still dies pre-write (exit 1, 0 files, sentinel message), so it is covered by the sentinel scan, not expanded. +- **S03** — `slug` is `slug_for()`'s sanitised output (`[^a-z0-9-]+` -> `-`), so a `{{` can never reach the canonical href from an entry field; the fixture class cannot be placed there from blocks.json. The `n`-keyed neighbour fields it is built from are covered by S10/S21/S22. +- **S24** — `year` is `sortable[:4]`, a 4-char slice of a date string; `{{` cannot survive the slice from any entry value. The unsliced source is covered by S12/S14/S25. +- **S28** — sitemap `loc` is built from the same sanitised `slug`, so it inherits S03's exclusion; no blocks.json field reaches it unsanitised. + +## URL fields: the scope decision + +**Decision: a token in a URL field must die.** Both URL sites die pre-write on two different +guards, and the pair is measured directly (`URL-CHECK.txt`): + +- `body_source_url` (S18) with a non-https value: `safe_url` (build_blocks.py:96-101) fires + first — `BUILD FAILED: block[30]: source URL must be https, got '{{x:'`, exit 1, 0 files. +- `body_source_url` (S18) with an https value carrying the token (`https://x.com/{{x:`): + `safe_url` passes, and the pre-write sentinel scan catches it — + `BUILD FAILED: magazine-001:body_source_url: token sentinel {{ in a field that is not a prose + panel`, exit 1, 0 files. +- `excerpts[].url` (S19): `safe_url` is never called on excerpt URLs, so the sentinel scan is + the only guard — same sentinel message (`url-field:excerpts[0].url`, exit 1, 0 files). +- The class fields (`status`, `ledger`) die earlier still, at entry validation: + `BUILD FAILED: block[30] unknown status '{{x:'` (`class:status`, exit 1, 0 files). + +So a token in a URL field cannot ship: either `safe_url` rejects the value or the sentinel scan +rejects the field, and both answers are fixtures with raw exit codes, not silence. The sentinel's +declared scope is therefore stated to include URL fields. + +## The scope clause, closed with option (a) + +The queue's 2026-10-11 00:43Z clause allowed either moving the cited-handle check above +`OUT.mkdir` or restating the guarantee. **Option (a) is implemented**: `check_uncited()` is new +(build_blocks_hard.py, beside `panels_for()`), runs the same `TOKEN_RE` scan `expand_prose` runs, +with the same message, above `OUT.mkdir`; `expand_prose` keeps its `die()` as a backstop behind +`pre_checked=True`. `check_tokens` now shares `panels_for(b)` instead of re-deriving the set. + +Measured before and after (fixture `prewrite:uncited-handle` = `{{x:NotACitedHandle}}` in +`magazine-001.uncertainty`): + +| state | exit | files written at failure | +|---|---|---| +| before (Q26 prototype, `d45cc28f…`) | 1 | **20** (116 of 123 pages short of a full tree) | +| after (`c4127c6c…`) | 1 | **0** | + +Same message both times: `BUILD FAILED: magazine-001:uncertainty: prose-anchor token names handle +@NotACitedHandle which no entry cites`. **All four token classes are now pre-write**, so the +deliverable's finding-3 language (a partial tree indistinguishable from a partial publish) cannot +arise from any of them. + +## Verification legs (`Q27-VERIFY.txt`, full log) + +== leg 1: no-token build == +exit=0 files=125 digest=91ecf6bf939a2a499983066a2331bb953eab8a4ca85c66a8a19f42cb1b28f7a8 +digest matches Q26 baseline 91ecf6bf...: True +== leg 2: uncited pre-write (was 20 files before the patch) == +exit=1 files=0 BUILD FAILED: magazine-001:uncertainty: prose-anchor token names handle @NotACitedHandle which no entry cites +== leg 3: uncited in quote-branch body (check_uncited fires first) == +exit=1 files=0 BUILD FAILED: block-6:body: token sentinel {{ in a field that is not a prose panel (panels: body_provenance, plain_summary.text, uncertainty) +== leg 4: cited token in all four panels builds and expands == +exit=0 files=125 anchors on magazine-001 page: 4 +== leg 5: malformed still dies pre-write == +exit=1 files=0 BUILD FAILED: magazine-001:body: malformed prose-anchor token — sentinel {{ left after token expansion; tokens must read exactly {{x:HANDLE}} with a 1-15 character handle +== leg 6: gap still dies pre-write == +exit=1 files=0 BUILD FAILED: coverage.gaps[4]: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plain_summary.text, uncertainty) +== leg 7: backstop — expand_prose still dies on uncited when pre_checked=False == +exit=1 BUILD FAILED: magazine-001:body: prose-anchor token names handle @NotACitedHandle which no entry cites +== leg 8: control build byte-identical to shared site-ledger == +diff -rq output: '' rc 0 +files in shared site-ledger: 125 +== leg 9: shared tree untouched == +97fedb5dd5e85d2b10071e8e4904b3a9b1573072149e722fbece93eaf0774672 /root/stackchain-legends-build/build_blocks.py +63c9cee6103a6824c90c71440fa983d2f5592e380f9c3fb40f7ad366ae41723d /root/stackchain-legends-build/blocks.json +files newer than 01:00Z today: '' + +## Raw fixture log (`Q27-RESULTS.json`) + +| fixture | entry | exit | files | first stderr line | +|---|---|---|---|---| +| panel-valid:body | magazine-001 | 0 | 125 | (built) | +| panel-malformed:body | magazine-001 | 1 | 0 | BUILD FAILED: magazine-001:body: malformed prose-anchor token — sentinel {{ left after token expansion; tokens must read exactly {{x:HANDLE}} with a 1-15 charac | +| panel-uncited:body | magazine-001 | 1 | 0 | BUILD FAILED: magazine-001:body: prose-anchor token names handle @NotACitedHandle which no entry cites | +| panel-valid:plain_summary.text | magazine-001 | 0 | 125 | (built) | +| panel-malformed:plain_summary.text | magazine-001 | 1 | 0 | BUILD FAILED: magazine-001:plain_summary.text: malformed prose-anchor token — sentinel {{ left after token expansion; tokens must read exactly {{x:HANDLE}} with | +| panel-uncited:plain_summary.text | magazine-001 | 1 | 0 | BUILD FAILED: magazine-001:plain_summary.text: prose-anchor token names handle @NotACitedHandle which no entry cites | +| panel-valid:body_provenance | magazine-001 | 0 | 125 | (built) | +| panel-malformed:body_provenance | magazine-001 | 1 | 0 | BUILD FAILED: magazine-001:body_provenance: malformed prose-anchor token — sentinel {{ left after token expansion; tokens must read exactly {{x:HANDLE}} with a | +| panel-uncited:body_provenance | magazine-001 | 1 | 0 | BUILD FAILED: magazine-001:body_provenance: prose-anchor token names handle @NotACitedHandle which no entry cites | +| panel-valid:uncertainty | magazine-001 | 0 | 125 | (built) | +| panel-malformed:uncertainty | magazine-001 | 1 | 0 | BUILD FAILED: magazine-001:uncertainty: malformed prose-anchor token — sentinel {{ left after token expansion; tokens must read exactly {{x:HANDLE}} with a 1-15 | +| panel-uncited:uncertainty | magazine-001 | 1 | 0 | BUILD FAILED: magazine-001:uncertainty: prose-anchor token names handle @NotACitedHandle which no entry cites | +| nonpanel:title | magazine-001 | 1 | 0 | BUILD FAILED: magazine-001:title: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plain_summary.text, uncertainty) | +| nonpanel:date_display | magazine-001 | 1 | 0 | BUILD FAILED: magazine-001:date_display: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plain_summary.text, uncertainty) | +| nonpanel:date_basis | magazine-001 | 1 | 0 | BUILD FAILED: magazine-001:date_basis: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plain_summary.text, uncertainty) | +| nonpanel:date | magazine-001 | 1 | 0 | BUILD FAILED: magazine-001:date: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plain_summary.text, uncertainty) | +| nonpanel:contributor.display_name | magazine-001 | 1 | 0 | BUILD FAILED: magazine-001:contributor.display_name: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plain_summary.text, | +| nonpanel:excerpts.0.text | magazine-001 | 1 | 0 | BUILD FAILED: magazine-001:excerpts[0].text: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plain_summary.text, uncertai | +| nonpanel:excerpts.0.url | magazine-001 | 1 | 0 | BUILD FAILED: magazine-001:excerpts[0].url: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plain_summary.text, uncertain | +| nonpanel:body_source_url | magazine-001 | 1 | 0 | BUILD FAILED: block[30]: source URL must be https, got '{{x:' | +| nonpanel:receipt.reuse_status | 5 | 1 | 0 | BUILD FAILED: block-5:receipt.reuse_status: token sentinel {{ in a field that is not a prose panel (panels: body_provenance, plain_summary.text, uncertainty) | +| url-field:body_source_url | magazine-001 | 1 | 0 | BUILD FAILED: magazine-001:body_source_url: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plain_summary.text, uncertain | +| url-field:excerpts[0].url | magazine-001 | 1 | 0 | BUILD FAILED: magazine-001:excerpts[0].url: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plain_summary.text, uncertain | +| excl:contributor.handle | magazine-001 | 1 | 0 | BUILD FAILED: magazine-001:contributor.handle: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plain_summary.text, uncert | +| class:status | magazine-001 | 1 | 0 | BUILD FAILED: block[30] unknown status '{{x:' | +| class:ledger | magazine-001 | 1 | 0 | BUILD FAILED: block[30] unknown ledger '{{x:' | +| class:variant | magazine-001 | 1 | 0 | BUILD FAILED: magazine-001:variant: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plain_summary.text, uncertainty) | +| head:jsonld-author | magazine-001 | 1 | 0 | BUILD FAILED: magazine-001:contributor.display_name: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plain_summary.text, | +| index:label | magazine-001 | 1 | 0 | BUILD FAILED: magazine-001:title: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plain_summary.text, uncertainty) | +| index:date | magazine-001 | 1 | 0 | BUILD FAILED: magazine-001:date_display: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plain_summary.text, uncertainty) | +| index:coverage.gaps | coverage.gaps[4] | 1 | 0 | BUILD FAILED: coverage.gaps[4]: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plain_summary.text, uncertainty) | +| pager:n | magazine-002 | 1 | 0 | BUILD FAILED: magazine-002:n: token sentinel {{ in a field that is not a prose panel (panels: body, body_provenance, plain_summary.text, uncertainty) | +| genesis:body | 5 | 1 | 0 | BUILD FAILED: block-5:body: token sentinel {{ in a field that is not a prose panel (panels: body_provenance, plain_summary.text, uncertainty) | +| prewrite:uncited-handle | magazine-001 | 1 | 0 | BUILD FAILED: magazine-001:uncertainty: prose-anchor token names handle @NotACitedHandle which no entry cites | +| control:notoken | - | 0 | 125 | (built) | + +## Control: no-token build unchanged + +Unmodified `blocks.json` (sha256 `63c9cee6103a6824c90c71440fa983d2f5592e380f9c3fb40f7ad366ae41723d`) +through the patched builder: exit 0, **125 files, tree digest `91ecf6bf939a2a499983066a2331bb953eab8a4ca85c66a8a19f42cb1b28f7a8`** — the Q26 baseline, byte for byte — and +`diff -rq /site-ledger /root/stackchain-legends-build/site-ledger` silent. A cited token +placed in all four panels of `magazine-001` expands to exactly 4 anchors on that page and moves +no other file (leg 4). + +## Live archive, re-measured (2026-10-11) + +- `https://alexanderwhitestone.com/stackchain/blocks/` — **HTTP 200, 34,488 B, sha256 `4f764ef4dfb9c08b2654ff0783550d20ad1bb7a31cb0c32070974a5fe451557e`**. + +## Limits + +- **Scratch only.** The patched builder lives in `/root/crucible/q27/` and is not staged to the + shared tree; publishing it is Alexander's decision, the same gate Q26 and Q13 state. +- **Fixtures target one entry per shape, not a census.** Q26's §9 limit 2 was about *entries*; + this item's answer is about *sites*, and a site's behaviour does not vary by entry beyond the + two `body_kind` branches, both of which are exercised (S17/S27 quote-branch, S29 summary). +- **Testimony only:** none. Every number in this record was produced by a command in this run; + the live index was fetched this run. +