From 947f20586790bfb5ef6e65e4d0ff9523ed7d5b97 Mon Sep 17 00:00:00 2001 From: alex Date: Wed, 9 Sep 2026 00:56:53 -0400 Subject: [PATCH] board: scope the C-exact proof to the early-game turn it was demonstrated on --- campaign/board.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/campaign/board.md b/campaign/board.md index 2a503e2..a24ba32 100644 --- a/campaign/board.md +++ b/campaign/board.md @@ -344,7 +344,7 @@ Status flow: `backlog → in-progress → mapped → verified` (or `blocked`). | LAB HAZARDS from L2 | meta | verified | high | 100% | 2026-09-08 | (1) **`pgrep -f "tap141i0"` matches QEMU's OWN command line** (`ifname=tap141i0`), so stopping a tcpdump SIGTERMed the VM. Use `pgrep -x tcpdump`. The guest came back clean (fsutil not dirty, same IP). (2) Driving the starmap needs **REAL MOUSE MOTION** - SetCursorPos alone does not move the game's cursor - plus wheel zoom; L2's driver is in verify/harness/l2-ui/. (3) From lane L4: **`move X Y` then `click X Y`** - a bare click is delivered at the PREVIOUS cursor position about half the time, which reads as "the click did nothing" then "the next click did the previous thing" | | FOURTH cross-lane commit sweep - now with plain git commit | meta | verified | high | 100% | 2026-09-08 | Lane L1's board commit swallowed all 22 of lane L2's staged files. Content intact and verified in HEAD; L2 correctly did NOT rewrite history with other lanes live. **This is the fourth instance of the hazard addresses.d/README documents, and it now happens with plain `git commit` too, not just addresses.json** - because a lane stages by path but another lane's commit picks up whatever is in the index. The index is shared per-repo; staging by path does not protect against someone else's commit. Needs a real fix, not another rule | | STRUCTURAL FIX for the commit-sweep hazard (rule 25) | meta | verified | high | 100% | 2026-09-08 | Four instances in one session, the last with plain `git commit` and NO `-A` anywhere - **every lane had staged by path exactly as instructed and it still happened**, because `git add ` puts a file in THE REPO'S ONE INDEX and the next commit takes all of it. Staging by path was never the protection. **THE FIX IS A FORM OF THE COMMAND**: `git commit -m "msg" -- path/one path/two` commits only those paths and leaves the rest of the index untouched - verified in a scratch repo (two files staged, pathspec commit took one, the other stayed staged). Lanes now commit with a pathspec, always. Deeper fix if it recurs: a per-lane CLONE of sots-re, mirroring the per-lane worktree of sots-engine - which is precisely why sots-engine has never had this problem | -| RESOLUTION: the byte-match SURVIVES, in a stronger form | meta | verified | high | 100% | 2026-09-08 | First re-resolver run, `findings/resolutions/2026-09-08-ai-seed-per-process.md`. **The AI is not non-deterministic - it is MT19937 from ONE 32-bit word per client, drawn once at construction from a per-process global, and we own that generator bit for bit.** So game/ai is a deterministic function of (save, per-client seed). Rung C splits: **C-exact** - capture the three seeds and our block matches element for element and the autosave byte-matches ON EVERY RUN (the user's framing made literal), precondition being a per-client DRAW LEDGER so we consume the stream in the original's order and count INCLUDING draws whose result never reaches the save; **C-set** - the fallback for references whose seeds were never logged, like turn2-state.sav, which **no process including the original can reproduce**. Instrument exonerated: three unrelated 32-bit words per process are successive generator outputs, not clock reads, so AI1's call-site reading STANDS and only its "never seeded" reading falls | +| RESOLUTION: the byte-match SURVIVES, in a stronger form | meta | verified | high | 100% | 2026-09-08 | First re-resolver run, `findings/resolutions/2026-09-08-ai-seed-per-process.md`. **The AI is not non-deterministic - it is MT19937 from ONE 32-bit word per client, drawn once at construction from a per-process global, and we own that generator bit for bit.** So game/ai is a deterministic function of (save, per-client seed). Rung C splits: **C-exact** - capture the three seeds and our block matches element for element and the autosave byte-matches ON EVERY RUN (the user's framing made literal), precondition being a per-client DRAW LEDGER so we consume the stream in the original's order and count INCLUDING draws whose result never reaches the save; **C-set** - the fallback for references whose seeds were never logged, like turn2-state.sav, which **no process including the original can reproduce**. Instrument exonerated: three unrelated 32-bit words per process are successive generator outputs, not clock reads, so AI1's call-site reading STANDS and only its "never seeded" reading falls **The shape recurs and is now a PREDICATE (resolver 2026-09-09)**: pick turns (`ResTNm == ''` at turn start: `turn1-state`, `as-turn15`) and heavy build turns (`ad-turn27`) **EXPOSE** the seed; quiet-consumer turns (`ar-turn37 -> 39`) do not, and agree byte-for-byte across three processes. **SCOPE of the C-exact proof: it was demonstrated on `turn1-state` (early game) only** - the rich-turn test is `ad-turn27` with `aiseed=pin`, queued on VM146. A control that agrees means "no exposed decision was reached", never "the AI is deterministic here". | | the tie-set claim: rescued as a STATEMENT, open as a RESULT | verify | mapped | high | 80% | 2026-09-08 | And **not on "equal cost"** - the resolver's sharpest correction. The 2000-RP tier-1s are not the picks; the picks are tier-2s at 13k-30k. S(D) is **the support of a random draw**, per save, not a set of equal-score candidates. `BIO_GnMod` (2 of 6 observations) proves a SECOND ARM whose producer is unidentified - likeliest producer A or B gated by a draw, never entering the walk - so **"we can name all k" is TO PROVE**. The four-part statement is in the resolution 3.1: derive S before any sweep; canonical pick = lowest tech id; containment; **and a pinned-seed sweep produces nothing outside S** - part (iv) is what makes it non-tautological | | THE ONE PROBE: pinned seeds THROUGH the resolver | verify | backlog | — | 0% | 2026-09-08 | The seed SOURCE is not the probe. The resolver probe is only an experiment **if the seed is pinned** - otherwise two runs with two unknown seeds cannot separate "draws from the stream" from "reads something else per-process". Implementation named: L1's `l1seed` Seed detour (return address 0x0078304b, three constants) + L4's instrument + a `left` region over client+0x134 at TryResearchCandidate 0x006c8580; ref-turn2 once as the pin's OWN control; turn1-state twice; then sweep by quit-to-menu/reload (the pin table advances per load, **no relaunch needed**), logging which producer returned non-null for player 512. Predictions committed in the resolution 4. If the four leaves still differ, extend the pin to the unidentified fourth seeded object | | NEW OPEN RISK: g_GlobalRNG has four other consumers | verify | backlog | — | 0% | 2026-09-08 | Including **RunCombatRound+0x60f** - and **no battle turn has ever been compared across two processes**. Add "twice, two processes" to the battle workload in backlog 5. Lane L2 verified combat lockstep between two clients in ONE game; this is the different question of whether a battle is reproducible across separate runs |