Commit graph

130 commits

Author SHA1 Message Date
alex
52581efbfb board: VM140 holder = lane H 2026-09-08 12:15:33 -04:00
alex
cfe07fef80 dashboard refresh 2026-09-08 12:15:23 -04:00
alex
f328b82b67 board: lane N output term closed and live-verified; blocker moves to the income tail; VM released 2026-09-08 12:13:40 -04:00
alex
58e3d85f3f board: lane V2 vtable inversion; 5,045 functions with no direct callers; tail draw surface is unobserved not absent 2026-09-08 12:06:22 -04:00
alex
7645399f97 dashboard refresh 2026-09-08 12:04:41 -04:00
alex
ef458bb3c8 board: lane B5 retreat pipeline; OID allocation closed; predicted original bug 2026-09-08 12:02:32 -04:00
alex
0253941d16 board: lane Y generator gap measured and attributed; BnkEl inversion oracle; divisor defect understated 2026-09-08 11:42:25 -04:00
alex
95b2bc81cf board: VM140 holder = lane N 2026-09-08 11:01:06 -04:00
alex
c3ec32be01 dashboard refresh 2026-09-08 11:00:57 -04:00
alex
a77b1c3427 board: RNG ledger closed with zero residual; trade-raid generation behind a virtual edge; VM released 2026-09-08 11:00:56 -04:00
alex
707da6f848 dashboard refresh 2026-09-08 10:39:40 -04:00
alex
f8f5581204 board: standalone scaffold runs on all 11 saves; 5 leaves closed, 0 regressed; ranked byte-match blockers 2026-09-08 10:39:39 -04:00
alex
c504729341 lane S2: the standalone scaffold, and the measured distance to the byte-match
tools/standalone_report.py drives sots-engine's sots_turn over each
consecutive-turn save pair and diffs the result against the game's own
post-turn save with state_checksum.py, which localises to named leaves and
proves its own coverage by re-serialisation.

  turn1-state -> turn2-state   baseline 209 diverging, after 204, closed 5
  turn2-state -> turn3-state   baseline 108 diverging, after 103, closed 5
  regressed 0 on both

`regressed` is reported next to `closed` and never netted off. It earned its
place immediately: committing the phase-31 player-status restore turned two
agreeing leaves into disagreeing ones, because the phase writes 1 and the file
carries 4.

The stable-system stand-in feeding the colony pass is a labelled hypothesis and
it survived a changed workload -- the same 3 ntdev leaves closed on both pairs,
six agreements, zero disagreements.

Two things deliberately NOT implemented: the TShn/ltis counters (18 leaves, a
`+1` would close them, but "+1 across one observed turn" is a hypothesis, not a
reading), and the RNG state write-back (an advanced-but-incomplete generator is
wrong in a different way from an untouched one).

dashboard.py gains section 6, reading verify/results/standalone/status.json:
phases modelled/committed per driver, baseline vs after, closed vs regressed,
the subsystem breakdown of what still differs, and the RNG gap. Sections 6-8
renumbered to 7-9; the delta footer tracks the two new counts.
DASHBOARD_README.md documents every number.

findings/control-flow/standalone-scaffold.md has the ranked blocker list.
2026-09-08 10:35:56 -04:00
alex
932f366597 dashboard refresh 2026-09-08 10:07:19 -04:00
alex
c15a45d0c6 board: lane I complete inlined-draw inventory; corrects lane J's 14 to 11; residual stated honestly 2026-09-08 10:07:18 -04:00
alex
1d7c6ef63e board+rules: lane J combat resolver; inlined draws invisible to call-graph sweeps; Ghidra sizes untrustworthy 2026-09-08 09:38:55 -04:00
alex
729cfc014c dashboard refresh 2026-09-08 09:07:48 -04:00
alex
7364e62986 board: lane Q 100% named coverage, three-cause reconciliation, second defect found at main 2026-09-08 09:07:47 -04:00
alex
49f1af466e board: VM140 holder = lane Z 2026-09-08 08:55:23 -04:00
alex
b8923121d8 dashboard refresh 2026-09-08 08:55:08 -04:00
alex
66bed1d6b1 board: lane K combat-done tail, autosave mechanism, tail RNG threat to the standalone milestone 2026-09-08 08:55:07 -04:00
alex
f490d69695 board: lane O built 7 workload saves; TurnCommands unblocked; waypoint type-2 negative result; click-helper correction 2026-09-08 08:37:13 -04:00
alex
46aebc9b13 board: VM140 holder FREE 2026-09-08 08:35:26 -04:00
alex
9de77f7e5e lane O: 7 purpose-built saves - issued turn commands, node routes, research-roll-pending
Produces the game states several board rows were blocked on, and reads each
one back out of the save before claiming it.

- CD/TurnCommands_v5 decoded: three saves with issued orders (research target,
  research boost, build orders, system rates, colonize, fleet move). Layout in
  SAVE_FORMAT.md section 11; ids cross-checked against the same file's Sys/Flt.
- Waypoint type 3 (NodeRoute) now has 16 instances in one save and the player's
  own fleet is a mover in two. Type 2 is shown NOT to be produced by a Move
  order for either node-drive race (Zuul and Human both emit type 3).
- research_roll_pending true at load in two saves; the ProcessTurn gate constant
  at 0x00a2c788 is a float 0.5, so the flag survives into ProcessResearch only
  while progress/cost <= 0.5 at the start of the turn.
- Budget tail: construction and a large maintenance are live; Nexp is empty in
  all 11 saves and the 1.8 UI has no expense slider, so slot 12 looks dead.

VM140 restored to the original 8-file SavedGames set (autosaves byte-identical)
and left at the main menu; VM140 row set FREE.
2026-09-08 08:35:13 -04:00
alex
648e9aae77 dashboard: count addresses.d fragments (was undercounting 615 vs 722), read layouts.json (22 -> 384), fix the layouts denominator and the 'objects' type row 2026-09-08 08:30:46 -04:00
alex
e1f038e440 dashboard refresh 2026-09-08 08:29:21 -04:00
alex
136f98b564 guides: the 15 earned method rules, each traced to the finding that produced it 2026-09-08 08:29:20 -04:00
alex
dcc4afddd3 dashboard refresh 2026-09-08 08:14:50 -04:00
alex
1df8d39047 board: lane T turn-driver map, two corrections, ResearchRollPending settled 2026-09-08 08:14:49 -04:00
alex
afa86208d7 dashboard refresh 2026-09-08 07:36:41 -04:00
alex
996f445313 board: lane A AIAgent blocks, 99.9% named coverage, StreamableEnum correction 2026-09-08 07:36:40 -04:00
alex
e1bdbe6edb dashboard refresh 2026-09-08 07:09:07 -04:00
alex
164f14fa7f board: lane W wire sections closed, oracle fixes byte-neutral, CD negative result 2026-09-08 07:09:06 -04:00
alex
a0dd707261 board: lane U research slice closed; claim VM140 for lane O 2026-09-08 07:00:52 -04:00
Alex
5a3f986f38 lane U: the unlock cascade, implemented and live-verified
Reads: TechTree::PrereqsMet 0x0057d8e0 (AND of ORs; zero groups TRUE, an empty
group FALSE), the prerequisite layout at TechDef+0x88/+0x98, the tail collector
0x00587cc3, and the head of OnTechResearched (RecordObservedTech unconditional;
the research-event roll gated on ResT == def && ResearchRollPending).

Live: 35 compared calls over three workloads, 0 divergences, tracecmp exit 0,
End-Turn oracle hashes unchanged. The EVENT_TECHS_UNLOCKED residual lane P
predicted and lane V measured is closed by running the cascade, not by posting
on completion.

12 new addresses in ghidra/addresses.d/lane-u.json (header 615 -> 627).
2026-09-08 06:57:37 -04:00
alex
ae00053e04 dashboard refresh 2026-09-08 06:36:55 -04:00
alex
314ca20352 board: lane G wire-schema channel, named coverage 38->97%, four reader defects 2026-09-08 06:36:54 -04:00
alex
48fcc3ff3a lane G: wire-schema channel — layouts.json -> generated stream schema for sots-engine
objects/layouts.json is a memory-layout projection: build() sorts fields by
off_abs (89 of 386 classes have offset order != write order) and merges
duplicate offsets into alt_tags, which is exactly the JewelsOfTheCrown
double-tag trap. Both losses are the substance of the on-disk format.

tools/streams.py is a second projection of the same recovery that keeps the
program order Lab.layout() already computes and the repeated tags, and drops
every memory fact — no off, size, sizeof, gaps or strides. The engine must read
and write the format, not inherit the original's ABI.

tools/gen_stream_schema.py emits sots-engine's include/generated/sots_stream_schema.h
under the same discipline as gen_addresses.py: generated, provenance header,
never hand-edited.

386 classes, 2042 wire items.
2026-09-08 06:29:30 -04:00
alex
545c715359 board: VM140 holder = lane U 2026-09-08 06:03:32 -04:00
alex
c9603d0508 dashboard refresh 2026-09-08 06:03:18 -04:00
alex
ce73fa95be board: lane V advance prediction held; Zuul closed; RNG 15/15 claim corrected 2026-09-08 06:03:17 -04:00
alex
857db3426e board: record a third instance of the add -A sweep (lane V's addresses.json edit) 2026-09-08 06:00:36 -04:00
alex
7eabfefff2 lane V: live verification of the event-posting model against an advance prediction
Lane P wrote the expected numbers into sots-engine docs/P-events-wiring.md §4 before
this run existed. Every one held.

First End Turn (ref-turn2 -> Launch -> End Turn, shim.cfg.recapb3 unchanged, build
eventlive-dd38117-20260908T0916Z, main dd38117 with no source change): 3 calls, 3
compared, 0 divergent, tracecmp exit 0 — where lane R's run exited 1 on
side.events.after.v.next_id orig=4 ours=3. Call 0 read turn=3,
events_turn_bucket_exists=true, events_next_id_in=3, events_in_turn_bucket=1,
events_dedup_risk=0, no events_scan_truncated, next_id 3->4 on both sides,
turns/turns_bytes 2/48 unchanged, node[144].progress 2879->5768, flag 1->2, rng
identical — the whole predicted list.

Five End Turns: exit 1 with 2 divergent calls instead of 3, each short by exactly 1
(next_id orig 7 ours 6, orig 12 ours 11) = the deliberately unmodelled
EVENT_TECHS_UNLOCKED. A 0-divergence result there would have been suspicious.

sizeof(Game::ObservedTech) = 44 measured live: observed_techs.bytes grew by exactly
44 on both completion calls (440->484, 484->528), confirming lane X's static pin
behaviourally. Non-researching players measured 880 = 20 x 44 and never moved.

One deviation from lane R, and it is a workload effect, not a defect: rng diverged on
call 9 because the completed tech had research_roll_pending set and the
OnTechResearched callback drew one word ours does not (left 374 vs 375). Lane R's
"RNG matched 15 of 15" was workload luck; the honest statement is that the rng region
matches on every call that does not complete a roll-triggering tech.

Zuul double roll CLOSED. No species-5 save existed, so this lane made one: a custom
game with only Zuul in the Available Species pool, 4 End Turns under the same compare
config. 8 calls, 8 compared, 0 divergent, exit 0; all four researching calls have
species=5 and advance the generator by two, not one (left 540->538, 522->520,
504->502, 485->483), and ours reproduced every post-state bit-for-bit. Save added as
verify/results/saves/zuul-turn5-species5.sav.

End-Turn oracle byte-identical to lane R's on the first turn, so none of this
perturbs the game. clean_room_check OK and host ctest 33/33, run as separate commands.
VM140 restored to the recap build at the main menu and released.
2026-09-08 05:59:22 -04:00
alex
3e918d7372 dashboard refresh 2026-09-08 05:55:28 -04:00
alex
3fcfd7f522 board: lane D mass struct recovery; fragment-dir structural fix 2026-09-08 05:55:27 -04:00
alex
0d84eb2d4c board: lane D serializer struct recovery (386 classes, 1,682 fields, 0 wrong on the 305-field regression set) 2026-09-08 05:52:07 -04:00
alex
795aa471d4 board: claim VM140 for lane V; record briefing error on fpu_cw parameters 2026-09-08 05:14:19 -04:00
alex
d4f868f823 board: std::string contradiction resolved (0x1c correct, 65 layouts audited, zero wrong); enumeration rule 2026-09-08 05:13:50 -04:00
alex
3768f24f7a dashboard refresh
Regenerated after the lane S integration; it was last written at fdd0b72 and had
drifted 12 board rows. Drops the now-resolved 'notes disagree on std::string
layout' open question.
2026-09-08 05:10:10 -04:00
alex
f965c8c769 lane S: std::string is 0x1c binary-wide; ObservedTech element fully mapped
Settles the 0x18-vs-0x1c contradiction lane X raised. 0x1c is right, everywhere,
and there is exactly one std::string instantiation in this binary:
_Bx@0, _Mysize@0x10, _Myres@0x14, _Alval@0x18.

ObservedTech+0x24 is that string's trailing empty-allocator word, not the
unaccounted data field it was read as. Three complete enumerations of the element
each skip it: ObservedTech::Write 0x00817cf0, the ctor 0x008562a0, and the copy
ctor inlined at 0x0079a184. Generalised with a new scanner, tools/strfootprint.py,
which recovers every (base, disp, tag) handed to the Mars::Stream string helpers:
65 std::string members off a non-stack base across every serializer in the exe,
ZERO with a sibling member inside the 0x1c span, and 51 of the 52 measurable
inter-member gaps exactly 0x1c. Corroborated by the vector<string> walk stride
(add esi,0x1c @0x00699c29), PostEvent's by-value strings at [ebp+8]/[ebp+0x24]
with RET 0x4c, and MoraleEvent 0x50 = name@0x34 + 0x1c.

Blast radius: zero recovered struct tables were wrong. Every string-bearing layout
already used 0x1c spans and 0x1c gaps -- ServerPlayer::pswd @0x2dc..0x2f7, the row
flagged for re-checking, included. Only prose carried the 0x18 number: the
loader-prototypes conventions line, the GlobalConst_ParseString prototype, and the
ObservedTech element table. struct-recovery S0 additionally had _Mysize/_Myres
transposed (size@0x14, res@0x18) while every table in the same file used the
correct offsets; fixed.

ObservedTech's four on-disk fields are now mapped rather than guessed, by reading
the serializer as lane X suggested: +0x04 uint16 otnF, +0x06 uint16 otnL, +0x08
bool odet (ONE BYTE, WriteBool), +0x0c std::string otch (0x1c), +0x28 int owith
= 0x2c exactly. That matches save_reader.py's on-disk order already. Game::
ObservedWeapon (0x00817bc0/0x00817b10) is the same element with tag owep.

Oracles unaffected and re-run: save_reader 36/36 and --strict exit 0 on all three
real saves; state_checksum 38 tests OK, coverage PROVED byte-for-byte on turn1 and
turn3. sots-engine wip/strings 32d3e36 syncs the header and corrects two stale
"unpinned" comments: clean_room_check OK, host ctest 33/33.

Standing rule this produced: never size a struct member from the offsets the code
touches. This build's STL puts the empty allocator LAST in both string (0x1c) and
vector (0x10), and an empty allocator is never loaded or stored, so a touch-scan
undercounts by exactly 4 every time. Size from an enumeration instead.
2026-09-08 05:09:33 -04:00