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.
150 lines
9.7 KiB
Markdown
150 lines
9.7 KiB
Markdown
# G10 — the deployed Helm page is a stale generation of the renderer, and the self-test cannot see it
|
||
|
||
**Merlin · Helm lane · Run 28 · 2026-10-14T13:0x–13:2xZ · this host**
|
||
Scratch tree `/root/crucible/q58/`. Nothing deployed: no `cp` into `/root/.helm/bin/`,
|
||
no write to the live document root, no `--deploy` anywhere in the G10 block.
|
||
`decisions/` and `inbox/` untouched, no another-party file edited, no secret printed.
|
||
|
||
---
|
||
|
||
## 1. The finding, measured
|
||
|
||
The Helm's `stackchain_site` card publishes a tamper/drift signal: the live body's
|
||
sha256 compared against a **pinned** copy. A pin comparison is a point-in-time
|
||
reading. The renderer was fixed (2026-10-11) to say so, on its own clock.
|
||
**The fix was never deployed, and the page the public reads still carries the
|
||
defect the fix removed.**
|
||
|
||
| # | what | measured |
|
||
|---|---|---|
|
||
| 1 | live pinned site | `GET https://www.stackchainmagazine.net/` → **HTTP 200 / 217,163 B / sha256 `c34ae2c245117ca73ba5720b2c22b6fab689840070ff68cda7bffe3e723986d4`** (UA `curl/8.5.0`) |
|
||
| 2 | the held pin | `/root/.helm/data/held/stackchain-home.html.sha256` → **120 B / sha256 `5b6d70716153c3f4bd82045d5d71edf88f793a240ce1275c3dfca5759d0ee297`**, text `f27326e8b13d1dec… stackchain-home.html pinned 2026-10-08T16:58:07.100Z` |
|
||
| 3 | pin vs live, now | **`pin_matches_live_now: false`** — `f27326e8…` ≠ `c34ae2c2…` |
|
||
| 4 | what the snapshot claims | `manifest_match: true`, `live_body_sha256: f27326e8…`, `observed_at: 2026-10-08T17:12:59.458Z` (snapshot 14,039 B / `aa842b0fd880…`) |
|
||
| 5 | the **deployed** page | `/var/www/alexander-whitestone/helm/index.html` → **9,865 B / sha256 `427b7b54c69b18d270288910fc810732463129f48ec4bdd7dbc75cdb22997ce4`** / mtime **2026-10-11T08:57:14.017Z**; renders `<span style="color:#22c55e">match</span>`; **`as_of=False`, `not_rechecked=False`** |
|
||
| 6 | the renderer that carries the fix | `helm-render.py` **21,766 B / sha256 `5c67473d89283c3d4434928dc96d45ff48a41d8f443ecc3c98e9236be8b597f9`** / mtime **2026-10-11T11:12:43.756Z** — **8,129.7 s later** than the deployed page |
|
||
| 7 | the real snapshot through the real renderer | `python3 /root/.helm/bin/helm-render.py --out <scratch>/helm-scratch.html --as-of 2026-10-14T00:00:00.000Z` → **rc 0**, **11,798 B / sha256 `f32191223931e74b421c1412833d6f225385f01d6ab2ff6dd4a38b414f25bccc`**, carrying `as of 2026-10-08T17:12:59.458Z · 5d 6h 47m ago · not re-checked since` |
|
||
|
||
So the live page states, in green, that a pin matches — against a pin that
|
||
**measurably does not match** — with no clock and no disclaimer. The fix exists in
|
||
the source tree, works, and was never rendered into the document root.
|
||
|
||
### Why the self-test was green
|
||
|
||
- `helm-selftest.py:420-421` — `check("G5", "the manifest claim carries its own clock and says it was not re-checked", "not re-checked since" in html and "as of 2026-10-08T17:12:59.000Z" in html)` — runs on a **synthetic fixture** (`fp`) at a **pinned clock**, with `hr.SNAPSHOT = fp`.
|
||
- `helm-selftest.py:422-425` — `check("G5", "build_page() writes nothing to the live document root", Path("/var/www/…/index.html").read_bytes() != html.encode("utf-8"))` — proves only that `build_page` did **not overwrite production**. It never compares the deployed page against the current renderer.
|
||
|
||
**A gate that tests the producer cannot vouch for the artifact in the document
|
||
root.** That is the class, and it is the same law Q40 and Q34 were filed under,
|
||
in a new place: the fix's own test passes while the fix is absent from production.
|
||
|
||
## 2. The fix — gate G10, four checks
|
||
|
||
On the Q45S10 gate `c56230e5a075c5a12fd2f0d336dcac71c1078cb692a9e6c995780098a051f13e`
|
||
(147,151 B / 2,798 lines / 127 registrations), inserted before the report block,
|
||
anchor `# ---------------------------------------------------------------- report`
|
||
asserted `count == 1`.
|
||
|
||
| gate | bytes | sha256 | lines | `check("` |
|
||
|---|---|---|---|---|
|
||
| `helm-selftest-q58.py` | **153,469** | **`3b98b62fa5c7ea626091f6d0f63566de79818ae414bcffe323dd1ddd53956158`** | **2,916** | **131** (127 + 4) |
|
||
|
||
No `--deploy` anywhere in the G10 block (`g10_block_has_deploy_flag: false`).
|
||
Every render goes to `--out` inside the gate's own scratch dir.
|
||
|
||
1. **The contract, on real data** — the real snapshot through the real renderer's
|
||
CLI at a pinned clock carries the qualifier. `PASS`
|
||
2. **The deployed artifact** — the page the public reads carries it. **`FAIL`**
|
||
3. **The discriminator** — the predicate returns true on a current-generation
|
||
render and false on a body with no qualifier. `PASS`
|
||
4. **Read-only** — bytes + sha256 + mtime_ns identical around the gate. `PASS`
|
||
|
||
### The discriminator, and the prediction stated before the run
|
||
|
||
`run_twin_q58.py` builds a twin: the shipped gate with `_g10_deployed` repointed at
|
||
a **scratch** path holding a current-generation render (`ast`-asserted, and the
|
||
G10 block contains no live-path token in any non-comment line).
|
||
|
||
| gate | reads | rc | verdict | G10 check 2 |
|
||
|---|---|---|---|---|
|
||
| shipped | the live page | **1** | **180 passed, 1 failed** | **FAIL** |
|
||
| twin | a scratch current-generation render | **0** | **181 passed, 0 failed** | **PASS** |
|
||
|
||
Predicted before the run: *"shipped 180/1, the one FAIL is G10 check 2; twin 181/0,
|
||
check 2 flips to PASS, every other row identical."* **Met exactly.** A red row that
|
||
cannot go green would prove nothing; this one goes green on the artifact it exists
|
||
to check.
|
||
|
||
- shipped: stdout **15,055 B / sha256 `e8304379529c4c8336a69e013d0eed464b7eddfe65cbf1895e6e41344a11b4de`**, stderr 1,791 B
|
||
- twin: stdout **14,824 B / sha256 `fe8c8c72825962d9ff08df7963be4b6cefa727958339b2a3bcd57482e3052d25`**, stderr 1,810 B
|
||
- the twin's stand-in is 11,798 B / `f32191223931e74b…`, renderer rc 0, carries the qualifier
|
||
|
||
### Live state, across all four gate invocations
|
||
|
||
`live_page_moved: false` on every one (bytes + sha256 + mtime_ns): 9,865 B /
|
||
`427b7b54c69b18d2…` / mtime_ns `1791709034017837233`. Snapshot 14,039 B /
|
||
`aa842b0fd880…` / mtime_ns `1791479579475780303` and held pin 120 B / `5b6d7071…` /
|
||
`1791478687099553071` unmoved. **Sandboxes 0/0 both ways** (shallow glob and
|
||
recursive `rglob`) before and after.
|
||
|
||
## 3. Byte-stability, measured not asserted
|
||
|
||
Two shipped runs: both **180 passed / 1 failed** at 15,055 B, and
|
||
`byte_stable_stdout` read **false**. Not smoothed over — the difference is
|
||
`mkdtemp` suffixes in the sandbox path the gate prints (`/tmp/tmp8wl8eb44` vs
|
||
`/tmp/tmpsp0jt2_3`; `helm-legs-gb5_6rox` vs `helm-legs-5rzmq0xa`;
|
||
`helm-q39-dlb_ysgs` vs `helm-q39-3i6olv_3`; `q31-g8-deploy-9mcza30j` vs
|
||
`q31-g8-deploy-v7_v9zrw`). Normalising those four patterns:
|
||
|
||
- the four **G10 rows are byte-identical** across both runs (`G10 block byte-identical: True`)
|
||
- normalised stdout sha256 **`1958d8212fa60e4458ba85b86221e459dcd2f7eaffc0351668e6b74f31e77856`** on both runs, `identical: True`, **residual differing lines: 0**
|
||
|
||
The sandbox path's effect on stdout is the lane's logged full-path-delta class; the
|
||
G10 rows themselves are stable, which is the part any reader would re-derive.
|
||
|
||
## 4. Deployed bin, unchanged
|
||
|
||
`/root/.helm/bin/` re-read after every run — `helm-collect.py` 27,907 B /
|
||
`ee0b36a82f23…`, `helm-render.py` 21,766 B / `5c67473d8928…`, `helm-selftest.py`
|
||
33,647 B / `7ed1bca8f9da…`, `helm-validate.py` 3,556 B / `12570786ba70…`,
|
||
`summarize.py` 1,463 B / `738699986778…`. **`grep -c HELM_COLLECTOR` on the deployed
|
||
self-test = 0** — Q40 stands, so **G10 is not in production** and nothing from
|
||
Q31 to Q45S10 is either. Disk `154G total / 110G used / 45G avail / 72%`.
|
||
|
||
## 5. Defects of mine, logged first
|
||
|
||
1. **Two claims in one cell.** The first G10 check 3 asserted *the predicate
|
||
discriminates* **and** *the deployed page fails it*. That would have made the
|
||
twin 180/1 rather than 181/0, hiding the discriminator behind the finding.
|
||
Split: check 3 is now a pure predicate test (green in both gates), check 2 is
|
||
the finding. This is the class the lane returns to counterparties for.
|
||
2. **A filter written from memory.** `summarise_r28.py` extracted report rows with
|
||
`startswith("PASS")` / `startswith("FAIL")`, which never matches the two-space
|
||
rendering — `PASS count: 0`, `FAIL lines: []`. The lane's own logged defect
|
||
class, reproduced by its author on a fresh artifact. Fixed with
|
||
`.strip().startswith`.
|
||
3. **A live-path assertion that fired twice on the wrong thing.** First on G5's
|
||
pre-existing read-only check at `:422-425`, then on G10's own explanatory
|
||
comment. Scoped to the G10 block and to non-comment lines.
|
||
4. **`byte_stable_stdout: false` reported as found**, with the cause measured by
|
||
normalisation rather than argued away.
|
||
5. **`ast.unparse` renders single quotes**; the first twin assertion expected
|
||
double and failed on a correct edit.
|
||
6. **`import pathlib` is not in the gate** — it uses `from pathlib import Path`
|
||
(`:154`). The first patch draft wrote `pathlib.Path` and would have raised
|
||
`NameError`; caught by an import census before the run, not after.
|
||
|
||
## 6. What is owed, and to whom
|
||
|
||
- **Alexander, under §4:** (a) re-render and re-deploy the Helm page — the command
|
||
is in §1 row 7 — because until then the public page publishes a green "match"
|
||
against a pin that measurably does not match; (b) the §4 adoption `cp`, now
|
||
collector `4e45021d80395d3f03fc58d7e99610e3c1c0d2fcf9c85f1db50b16cfd2043c6c`
|
||
+ gate `3b98b62fa5c7ea626091f6d0f63566de79818ae414bcffe323dd1ddd53956158`.
|
||
Neither is a task; both are decisions, and this record does not execute them.
|
||
- **Nothing is owed to the pipe from this run**, and no queue item was opened: the
|
||
Helm lane's *executable* set was empty at the start of the run (Q49's
|
||
`Status: open and unclaimed` at `WORK-QUEUE.md:6847` is stale — the pipe'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.
|