diff --git a/campaign/backlog.md b/campaign/backlog.md index a8638ba..09b03cd 100644 --- a/campaign/backlog.md +++ b/campaign/backlog.md @@ -52,6 +52,15 @@ So the rungs are: replays the AI's (and human's) orders captured from a real turn, and the output must match that turn's autosave byte-for-byte. This is what "the engine is the game" means when the game's own decision layer is not reproducible from a save. Lane AI1's fallback becomes the primary path. + + **Correction 2026-09-09.** I previously told lane RB that Rung B was insulated from the strategic + generator "because replay runs no AI". That was wrong, and the resolver caught it. Replay **does** + run the post-combat tail (`command_replay.h:83`), and lane AC has now measured a **sim** draw in + that tail — on `S+0x16c`, gated on a predicate over save fields, nothing to do with the AI. So + **Rung B needs the same generator model as Rung A**: the tail's draws are ours to reproduce in + both. The canonical pair is untouched by the predicate (`tscr = 252`, no fleet at a trade sector), + so nothing already measured is invalidated — but a replay of any raid turn would have diverged + silently under the reasoning I gave. - **Rung C — `game/ai` as a deterministic function of (save, per-client seed).** The original's AI is not non-deterministic: it is MT19937 from **one 32-bit word per AI client**, drawn once at construction from a per-process global generator — and that generator is one we already own bit diff --git a/campaign/board.md b/campaign/board.md index f325fdf..e923a05 100644 --- a/campaign/board.md +++ b/campaign/board.md @@ -404,3 +404,4 @@ Status flow: `backlog → in-progress → mapped → verified` (or `blocked`). | MY ERROR: Rung B IS affected - replay runs the tail | meta | verified | high | 100% | 2026-09-09 | I told lane RB that command-stream replay was unaffected by a tail draw "because replay runs no AI". **Wrong.** The resolver: this is a **sim draw on S+0x16c keyed on save state**, and `--turn-commands` replay **runs the tail** (`command_replay.h:83`). **Rung B needs the same generator model as Rung A.** The canonical pair happens to be untouched by the predicate (tscr = 252, no fleet at a sector), so nothing measured is invalidated - but the reasoning I gave RB was wrong and would have bitten on any raid-turn replay | | AC's numbers are at probes=11, which is NOT byte-neutral | verify | verified | high | 100% | 2026-09-09 | The resolver's exoneration is partial and precise. **The tail's +1 stands** - control 0 / active 1 under identical guest, build and config, with the callee going 0 -> 1 entries on the same turns. **But every AC number is at `probes=11`, which lane H bisected as NOT byte-neutral**, and AC's own predictions doc promised a `probes=8` primary reading **it never took**. Consequences: the turn totals 20/18 are **not calibration data**, and **no AC autosave is an oracle pair**. `ac-turn22-raider.sav` remains a valid INPUT state. A reminder that rule 19's control must be at the configuration you are quoting | | lane Z's ledger: the method is sound, the AUDIT is not | meta | verified | high | 100% | 2026-09-09 | The resolver's structural ruling. A bracket state-difference **cannot miss a draw that happens** - the instrument is sound. But **the audit is indexed by FIRING**: a site enters the table when a state reaches it, so **it can only grow by luck** (hives, now the raid roll - two qualifications in two days). **What makes the next audit complete: GATE-INDEXED** - one row per statically reachable site (lane I's 22+28, V2's 8, L1's hive, node-line decay, the SVSO overrides), each carrying **either a measured firing or a decoded predicate on save fields plus the corpus count satisfying it**. Today's unfilled rows are named: 0x0088b613, 0x0082cdb8, 0x0088dc43, the spy-13 family, and the SVSO generator which is still unknown | +| rule 24 earns its keep in the OTHER direction | meta | verified | med | 100% | 2026-09-09 | The AC merge gate, run properly for the first time on **fresh** build dirs on both halves, failed the shim cross-build: `ai_orders.cpp` tripped `-Werror=array-bounds` because gcc reasons about a `reinterpret_cast` from `uintptr_t` as an object of its own once the read inlines at a constant offset. Three earlier gate runs on a **reused** `build-shim` reported the DLL present and green - they were relinking nothing. Note the direction: rule 24's first instance was a stale dir hiding a **fix** (a passing test that was really stale); this one is a stale dir hiding a **break**. A reused build directory does not bias toward good news or bad, it reports the past. Fixed with the asm barrier `watchpoints.cpp` already uses for its TIB reads; engine `0c6d0a3`, host 58/58 and shim both green on fresh dirs |