lane AS merged: the detection roll fires, spies2 closed, rule 28 grown to six practices

This commit is contained in:
alex 2026-09-09 00:14:24 -04:00
parent aef3d487f3
commit 5e4c27772d
3 changed files with 39 additions and 17 deletions

View file

@ -1,16 +1,16 @@
# SotS RE campaign — coverage dashboard
Generated 2026-09-09 03:02 UTC · `sots-re` @ 6d33a74,2026-09-08 · `sots-engine` @ 989c692,2026-09-08 (240 commits) · regenerate with `tools/dashboard.py`
Generated 2026-09-09 04:14 UTC · `sots-re` @ aef3d48,2026-09-09 · `sots-engine` @ 989c692,2026-09-08 (240 commits) · regenerate with `tools/dashboard.py`
> **North star:** A functional reimplementation of the engine — behavior-equivalent, NOT byte-for-byte
## 1. Map coverage (campaign/board.md)
410 targets · mapped-or-better **363/410** `[█████████░] 89%` · verified **321/410** `[████████░░] 78%`
414 targets · mapped-or-better **367/414** `[█████████░] 89%` · verified **325/414** `[████████░░] 79%`
| Status | Count | % |
|---|---:|---:|
| verified | 321 | 78% |
| verified | 325 | 79% |
| mapped | 42 | 10% |
| in-progress | 4 | 1% |
| backlog | 41 | 10% |
@ -22,23 +22,23 @@ Generated 2026-09-09 03:02 UTC · `sots-re` @ 6d33a74,2026-09-08 · `sots-engine
| control-flow | 29 | 2 | 0 | 0 | 0 | 31 |
| subsystems | 4 | 8 | 0 | 2 | 1 | 15 |
| engine | 30 | 0 | 0 | 0 | 0 | 30 |
| verify | 101 | 15 | 3 | 35 | 0 | 154 |
| verify | 102 | 15 | 3 | 35 | 0 | 155 |
| phase2 | 13 | 3 | 1 | 0 | 0 | 17 |
| meta | 79 | 6 | 0 | 1 | 0 | 86 |
| meta | 82 | 6 | 0 | 1 | 0 | 89 |
| other | 19 | 2 | 0 | 0 | 0 | 21 |
## 2. Binary understanding
- RTTI type descriptors: **1,924** (`Game::` 1,404, `Mars::` 194; serializable types 179)
- Classes with recovered member layouts: **384** / 1,598 named classes `[██░░░░░░░░] 24%` — `objects/layouts.json` (serializer recovery) plus classes recovered by hand in `struct-recovery.md` + `schema-gaps-resolved.md`. Note 179 types are *serializable*; the recovery also reaches non-serializable ones, so this is not a subset of that
- Functions: **41,411** (parsed from `01-fingerprint.md`); named/annotated in the **address contract** (`ghidra/addresses.json`, not Ghidra's full rename count): **1276**, verified **1145** `[█████████░] 90%`
- Functions: **41,411** (parsed from `01-fingerprint.md`); named/annotated in the **address contract** (`ghidra/addresses.json`, not Ghidra's full rename count): **1283**, verified **1152** `[█████████░] 90%`
## 3. Data layer
- Catalogs: **1,595/1,595** files parsed (91 block kinds in `schema_stats.json`), dangling cross-refs **0** (`crosslink.json`)
- Oracle `mars-parse`: **1,531/1,531** files agree `[██████████] 100%`
- Oracle `mars-text`: **64/64** files agree `[██████████] 100%`
- Saves: **25/25** real saves strict-clean — strict exit 0, 0 errors, 0 warnings
- Saves: **29/29** real saves strict-clean — strict exit 0, 0 errors, 0 warnings
- Design rules: **127/127** stock designs pass `[██████████] 100%`
- Value domains: **490/724** typed fields have been seen to vary `[███████░░░] 68%` — the other **234** have only ever held one value across the corpus, so their typing is untested (`value-domain-census.md`)
@ -112,7 +112,7 @@ Detail: `verify/results/standalone/report.txt`.
## 7. Verification ledger
- ✅ Saves strict: 25/25 (strict exit 0, 0 errors, 0 warnings)
- ✅ Saves strict: 29/29 (strict exit 0, 0 errors, 0 warnings)
- ✅ Design rules: 127/127
- ✅ oracle mars-parse 1531/1531 · ✅ oracle mars-text 64/64
- ✅ Compare harness present (`verify/harness/compare/`)
@ -133,11 +133,11 @@ Most recent open:
## 9. Delta since previous dashboard
- verified targets: 317 → 321 (+4) · mapped-or-better: 359 → 363 (+4)
- verified targets: 321 → 325 (+4) · mapped-or-better: 363 → 367 (+4)
- engine LOC: 58,647 → 58,647 (+0) · test files: 122 → 122 (+0) · checks: 4,257 → 4,257 (+0)
- addresses verified: 1,139 → 1,145 (+6) · recovered layouts: 384 → 384 (+0) · open questions: 26 → 26 (+0)
- addresses verified: 1,145 → 1,152 (+7) · recovered layouts: 384 → 384 (+0) · open questions: 26 → 26 (+0)
- standalone leaves closed: 45 → 45 (+0) · leaves still diverging: 63 → 63 (+0)
---
warnings: board.md: unknown types subsystems; mars-rng.md: no oracle total row parsed; mars-stream.md: no oracle total row parsed; mars-vfs.md: no oracle total row parsed
<!-- dashboard-metrics {"verified": 321, "mapped_plus": 363, "targets": 410, "loc": 58647, "tests": 122, "checks": 4257, "addr_verified": 1145, "addr_total": 1276, "layouts": 384, "open_q": 26, "sa_closed": 45, "sa_left": 63} -->
<!-- dashboard-metrics {"verified": 325, "mapped_plus": 367, "targets": 414, "loc": 58647, "tests": 122, "checks": 4257, "addr_verified": 1152, "addr_total": 1283, "layouts": 384, "open_q": 26, "sa_closed": 45, "sa_left": 63} -->

File diff suppressed because one or more lines are too long

View file

@ -413,5 +413,23 @@ So, four practices:
252 everywhere looked like a fact about the game; it was a fact about our saves. Compare rule 8's
eighteen fields that split a roster identically because nothing exercised them.
4. **Pair entry probes with the return-address ledger before calling a subtree draw-free.** An entry
probe on an inner function reading zero says nothing about an *inline* draw in its caller — which
is exactly where the spy half's detection roll lives.
probe on an inner function reading zero says nothing about a draw sited in its *caller* — which is
exactly where the spy half's detection roll lives.
**Confirmed live, 2026-09-09.** Lane AS measured both instruments on the same turn: the entry probe
on `SpyManager::Slot13RngCallee` read **0**, while the return-address ledger recorded the detection
roll firing for **one word** in the caller's body. The zero was never a statement about the subtree —
only about which function the call happens to sit in. (The roll is a plain call, not an inlined one;
the earlier claim that it was inlined was wrong, and the practice holds either way.)
5. **A fact about one map is not a fact about the game.** Practice 3's sibling, and it cost a lane a
whole workload plan. One lane reported that "an enemy colony with an asteroid belt does not exist in
this game", which was true of *its* map. All twenty-two corpus saves have a usable belt, two of them
already hold four AI-owned ones, and the next lane's very first generated map had two — **zero
regenerations**. Before building a state to satisfy a condition, count the corpus against it: the
state you need may already be sitting in the save set.
6. **Read the polarity before reading the count.** In the same chain, the jump goes *past* the roll:
with the belt gone there is **no draw and the spy is detected anyway**. A zero at that site therefore
means two opposite things, and a lane that assumed the intuitive polarity would have reported the
detection case as "did not fire".