sots-re/verify/results/shim/l1/README.md
alex 4f805e381a L1: CDiff crosses at frame 50, and the AI client seed is fresh in every process
Two results from the same VM session, both of which needed a workload the
corpus cannot supply.

CDiff, played forward. ref-turn2 loaded and 49 End Turns driven through the UI
helper to frame 51, with the entry hook emitting one record per turn:

  50 calls, frames 2..51, EXACTLY TWO STORES
    frame  2  -1 -> 0
    frame 50   0 -> 1     <- the modelled tier transition, at the modelled frame
  and 47 turns between them on which the writer ran and wrote NOTHING

predict_path was computed at entry from the transcribed threshold table on all
fifty turns and agreed with the cdiff region on every one. Frame >= 100 is still
a code read and is not claimed as a measurement.

The AI seed probe (asked for by the coordinator, ranked above CDiff). Hooks on
Mars::RNG::Seed and StrategyApp::RunAI, two launches from turn1-state, load
only. Every AI client seed differs between processes -- net 32, 496 and 512 all
move -- while the record structure is identical and one Seed call with seed=0
produces a byte-identical state in both runs.

So the turn1-state -> turn2 nondeterminism is a SEED effect, not the ordering
effect predicted, and the 'one of three varies' observation is explained by two
of the three empires having a research pick that is robust to the stream. This
falsifies lane AI1's 'every draw from the static generator returns 0', which
that lane had explicitly flagged as arithmetic rather than measurement.

Where the seed comes from is NOT established; the finding names the one hook
that would settle it and the six values it must reproduce.

VM140 left as found: the 8-file save set with its oracle bytes intact.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ARBgSooAfokKUy6wKUKEyZ
2026-09-08 18:23:19 -04:00

31 lines
3.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Lane L1 — the turn-begin RNG run, 2026-09-08
Instrument: `sots-engine` `wip/l1`, build `0117495-dirty-20260908T2113Z`. Findings:
`findings/control-flow/hive-creation-rng.md` and `findings/subsystems/snlv-measured.md`.
| file | what |
|---|---|
| `trace-et1.jsonl` | `l1-turn1.sav` (= `verify/results/saves/turn1-state.sav`) + **one** End Turn — the hive-creation turn. `SVSOSwarmQueen::RegisterHives` words 170 → 172. |
| `trace-et2.jsonl` | the same session after a **second** End Turn; the second bracket is 192 → 211 with a residual of 0. Supersedes `trace-et1.jsonl`, which is kept because it is the record as it stood before the control turn existed. |
| `trace-oracle.jsonl` | `ref-turn2.sav` + one End Turn with the same build and config. This run reproduced the determinism oracle byte for byte (`bb4fd9ac…` / `978041ac…`), so it is the rule-19 control for everything in the other two. |
| `watch-arm.txt` | the `watch.mode=snlv` arming sweep: all 28 systems with `AFlags`, `SnLv` and the decoded per-player 2-bit contact levels, plus the canary self-test. |
| `watch-hits.txt` | 24 hardware watchpoint hits — 20 writes to Spica's `SnLv` (all from 0x0086a789) and 4 to its `NVO` record's `{touched, TShn}` pair. |
| `saves/l1-t1t2-post.sav` | post-turn autosave of the hive-creation turn, **full L1 hook set**. |
| `saves/l1-t1t2-post-hooksoff.sav` | the same turn with **`hooks=off`, nothing installed**. It differs from the line above AND from the historical `turn2-state.sav`, in one field: player 3's `ResTNm`. See the finding's §6.1 — this pair is why `turn1-state.sav` must not be used as a determinism oracle. |
| `saves/l1-t2t3-pre.sav`, `saves/l1-t2t3-post.sav` | the second bracket's two autosaves. |
| `rep.py` | the reader used for every table in the finding: prints each record's hook, depth, `rng` word delta and non-pointer arguments. `uv run python3 rep.py trace-et2.jsonl`. |
## Added later the same session
| file | what |
|---|---|
| `trace-playforward-f51.jsonl` | `ref-turn2.sav` played forward **49 End Turns** to frame 51, `shim.cfg.l1hive`. One `UpdateDifficultyTier` record per turn. |
| `cdiff-frames-2-51.txt` | that trace reduced by `cdiff.py`: 50 entries, **exactly two stores** — frame 2 (`CDiff` −1 → 0) and **frame 50** (0 → 1) — and 47 turns on which the writer ran and wrote nothing. |
| `cdiff.py` | the reducer. `uv run python3 cdiff.py trace-playforward-f51.jsonl`. |
| `trace-seed-proc1.jsonl`, `trace-seed-proc2.jsonl` | the AI seed probe: `l1-turn1.sav` loaded in two freshly launched processes under `shim.cfg.l1seed`, hooks on `Mars::RNG::Seed` and `StrategyApp::RunAI`, **no End Turn**. |
| `seed-two-processes.txt` | both rendered side by side. Every AI client seed differs; the structure does not. See `findings/subsystems/ai-client-seed-is-per-process.md`. |
| `seedrep.py` | the reader for those two. |
**The VM was left as it was found:** the 8-file `SavedGames` set with the oracle bytes
`(Autosave).sav` = `978041ac…`, `(Autosave EndTurn).sav` = `bb4fd9ac…`,
`(Autosave Backup).sav` = `978041ac…`, and the working file `l1-turn1.sav` removed.