Lane BQ (VM145) takes the seed-exposure predicate's first forward test. Part 1b: ar-oracle-A-pre.sav + one End Turn from a LOAD must reproduce 7a8b3d5e... (it has only ever been reached by continuation). Part 1: ar-oracle-A-post.sav in two fresh hooks=off processes must DIFFER, confined to Player[32]'s research leaves, because that save carries ResTNm == '' for the one player that can research. Also records the exposure facts (ResTNm / NumDes / NumOwn / completions) for every player on both inputs, and names a false-positive class in the predicate before the run: four NPC players carry ResTNm == '' on the very turn whose control agreed, and all four have NumOwn == 0.
223 lines
13 KiB
Markdown
223 lines
13 KiB
Markdown
# The seed-exposure predicate's first forward test — probe 1 (parts 1b and 1)
|
||
|
||
- **Type:** control-flow / determinism (two `hooks=off` measurements from saves already on disk; no
|
||
build, no shim config change, no instrument)
|
||
- **Owner / date:** lane **BQ** · 2026-09-09 · guest **VM145** (`sots-re-win10-145`, 192.168.10.145)
|
||
- **Spec:** `findings/resolutions/2026-09-09-seed-exposure-is-a-predicate.md` §6, probe 1
|
||
- **Tests:** `guides/method-rules.md` rule 26 corollary (c) — the predicate written from lane AR's
|
||
falsified P7, so far supported only by three states read *after* the fact
|
||
- **Depends on:** `findings/control-flow/raid-target-pick-verdict.md` §6 (lane AR's pair)
|
||
|
||
---
|
||
|
||
## 1. Predictions, committed before either run (rule 2)
|
||
|
||
*Everything in §1 and §2 was written and committed before the game was launched on VM145 and before
|
||
any hash was read. It is not edited after the fact, only annotated with verdicts in §5.*
|
||
|
||
### 1.1 What is actually at stake
|
||
|
||
The resolver ruled that the per-process AI client seed (row 326) is present in **every** process on
|
||
**every** turn, and reaches the save **only** through a decision whose outcome set is larger than one
|
||
given the state — and that whether such a decision is reached is a **predicate on the pre-turn save**.
|
||
That ruling currently rests on three states read *after* their controls were run (lane AD's turn 28,
|
||
lane AS's turn 16, lane AR's turns 38–39). It has never made a forward prediction.
|
||
|
||
This lane makes two, on states nobody has run, and both can fail.
|
||
|
||
### 1.2 Part 1b — the precondition
|
||
|
||
**Procedure.** `ar-oracle-A-pre.sav` (Frame 38, sha256 `15b99255e1f03dab3e35ab8c1ac64f221cb5aa9321f113c7a6e3d1263c3f34ca`),
|
||
one fresh process, `hooks=off`, **one End Turn**, no other input.
|
||
|
||
> **P1b — committed.** The resulting `(Autosave).sav` (Frame 39) hashes to
|
||
> `7a8b3d5eb3a60ebac9f40646d3e4b15768a24a0af047a439ce090c7cf38e8b38`.
|
||
|
||
Why it matters. Lane AR's `15b99255…` → `7a8b3d5e…` step has only ever been reached **by
|
||
continuation** — the second of two End Turns inside one process that started from
|
||
`ar-turn37-816raiders.sav`. A calibration pair for the standalone must be a **load → turn**
|
||
procedure. If P1b holds, the single-turn pair is certified in that form and is the first pair
|
||
anywhere that exercises the trade-raid roll (four raid rolls, one word each, no encounter). If it
|
||
fails, the pair remains valid **only** as the two-turn procedure from turn 37, and the resolution
|
||
names the first suspect: the **resave canonicalisation** (`determinism-oracle.md`, round-trip
|
||
section).
|
||
|
||
> **P1b-aux — committed, and it costs nothing.** The same run also writes
|
||
> `(Autosave EndTurn).sav`, which is the state **as End Turn is pressed** — i.e. a resave of the
|
||
> file that was loaded. I predict it hashes to `15b99255…`, the input's own hash. **This is a direct
|
||
> test of the resave-canonicalisation suspect**, taken in the same run whichever way P1b goes:
|
||
>
|
||
> - P1b holds **and** P1b-aux holds ⇒ load→resave is byte-exact here and the pair is clean.
|
||
> - P1b fails **and** P1b-aux fails ⇒ the divergence is present *before the turn runs*; it is the
|
||
> round trip, not the turn, and the resave canonicalisation is confirmed as the cause.
|
||
> - P1b fails **and** P1b-aux holds ⇒ the round trip is exact and the **turn** diverged from its
|
||
> continuation form. That is the interesting failure and it is not one the resolution anticipated;
|
||
> it would mean a load boundary changes turn 39's outcome, and it is a resolver case, not a lane
|
||
> result.
|
||
> - P1b holds **and** P1b-aux fails ⇒ the resave is not byte-exact but is behaviourally equivalent;
|
||
> the pair is certified and `determinism-oracle.md`'s round-trip section needs a note.
|
||
|
||
### 1.3 Part 1 — the exposure test
|
||
|
||
**Procedure.** `ar-oracle-A-post.sav` (Frame 39, sha256 `7a8b3d5e…`), **two fresh processes**,
|
||
`hooks=off`, **one End Turn each**, any encounter query resolved with **`Auto Resolve Peacefully` in
|
||
both**.
|
||
|
||
> **P1 — committed.** The two `(Autosave).sav` files **differ**, and the difference is confined to
|
||
> `Player[32]`'s `TechTree/*`, `ResTNm`, `otch`, `Events`, `turnstats/…/tch` and `Summary/Checksum`,
|
||
> while `/Sim/RNG`, `/Sim/trdmgr`, **every** `Player[16]` leaf and **every** player-0 fleet are
|
||
> identical.
|
||
|
||
The reasoning, and it is the predicate speaking: `ar-oracle-A-post.sav` carries `ResTNm == ''` for
|
||
Player[32] (§2). By the AS precedent (`as-turn15 → 16`, 22 leaves, entered with `ResTNm == ''`) and
|
||
the row-326 precedent on `turn1-state`, that is a research-pick turn. So the predicate says, **in
|
||
advance**, that lane AR's pair must not be extended by a turn — and this run is what makes that a
|
||
measurement rather than an inference.
|
||
|
||
**How P1 can be wrong, and the symptom of each way** (rule 2):
|
||
|
||
| way it could be wrong | symptom |
|
||
|---|---|
|
||
| a producer supplied the target, so the pick had an outcome set of size 1 (as for player 32 on `turn1-state`) | the two files **agree** byte-for-byte; the predicate survives but needs a **producer gate**, and lane L4's `airesearch=on` dump names which producer returned non-null |
|
||
| something else on turn 40 is exposed as well as the pick | the files differ, but **outside** the named leaf set — e.g. in fleets, `trdmgr`, or `Player[16]` |
|
||
| the pick is exposed but its outcome-set is 1 for a different reason (only one affordable node) | files agree; same follow-up as the producer case, and `otch`/`TechTree` at turn 40 says which node was taken |
|
||
| VM145 is not byte-faithful to the lineage | **P1b fails** as well, and part 1b is the guard against reading part 1 off a guest that cannot reproduce anything |
|
||
|
||
**A negative here is a result, not a null.** If the two files agree, the honest statement is *"no
|
||
exposed decision was reached on turn 40 either, and the pick is therefore producer-supplied on this
|
||
state"* — never *"the AI is deterministic here"* (rule 26 (c)).
|
||
|
||
### 1.4 A false-positive class in the predicate, named before the run
|
||
|
||
Read off the two saves (§2), and stated here because it is a *pre-run* correction to the predicate
|
||
as the resolution words it:
|
||
|
||
**`ResTNm == '' at turn start` is true of four players on `ar-oracle-A-pre.sav` — the turn whose
|
||
control agreed byte-for-byte.** Players 528 (`Alien Menace`), 544 (`Peacekeeper Enforcer`), 560
|
||
(`Von Neumann`) and 576 (`Independent Colony`) all carry `ResTNm == ''` on turn 38 **and** turn 39,
|
||
and player 16 (the human) does too. They have `NumOwn == 0`: no colonies, no research income, no
|
||
pick to make. So the raw predicate has a known false-positive class already sitting inside the very
|
||
state that falsified AR's P7.
|
||
|
||
The sharp form the next lane should use is therefore:
|
||
|
||
> `ResTNm == ''` **at turn start, for a non-eliminated AI player with `NumOwn > 0`**, names a
|
||
> research-pick turn.
|
||
|
||
On `ar-oracle-A-post.sav` exactly one player satisfies that: **Player[32]**, `NumOwn 18`. That is
|
||
the whole basis of P1, and it is why P1 names Player[32]'s leaves and no one else's.
|
||
|
||
*(Note for honesty: players 496 and 512 — the two `Spengler` NPCs — hold non-empty `ResTNm` and also
|
||
have `NumOwn == 0`. They are not evidence either way; they are listed in §2 for completeness.)*
|
||
|
||
### 1.5 What this lane will not settle (rule 15)
|
||
|
||
- **Two processes, not three**, for part 1 — rule 26's bar, matching AR's.
|
||
- **One state.** Neither part says anything about `ad-turn27`, which is probe 2's job on VM146.
|
||
- **The producer gate is not run here** unless part 1 comes out as agreement and time allows; if it
|
||
does not, this document names it as the next step rather than guessing at it.
|
||
- **`0x0069dbb0`'s 3–40-turn fuse cannot fire** in a one-turn-from-load run, by construction — so
|
||
neither part can say anything about it, in either direction.
|
||
- **No instrument.** `hooks=off` throughout, so this lane measures behaviour and never attributes it
|
||
to a draw site. The consumer identification is probe 3's job.
|
||
|
||
---
|
||
|
||
## 2. The exposure facts, read off the saves before the runs (rule 26 (c))
|
||
|
||
`uv run python3 verify/save-reader/save_reader.py --json`, three saves on the AD/AR lineage.
|
||
`NumDes` = the `designs` list length, `NumOwn` = the `owners` list length (both are the on-wire count
|
||
prefixes; verified against the `--dump` tree at `NumOwn`/`NumDes`). "ships +" is the per-owner
|
||
`ShipID` set delta from the previous save in the lineage.
|
||
|
||
### 2.1 `ar-oracle-A-pre.sav` — Frame 38, `ModCount 2108`, the input to part 1b
|
||
|
||
| PID | PlyrIdx | name | species | NPC | `ResTNm` | `NumDes` | `NumOwn` | ships | fleets |
|
||
|---|---|---|---|---|---|---|---|---|---|
|
||
| 16 | 0 | `re` (human) | 0 | no | `''` | 6 | 3 | 5 | 5 |
|
||
| **32** | **1** | **The Eternal Empire** | 2 | no | **`BIO_EnvTail`** | **47** | **18** | 243 | 59 |
|
||
| 496 | 2 | Spengler | 0 | yes | `DRV_PlsFiss` | 0 | 0 | 0 | 0 |
|
||
| 512 | 3 | Spengler | 2 | yes | `XNC_TrnsMorr2` | 0 | 0 | 0 | 0 |
|
||
| 528 | 4 | Alien Menace | 4 | yes | `''` | 19 | 0 | 0 | 0 |
|
||
| 544 | 5 | Peacekeeper Enforcer | 4 | yes | `''` | 1 | 0 | 0 | 0 |
|
||
| 560 | 6 | Von Neumann | 4 | yes | `''` | 6 | 0 | 0 | 0 |
|
||
| 576 | 7 | Independent Colony | 4 | yes | `''` | 1 | 0 | 0 | 0 |
|
||
|
||
**Predicate reading for turn 38→39:** the only player that can research holds a target
|
||
(`BIO_EnvTail`), `NumDes` is constant at 47, `NumOwn` constant at 18. **No exposed decision
|
||
predicted** — which is exactly what AR measured (three processes agreed). Part 1b is therefore a
|
||
*re-run of an agreeing turn from a load*, and its only open question is the load boundary itself.
|
||
|
||
### 2.2 `ar-oracle-A-post.sav` — Frame 39, `ModCount 2147`, the input to part 1
|
||
|
||
| PID | PlyrIdx | name | species | NPC | `ResTNm` | `NumDes` | `NumOwn` | ships | fleets |
|
||
|---|---|---|---|---|---|---|---|---|---|
|
||
| 16 | 0 | `re` (human) | 0 | no | `''` | 6 | 3 | 5 | 5 |
|
||
| **32** | **1** | **The Eternal Empire** | 2 | no | **`''`** ← **pick signature** | **47** | **18** | 245 | 59 |
|
||
| 496 | 2 | Spengler | 0 | yes | `DRV_PlsFiss` | 0 | 0 | 0 | 0 |
|
||
| 512 | 3 | Spengler | 2 | yes | `XNC_TrnsMorr2` | 0 | 0 | 0 | 0 |
|
||
| 528 | 4 | Alien Menace | 4 | yes | `''` | 19 | 0 | 0 | 0 |
|
||
| 544 | 5 | Peacekeeper Enforcer | 4 | yes | `''` | 1 | 0 | 0 | 0 |
|
||
| 560 | 6 | Von Neumann | 4 | yes | `''` | 6 | 0 | 0 | 0 |
|
||
| 576 | 7 | Independent Colony | 4 | yes | `''` | 1 | 0 | 0 | 0 |
|
||
|
||
**Predicate reading for turn 39→40: EXPOSED.** Player[32] enters with `ResTNm == ''` and `NumOwn 18`.
|
||
`otch` moved 46 → 47 across turn 39 (`BIO_EnvTail` completed), which is the same shape AS recorded.
|
||
|
||
### 2.3 Ship completions on the lineage, for the fleet-assignment half of the predicate
|
||
|
||
| transition | `ModCount` | PID 16 ships | PID 32 ships | reading |
|
||
|---|---|---|---|---|
|
||
| turn 37 → 38 | 2057 → 2108 | **−7408** (`Zeta Fleet`'s destroyer, lost in the encounter) | **+8784, +8800** | 2 completions, into existing fleets — not a batch |
|
||
| turn 38 → 39 | 2108 → 2147 | none | **+8816, +8832** | 2 completions, into existing fleets — not a batch |
|
||
|
||
Two ships a turn into existing `Freighters` fleets is the *quiet* fleet consumer, not the
|
||
thirteen-into-five-new-fleets batch that AD's turn 28 carried. `designIds` is constant at 95 and
|
||
`fleetIds` at 64 across both transitions, corroborating "no design turn, no fleet creation".
|
||
|
||
**So: on the input to part 1b the predicate says NOT exposed; on the input to part 1 it says
|
||
EXPOSED, via the research pick, for exactly one player.**
|
||
|
||
---
|
||
|
||
## 3. Procedure and configuration
|
||
|
||
`hooks=off` throughout, no build (rule 24 is satisfied trivially — nothing is compiled).
|
||
|
||
| item | value |
|
||
|---|---|
|
||
| guest | VM145 `sots-re-win10-145`, 192.168.10.145 |
|
||
| shim build | `C:\SOTS\shimdist-l4\binkw32.dll`, `BUILD_ID l4r-20260908T2208Z` |
|
||
| config | `C:\SOTS\shimdist-l4\shim.cfg.l4off`, **unmodified** — `hooks=off`, installs nothing |
|
||
| why this build | lane L4 proved *on this guest, with this exact DLL and this exact config* that VM145 reproduces the campaign's published autosave oracle byte-identically (`ai-order-capture.md` §3: `bb4fd9ac89f41e3b` / `978041acd168b56e`). It is the only hooks=off pair on VM145 with a published byte-fidelity result behind it |
|
||
| `SavedGames` | reset to **exactly one file** — the run's input save — before every launch, so the Load dialog has one row and its position is re-derived from a screenshot anyway |
|
||
| main menu | verified from a `qm monitor` screendump (`tools/vmshot.py --one 145`), never by sleeping |
|
||
| encounter query | detected by sampling the `Done` pixel at (233, 673): ≈(183,18,0) query up, ≈(8,8,8) map. `Auto Resolve Peacefully` (667,641), `Done` (233,673) |
|
||
|
||
**VM145 as found**, recorded so it can be put back (§8):
|
||
|
||
```
|
||
binkw32.dll 15,527,327 B sha256 903527f4a698eea9fbe25f3a6236657c7d8348f994eef394696f187e5e554b97
|
||
(= shimdist-recap, BUILD_ID recap-7584bad-20260908T0615Z)
|
||
shim.cfg sha256 0ae410cc72fe155837d711c78543e14b1f5743310cd023298eb1e5bbd5457e71 (hooks=trace, lane R recapture)
|
||
SavedGames 9 files, saved to C:\SOTS\ui\preBQ\
|
||
game not running
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Results
|
||
|
||
*(added after the runs; nothing above this line is edited)*
|
||
|
||
---
|
||
|
||
## 5. Verdicts on the committed predictions
|
||
|
||
*(added after the runs)*
|
||
|
||
---
|
||
|
||
## Proposed board rows
|
||
|
||
*(added after the runs)*
|