diff --git a/findings/control-flow/tail-rng-ledger.md b/findings/control-flow/tail-rng-ledger.md index 0e87526..95879be 100644 --- a/findings/control-flow/tail-rng-ledger.md +++ b/findings/control-flow/tail-rng-ledger.md @@ -386,19 +386,52 @@ Three things follow, none of which was knowable before: 3. It explains why the campaign never noticed: no save in the corpus is within 40 turns of a decay event, and the ones that could get there are the newest saves in it. -**Phase 11's draw therefore remains a path no save exercises — a hypothesis, and labelled one.** What *is* -now instruction-verified is the predicate that decides it (§6.1), and what is measured is the distance. +### 9.1 The prediction, and the turn it came true -### 9.1 The model is stated but not yet tested +Because `min_life` was falling by exactly 1 per turn — 43, 42, 41 … 30 at turn 34, with the traffic term +contributing nothing on this map — a numeric prediction became possible, and it was committed to +`sots-engine/docs/Z-tail-rng.md` §6 at turn 34 with the run still in flight: -`predict_words` is computed at hook entry, before the original runs, and recorded on every node-line-decay -record. It read **0** on every call and the measured delta was **0** on every call. That agreement is worth -exactly nothing as a test of the model — it is the "0 diverged while comparing nothing" shape this campaign -has already paid for — and it is reported that way rather than as a green tick. +> **P9. The first phase-11 draw happens on turn 64, and costs exactly 1 word.** Node-line decay records +> `np_min_life = 0`, `predict_words = 1`, and a measured `rng` delta of 1; the tail's total becomes 1 +> instead of 0; the bracket total becomes `ProcessTurn + 1`. -Compare mode was **not** run on this hook for the same reason: with a prediction of 0 and a measurement of 0, -`ours` would advance the scratch generator by nothing, diff clean, and prove only that the harness works. -The model becomes checkable the first time a line expires, and the descriptor is ready for that day. +The game was played to turn 64. **Every clause held.** + +| turn | node paths | mortal | min life | ≤5 | expired | `predict_words` | node-decay words | **tail words** | `ProcessTurn` | bracket | residual | +|---|---|---|---|---|---|---|---|---|---|---|---| +| 62 | 64 | 13 | 2 | 1 | 0 | 0 | 0 | 0 | 18 | 18 | 0 | +| 63 | 64 | 13 | 1 | 1 | 0 | 0 | 0 | 0 | 18 | 18 | 0 | +| **64** | 64 | 13 | — | 0 | **1** | **1** | **1** | **1** | 20 | **21** | **0** | + +**That is the first non-zero tail cost this campaign has ever recorded**, and it is exactly the draw lane K +found by reading 0x007ae095. The defect lane K warned about is no longer latent, no longer inferred and no +longer a hypothesis: **on turn 64 of this save, a reimplementation that models `ProcessTurn` perfectly and +stops would have written an autosave one generator word out of step, and every subsequent turn would +diverge.** + +`predict_words` is computed at hook entry, *before* the original runs, from the same `RemainingLife` +predicate transcribed in §6.1. It said 1; the measurement said 1. That is a real check of the model — as +opposed to the 63 preceding turns, where it said 0 and the measurement said 0, which checked nothing and was +reported that way. + +### 9.2 The twist path ran, live, on the same turn + +The instrument's thinnest part (§8: "the block-chain machinery has never run live") was exercised on this +very turn. `ProcessTurn` entered with `left = 11` and left with `left = 615` — it **crossed a block +boundary**, the generator twisted, and the ledger reported `11 + (624 − 615) = 20` words. Sixty-three turns +of measurements had all sat inside a single block, so every earlier word count reduced to a subtraction; this +one did not, and the bracket still reconciled to a residual of 0. + +### 9.3 What is still not settled about node lines + +* **One expiry, on one map.** 51 of the 64 lines are permanent; the 13 mortal ones are Zuul-dug. A + non-Zuul game may never produce a mortal line at all. +* **The `0x20000`-fleet gate has never been exercised**, because it only matters when the roll *succeeds* + and no fleet was riding this line. Whether the roll succeeded here is not visible in a word count — the + draw costs 1 either way, which is the whole point of §6's correction. +* **Two expiries on one turn has never been observed** (`np_within5` read 1, never 2), so "one word per + expired line" is confirmed for *one* line and extrapolated for two. --- diff --git a/verify/traces/tailrng-zuul-long.jsonl.gz b/verify/traces/tailrng-zuul-long.jsonl.gz new file mode 100644 index 0000000..6f9cfe6 Binary files /dev/null and b/verify/traces/tailrng-zuul-long.jsonl.gz differ