BS: predictions for the per-history residue, committed before the runs
This commit is contained in:
parent
a05f54d2b0
commit
15c44711c1
1 changed files with 215 additions and 0 deletions
215
findings/control-flow/per-history-residue.md
Normal file
215
findings/control-flow/per-history-residue.md
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
# The per-history residue — the same save, two routes to turn 39, both reproducible
|
||||
|
||||
- **Type:** control-flow / determinism (two instrumented runs; one build, no static reading)
|
||||
- **Owner / date:** lane **BS** · 2026-09-09 · guest **VM144** (`sots-re-win10-144`, 192.168.10.144)
|
||||
- **Spec:** `findings/resolutions/2026-09-09-fleet-id-order-residue.md` §8 (VM144 paragraph) and §9
|
||||
- **Tests:** §9.2's ranked candidates for the per-history input; §9.3's committed predictions (a)–(d)
|
||||
- **Depends on:** `findings/control-flow/seed-exposure-forward-test.md` (lane BQ — the residue, the
|
||||
click path, the `Done`-pixel test); `findings/control-flow/pinned-seed-rich-turn.md` (lane BP — the
|
||||
*per-process* residue, which this is not)
|
||||
- **Rules exercised:** 2 (predict first), 15, 19, 20, 21, 24, 25, 26 and its corollary (c), 28
|
||||
|
||||
---
|
||||
|
||||
## 1. Predictions, committed before the build was deployed and before the game was launched (rule 2)
|
||||
|
||||
*Everything in §1–§3 was written and committed before `binkw32.dll` was copied onto VM144 and before
|
||||
any hash was read. It is not edited afterwards, only annotated with verdicts in §5.*
|
||||
|
||||
### 1.1 What is at stake
|
||||
|
||||
Lane BQ measured something the campaign had no model for: **`ar-oracle-A-pre.sav` runs turn 39 one
|
||||
way when the state is reached by continuation and another way when it is reached by a load, and both
|
||||
routes are reproducible.**
|
||||
|
||||
| route | processes | `(Autosave EndTurn)` | `(Autosave)` |
|
||||
|---|---|---|---|
|
||||
| continuation — load `ar-turn37-816raiders.sav`, End Turn, Auto Resolve Peacefully, End Turn | 3 (lane AR) | — | `15b99255…` (F38) then **`7a8b3d5e…`** (F39) |
|
||||
| load — load `ar-oracle-A-pre.sav`, End Turn | 2 (lane BQ) | **`33e30092…`** | **`4c356f59…`** |
|
||||
|
||||
23 leaves apart, **17 of them one AI fleet**: `Flt[1570 "Zeta Fleet V"]` (PID 32). Both routes'
|
||||
turn-39 input has it parked at Alpha Centauri (`LocID 432`, `HFPlan False`, `FtFlg 12`, both ships at
|
||||
`Range 9.0`) — and so does turn 37's save, so it had already sat still for a turn. The continuation
|
||||
issued it a move order on turn 39; **both** loads issued nothing.
|
||||
|
||||
So the pre-turn save does not fully determine the next turn's AI fleet-task decisions. §9.2 ranks the
|
||||
candidates and this lane's job is to say which survives:
|
||||
|
||||
1. **AI agent state the save does not carry** — `AISystem::Write` emits nothing; the three `AIAgent`
|
||||
save blocks are cache. A task created on turn 38 exists on turn 39 only in the process that ran
|
||||
turn 38. Same class as the `0x0069dbb0` fuse and the client id counter. **Leading.**
|
||||
2. **Client generator stream position** — *rejected by the resolver*: both routes are
|
||||
seed-insensitive on this turn (AR's three continuation processes had three seed sets and agreed;
|
||||
BQ's two loads had two and agreed).
|
||||
3. **Server-side state not in the save** — nothing in the record points here. Last.
|
||||
|
||||
### 1.2 P0 — the neutrality gate, and it is checkable at k = 1 here
|
||||
|
||||
Rule 19 asks for the measurement with the instrument removed. Unusually, **both** routes already have
|
||||
`hooks=off` controls that agree with themselves, so rule 26 is satisfied on both sides and an
|
||||
instrumented run agreeing with one is *not* a 1/k coincidence — k is 1 on each route.
|
||||
|
||||
> **P0 — committed.** With `shim.cfg.bsrun` installed:
|
||||
>
|
||||
> * **continuation:** the `(Autosave).sav` after End Turn #1 is `15b99255e1f03dab…` and the
|
||||
> `(Autosave).sav` after End Turn #2 is `7a8b3d5eb3a60eba…`;
|
||||
> * **load:** the `(Autosave EndTurn).sav` is `33e3009254f5acd1…` and the `(Autosave).sav` is
|
||||
> `4c356f5916f0e6e4…`.
|
||||
>
|
||||
> **If either route misses either hash, that route is VOID.** The instrument is not neutral on it and
|
||||
> nothing — not one probe count, not one `airng` row — may be read from it. This is stated as a stop
|
||||
> condition, not as a caveat.
|
||||
|
||||
### 1.3 The measurements — §9.3's (a)–(d), committed as mine, plus one of my own
|
||||
|
||||
> **P1 (= §9.3 a) — the block.** In the **continuation's turn-39** `aiorders` batch, the block for
|
||||
> `pid=32` carries a **list-8 element whose first word is 1570** and at least one **list-14 element
|
||||
> whose first word is 1570**. In the **load's turn-39** block for `pid=32`, **neither is present.**
|
||||
>
|
||||
> Basis: in lane BP's dump the first word of a list-8, list-10 and list-14 element is the fleet id
|
||||
> (list 8 idx0 `ints=[ 2002 … ]`, list 14 idx0 `ints=[ 1970 0 … ]`), and the save-side difference BQ
|
||||
> measured is exactly a `FPlan` with one waypoint (`Wpt 320`) appearing only in the continuation.
|
||||
|
||||
> **P2 (= §9.3 b) — the task.** The two routes' `aiprobe` counts for the turn-39 window differ in at
|
||||
> least one row, and the difference is on a **task `Execute` entry** (probe idx 2–9) — either a task
|
||||
> that fires in the continuation and not in the load, or the same task firing with a different
|
||||
> `AcquireFleetsForTask` (13) / `IsClaimedByAnotherTask` (14) count. Probe 11
|
||||
> (`AssignFleetsAndIssueOrders`) is entered in **both** routes, and probe 0 (`RunTaskList`) is
|
||||
> non-zero in both — without which every other row is meaningless (rule 20 is built into the report).
|
||||
|
||||
> **P3 (= §9.3 c) — the draws.** In every `OnResumePlaying` bracket on **both** routes:
|
||||
> `foreign_words=0`, `foreign_calls=0`, `residual=0`, and no `airngcensus` row whose `rng` is
|
||||
> anything but that client's `+0x134`. The two routes' per-client word counts differ by at most the
|
||||
> cost of the task P2 names. **RNG is not the mechanism**, and this is the measurement that says so
|
||||
> rather than the inference.
|
||||
|
||||
> **P4 (= §9.3 d) — the pre-turn states.** The continuation's own frame-38 autosave and the load
|
||||
> run's `(Autosave EndTurn).sav` differ in **exactly one leaf**, `/CD[1]/NPrvVa` (+5.00), under
|
||||
> `--floats bits --mask resave`. Restated: the two routes enter turn 39 from *the same state*, so
|
||||
> whatever differs is not in the file. (BQ measured this without an instrument; if it moves under
|
||||
> mine, the instrument moved it and P0 will have said so first.)
|
||||
|
||||
> **P5 — mine, the exposure fact the standing instruction asks for.** `airng` emits one bracket row
|
||||
> per `StrategyClient::OnResumePlaying` entry carrying `agent=`, so it reports **which clients
|
||||
> actually run an AI turn**. I predict **three** clients run on both routes — `pid` 32, 496 and 512 —
|
||||
> and that players 528/544/560/576 produce **no bracket row with a non-null agent**, matching lane
|
||||
> BP's count of three clients from seven non-human players on the same lineage. `NumOwn == 0` gates
|
||||
> nothing: 496 and 512 have `NumOwn == 0` and are predicted to run.
|
||||
|
||||
**How each can be wrong, and the symptom** (rule 2):
|
||||
|
||||
| way it could be wrong | symptom | what it would mean |
|
||||
|---|---|---|
|
||||
| the residue is not in the AI's emission at all | **P1 fails in the null direction**: both routes' pid-32 blocks are element-for-element identical | the divergence is downstream of `BuildTurnCommands` — in the server's application of the block, or in `ProcessFleetMovement`. **This relocates the question and is the more valuable outcome**, because it would exonerate the whole AI-agent-state candidate in one run |
|
||||
| the block differs but no probe does | P1 holds, **P2 fails** | the task set is the same and the *gathering* differs — the fleet set `AcquireFleetsForTask` returns. That is BR's stage-2 territory (`AssignFleetsAndIssueOrders 0x006c16c0` and its 992-byte hub), and the two lanes converge on one function from two directions |
|
||||
| a draw is involved after all | **P3 fails**: a non-zero `foreign_words`, or a census row on `0x00af6e58` | the resolver's rejection of candidate 2 was wrong; the return address names the consumer and the follow-up is a global pin |
|
||||
| the routes do not enter turn 39 from the same state | **P4 fails on a leaf other than `NPrvVa`** | there is a *save-visible* difference and the whole "not in the file" framing is wrong. This is the one failure that would overturn BQ's headline rather than extend it |
|
||||
| the instrument perturbs | **P0 fails** | the run is void; report the miss and stop |
|
||||
| more or fewer than three clients run | **P5 fails** | the client count is a property of the state, not of the lineage, and rule 26 (c)'s "read the predicate against who actually runs" needs a per-save count |
|
||||
|
||||
**A null result is a real result.** If both routes produce identical AI fleet-task probe sequences
|
||||
*and* identical blocks, I will report that as the finding, not hunt for a difference elsewhere.
|
||||
|
||||
### 1.4 What this lane will not settle (rule 15)
|
||||
|
||||
* **One process per route.** Each route's reproducibility is already established by two or three
|
||||
`hooks=off` processes (AR, BQ); this lane adds the *instrument*, not a third control. So it can say
|
||||
what the AI emitted on each route; it cannot add evidence about whether a route is reproducible.
|
||||
* **No static reading, no build of `game/ai`.** If the answer is "the fleet set differs", naming the
|
||||
container is BR's stage 2, not this lane's.
|
||||
* **The `0x0069dbb0` fuse cannot fire** in a load→one-turn run by construction, so the load arm says
|
||||
nothing about it. The continuation arm runs two turns from a load, which is still inside the
|
||||
3–40-turn fuse window, so neither arm bears on it in either direction.
|
||||
* **The research probes (16–19) are not installed.** BQ measured `candidatesTried=1` and an agreeing
|
||||
pick on this lineage; four fewer detours is four fewer ways to fail P0. So this lane says nothing
|
||||
about the research half.
|
||||
* **Turn 38's encounter is auto-resolved peacefully on the continuation arm, and that is only safe
|
||||
here because the other side has nothing to fight with** (lane BQ: `Auto Resolve Peacefully` means
|
||||
"I commit no ships", not "no combat occurs"; on a later turn a *planet* fired and killed a different
|
||||
number of raiders in each process). AR's turn-38 encounter reproduced across three processes, which
|
||||
is the only reason this procedure is admissible at all. **It does not generalise.**
|
||||
* **`aiorders.deep=off`**, so list 8's route vector and list 10's counted vector are behind pointers
|
||||
and are *absent* from the dump. The fleet id is in the element window; the waypoint list is not.
|
||||
|
||||
---
|
||||
|
||||
## 2. Exposure facts, read off the inputs before the runs (rule 26 (c), with the route)
|
||||
|
||||
Read with `verify/state-checksum/state_checksum.py`'s leaf walk over the typed tree. The standing
|
||||
instruction: record **which players have an AI client**, and record **the route** as part of the
|
||||
procedure. The client list is a *run-time* fact, so it is predicted in P5 and reported in §4; what the
|
||||
saves carry is below.
|
||||
|
||||
### 2.1 `ar-turn37-816raiders.sav` — Frame 37, the continuation arm's input
|
||||
|
||||
| PID | name | NPC | `ResTNm` | `NumOwn` |
|
||||
|---|---|---|---|---|
|
||||
| 16 | `re` (human) | no | `''` | 3 |
|
||||
| **32** | **The Eternal Empire** | no | **`BIO_EnvTail`** | **18** |
|
||||
| 496 | Spengler | yes | `DRV_PlsFiss` | 0 |
|
||||
| 512 | Spengler | yes | `XNC_TrnsMorr2` | 0 |
|
||||
| 528 / 544 / 560 / 576 | Alien Menace / Peacekeeper Enforcer / Von Neumann / Independent Colony | yes | `''` | 0 |
|
||||
|
||||
`Flt[1570 "Zeta Fleet V"]` (PID 32) on **turn 37**: `LocID 432`, `HFPlan False`, `FtFlg 12`,
|
||||
`NShips 2`, both ships `Range 9.0`. **Identical to its turn-38 state** — so the AI left it parked on
|
||||
turn 38 in the continuation too, and the order it issued on turn 39 is not a continuation of an order
|
||||
in flight.
|
||||
|
||||
### 2.2 `ar-oracle-A-pre.sav` — Frame 38, the load arm's input and the continuation arm's midpoint
|
||||
|
||||
Per-player table as lane BQ published it (§2.1 there): the only player that can research holds a
|
||||
target, `NumDes` 47 constant, `NumOwn` 18 constant, two completions a turn into *existing*
|
||||
`Freighters` fleets — **no new fleet is formed on this turn**, which is why BP's per-process visit
|
||||
order has nothing to vary and why this turn shows no per-process residue.
|
||||
|
||||
`Flt[1570 "Zeta Fleet V"]`: `LocID 432`, `HFPlan False`, `FtFlg 12`, `NShips 2`, ships 5840 and 6144
|
||||
both at `Range 9.0`. **This is the leaf set the two routes disagree about.**
|
||||
|
||||
**Predicate reading, both routes:** no research pick (target held), no design turn, no
|
||||
fleet-assignment batch, no AI fleet at an enemy colony. Rule 26 (c) screens this turn as *not
|
||||
exposed* — and it is exposed anyway, through a term the predicate does not have. That is the point of
|
||||
the lane.
|
||||
|
||||
---
|
||||
|
||||
## 3. Procedure and configuration
|
||||
|
||||
### 3.1 The two runs
|
||||
|
||||
| | route | procedure |
|
||||
|---|---|---|
|
||||
| **run C** | **continuation** | `SavedGames` reset to exactly `ar-turn37-816raiders.sav`; fresh process; Load → Single Player → row 1 → OK; **End Turn**; the turn-38 encounter resolved with **Auto Resolve Peacefully** then **Done**; **End Turn** |
|
||||
| **run L** | **load** | `SavedGames` reset to exactly `ar-oracle-A-pre.sav`; fresh process; Load → Single Player → row 1 → OK; **End Turn** |
|
||||
|
||||
Both saves are copied in from `verify/results/saves/`, which moves the Load-dialog rows; with exactly
|
||||
one file the dialog is one row and it is screenshotted and re-derived anyway (lane BQ's tip). The
|
||||
`Done` pixel at (233,673) is sampled to detect the encounter query rather than assumed
|
||||
(≈(183,18,0) query up, near-black on the map). One click per helper call with a screenshot between
|
||||
(lane M, confirmed by BQ on a second guest); ≥ 9 s after `schtasks /Run` before believing a shot
|
||||
(lane AP's nine-minute gotcha).
|
||||
|
||||
### 3.2 Configuration — `shim.cfg.bsrun`, one file, both runs
|
||||
|
||||
| item | value |
|
||||
|---|---|
|
||||
| guest | VM144, **held by lane BS** |
|
||||
| build | `C:\SOTS\shimdist-bs\binkw32.dll`, built fresh in `/srv/re-lab/build/sots-engine-bs` (`rm -rf`'d first, rule 24) from worktree `wip/bs` (rule 21) |
|
||||
| config | `shim.cfg.bsrun` — `hooks=trace` with **all 27 registered hooks named `off`** (the `# exhaustive` marker; `tools/check_shim_configs.py` passes) |
|
||||
| instrument | `aiorders=on` `aiorders.words=32` `aiorders.deep=off`; `aiprobes=16` (probes 0–15: the control+pass recorder, **every task `Execute` entry the table carries**, the three emission exits, the hub, the claim test, `BuildTurnCommands`); `airng=on` `airng.pin_seed=off` |
|
||||
| off | `probes=off`, `watch=off`, `airesearch=off`, `aidesign=off`, `aiseed=off`, no pin of any kind |
|
||||
|
||||
`aiseed=off` means the **`RunAI` net-id list is not logged** — the brief's config says every template
|
||||
hook off by name, and `aiseed=log` would have been one more detour on `RunAI` than the brief asked
|
||||
for, on a run whose whole value is a k = 1 neutrality check. The exposure fact is taken instead from
|
||||
`airng`'s per-bracket rows, which carry `pid` and `agent` for every `OnResumePlaying` entry — the
|
||||
clients that actually run, measured at the bracket rather than at the seed. §4 reports it as such.
|
||||
|
||||
### 3.3 VM144 as found, recorded so it can be put back
|
||||
|
||||
```
|
||||
binkw32.dll 22,972,439 B sha256 479b8614d2417603b64e66482e429ecd3cdfe4033a2c99969ca91553642e517d
|
||||
(= shimdist-l3, BUILD_ID l3cont2-0117495-20260908T2124Z)
|
||||
shim.cfg sha256 692dabb6f00343bfcc2f86d62ade827c295acc4630a18a1f2ddcebd53640978d
|
||||
SavedGames 15 files (hashes in §8)
|
||||
game RUNNING at the main menu (pid 8408), screenshot-verified
|
||||
```
|
||||
Loading…
Add table
Reference in a new issue