docs: B6 measured -- prediction held, closed 0 regressed 0 on both reference pairs
209 -> 158 (closed 51, regressed 0) and 108 -> 87 (closed 21, regressed 0), identical to the pre-lane baseline, measured on CT111. Falsification hypotheses 1 and 2 refuted by measurement (three empty BQ frames per reference save, every hbq false, the one command block empty); hypothesis 3 refuted by the corpus oracle; hypothesis 4 stands as a labelled hypothesis. construction.h also carries the ship/fleet birth shape as read but NOT implemented, with the reason stated: the newborn hull copies four cached stat words the engine does not yet compute.
This commit is contained in:
parent
0fcbb69ba5
commit
db3909bcd4
2 changed files with 131 additions and 3 deletions
|
|
@ -39,14 +39,14 @@ What this lane does deliver, and what it is worth:
|
|||
* the build-queue advance read byte for byte from `Game::BuildQueue::ProcessTurn`
|
||||
(`0x00890d50`, real end `0x00891240` — Ghidra says 1230 bytes, the body runs 1264), which
|
||||
**independently confirms** lane B4's `sim::ProcessBuildQueue` and finds **one divergence**
|
||||
in it (§4);
|
||||
in it (§4, "What changed in the engine");
|
||||
* the `ShipRecords` update the pass performs, whose per-class counter has **exactly one
|
||||
writer in the whole image**;
|
||||
* the pass wired into the standalone's S11 as its own reported sub-pass;
|
||||
* a real oracle for the pass that the campaign already owns and had not noticed:
|
||||
`zuul-turn16-noderoute.sav` → `zuul-turn17-rollpending.sav` is a genuine consecutive-turn
|
||||
pair (frames 16 and 17) in which **six orders complete and one is partially advanced**
|
||||
across two systems (§5).
|
||||
across two systems (§3, "The corpus oracle").
|
||||
|
||||
## 2. How this prediction could be wrong, and the symptom of each way
|
||||
|
||||
|
|
@ -65,7 +65,98 @@ What this lane does deliver, and what it is worth:
|
|||
test: a per-order point budget, a non-FIFO order, or a "skip and continue" rule instead of
|
||||
"stop" each fail it.
|
||||
4. **The `points <= 0` gate on the removal sweep is wrong.** Unobservable in this corpus
|
||||
(§4) and therefore carried as a labelled hypothesis, not a result.
|
||||
and therefore carried as a labelled hypothesis, not a result.
|
||||
5. **`shpt` is not the fleet walk.** If the census leaf were fed by `ShipRecs` rather than by
|
||||
walking fleets, the fix would be different. Lane E2 already falsifies this: the fleet walk
|
||||
reproduces 480/480 archived census leaves.
|
||||
|
||||
---
|
||||
|
||||
## 3. Measured
|
||||
|
||||
Built on CT111 (`/srv/re-lab/build/sots-engine-b6`), report run there with
|
||||
`tools/standalone_report.py --binary …`. Host gates run separately, never `&&`-chained.
|
||||
|
||||
| pair | baseline | after | **closed** | **regressed** |
|
||||
|---|---:|---:|---:|---:|
|
||||
| `turn1-state.sav` → `turn2-state.sav` | 209 | 158 | **51** | **0** |
|
||||
| `turn2-state.sav` → `turn3-state.sav` | 108 | 87 | **21** | **0** |
|
||||
|
||||
Identical to the pre-lane baseline, which is the prediction holding: **this lane closed 0 and
|
||||
regressed 0.** `regressedPaths` is empty on both pairs.
|
||||
|
||||
The prediction's own numbers, checked one by one:
|
||||
|
||||
* three `BQ` frames per reference save (systems owned by players 16, 32 and 576), **0 orders in
|
||||
all three**, on both sides of both pairs — the standalone now prints this on its own line;
|
||||
* every `hbq` in `turn1/2/3-state.sav` is `false` (15, 16 and 17 of them), so **0 ship-borne
|
||||
orders**;
|
||||
* the four `CDT` ids are `Player.00000016.TurnCommands_v5` plus three `AIAgent` blobs, and the
|
||||
one command block is the 36-node empty one.
|
||||
|
||||
Falsification hypotheses 1 and 2 are therefore both refuted by measurement rather than by
|
||||
argument, and hypothesis 3 is refuted by the corpus oracle below. Hypothesis 4 stands as a
|
||||
labelled hypothesis; hypothesis 5 was already refuted by lane E2.
|
||||
|
||||
### What the pass does on the saves that are not the reference pair
|
||||
|
||||
`sots_turn <save> --phases` now prints a `build queue:` line under S11 on every save:
|
||||
|
||||
| save | queues | pending orders | demand (points) |
|
||||
|---|---:|---:|---:|
|
||||
| `turn1/2/3-state.sav` | 3 | 0 | 0 |
|
||||
| `human-turn2-orders.sav` | 20 | 0 | 0 |
|
||||
| `zuul-turn5-species5.sav` | 4 | 4 | 7,120 |
|
||||
| `zuul-turn16-noderoute.sav` | 4 | 7 | 12,099 |
|
||||
| `zuul-turn17-orders2.sav` | 4 | 2 | 5,109 |
|
||||
| `zuul-turn23-fleet23.sav` | 4 | 1 | 370 |
|
||||
|
||||
Five of eleven saves exercise the pass the moment points exist. Nothing is committed: an order
|
||||
that advanced with no ship behind it leaves a state the game never produces.
|
||||
|
||||
### The corpus oracle, which the campaign already owned
|
||||
|
||||
`zuul-turn16-noderoute.sav` (frame 16) → `zuul-turn17-rollpending.sav` (frame 17) is a real
|
||||
consecutive-turn pair. Two systems, six completions, one partial advance:
|
||||
|
||||
| system | owner | before (`desID`:`conleft`) | after | solved points |
|
||||
|---|---|---|---|---:|
|
||||
| 384 | 16 | 608:1753, 576:1860, 576:1860 | 576:**1291** | **4182** |
|
||||
| 80 | 32 | 114:959, 114:1889 ×3 (+816:6974 appended in-turn) | 816:**3818** | **9782** |
|
||||
|
||||
`test_construction.cpp` does not assume those totals — it **searches** 0..200,000 and asserts a
|
||||
solution exists and is **unique**. A per-order budget, a non-FIFO drain, or skip-instead-of-stop
|
||||
each make the search come back empty. The completions then reproduce the `ShipRecs` deltas the
|
||||
same two files carry (class-0 `srb` 2→4 and 53→57; design 608 2→3; a new record for 576;
|
||||
design 114 18→22; design 816 unchanged because its order did not finish).
|
||||
|
||||
## 4. What changed in the engine
|
||||
|
||||
* **`game/sim/construction.{h,cpp}`** — `ShipRecords` and the completion bookkeeping. The
|
||||
per-class `built` counter's indexed increment has **exactly one writer in the whole image**
|
||||
(an image-wide byte scan for the form at that displacement returns one site, inside this
|
||||
pass), so a hull on the wire with that counter bumped came through the build queue and
|
||||
nothing else — the encounter spawner that also creates ships touches no `ShipRecords`.
|
||||
`RunSystemConstruction` wraps the point pass and keeps each completion's design id.
|
||||
* **`game/sim/colony.{h,cpp}`** — one corrected rule: with `points <= 0` the original skips the
|
||||
**removal sweep** as well, because the entry test branches to the epilogue. Carried as a
|
||||
labelled hypothesis; no corpus save can reach the state that shows it, and the workload that
|
||||
would is named in the header.
|
||||
* **`app/construction_phase.{h,cpp}`** — S11's build-queue sub-pass, reported on its own line.
|
||||
* **`app/phase_catalog.cpp`** — S11's blurb no longer calls the build queue the input boundary
|
||||
for the census leaf.
|
||||
|
||||
## 5. What this lane did NOT do, said plainly
|
||||
|
||||
* **It did not close `shpt[0]`, and no build-queue work can.** The blocker moves to `game/ai`.
|
||||
* **It did not model the ship or the fleet at birth in code.** The chain is read end to end and
|
||||
written up in the RE repo (`findings/subsystems/ship-construction.md` §4): `StarShip` is 0xb0
|
||||
bytes, its id comes from the object-id allocator and lands in `+0x04`, `FltID` is born NULL;
|
||||
the hull joins its system's **cached home fleet** (`ServerSystem+0x238`) and a fleet is created
|
||||
only when that slot is empty; every fleet born that way gets `FtFlg |= 0x400` — which
|
||||
**corrects lane B5**, that bit is not a retreat marker. It is not implemented because the
|
||||
newborn hull's stats are copied from design words the engine does not yet compute, and because
|
||||
no save exercises the path with an oracle behind it.
|
||||
* **The money charge has never fired.** No design in the corpus costs money, so the slot-9
|
||||
refusal path is read from the bytes and never observed.
|
||||
* **`srl`, `srk`, `sri` carry no model.** Losses and kills are zero in all eleven saves.
|
||||
|
|
|
|||
|
|
@ -106,4 +106,41 @@ struct SystemConstructionResult {
|
|||
// CONFIDENCE: high -- see colony.h's ProcessBuildQueue for the rules and their evidence.
|
||||
SystemConstructionResult RunSystemConstruction(std::vector<BuildOrder>& queue, int points);
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// The hull and the fleet at birth -- READ, NOT YET IMPLEMENTED
|
||||
// ---------------------------------------------------------------------------------------
|
||||
//
|
||||
// This is written down here rather than coded because the newborn hull copies four cached
|
||||
// stat words out of its design, and those words are recomputed by the design's own stats
|
||||
// pass, which this engine models only far enough to get a hull class. Coding it now would be
|
||||
// writing fields we cannot compute. The whole chain is read instruction by instruction in
|
||||
// the RE repo; the shape, for the lane that gets the design stats:
|
||||
//
|
||||
// THE SHIP. 176 bytes. The object id comes from the network-node id allocator --
|
||||
// `(counter << 4) | (node & 0xF)`, per-node counters, PRE-incremented, never issuing 0 --
|
||||
// and is written into the object by the id-map insert, not by the constructor. At birth:
|
||||
// the owner is the queue's owner and the design is the order's design; range, health,
|
||||
// construction capacity, refuel capacity and repair capacity are copied from the design's
|
||||
// cached stat words; the plague and one other word are -1 and everything else is zero.
|
||||
// Two fields matter to a reimplementation:
|
||||
// * the FLEET LINK IS NULL at birth and is set by the fleet-join step, not here;
|
||||
// * the TURN-BUILT stamp is the sim's frame counter, i.e. the number of the turn being
|
||||
// produced -- MEASURED: the six hulls the zuul frame-16 -> frame-17 pair adds all
|
||||
// carry the NEW turn number, which is independent evidence that the frame counter is
|
||||
// incremented before the spine runs.
|
||||
//
|
||||
// THE FLEET. 288 bytes. A system caches ONE home fleet; every hull built there joins it,
|
||||
// and a fleet is created only when that cache is empty. So a second turn of building at
|
||||
// the same system creates no fleet. A created fleet takes an id from the same allocator,
|
||||
// is born at the system's position, and always carries flag 0x400 -- which is NOT a
|
||||
// retreat marker (that reading is corrected) and is NOT the design flag of the same
|
||||
// numeral that game/design/hull.h warns about. The build path adds 0x20 on top. There is
|
||||
// NO scalar ship count: the wire's count is the length of the fleet's ship vector.
|
||||
// A fleet created with no name override asks the player's name generator, which is what
|
||||
// bumps the generator's counter -- one bump per generated name.
|
||||
//
|
||||
// Ships are also created OUTSIDE this pass, by the trade manager's encounter spawner. That
|
||||
// path touches no ShipRecords at all, which is what makes the per-class built counter a
|
||||
// clean discriminator between player-built hulls and spawned ones.
|
||||
|
||||
} // namespace sots::sim
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue