sots-engine/src/app
alex 586171cb72 app: T34 RecordObservedDesigns -- the observed-design list, and the three rules the save cannot show
The tail's phase 34 sweeps every player over every ship of every fleet and
records the design of each ship it can see. Three of the recorder's rules are
invisible from a save and every one of them changes the answer:

  * the lookup key is the DESIGN ID ALONE, not the (design, owner) pair;
  * a re-observation ERASES the record and PUSHES A COPY ON THE BACK rather than
    updating in place, so the list ends in last-observation order and the record's
    first-seen turn survives the move. This is why a turn's output is a
    PERMUTATION of its input and not an append -- which is what made the group
    look like 55 unrelated leaves;
  * the list is CAPPED AT 20 RECORDS PER DESIGN OWNER, counted from the most
    recent end, and the cap is applied after EVERY record call rather than once
    per sweep. On an empire with more than twenty designs in service that thrashes
    inside the one sweep: records are evicted and re-created, and a re-created
    record's first-seen turn is reset.

A fourth rule is a guard on the DESIGN'S OWNER and not on the observer: a design
owned by an NPC that is not a rebel AI is never observed by anyone. Every
observation record in every corpus save agrees -- the NPC factions' 26 designs
appear in nobody's list -- and removing the guard costs 9 leaves on the canonical
pair while costing nothing on the rich turn, so the two pairs test different rules
and both were run.

TWO THINGS ARE NOT MODELLED AND BOTH ARE NAMED IN THE CATALOG TEXT. The gate is a
two-bit-per-player word on the ship that is NOT serialised; this phase stands it
in with ownership, which is the smallest rule correct on every state the corpus
holds, because on both reference pairs no player observes another player's ship.
That is a hypothesis with a cheap falsifier and it is labelled as one. And the
phase's tech and weapon arms are not implemented: the original feeds the design
through three set builders into the observed-tech and observed-weapon lists, and
those builders are not decoded.

Measured, closed and regressed never netted:
  canonical pair turn2 -> turn3   62 -> 61 leaves   1 closed / 0 regressed
  rich turn ad-turn27 -> pinB   1092 -> 1058        36 closed / 2 regressed
The 2 are two `otnF` words at positions whose `odid` also moves, i.e. positions
that now hold a different record; and the 21 design leaves that remain are the
shadow of ship construction, not of this phase -- two designs receive their first
ships during that turn and no phase here builds a ship. Fed the true post-turn
ship list, the same code leaves 1 leaf of 55.

Host build 255/255; host ctest 57/59 with the two pre-existing corpus-writer
failures unchanged (12 of 43 saves, the SpecialProjectNameGen `usp` item, not
this lane's); shim cross-build green; clean-room and shim-config checks green.
2026-09-09 10:15:12 -04:00
..
alliance.cpp lane A2: S04, the alliance mask -- 80 player-records, 560 fields, 0 mismatches 2026-09-08 12:44:00 -04:00
alliance.h lane A2: S04, the alliance mask -- 80 player-records, 560 fields, 0 mismatches 2026-09-08 12:44:00 -04:00
CMakeLists.txt app: T34 RecordObservedDesigns -- the observed-design list, and the three rules the save cannot show 2026-09-09 10:15:12 -04:00
command_replay.cpp RB: sots_turn --turn-commands replays a recorded command stream, and ModCount closes 2026-09-08 18:57:46 -04:00
command_replay.h RB: sots_turn --turn-commands replays a recorded command stream, and ModCount closes 2026-09-08 18:57:46 -04:00
construction_phase.cpp game/sim + app: ship construction -- the build-queue completion bookkeeping, and S11's sub-pass wired in 2026-09-08 14:39:20 -04:00
construction_phase.h game/sim + app: ship construction -- the build-queue completion bookkeeping, and S11's sub-pass wired in 2026-09-08 14:39:20 -04:00
event_phase.cpp P11: post the no-research event into the save's turn bucket 2026-09-08 15:39:42 -04:00
event_phase.h P11: post the no-research event into the save's turn bucket 2026-09-08 15:39:42 -04:00
growth_phase.cpp S11 civilian growth; fix ComputeBudget's interest literals 2026-09-08 15:52:38 -04:00
growth_phase.h S11 civilian growth; fix ComputeBudget's interest literals 2026-09-08 15:52:38 -04:00
main.cpp RB: refuse to replay a capture silently against the wrong board 2026-09-08 19:05:29 -04:00
observed_phase.cpp app: T34 RecordObservedDesigns -- the observed-design list, and the three rules the save cannot show 2026-09-09 10:15:12 -04:00
observed_phase.h app: T34 RecordObservedDesigns -- the observed-design list, and the three rules the save cannot show 2026-09-09 10:15:12 -04:00
phase_catalog.cpp app: T34 RecordObservedDesigns -- the observed-design list, and the three rules the save cannot show 2026-09-09 10:15:12 -04:00
phase_catalog.h src/app: the standalone -- load a save, run a turn, write a save 2026-09-08 10:35:45 -04:00
report.cpp RB: sots_turn --turn-commands replays a recorded command stream, and ModCount closes 2026-09-08 18:57:46 -04:00
report.h RB: sots_turn --turn-commands replays a recorded command stream, and ModCount closes 2026-09-08 18:57:46 -04:00
script_phase.cpp SV: the script-object event bus, and what it writes in a turn 2026-09-08 16:46:25 -04:00
script_phase.h SV: the script-object event bus, and what it writes in a turn 2026-09-08 16:46:25 -04:00
trade_raid.cpp Y: model the turn's dominant generator cost, and the tail's turn record 2026-09-08 11:33:36 -04:00
trade_raid.h Y: model the turn's dominant generator cost, and the tail's turn record 2026-09-08 11:33:36 -04:00
treaty.cpp lane T2: the phase's leaf self-report is its own accounting, not the report's 2026-09-08 14:51:12 -04:00
treaty.h lane T2: the treaty-turn stamp; 76 leaves closed across five pairs, 0 regressed 2026-09-08 14:47:47 -04:00
turn.cpp app: T34 RecordObservedDesigns -- the observed-design list, and the three rules the save cannot show 2026-09-09 10:15:12 -04:00
turn.h RB: sots_turn --turn-commands replays a recorded command stream, and ModCount closes 2026-09-08 18:57:46 -04:00
turn_record.cpp lane E2: wire the ship census into the turn record; T36 still blocked, now on two named things 2026-09-08 13:25:17 -04:00
turn_record.h lane E2: wire the ship census into the turn record; T36 still blocked, now on two named things 2026-09-08 13:25:17 -04:00
visibility_phase.cpp lane E3: the per-system visibility record, the explored sweep and the system observed-stamp 2026-09-08 13:38:12 -04:00
visibility_phase.h lane E3: the per-system visibility record, the explored sweep and the system observed-stamp 2026-09-08 13:38:12 -04:00