# CURRENT_PHASE — Phase 37: the structs phase — the original's types back into the matched C (v2.2.0 → v2.3.0) > **Gate 1 approved by Drew on 2026-09-11 (S106; plan mode at Max; Opus 5).** The Gen3 order is Drew's: dedup (P35, closed) → pins > (P36, closed) → **structs** → names. The phase's product: one canonical struct definition per layout, every raw pointer cast a member > of a typed base, one canonical prototype per definition, the 4,010 Phase-36 lever survivors closed by the shape that was missing — with > Drew's stop rule **grind to zero** on all three volume counters (raw casts, lying declarations, levers), each "zero" defined honestly in > the plan's §"What zero means". Names are placeholders + cited evidence (`Unkstruct_`, `unk`); meaning-naming is Phase 38. > The approved plan is reproduced VERBATIM at the end of this file (§"Approved plan"). **Baseline HEAD at open: `79b2f6f15`** (the > Phase-36 close commit — made by Claude on Drew's word "you commit the last phase end" and pushed on his word "just push the last > phaseend as a normal commit", two one-off R6 waivers; **no tag, no release** at phase closes — Drew, S106; the PhaseEnd blocks' > `git tag` lines are retired from T10 on). > **R22 obligation:** every batch that touches `src/` is followed by the clean fleet run (218/218) before its commit — this phase changes > no byte, ever. **Rules ratified at gate 1 by the plan approval: R107–R117** (the PhaseEnd_Phase36 candidates (a)–(k); Drew may still > veto any of them — say so and the DIGEST entry is amended). ## Milestone (gate 2 — what Drew confirms, each with its literal output) 1. **Definitions:** `type_census --check` → **0 duplicate struct definitions fleet-wide** (one canonical definition per layout, in the canonical type files, hex offset comments, VARIANT camps named apart), 0 dead names, 0 definitions outside the canonical files, every converted site a field of its type, controls green. 2. **Casts:** `type_census --check` → **0 raw cast sites** in all four forms (`*(T *)(…)`, `*(T *)ident`, `((T *)e)[i]`, `M2C_FIELD(`); reinterpret sites counted apart by macro; the player block and the first-parameter entity type are structs in `src/`; the counts published in the readability series with the dated snapshot (R75). 3. **Declarations:** **0 lying declarations**; K&R sites counted apart, each marked with its bytes' cause; one canonical prototype per definition; the 51 TU-CONFLICT rows resolved (the ledger rows deleted with the bytes that resolved them); the 24 parked P36 classes landed; classes E/F/G at 0. 4. **Levers:** `lever_census --check --strict` → **0 pins, 0 asm statements outside the GTE header, 0 per-TU asm macro definitions**; every removal attributed `(P37 …)` in the ledger; `verbatim_check --strict` unchanged (the 1998 routines untouched). 5. `make clean && make extract-all JOBS=16 && make check-all JOBS=16` → `check-all: 218 passed, 0 failed of 218` (R22); `make tools-health` OK with the new rung; `ghidra_rebuild --proof` PASS with the types; the record (T9), the PhaseEnd, the DIGEST append, the log archived; v2.3.0. ## Effort / model (R7/R26/R27 — every transition is PROMPTED, never assumed) - **Max** for T2 (the probe and its pricing), T3's design, T5's head-type layouts, T10 (the PhaseEnd); **xHigh** for T0, T1, T3's finish, T4, T6, T8, T9; **low** for T0's bookkeeping. Max is session-only (re-apply each session); xHigh is the highest persistent level. - **T7 = the P36 lane:** the Agent tool, one agent per TU batch, at Drew's concurrency cap (he sets and retunes it); it STARTS only on his word in the session that runs it (the S98 rule); **never an Ultracode wave without his direct approval** (R27). The coordinator's own judgment (harvest, toolify, the packs) stays at Max. - **Drew-only (R6):** every `git push`; the gate-2 confirmation; the milestone-close commit + the `v2.3.0` tag. - No harness task-list tool exists in this build (no TaskCreate/TodoWrite — checked 2026-09-11) — R28's list is THIS file's ☐/☑ checklist. ## Tasks (plan order; one commit each; ☐ → ☑ with the verify line quoted in the log) - ☑ **T0** (S106; the commit carrying this line) — Precondition, baseline and the phase file: the P36 close commit `79b2f6f15` (done and pushed this session, on Drew's word; the `v2.2.0` tag created then DELETED — no tags/releases at closes, Drew); R22 clean fleet at the open `extract-all: 217 extracted, 0 failed of 217 (+ main, serial)` · `check-all: 218 passed, 0 failed of 218` · `real 1m25.976s` · exit 0 (`.run/P37/baseline/r22_t0.log`, HEAD `db212f167` — the close commit adds no build input); `delever_oracle --recipes` `4284 recipes captured in 14.6 s at -j16; errors 0` · `--snapshot-baseline` `7428 object(s) under .run/P36/delever/baseline at db212f167` · `--calibrate main md_SC07_004 ov_SC02_005 ov_SC04_011: 147/147 objects byte-identical untouched; twin checks 0 (0 mismatch); positive control DIFFERS on build/src/800.o; 2.3 s — OK` (main 0.108 s/object, ov 0.15–0.16, md_SC07_004 0.504) (`.run/P37/baseline/oracle_t0.log`); `.gitignore` P37 allowlist (by-contents, R84; `git check-ignore` verified: logs and `.tsv` tracked, `.o` ignored); this file. Verify at the commit: `git status` clean. - ☑ **T1** (S106; the commit carrying this line) — `tools/type_census.py` + **the struct map** (added after T0 — Drew asked, Claude recommended, Drew approved "Yes — T1 delivers the map"; P5d): definitions with o32 layouts + duplicate classes + VARIANT camps + dead names; cast sites in all four forms + `M2C_FIELD` with base class/offset/width/sign/load-store; the declaration layer (definitions K&R-read, in-scope declarations per TU, the lying set, multi-spelled callees, aliases, builtins, attributes); the P36 inheritance in ONE file (`.run/P37/census/parked.tsv`) and the func_8013D9B0 `gte-unsigned` inconsistency resolved; coverage (R32) vs the raw regex totals; controls (the player block's live-verified fields, MATRIX vs MATRIX_L48, one TU-CONFLICT diagnostic); `progress.py` `types` block + README sentence; `readability_progress` learns the uncounted forms; dictionary + SETUP rows; `lever_census`'s stale controls re-keyed. **The struct map** (`.run/P37/census/struct_map.json` + the rendered `docs/struct-map.md`, generated — R75): every function analysed, every cast site assigned to a base, bases clustered into the types the fleet needs — membership (which functions, which parameter/global), the evidence class per merge (same `D_` base · call-graph argument flow · dedup-registry identity · allocator return · signature-only, which never merges alone), each type's layout from the union of its sites' (offset, width, sign), its site coverage (how many of the 412k it explains — the campaign's leverage order), and every conflict (two incompatible layouts on one base → two types or a union); consumed by T2's sampling, T4's typed prototypes and T5/T6. Verify: `type_census: definitions ( layouts, duplicate classes, variant camps) · cast sites in bodies over bases ( forms, coverage OK) · lying declarations / callees · controls 4/4` and `struct_map: types over bases explain / sites (

%); unassigned bases; conflicts`. - ☑ **T2** (S106; the commit carrying this line) — The probe: (i) struct spelling on ~150 bodies over the top bases (identical / differing / closing under S+A / residual by pass); (ii) the canonical prototype per TU on ~300 TUs (free / byte-changing / refused, causes) + the 24 parked patches as the known-true set; (iii) the definition fold on 20 TUs; seconds per object, objects per header edit. Prices T4–T7 with denominators (R41). Verify: the probe table in the log with its commands. - ☑ **T3** (S107, Max; the commits `21d2ccc14`, `42a57f576` and the close commit carrying this line) — `tools/restruct.py` (rungs S/S2/S+A/X/R/D/L, the delever pattern, the ledger, inflight restore, selftest 48 + `--real` 53 incl. the known-true no-op and the negative controls), `tools/struct_layout.py` (the layout engine + the writer + the naming invariant), `delever_oracle`'s LINKED mode (+ the snapshot guard), the reinterpret macros in `include/common.h` (proven equal on cc1's assembly), `tools/restruct_cycle.sh` (detached, R115); the Plan agent's stress-test landed as the design (the S106 "T1 design" entry + the S107 design statement). **Verify:** `restruct --selftest: 48/48 OK` · `--selftest --real: 53/53 OK` · `delever_oracle --calibrate main md_SC07_004 ov_SC04_011: 114/114 objects byte-identical untouched … positive control DIFFERS … OK` · `--linked-control: OK` · **the batch on one overlay:** `restruct: batch t3d1 rung D — 27 files … 258 declaration units: 242 canonical / 0 promoted / 6 K&R marked / 16 kept … final 27/27 identical · written 27 files` + the redraw `t3d2 … 8 K&R marked / 16 kept … final 26/26 identical · written 5 files`, each followed by R22 **`check-all: 218 passed, 0 failed of 218`** (`r22_t3d1.log`, `r22_t3d2.log`; and `r22_t3c.log` after the `common.h` macros). Deviations from the brief, recorded in the log: a new base symbol goes into the binary's splat symbol file (R15), not a `-T` fragment; T4 canonicalises widths/arity — the typed signature is T6's per-callee S → T → D unit (pointer arithmetic scales). - ☐ **T4** (xHigh; unattended cycles) — The declaration layer over the fleet by symbol space (rung D): canonical prototypes where free — carrying the struct map's parameter types (`Unkstruct_X *a0`, not `s32 a0`) in the same pass —, the free repairs, the 24 parked signature changes with their callers, the 51 TU-CONFLICT rows, class E aliases, `__builtin_abs`, K&R sites marked and counted apart, the "carried decl layer" banners deleted. R22 every 2 batches; one commit per batch. **Rules check (P6) after T4.** - ☐ **T5** (Max for the head types; xHigh to run) — Struct unification (rung L): one canonical definition per layout in the final style, VARIANT camps uniquified, dead names deleted, PsyQ layouts under Sony's names, the entity type and the player block authored, main + `md_*` onboarded. Verify: `type_census: 0 duplicate definitions …; 0 dead names; controls 4/4`; R22. - ☐ **T6** (xHigh; unattended cycles) — The cast campaign (rungs S/S+A/X/R), largest leverage first; the 138 absolute casts; `M2C_FIELD`; `__builtin_memcpy`; carved word runs (R60 audits). R22 every 2 batches; the readability and lever series fall per commit. **Rules check (P6) every 4 batches' worth of tasks.** - ☐ **T7** (agents at Drew's cap; starts on his word) — The residue lane to zero (rung E), harvest → toolify → regen between draws, the residue re-bucketed at every landing (R117). - ☐ **T8** (xHigh) — The gates: `type_census --check` in `make tools-health`; `attribution_check` folded into `lever_census --check`; the close snapshots published; the canonical types into the Ghidra programs (`ExportAnnotations` type rows) with `ghidra_rebuild --proof` PASS. - ☐ **T9** (xHigh) — The record: cookbook § (incl. the §396(a) correction with its bytes), decision log P37, accelerators, SETUP rows, the wiki, the Gen3 pages, the series rendered, tool-index + kit corpus, `doc_links --strict`, tools-health OK; **the post-100 % story** — `docs/story.md` §10 ("After 100 %") and `docs/retrospective.md` §7 brought to the phase's close, `tools/timeline.py`'s lower panel (the lever and readability series) regenerated (added 2026-09-12 on Drew's word; the per-session step is in the checkpoint procedure). - ☐ **T10** (Max) — Close: R22 218/218; tools-health OK; PhaseEnd_Phase37.md + DIGEST §0/§2/§3 + this log archived (R19) + kit corpus; left uncommitted for Drew's close commit; v2.3.0. ## Decisions (owner's words, in order) - **Gate 1 (2026-09-11, S106), the four forks (AskUserQuestion):** stop rule → **"Grind to zero"** (the phase does not close while any raw cast, lying declaration or lever remains; the agent lane runs until the counters are 0 regardless of token cost); naming → **"Placeholders + cited evidence"**; T7 → **"P36 pattern at your cap"**; the declaration layer → **"Full canonical layer"**. The plan's §"What zero means" gives each counter its honest, reachable definition (reinterpret macros and unions for the genuine reinterpretations; byte-proven K&R sites counted apart; legitimate GTE sequences as project-local macros in the one header, clobber-only steers closed by the shape). - **Gate 1, Drew's question mid-plan:** *"did we do this project wrong from the start? should we have focused on building structs and not letting compiler hints/register pins add up?"* → answered from the record (levers.md §5, DK-65, the S91-b hindsight, P36's `/s` finding): the levers' error was the SILENCE, not the lever (38 % never load-bearing; the rest needed knowledge that did not exist until P23–P32); types were the larger error — Phase 17 measured correctly that types did not move match-% for m2c and wrongly concluded they could wait: they were the banking lever (§236), the width lever, and — P36's finding — a codegen lever through `MEM_IN_STRUCT_P`. A canonical type layer growing from the first bank (sotn's shape) was achievable and is the kit's day-one rule. The T2 probe puts the number on it (how much of the 4,010 the struct hypothesis closes) → the decision log (R31). - **Gate 1, after the plan approval:** *"you commit the last phase end"* → Claude made the Phase-36 close commit `79b2f6f15` (a one-off R6 waiver). Then: *"there is no tag and release, just push the last phaseend as a normal commit"* → the local `v2.2.0` tag deleted (no tags or releases at phase closes — the PhaseEnd 🛑 blocks drop their `git tag` lines from T10 on) and `git push origin 79b2f6f15:main` run on his word (a second one-off waiver; R6 unchanged for everything else — Drew pushes). - **S106, after the checkpoint (Drew):** *"we are documenting our story about this post 100% work correct?"* → the record showed the story and the retrospective ended at Phase 33 and the timeline's axes read 100 % forever; recommended and approved (*"agreed. do it now and update checkpoint memory to do this at the end of each session"*): `docs/story.md` §10 "After 100 %" + `docs/retrospective.md` §7 written from the record (P35–P37 so far), `tools/timeline.py` extended with the lever and readability series as a lower panel + two columns, the rule in the wiki conventions page, T9 amended, and **the checkpoint procedure gains a step: advance §10/§7 + regenerate the timeline at the end of EVERY session** (the memory `checkpoint-current-phase-before-pause` updated). - **Gate 1, after T0 (Drew):** *"insted of our phase plan, should we analyze every single func, and group together all the funcs that need a struct that share, so we can build a final struct map of all needed structs?"* → Drew asked, he did not propose (*"i wasn't suggesting we do it. im not the expert you are. I was asking you"*); Claude's answer and recommendation: yes — not instead of the plan, it is T1's clustering made a first-class deliverable, and it lets T4's canonical prototypes carry the mapped parameter types in one pass (order: census → **map** → probe → tools → declarations-with-types → unification → casts). AskUserQuestion: **"Yes — T1 delivers the map"** (P5d, a deliverable added to T1; the task order unchanged). ## Rules at gate 1 (P10) **R107–R117 ratified by the plan approval (2026-09-11; the PhaseEnd_Phase36 candidates (a)–(k), operated through P36):** R107 ban the silence, not the lever — a compiler-forcing construct is allowed in a banked body only marked, ledgered and published from the first bank, with a one-compile bank-time trial of the body without it · R108 a generator ships with a negative-control corpus of real bodies where it must fire, and a regen pass reports its refusal reasons as a histogram · R109 at every landing, run every registered family on the agent's START text before banking · R110 a scorer's target is the tree's own bytes compiled by the build's own tail, never a disassembly — a known-true case (the tree's body scores 0) before any campaign · R111 scratch is keyed by the unit of work, never by a worker tag or a file (R48 extended) · R112 a gate's baseline is a snapshot, not the build directory — a clean rebuild never runs where a live scorer reads `build/` · R113 a lever's marker names its PASS and its INSTRUMENT (R65 for markers), asserted by an attribution check at the close · R114 a ledger's "done" is per body (unit, function, after-hash), never by text alone · R115 a long unattended run is DETACHED with a progress log, never a harness background task (R55 operated) · R116 a marked ordinary-C fake (do-while, dead initialiser) is counted apart from levers and never an orphan; an invented condition, a dead store or a dummy reassignment is never banked · R117 a "stalling?" question is answered with the residue bucketed by what each bucket needs before any plan is proposed. **Candidates for Phase 38 gate 1 accumulate here as the phase produces them.** ## Log (append-only; one entry per step, with the literal verify line) - **S106 2026-09-11 — session start.** Session-start protocol at low effort (the P36 close artifacts still uncommitted in the tree), then Drew: `/effort max` + plan mode. Reconnaissance: three Explore agents (the type layer as it stands — 196k tokens; the P36 residue and its artifacts — 243k; sotn-decomp's type layer + our types doctrine — 207k) and one Plan agent (the tool/oracle design stress-test, still running at the T0 commit — its report lands in T3's design notes). Four AskUserQuestion forks answered (the decisions above). Plan approved (ExitPlanMode). Facts the plan rests on, verified this session: `PROMOTE_PROTOTYPES` at `tools/reference/gcc-2.7.2/config/mips/mips.h:1153` and the caller-side conversion at `c-typeck.c:1740` (convert to the parameter type, THEN default-promote); the `/s` model in `docs/gcc-2.7.2-map/cse_expr.md` §4; `ExportAnnotations.java` carries `type` rows (0 tracked today); `delever_oracle.py` is object-scoped and header-capable through `delever.includers()`. - **S106 — the P36 close commit.** Drew: *"you commit the last phase end"* → `git add -A phase-ends decomp-architect config/kit_coverage_map.tsv docs/story-timeline.md docs/story-timeline.svg` (8 files, 632 insertions; nothing ROM-derived) → `79b2f6f15` with the PhaseEnd's message; `git tag -a v2.2.0` created locally. **Not pushed (R6) — Drew: `git push origin main --tags`.** - **S106 — T0 baseline.** `make clean && make extract-all JOBS=16 && make check-all JOBS=16` → `extract-all: 217 extracted, 0 failed of 217 (+ main, serial)` · **`check-all: 218 passed, 0 failed of 218`** · `real 1m25.976s` · `exit=0` (`.run/P37/baseline/r22_t0.log`; run at HEAD `db212f167` 04:42 UTC, before the close commit — which adds no build input). `delever_oracle --recipes -j 16` → `4284 recipes captured in 14.6 s at -j16; errors 0`; `--snapshot-baseline` → `7428 object(s) under .run/P36/delever/baseline at db212f167` (the oracle's baseline path is still P36's — T3 decides whether `restruct` shares it or takes `.run/P37/`); `--calibrate main md_SC07_004 ov_SC02_005 ov_SC04_011 -j 16` → `147/147 objects byte-identical untouched; twin checks 0 (0 mismatch); positive control DIFFERS on build/src/800.o; 2.3 s — OK` · `main 85/85 identical, mean 0.108 s per object` · `md_SC07_004 1/1, 0.504 s` · `ov_SC02_005 33/33, 0.152 s` · `ov_SC04_011 28/28, 0.163 s` (`.run/P37/baseline/oracle_t0.log`). `.gitignore` P37 block inserted before the outreach block (by-contents form); `git check-ignore -v`: `r22_t0.log`/`oracle_t0.log` → `!/.run/P37/baseline/*.log`, `census/parked.tsv` → `!/.run/P37/census/*.tsv`, a `.o` → ignored. - **S106 — T0 committed `0a55cb0fd`** (this file, `.gitignore`, the two baseline logs, the recalibrated `calibration.json`); tree clean. - **S106 — the close pushed.** Drew: *"there is no tag and release, just push the last phaseend as a normal commit"* → `git tag -d v2.2.0` (0 `v2*` tags remain — none ever existed for v2.0.0/v2.1.0 either); `git push origin 79b2f6f15:main` → `db212f167..79b2f6f15 main`; `origin/main` = the close commit; local main 1 ahead (T0). - **S106 — gate-1 adjustment (P5d): T1 delivers the struct map.** Drew's question + "Yes — T1 delivers the map"; the T1 task line, T4's typed prototypes and the decisions above updated; committed as the next log commit. - **S106 — T1 design (X1).** One walker per file in worker processes (the masking and the function spans from `share_census`, the cache/coverage pattern from `lever_census`) → definitions with o32 layouts (`Resolver`), six cast-site forms with base/offset/width/ sign/access, the declaration records, the flow edges; the parent computes duplicate tiers, coverage, controls, global blocks and the struct map (union-find over evidence only). **The Plan agent's stress-test landed** (322k tokens; its design goes into T3's notes) and corrected four premises before the fleet run: (1) a whole-object oracle says DIFFERS on a correct global-block edit because the RELOCATION SPELLING changes (`D_80078EB4` → `g.hp`) while the linked bytes are identical — T3 needs a resolved-relocation mode (control: `md_SC07_004`'s `D_801F8870[1]`) and a committed linker fragment for every new base symbol; (2) function identity is never the bare name (6,415 names carry >1 body text) — the map keys a function by its body hash; (3) a sixth site form exists, `((T *)p)->f` (36,681 sites: a COMPONENT_REF already, the readability MEMBER regex counts it as a member — it is the rewrite's rung 1, not a finished member); (4) "one definition per layout" is too strong — `{s16 ×4}` carries 177 names, some genuinely different types (`Rect` vs `SVECTOR`): a duplicate is same layout AND (identical meaningful member names | an opaque copy block | flow evidence); layout twins without evidence are reported, not merged — **milestone item 1's "per layout" reads "per type" from here (a clarification for Drew, not a scope change)**. Also from the agent: caller bytes DO depend on a narrow prototype's widths in both directions (the return axis too: `extern u8 f(void)` makes the caller mask eagerly), and rung 1 (body-local `((Unk *)a0)->f`, no signature change, the same `/s`) decouples the byte question from the declaration question — rung 2 (the typed signature) follows the declaration solver. - **S106 — T1 built.** `tools/type_census.py` (selftest 21/21 on a fixture with every form); five fleet runs to converge the map: run 1 a mega-cluster of 297,668 sites (Steensgaard's classic over-merge through untyped conduit parameters) and A/C sites counted against a deref denominator (105 %); run 2 typed-use parameters + a width-conflict veto + nested bases → 173,025; run 3 the single-source rule for locals + declared-type seeding of `AT:` nodes → 166,789 (the entity type: max offset 0x24C = `actor-struct.md`'s record size); run 4 positive shared evidence required on inter-function edges (the callee's map structured ≥2 offsets, ≥1 offset in common) → two large types (107,598 sites / 0x10C spanning 9,753 pointer globals — the cross-address copies of per-overlay globals, still partly fused at low offsets; 65,397 sites / 0x24C with one instance global `D_80126B58`), their conflicts mostly same-width sign mixes (a store's signedness leaves no byte), now counted apart from width conflicts; run 5 = the final numbers. **The map is a model with stated rules and reported conflicts; T2 tests it on bytes, T5 refines it.** - **S106 — T1 verify lines (HEAD `23fc5d215`, 3 m 20 s at -j16).** `type_census: 7261 definitions (525 layouts, 206 duplicate classes, 39 variant camps) · 503016 cast sites in 69497 bodies over 8 base classes (4 forms + A, coverage OK) · 98648 lying declarations / 1609 callees · controls 4/4` · `struct_map: 18760 types over 18760 clusters explain 498896/503016 sites (99.2 %); 4120 unassigned sites; 729 types with conflicts`. DEFINITIONS: canonical header 1,179 · `.c` file-scope 4,091 · `.c` block-scope 1,904 · per-function shared headers 63 · other headers 24; 3,109 distinct names; duplicate tiers: 122 same-named + 84 opaque classes (2,789 names), 46 layout-twin classes / 1,844 names kept apart; 588 exact-text classes / 4,469 copies; 39 VARIANT names; 141 dead canonical names; 75 canonical names redefined in `.c`. CAST SITES: **deref 503,016 = P 409,007 + I 60,666 + X 13,800 + M 19,543** (+ A 18,912 address-of; + C 36,681 typed cast-member) in 69,497 bodies; coverage OK on all six forms; refused 0; the readability regex over raw text 411,850 (the 2,843 difference = casts inside comments/strings/macro blocks); by base: param 276,860 · local 149,915 · gaddr 40,122 · nested 24,076 · global 8,860 · other 1,678; by width: s4 145,167 · u2 142,775 · s2 131,818 · u1 43,174 · agg 13,472 · p4 12,016 · u4 11,165 · s1 3,429; top bases a0 92,255 · param_1 81,595 · arg0 67,704 (the first parameter 241,554 = 48 %). DECLARATIONS: 99,130 definitions (1,889 K&R) · 4,279,365 extern function declarations over 12,139 names (3,870 spelled >1 way) · 6,415 names with >1 body text · 1,078,837 data externs over 55,569 symbols (18,442 typed >1 way) · asm-label aliases 5,749 (225 names) · builtins memcpy 301 / abs 144 · attributes packed 64 / aligned 12 · lying 98,648 / 1,609 callees (K&R-empty 91,357, narrow 7,291). GLOBAL BLOCKS: 2,123 runs of ≥4 adjacent scalar `D_` symbols (14,251 symbols). PARKED (P36): **24 classes / 453 bodies / 691 needed sites → `.run/P37/census/parked.tsv`**, needs {signature 13, struct 7, ? 4}; 22 PARK names are minimum-lever banks. CONTROLS 4/4 (the doc dispute reported: `D_80078F08/0C` code 4 vs `actor-struct.md` 2 — a T9 correction; the bytes side with the code). `lever_census`: controls re-keyed (14 / 8 / `func_801896EC` 2, each counted independently) → 4/4 OK; `--check: 4,010 … 0 UNMARKED — OK`; **`--check --strict: pins 2141, asm 1419, gte-levers 450, direct GTE statements in bodies 6717, per-TU asm macro definitions 314 … FAIL`** — `--strict` now reads its own words: a direct GTE coprocessor statement in a body is an asm statement outside the GTE header (the P36 close excluded 6,447 `gte` + 270 `gte-unsigned` as Sony's idiom; under decision 1 they are work — macro calls from the one header; `func_8013D9B0`'s 268 are among them, resolved this way). Published (R75): `progress.py --json --readme` → `counts.types` + the README "Types (Phase 37, snapshot 2026-09-12)" sentence + two dated `corrections` (the four-form count; `--strict`'s direct GTE statements); `progress.py --check` fresh; `readability_progress --snapshot` (the TSV now read by column NAME; 16 census columns appended) → `503016 by the census's four forms (+36681 typed cast-member, +18912 address-of) … 7261 struct definitions over 525 layouts (206 duplicate classes / 2789 names); the map: 18760 types (99.2 % of sites)`; `lever_progress --snapshot` (79 milestones, 4,010 unchanged) → `--check OK`; `docs/struct-map.md` generated (200 types) + its Reference-index row; dictionary row + SETUP §P37 S106 (R87/R21); `make kit-corpus` → `tool_census --check: OK`; `doc_links --strict: OK`; `kit_lint: OK`; `kit_coverage: OK`. Files: `.run/P37/census/{type_census.json,type_census.txt,struct_map_top.json, parked.tsv}` tracked; `struct_map.json` (6.4 MB) and `sites.jsonl` (213 MB) regenerable, ignored. - **S106 — T2 the probe (Max).** Harness: `tools/restruct.py` — the rewrite engine's first form (`--try` rung 1 on one body, `--probe`, `--probe-decls`, `--probe-defs`, `--audit-layouts`, `--fanout-cost`; SETUP §P37 S106, dictionary row). Every judgement through `delever_oracle` in place and restored (R102); header bodies on every includer; the residual classified by `delever_search.classify`. **Five probes, every number with its denominator (R41):** 1. **Struct spelling (rung 1) — 165 bodies, stratified (A entity/0x24C 40, B pointer-globals 25, C matrix/vector-shaped 25, D record tables 25, E shared headers 20, F other multi-body 20, G single-body 10; half lever-bearing where available), seed 37, 385 s wall at -j12, `.run/P37/probe/probe_table.md` + `probe_rows.jsonl`:** 139 judged (23 had no convertible site on the base, 3 compile errors — one shape: a pointer field typed `void *` because the sites' pointees disagree, then indexed; the rewrite now skips those sites) → **IDENTICAL 126 (90.6 %), DIFFERS 13; 716 sites moved**. The DIFFERS were all COUNT/ORDER residuals = the `/s` alias asymmetry: after rung 1 the struct stores carry MEM_IN_STRUCT_P and the body's bare fixed globals do not, so `sched.c:837`'s escape hoists a fixed load over a struct store the original kept below it — read on the bytes of `func_801814AC` (ov_SC05_010): every `D_801C7E30` site a member except the store at +0x34 → IDENTICAL; that one store a member → the pointer reload hoists; the pointer global itself spelled as a struct member fixes that store and moves a constant elsewhere (§351: the `/s` flag is a dial per ACCESS). **Rung S2** (the minimal set of sites kept as casts — leave-one-out, then cumulative revert with minimisation, delever's rung-B shape) **closes 13/13 DIFFERS keeping 27 casts → 139/139 judged bodies byte-identical with members everywhere but 27 of 716 sites (3.8 %)**; C (matrix/ vector) keeps the most (20 casts over 7 bodies). Skipped by the rewrite, counted: 226 of 942 candidate sites (24 %): no-field 133 (the cluster layout has no field at that offset — overlaps/misalignment), sign 44 (a load whose sign differs from the field's), width 33 (a union/LOH shape), index 13, negative offset 3 — T5's type-authoring residue. S+A (struct + levers off) closed 0 of the 5 DIFFERS bodies with levers — the struct hypothesis is unmeasured at this sample size; T6's S+A rung on all 1,980 lever-bearing bodies measures it. Cost: mean 2.0 s per body judgement (max 45 s: a header on 141 includers); S2 ≤ 2n+1 compiles on ~10 % of bodies. 2. **Declarations — 4,828 (TU, callee) judgements (ov 4,666, md 80, main 41, shared headers 41) over the argcheck rows of 300 TUs, 941 s wall, `decl_table.md` + `decl_rows.jsonl`:** the definition's ANSI signature written into the callee's lying declarations → **IDENTICAL 4,473 (92.6 %), DIFFERS 0, COMPILE-ERROR 355**: arity contradictions 136 (`too few/many arguments` — the byte-proven K&R sites), conflicting declarations elsewhere in the TU 121 (the repair must replace EVERY declaration of the callee in the TU, not only the lying ones), 98 whose message the cause reader did not classify (main's `At top level:` 22, a `#define NULL` context line 14 — T3's solver reads the full message, R103). Zero DIFFERS: the caller-side width conversion the Plan agent warned of did not appear in this sample — either the narrow parameters already carry the right widths or their callers pass narrow values. 3. **Definitions — 20 overlay TUs (the 60 with the most file-scope definitions, shuffled), 365 folds, `defs_rows.jsonl`:** a duplicate of a canonical type (same layout, tier 1/2) replaced by `typedef ;` → **IDENTICAL 12 TUs, COMPILE-ERROR 8** (`structure has no member named a/f0/v`: an opaque-tier fold changes the member NAMES, so the TU's accesses must be renamed with it — T5's engine rewrites members, not only the definition; the tier-1 folds are free). 4. **The layout engine vs cc1 — 5,283 file-scope definitions / 29,248 named fields asserted (`sizeof` + every named field's offset by the negative-array-size idiom, the TU's real include environment in source order): rejected 0, unresolved 0** (`layout_audit.json`). Reached through three probe defects (R40: the environment lacked the canonical header; typedefs emitted out of order; block-scope typedefs hoisted) and two REAL engine gaps it found: `__attribute__((aligned(4)))`'s nested parens broke the attribute regex and dropped the field (`MZ` in md_MAIN_027), and per-field `aligned(N)` was ignored — both fixed in `type_census.py`; plus a census over-count: 27 `#ifndef BFM_ENGINE_TYPES_H` standalone blocks in 21 TUs (inert in a TU that includes the canonical header) now blanked — definitions 7,261 → 7,255, layouts 525 → 527, variants 39 → 40 after the re-run. 5. **The oracle — the relocation-spelling control (f3's `D_801F8870[3]` array walked through a pointer, md_SC07_004 `func_801A4258`): whole-object DIFFERS, `make build BINARY=md_SC07_004` with the candidate in place → `sha1 87ac0de3… == config/check.md_SC07_004.sha (BYTE-IDENTICAL)`** — T3's linked-relocation mode is required for the global-block class. **Fan-out cost: `engine_types.h` reaches 3,818 TUs / 3,975 objects; one typedef appended → 3,949 IDENTICAL in 35 s wall at -j16 (0.141 s/object)**, 26 transient COMPILE-ERRORs that vanished on re-run (a fan-out judgement retries a failure once before believing it, R40). **Pricing (R41):** T4 declarations ≈ 94k (TU, callee) pairs × 0.15–0.8 s ≈ 1 session unattended (≈93 % mechanical; ~6.6k pairs to the solver: ~2.9 % K&R sites, ~2.5 % multi-spelling, ~2 % unread causes). T5 unification: 5,995 in-`.c` definitions, ~60 % by alias alone, the rest with member renames; canonical-header batches of dozens per 35-s fan-out ≈ 1 session. T6 casts: 69,497 bodies × 2 s ≈ 2.4 h compute for rung 1 + S2 on ~10 % (≈3 h) + R22 per batch → 1–2 sessions unattended; expected floor after S2 ≈ 4 % of converted sites kept as casts (≈20k sites) plus the 24 % the current types cannot hold (≈120k sites) — T5's types decide most of those. T7: the per-access `/s` residue (the kept casts) and the lever bodies — open-ended by decision 1; the S+A measurement comes with T6's first batches. **Rewrite table fixed by the probe:** misaligned layout entries skipped; pointer fields need the site's pointee; sign-mismatch loads stay casts; the typedef inserted at file scope before the function; S2 before any agent. - **S106 — T2 verify.** `restruct --audit-layouts: 5283 file-scope definitions (29248 named fields) asserted against cc1; rejected 0; unresolved layouts 0` · `restruct --fanout-cost: … 3818 TUs / 3975 objects … wall 35 s at -j16 (cpu 560 s, 0.141 s/object)` · the probe tables above · the census re-run `type_census: 7255 definitions (527 layouts, 206 duplicate classes, 40 variant camps) · 503016 cast sites … coverage OK … controls 4/4`; `readability_progress --snapshot` (a T2 row) + `progress.py --check` fresh. - **S107 2026-09-12 — T3 in progress (Max design, the first bank).** Design stated (X1) and built: **`tools/struct_layout.py`** (the o32 layout engine factored out of `type_census.py` — `Resolver`, `parse_struct_body`, `layout_hash`, `field_offsets`; new: `field_map`, `leaf_at`, the WRITER `render_struct`/`entries_from_layout` in the final style — `/* 0xNN */` comments, `unk` for accessed-unknown, `u8 pad[n]` for never-touched gaps, `// size = 0x..` — and the INVARIANT `audit_definition`: every `unk/pad` at offset HEX, every comment = the computed offset, the trailer = sizeof; selftest 9/9; `type_census.py` imports it — its selftest 21/21 unchanged; `walk_all()` factored out of `run_census` for the engine). **`tools/delever_oracle.py`** gained the LINKED MODE: `link_vars` (the Makefile's own link variables per binary, asked of make), `snapshot_links` (every binary's `.ld` + `undefined_*_auto.txt` + main's 11 `build/psyq/*_externals.ld` into the snapshot's `_link/`, `links.json`), **`judge_linked`** (the candidate object linked by the build's own `ld/objcopy/trim` against the snapshot's other objects, SHA1 vs `config/check..sha` — ~10 ms), `reloc_only_diff` (the cheap pre-check: `.text` words equal under the mask, only relocation operands differ), `--linked-control` (the f3 body `func_801A4258`: **`p[1]/p[2]` whole-object DIFFERS · reloc-only True · linked IDENTICAL ✓; the negative `p[2]/p[3]` linked DIFFERS ✓**) — and a GUARD on `--snapshot-baseline`: a changed object must reproduce from an untouched compile or the refresh is REFUSED. **The guard was needed the same hour:** the first control read `whole-object IDENTICAL` for the `p[1]` spelling because `build/src/md_SC07_004/md_SC07_004.o` was NOT the tree's object — T2's relocation control had run `make build BINARY=md_SC07_004` with the candidate in place (linked-identical, differently spelled relocs) and my refresh copied it into the snapshot (R56/R112). Fixed by the clean fleet run (`.run/P37/baseline/r22_t3a.log`: `check-all: 218 passed, 0 failed of 218`, exit 0), a re-snapshot (`1 changed since the previous snapshot`) and `--calibrate main md_SC07_004 ov_SC02_005 ov_SC04_011` → `147/147 … positive control DIFFERS … OK`. **`tools/restruct.py`** (2,900 lines; the T2 functions kept verbatim): the judge on a multi-file job (`judge_files`: whole-object, then linked when reloc-flagged or reloc-only), the ledger `.run/P37/restruct/ledger.jsonl` keyed (rung, tu, unit, hash) with `--restore` from `inflight.json`, the shared ladder (all units at once, else cumulative greedy — delever's rung-B shape), **rung S** on every typed base with the declared-type-aware spelling (`a1->unk4` / `D_x.unk4` / the cast form), **S2** (greedy kept casts), **S+A** (delever's ladder on the struct-spelled text, `(P37 S+A …)` markers via `delever.marker_edits(phase=)`, stale `_m` markers scrubbed), **X** (`pass_hint`: SCHED-ALIAS / CSE-KILL / WIDTH / ADDRESS-FOLD / ALIGNMENT / REGALLOC / OTHER), **R** (the registry: R1 the pointer global as a struct member (§458), R2 `extern T X[]` (a18), R3 the walked pointer (f3, reloc-flagged)), **D** (every declaration of a callee → the definition's ANSI signature > the width-promoted form > all-`()` + `// K&R: n of m args (P37 rung D