169 KiB
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_<addr>,unk<HEX>); 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 taglines are retired from T10 on). R22 obligation: every batch that touchessrc/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)
- 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. - 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 insrc/; the counts published in the readability series with the dated snapshot (R75). - 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.
- 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 --strictunchanged (the 1998 routines untouched). make clean && make extract-all JOBS=16 && make check-all JOBS=16→check-all: 218 passed, 0 failed of 218(R22);make tools-healthOK with the new rung;ghidra_rebuild --proofPASS 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 + thev2.3.0tag. - 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; thev2.2.0tag created then DELETED — no tags/releases at closes, Drew); R22 clean fleet at the openextract-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, HEADdb212f167— the close commit adds no build input);delever_oracle --recipes4284 recipes captured in 14.6 s at -j16; errors 0·--snapshot-baseline7428 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);.gitignoreP37 allowlist (by-contents, R84;git check-ignoreverified: logs and.tsvtracked,.oignored); this file. Verify at the commit:git statusclean. - ☑ 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_FIELDwith 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_8013D9B0gte-unsignedinconsistency 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.pytypesblock + README sentence;readability_progresslearns the uncounted forms; dictionary + SETUP rows;lever_census's stale controls re-keyed. The struct map (.run/P37/census/struct_map.json+ the rendereddocs/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 (sameD_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: <D> definitions (<L> layouts, <C> duplicate classes, <V> variant camps) · <S> cast sites in <B> bodies over <K> bases (<F> forms, coverage OK) · <Y> lying declarations / <Q> callees · controls 4/4andstruct_map: <T> types over <K> bases explain <S'>/<S> sites (<p> %); <U> unassigned bases; <C> 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,42a57f576and 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 +--real53 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 ininclude/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 redrawt3d2 … 8 K&R marked / 16 kept … final 26/26 identical · written 5 files, each followed by R22check-all: 218 passed, 0 failed of 218(r22_t3d1.log,r22_t3d2.log; andr22_t3c.logafter thecommon.hmacros). Deviations from the brief, recorded in the log: a new base symbol goes into the binary's splat symbol file (R15), not a-Tfragment; 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, nots32 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 --checkinmake tools-health;attribution_checkfolded intolever_census --check; the close snapshots published; the canonical types into the Ghidra programs (ExportAnnotationstype rows) withghidra_rebuild --proofPASS. - ☐ 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 %") anddocs/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
/sfinding): 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 throughMEM_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 localv2.2.0tag deleted (no tags or releases at phase closes — the PhaseEnd 🛑 blocks drop theirgit taglines from T10 on) andgit push origin 79b2f6f15:mainrun 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.pyextended 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 memorycheckpoint-current-phase-before-pauseupdated). - 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_PROTOTYPESattools/reference/gcc-2.7.2/config/mips/mips.h:1153and the caller-side conversion atc-typeck.c:1740(convert to the parameter type, THEN default-promote); the/smodel indocs/gcc-2.7.2-map/cse_expr.md§4;ExportAnnotations.javacarriestyperows (0 tracked today);delever_oracle.pyis object-scoped and header-capable throughdelever.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) →79b2f6f15with the PhaseEnd's message;git tag -a v2.2.0created 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 HEADdb212f16704: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 whetherrestructshares 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)..gitignoreP37 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 recalibratedcalibration.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(0v2*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 fromlever_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'sD_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 (RectvsSVECTOR): 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 ofAT: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 globalD_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 ·.cfile-scope 4,091 ·.cblock-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 scalarD_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/0Ccode 4 vsactor-struct.md2 — a T9 correction; the bytes side with the code).lever_census: controls re-keyed (14 / 8 /func_801896EC2, 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—--strictnow 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,447gte+ 270gte-unsignedas 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 datedcorrections(the four-form count;--strict's direct GTE statements);progress.py --checkfresh;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.mdgenerated (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) andsites.jsonl(213 MB) regenerable, ignored. -
S106 — T2 the probe (Max). Harness:
tools/restruct.py— the rewrite engine's first form (--tryrung 1 on one body,--probe,--probe-decls,--probe-defs,--audit-layouts,--fanout-cost; SETUP §P37 S106, dictionary row). Every judgement throughdelever_oraclein place and restored (R102); header bodies on every includer; the residual classified bydelever_search.classify. Five probes, every number with its denominator (R41):- 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 typedvoid *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/salias asymmetry: after rung 1 the struct stores carry MEM_IN_STRUCT_P and the body's bare fixed globals do not, sosched.c:837's escape hoists a fixed load over a struct store the original kept below it — read on the bytes offunc_801814AC(ov_SC05_010): everyD_801C7E30site 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/sflag 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. - 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'sAt top level:22, a#define NULLcontext 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. - 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 bytypedef <Canon> <Local>;→ 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). - 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 (MZin md_MAIN_027), and per-fieldaligned(N)was ignored — both fixed intype_census.py; plus a census over-count: 27#ifndef BFM_ENGINE_TYPES_Hstandalone 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. - The oracle — the relocation-spelling control (f3's
D_801F8870[3]array walked through a pointer, md_SC07_004func_801A4258): whole-object DIFFERS,make build BINARY=md_SC07_004with 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.hreaches 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-.cdefinitions, ~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/sresidue (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.
- 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,
-
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-runtype_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 --checkfresh. -
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 oftype_census.py—Resolver,parse_struct_body,layout_hash,field_offsets; new:field_map,leaf_at, the WRITERrender_struct/entries_from_layoutin the final style —/* 0xNN */comments,unk<HEX>for accessed-unknown,u8 pad<HEX>[n]for never-touched gaps,// size = 0x..— and the INVARIANTaudit_definition: everyunk/pad<HEX>at offset HEX, every comment = the computed offset, the trailer = sizeof; selftest 9/9;type_census.pyimports it — its selftest 21/21 unchanged;walk_all()factored out ofrun_censusfor the engine).tools/delever_oracle.pygained 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 11build/psyq/*_externals.ldinto the snapshot's_link/,links.json),judge_linked(the candidate object linked by the build's ownld/objcopy/trimagainst the snapshot's other objects, SHA1 vsconfig/check.<alias>.sha— ~10 ms),reloc_only_diff(the cheap pre-check:.textwords equal under the mask, only relocation operands differ),--linked-control(the f3 bodyfunc_801A4258:p[1]/p[2]whole-object DIFFERS · reloc-only True · linked IDENTICAL ✓; the negativep[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 readwhole-object IDENTICALfor thep[1]spelling becausebuild/src/md_SC07_004/md_SC07_004.owas NOT the tree's object — T2's relocation control had runmake build BINARY=md_SC07_004with 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.jsonlkeyed (rung, tu, unit, hash) with--restorefrominflight.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 viadelever.marker_edits(phase=), stale_mmarkers 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), R2extern 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 <label>); the definitions index keyed by the TU's visible files — own TU, its binary's dir, its headers, then main/resident — REFUSING when two definitions disagree;--callee/--signaturefor a definition-side change judged on every declaring TU), L (folds with member renames by the offset map, REFUSED on an ambiguous member name),--write-types(the writer's preview from the struct map),--audit-types,--check-ledger,--try-file(a real-oracle dry run, nothing written),--redraw. Selftest 48/48 (a stub oracle; every form, the no-op, S2's two paths, D's three verdicts, L, the three recipes, the ledger, the inflight parser, negative controls) ·--real51/51 (calibration current; the tree's own text IDENTICAL; a nop DIFFERS; the linked control). Known-true on the bytes:--try … func_801814AC --base global:D_801C7E30 --recipes→DIFFERS · S2 IDENTICAL kept 1 (+0x34, 1 compile) · R1-ptr-global-member IDENTICAL (adopt)— §458's body closes mechanically;--try-file … func_8017E830→ S IDENTICAL (2 members) · S+A LEVER-FREE: 6gte_rtv0tr_mlevers off, markers scrubbed, re-judged IDENTICAL, nothing written (the T2 row says levers-off-alone was IDENTICAL too — a P36_mleftover, not the struct hypothesis; the path is proven either way). The end-to-end batch — rung D on ov_SC04_011 (--apply --rung D --batch 27 --only ov_SC04_011 --label t3d1 -j 12):restruct: batch t3d1 rung D — 27 files (TUs; 27 drawable) · 258 declaration units: 242 canonical / 0 promoted / 6 K&R marked / 16 kept · compiles 223 in 31 s wall · final 27/27 identical · written 27 files→ R22 (.run/P37/baseline/r22_t3d1.log)check-all: 218 passed, 0 failed of 218(108 s, exit 0). The kept causes, read:func_800D20C0×7 = the prototype namesPos800D20C0, a type the overlay TU cannot see (T5's canonical file closes it);too few arguments= the K&R sites (marked);func_8016BF50= a mix of()and truncated ANSI declarations (the all-()candidate added after this run). Three instrument findings on the way, each fixed at its cause: the fleet walk (a process pool) forked from inside the worker threads and deadlocked the first run at 0 % CPU (now computed before any thread exists); 1,889 K&R definitions re-masked per TU (now one mask per file); the selftest's inflight probe used the LIVEinflight.jsonand deleted batch t3d1's snapshot (now a scratch path — the batch's files were already proven by R22, so nothing was lost)..gitignore: the argcheck cache excluded. This commit = the bank (R42): the 27 TUs, the tools, the evidence. -
S107 — T3 batch
t3d2(the redraw of the 16 kept units,--redraw DECL-KEPT, after the cause reader learned cpp's context lines and the all-()arity candidate):restruct: batch t3d2 rung D — 26 files … 16 declaration units: 0 canonical / 0 promoted / 8 K&R marked / 16 kept · compiles 27 in 5 s wall · final 26/26 identical · written 5 files(two more K&R sites closed by the all-()form; the causes now readconflicting types for func_800D2318 … prev: shared/ov/func_80168BDC.h:3— a per-function shared header carries the lying spelling, rung D's--headersmode — andparse error before '*'= the prototype names a type the TU cannot see, T5's). R22 (.run/P37/baseline/r22_t3d2.log)check-all: 218 passed, 0 failed of 218(110 s, exit 0). Fixed after the run: a K&R-marked unit (every declaration()+ the marker) is settled and no longer drawn by a redraw (t3d2 re-labelled three already-marked units — comment churn only, byte-neutral). -
S107 — T3 closed. After the two D batches:
tools/restruct_cycle.sh(the detached cycle: clean tree → guarded snapshot refresh + calibration when stale →--applyread by exit code andfinal X/X identical→ R22 →type_census --sites+ the readability snapshot → the log entry + 🛑 headline → one commit;bash -nOK);include/common.h:LOBU/LOH/HIH/LOHU/HIHU/LOW/LOWU(sotn's shape) + theM2C_FIELDnote corrected (the "identical codegen" claim owed at T9 — done now, same edit); the macro proofrestruct.macro_probe(cc1's assembly for the macros == the bare casts, 7 loads) in--selftest --real; R22 after the header edit (r22_t3c.log)check-all: 218 passed, 0 failed of 218(104 s, exit 0). The writer's preview (--write-types --top 6→.run/P37/restruct/types_preview/ov.h):Unkstruct_800B5CB8: 90 fields, size 0x10c · skipped {'overlap': 44}·Unkstruct_80126B58: 146 fields, size 0x24c · skipped {'overlap': 28, 'misaligned': 1}· four more clean — the overlaps are the map's width conflicts (T5 decides union vs split).--audit-typeson the legacy header: 26 violations, every one a legacypad<SIZE>name (T5's rename list) — after two instrument corrections (a TRAILING legacy comment was paired with the next field: 1,013 false flags; a multi-declarator line's comment names its FIRST declarator).--check-ledger: 0 MEMBER sites … 0 violation(s)(no S bank yet). Rows:config/tool_dictionary.tsv(restruct updated; struct_layout, restruct_cycle added), SETUP §P37 S107,make kit-corpus→tool_census --check: OK,doc_links --strict: OK,cookbook-index OK; the record: decision log P37 S107 (R31), accelerators P37 S107 (five), cookbook §458 addendum (the engine reproduces and closes the exemplar: S2 keeps 1, R1 IDENTICAL). Found on the way, for Drew:tools/audit_public.pyis RED on HEAD —.run/P36/delever/ledger.jsonlis tracked at 78,396,681 bytes (> 50 MiB, GitHub's warning cap), since the P36 S105 commit31cf8695f; the public CI's no-rom job has been red since that push. Not touched (P36's evidence; a decision): recommendation below the checkpoint. Also: 19,343 stale scratch files under.run/P36/delever/obj/(ignored; hygiene, not correctness). -
S107 — Drew's decision on the red
no-romCI (the P36 ledger's size): "did we accidentally push rom info? or is that just a file >50 failing our test? if so, just relax the size gate to 100MB per github limit" → evidence shown:audit_public's checks 1 (purge paths), 2 (1,422 ROM-derived SHA1s vs 15,203 tracked files) and 4 (disassembly-shaped runs; longest 14 lines, cap 64) all CLEAN — only check 3 (SIZE) fired; the ledger is 29,649 rows of our own tool's verdicts on our own C (0 eight-hex-digit words outside the hash fields). No ROM content was pushed. The gate raised to GitHub's HARD limit:tools/audit_public.pySIZE_CAP = 100 MiB(+ aWARNabove 80 MiB, so a file approaching the limit is announced before a push can be rejected — R54), the docstring,.github/workflows/no-rom.yml, SETUP's row,docs/wiki/The-ROM-firewall.mdanddocs/wiki/Verification-and-progress.md(the wiki's live copy needs Drew's sync).audit_public: OK — 0 offenders among 15219 tracked paths. (The ledger is 74.8 MiB today; P36's rows are frozen — only P37's S+A rows are appended to it.) -
2026-09-12 — T4 batch
t4_D1(.run/P37/restruct/run_t4_D1.log,batch_t4_D1.json):restruct: batch t4_D1 rung D — 40 files (TUs; 3878 drawable) · 1441 declaration units: 1261 canonical / 0 promoted / 29 K&R marked / 60 aliases typed / 0 __builtin_abs → abs / 120 kept · compiles 1554 in 70 s wall · final 40/40 identical · written 40 files→ R22 (.run/P37/baseline/r22_t4_D1.log)check-all: 218 passed, 0 failed of 218(wall=80.19 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D2(.run/P37/restruct/run_t4_D2.log,batch_t4_D2.json):restruct: batch t4_D2 rung D — 300 files (TUs; 3878 drawable) · 4995 declaration units: 4354 canonical / 1 promoted / 85 K&R marked / 84 aliases typed / 7 __builtin_abs → abs / 469 kept · compiles 5836 in 196 s wall · final 300/300 identical · written 264 files→ R22 (.run/P37/baseline/r22_t4_D2.log)check-all: 218 passed, 0 failed of 218(wall=80.17 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D3(.run/P37/restruct/run_t4_D3.log,batch_t4_D3.json):restruct: batch t4_D3 rung D — 300 files (TUs; 3878 drawable) · 3441 declaration units: 2948 canonical / 0 promoted / 24 K&R marked / 61 aliases typed / 3 __builtin_abs → abs / 261 kept · compiles 3981 in 100 s wall · final 300/300 identical · written 220 files→ R22 (.run/P37/baseline/r22_t4_D3.log)check-all: 218 passed, 0 failed of 218(wall=80.46 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D4(.run/P37/restruct/run_t4_D4.log,batch_t4_D4.json):restruct: batch t4_D4 rung D — 300 files (TUs; 3878 drawable) · 2941 declaration units: 2549 canonical / 0 promoted / 0 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 213 kept · compiles 3277 in 92 s wall · final 300/300 identical · written 214 files→ R22 (.run/P37/baseline/r22_t4_D4.log)check-all: 218 passed, 0 failed of 218(wall=82.75 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D5(.run/P37/restruct/run_t4_D5.log,batch_t4_D5.json):restruct: batch t4_D5 rung D — 300 files (TUs; 3878 drawable) · 2618 declaration units: 2213 canonical / 0 promoted / 2 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 189 kept · compiles 2851 in 76 s wall · final 300/300 identical · written 187 files→ R22 (.run/P37/baseline/r22_t4_D5.log)check-all: 218 passed, 0 failed of 218(wall=80.94 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D6(.run/P37/restruct/run_t4_D6.log,batch_t4_D6.json):restruct: batch t4_D6 rung D — 300 files (TUs; 3878 drawable) · 2086 declaration units: 1670 canonical / 0 promoted / 2 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 159 kept · compiles 2215 in 73 s wall · final 300/300 identical · written 152 files→ R22 (.run/P37/baseline/r22_t4_D6.log)check-all: 218 passed, 0 failed of 218(wall=83.38 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D7(.run/P37/restruct/run_t4_D7.log,batch_t4_D7.json):restruct: batch t4_D7 rung D — 300 files (TUs; 3878 drawable) · 1566 declaration units: 1084 canonical / 0 promoted / 108 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 160 kept · compiles 1564 in 76 s wall · final 300/300 identical · written 103 files→ R22 (.run/P37/baseline/r22_t4_D7.log)check-all: 218 passed, 0 failed of 218(wall=92.91 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D8(.run/P37/restruct/run_t4_D8.log,batch_t4_D8.json):restruct: batch t4_D8 rung D — 300 files (TUs; 3878 drawable) · 1268 declaration units: 767 canonical / 0 promoted / 140 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 140 kept · compiles 1149 in 66 s wall · final 300/300 identical · written 70 files→ R22 (.run/P37/baseline/r22_t4_D8.log)check-all: 218 passed, 0 failed of 218(wall=83.95 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D9(.run/P37/restruct/run_t4_D9.log,batch_t4_D9.json):restruct: batch t4_D9 rung D — 300 files (TUs; 3878 drawable) · 551 declaration units: 53 canonical / 0 promoted / 11 K&R marked / 2 aliases typed / 0 __builtin_abs → abs / 34 kept · compiles 102 in 65 s wall · final 300/300 identical · written 6 files→ R22 (.run/P37/baseline/r22_t4_D9.log)check-all: 218 passed, 0 failed of 218(wall=84.05 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D10(.run/P37/restruct/run_t4_D10.log,batch_t4_D10.json):restruct: batch t4_D10 rung D — 300 files (TUs; 3878 drawable) · 528 declaration units: 55 canonical / 0 promoted / 4 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 8 kept · compiles 70 in 44 s wall · final 300/300 identical · written 3 files→ R22 (.run/P37/baseline/r22_t4_D10.log)check-all: 218 passed, 0 failed of 218(wall=87.73 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D11(.run/P37/restruct/run_t4_D11.log,batch_t4_D11.json):restruct: batch t4_D11 rung D — 300 files (TUs; 3877 drawable) · 16 declaration units: 16 canonical / 0 promoted / 0 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 0 kept · compiles 2 in 26 s wall · final 300/300 identical · written 1 files→ R22 (.run/P37/baseline/r22_t4_D11.log)check-all: 218 passed, 0 failed of 218(wall=84.99 s) → census(census skipped). -
S107 — T4 in progress: the D cycles and the alias-defined-function class. The detached cycle (
restruct_cycle.sh,CENSUS=0) ran batchest4_D1–t4_D11(300 TUs each after D1's 40): ≈17,000 declaration units canonical, ≈400 K&R sites marked, 207 asm-label data aliases typed, 10__builtin_abs→abs, ≈1,300 kept with causes (each batch:final N/N identical, R22218 passed, 0 failed of 218, one commit —dd21e7e26,2dd78c3e4,4741f6cba,42d9cf570,cebc2a3c4,8f99ec5a2,4eeb4412f,f1606cb4c,738115621,2f591071c,37b832c4f). Two planner defects found from the batch numbers and fixed at their cause: (1) D9 stopped onsrc/800.c— a same-name data alias (extern u8 D_80078E7C __asm__("D_80078E7C")) renamed uses inside the_walias's__asm__("D_80078E7C")label → overlapping edits → a file-level TOOL-ERROR; now a same-name alias is a declaration-only edit, use-renames skip every alias declaration span, and an overlap is a unit REFUSAL (the batch restored, re-run, committed); (2) the planner re-drew settled TUs (their KEPT rows kept them ranked high: 300 files for 6 written at D9) —plan_Dnow skips TUs whose every lying callee has a DONE ledger row (settled_units;--redrawlifts it). D12 then drew 300 TUs for 0 units and the disagreement was read (R34): argcheck's remaining rows are the alias-defined functions —s32 aF8012EFB8(param_1, param_2) __asm__("func_8012EFB8"), a body defined under an alias C name because the fleet's declarations of its real name lied (void (s32)for as32 (void *, void *)body); the callers declare/callaF…. 149 such functions (16 in shared headers, 47 K&R heads) over 1,855 files — and their 3,529 real-name callers' lies were invisible to argcheck (no definition under the real name). Built--unalias: the definition back under its real name with its byte-true ANSI signature (K&R heads promoted viaargcheck.kr_params), every alias prototype deleted, alias declarations/calls renamed, the real name's declarations canonical in the unit's scope = the definition's includers + every file mentioning the alias + every shared header declaring the real name (REFUSED unless its includers ⊆ the members) + those headers' includers; a per-file K&R fallback (too few arguments→ that file keepsextern s32 f(); // K&R: n of m args (P37 unalias …)); ONE judged job, IDENTICAL on every object or nothing written. First unitt4_ua1— func_8012EFB8:337 files (194 alias prototypes, 375 real-name declarations, 0 renames), two shared headers K&R-marked (func_8012EF34.h,func_8012EF70.hpass 1 of 2 args), IDENTICAL on 478 objects (139 s), 337 files written; R22 (r22_t4_ua1.log)check-all: 218 passed, 0 failed of 218. The cycle was stopped by pid after D12 (empty);--unalias ALLfor the other 148 next, then the D cycle again (argcheck now sees the real-name callers). -
S107 — T4 unalias sweep
t4_ua2(--unalias ALL, detached):restruct: unalias t4_ua2 — 148 alias-defined functions: 98 back under their real name / 50 kept · 1074 files written(592 distinct files) → R22 (r22_t4_ua2.log)check-all: 218 passed, 0 failed of 218. The 50 kept, bucketed by cause (R117): 18 DIFFERS (one caller object each — the lying prototype is load-bearing there, half of them inov_MAIN_012), 12conflicting types(a TU outside the unit's file set declares the real name another way while a header it includes went canonical), 11too few/many arguments(a caller passing another count sees a shared header's canonical prototype — the K&R fallback must mark the HEADER), 9 REFUSED (a shared header declares the real name for non-member binaries: the declaration must be hoisted into the includers first). Three fallbacks to add, then the 50 re-run. -
2026-09-12 — T4 batch
t4_D20(.run/P37/restruct/run_t4_D20.log,batch_t4_D20.json):restruct: batch t4_D20 rung D — 300 files (TUs; 3877 drawable) · 193 declaration units: 104 canonical / 0 promoted / 0 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 89 kept · compiles 242 in 32 s wall · final 300/300 identical · written 12 files→ R22 (.run/P37/baseline/r22_t4_D20.log)check-all: 218 passed, 0 failed of 218(wall=91.50 s) → census(census skipped). -
S107 — T4 in progress, CHECKPOINTED at 84 % context (the cycle stopped at a batch boundary; tree clean at
f2b58011e+ this commit). The alias-defined-function class after five passes (t4_ua1…t4_ua9): 120 of 149 back under their real names, 29 kept with causes. The unit's ladder as it stands (every step judged on every object of the unit; the definition keeps its exact ANSI head): the exact prototype everywhere → a pure caller that DIFFERS gets the promoted prototype, then(), then is left UNTOUCHED (its ownaF… __asm__prototype still binds; its lie is load-bearing — a rung-D KEPT row) → an arity error marks that file (and the in-scope headers it includes)(), a second such file marks every declaration(), a persisting arity error spells the DEFINITION K&R-style (its narrow types in the block — callers pass more arguments than the byte-true head declares;func_80131CA8landed so, 202 objects) → aconflicting typesfile joins the unit → a shared header declaring the real name for NON-member binaries has its declaration HOISTED into its includers first (byte-neutral by construction; 4 units landed through it). The 29 kept: 11 "the callers in one jr-merged TU disagree with the definition's head inside one unit (the original was separate translation units — the file-layout phase's fix)", ~12 "a pure caller differs under every prototype form" where the 20-iteration bound stopped a long chain of such callers (each such file is left untouched now, so a re-run lands more), the rest arity errors against a K&R-style definition (the definition TU's own declarations were excluded from()— fixed after the last pass, untested on them). The D cycle, second run (t4_D20): the real-name callers exposed by the unaliasing — 104 canonical / 89 kept in 300 TUs;t4_D21then drew 300 TUs for 0 units: the planner's rows (argcheck's) include callees the engine cannot act on (no visible definition: the 29 still-aliased functions' callers; externals) — now every such requested callee settles in the ledger asDECL-NONEwith its reason, so the plan converges (work_file_D'sskipped; untested on a batch — the next session's first cycle batch is the test).signature_changegained--all-defs/--tu(the same body over every same-address copy, declarations scoped to the definitions' binaries) for the parked classes with 2–6 TU-local copies. T4's numbers at this checkpoint (the ledger, latest row per unit): declaration units 17,316 canonical + 1 promoted / 1,522 kept (1,302 rows are marked K&R sites); data aliases 207 typed / 253 kept (second typed views → T6);__builtin_abs10 →abs; alias-defined functions 120 / 29; 2,420 files carry a D row; 21 commits since T3, eachcheck-all: 218 passed, 0 failed of 218. Three instrument findings this stretch: the fork-in-threads deadlock, the same-name alias overlap, the planner's re-draw of settled TUs — each fixed at its cause and recorded here. The stopped batch (t4_D21, relaunched) wrote nothing (0 modified files; no ledger rows); its logs are kept. -
S107 — Drew (at the checkpoint): the timeline's lower panel — the purple line ran above 100 % (the 2026-09-12 four-form census read as a rise of the one-form regex count) and the red line had two points. Redrawn: every lever increment (95: the P36 log's T1/T4/T5 census lines + the TSV's rows) on an ordinal axis with a marker at each change of method; the raw casts as two instruments.
tools/timeline.py, SETUP. -
S108 2026-09-12 — session start; T4 resumed (xHigh). Session-start protocol (Drew: "xhigh set"). Step (a) launched per the checkpoint and stopped at once:
cycle: the snapshot refresh FAILED/REFUSED—build/held 0 objects (S107's relaunchedt4_D21was stopped after its R22'smake clean), and--snapshot-baselinehad stampedTAKEN_AT.txtwith HEAD and "0 objects" over the 7,428 objects of another tree before returning 0 — a false "fresh" (R68: a helper must refuse an empty work list; the guard only re-derived CHANGED objects). Fixed at the cause intools/delever_oracle.py: the object count and the previous stamp's count are read BEFORE anything is written; an empty or shrunkenbuild/isREFUSED — build/ holds 0 object(s), the previous snapshot 7428: … nothing written(exit 1; negative-controlled on the empty tree, stamp untouched). The stamp restored from the objects' own mtimes (14:12:24–14:13:11 = the D20 R22 build;calibrate_t4_D21.logat 14:13:24 proves the D21 relaunch refreshed it atf2b58011e). Then R22 at HEAD (.run/P37/baseline/r22_s108_pre.log):extract-all: 217 extracted, 0 failed of 217 (+ main, serial)·check-all: 218 passed, 0 failed of 218·wall=92.17 s· exit 0 →--snapshot-baseline7428 object(s) … at f3b8af0ec … 0 changed since the previous snapshot(the objects were the tree's) →--calibrate … ok→ the D cycle relaunched (cycle_t4e.log, batches 21–34). -
2026-09-12 — T4 batch
t4_D21(.run/P37/restruct/run_t4_D21.log,batch_t4_D21.json):restruct: batch t4_D21 rung D — 300 files (TUs; 3877 drawable) · 0 declaration units: 0 canonical / 0 promoted / 0 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 0 kept · compiles 0 in 259 s wall · final 300/300 identical · written 0 files→ R22 (.run/P37/baseline/r22_t4_D21.log)check-all: 218 passed, 0 failed of 218(wall=87.91 s) → census(census skipped). -
S108 — T4 batch
t4_D21= the DECL-NONE test: FAILED the test, and the failure was the INSTRUMENT (R40).restruct: batch t4_D21 rung D — 300 files (TUs; 3877 drawable) · 0 declaration units … compiles 0 in 259 s wall · final 300/300 identical · written 0 files→ R22check-all: 218 passed, 0 failed of 218→ committeda6ea4252fby the cycle (0 files; 11,885DECL-NONErows: 10,495 "no visible definition (external to this TU's binary…)", 1,387 "already canonical", 3 K&R). Read against the tree (R14):func_80147514— DECL-NONE in all 300 TUs — is defined insrc/shared/ov/func_80147514.h, included by the binary's ownov_SC05_000_after.c.defs_visibleindexed the sibling TUs' bodies but not the shared headers the siblings include — and since P35 every shared body IS such a header, so a binary's own shared functions read as external. The class was invisible to D1–D20 too (before the DECL-NONE settling those callees were silently not units, never touched — the lying declarations of shared-header-defined functions across the fleet are still owed). Fixed at the cause: a sibling TU's headers join the index (defs_visible); known-true: the three sample callees now resolve to theirsrc/shared/ov/*.hdefinitions with units,skipped {}. My own race on the way (recorded, not repeated): I sentkill -INTto the D22 judge and ran--restore8 s later while the judge was still unwinding (it honours the SIGINT only after its in-flight units — ~2 min); the restore consumedinflight.jsonand dropped 1,321 rows, the judge then wrote 6 more files and 197 rows with no tool-side restore left. Recovery: the 6 files (declaration rewrites only, IDENTICAL-judged, but a killed batch's unbanked candidate text) reverted to HEAD by an operatorgit checkout— stated here (R102 governs tools; R42's banked work is not at issue) — and the 197 orphan rows dropped (ledger.jsonl48,114 → 47,917;--check-ledger0 violations;git diff srcempty). Gotcha for the checkpoint: afterkill -INT, WAIT for the judge's exit (ps) before--restore. BecauseDECL-NONEis a DONE verdict, D21's 300 TUs are settled on the blindness: the cycle relaunched withREDRAW="DECL-NONE"(batches 22–40) so every such pair is drawn again — the genuinely external ones re-settle at zero compiles. -
2026-09-12 — T4 batch
t4_D22(.run/P37/restruct/run_t4_D22.log,batch_t4_D22.json):restruct: batch t4_D22 rung D — 300 files (TUs; 3877 drawable) · 10185 declaration units: 10123 canonical / 0 promoted / 47 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 62 kept · compiles 2888 in 442 s wall · final 300/300 identical · written 300 files→ R22 (.run/P37/baseline/r22_t4_D22.log)check-all: 218 passed, 0 failed of 218(wall=87.29 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D23(.run/P37/restruct/run_t4_D23.log,batch_t4_D23.json):restruct: batch t4_D23 rung D — 300 files (TUs; 3852 drawable) · 9221 declaration units: 9170 canonical / 0 promoted / 28 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 51 kept · compiles 1640 in 245 s wall · final 300/300 identical · written 299 files→ R22 (.run/P37/baseline/r22_t4_D23.log)check-all: 218 passed, 0 failed of 218(wall=82.36 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D24(.run/P37/restruct/run_t4_D24.log,batch_t4_D24.json):restruct: batch t4_D24 rung D — 300 files (TUs; 3719 drawable) · 8965 declaration units: 8788 canonical / 0 promoted / 133 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 177 kept · compiles 2398 in 239 s wall · final 300/300 identical · written 299 files→ R22 (.run/P37/baseline/r22_t4_D24.log)check-all: 218 passed, 0 failed of 218(wall=88.86 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D25(.run/P37/restruct/run_t4_D25.log,batch_t4_D25.json):restruct: batch t4_D25 rung D — 300 files (TUs; 3681 drawable) · 8577 declaration units: 8094 canonical / 0 promoted / 384 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 483 kept · compiles 3977 in 292 s wall · final 300/300 identical · written 299 files→ R22 (.run/P37/baseline/r22_t4_D25.log)check-all: 218 passed, 0 failed of 218(wall=89.85 s) → census(census skipped). -
S108 — the D cycle after the fix (
cycle_t4f.log,REDRAW=DECL-NONE):t4_D2210,185 units: 10,123 canonical / 47 K&R / 62 kept (d09cadd4f) ·t4_D239,221: 9,170 / 28 / 51 (f72340ff4) ·t4_D248,965: 8,788 / 133 / 177 (d8dc045e9) ·t4_D258,577: 8,094 / 384 / 483 (8ef6fc3a6) — eachfinal 300/300 identical, R22check-all: 218 passed, 0 failed of 218. The kept causes bucketed (R117, D22–D25, 745 rows): K&R sites 592 (the calls pass fewer arguments —func_80146C3C,func_801483E8,func_800D2318,func_80160B00,func_8016EE40at ~128 rows each = one per overlay, the same shape fleet-wide),conflicting typeselsewhere in the TU 139, arity 6, other compile 8. 306 of the K&R rows read "the calls pass[]arguments" /? of N args— read on the bytes: the ANSI form wasCOMPILE-ERROR shared/ov/func_80161124.h:19: too few arguments to function 'func_801483E8'— the call sits in a shared BODY the TU includes, whichcall_arg_countsnever scanned (the TU's own text has only a cast-pointer call). The verdict was right, the record blind:unit_call_countsnow unions the counts from every included shared body and the cause names the header ((in shared/ov/func_80161124.h)); known-true on that unit([0], ['src/shared/ov/func_80161124.h']);--selftest 54/54 OK. The D22–D25 rows keep their[]/?(settled K&R units are not redrawn; the T4 close's census reads the markers, not the counts). -
2026-09-12 — T4 batch
t4_D26(.run/P37/restruct/run_t4_D26.log,batch_t4_D26.json):restruct: batch t4_D26 rung D — 300 files (TUs; 3386 drawable) · 7264 declaration units: 6872 canonical / 0 promoted / 353 K&R marked / 6 aliases typed / 0 __builtin_abs → abs / 386 kept · compiles 6592 in 208 s wall · final 300/300 identical · written 296 files→ R22 (.run/P37/baseline/r22_t4_D26.log)check-all: 218 passed, 0 failed of 218(wall=86.78 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D27(.run/P37/restruct/run_t4_D27.log,batch_t4_D27.json):restruct: batch t4_D27 rung D — 300 files (TUs; 3100 drawable) · 6538 declaration units: 6495 canonical / 0 promoted / 39 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 43 kept · compiles 1555 in 127 s wall · final 300/300 identical · written 295 files→ R22 (.run/P37/baseline/r22_t4_D27.log)check-all: 218 passed, 0 failed of 218(wall=86.19 s) → census(census skipped). -
S108 —
t4_D267,264: 6,872 canonical / 353 K&R / 386 kept / 6 aliases (3a9f96760) ·t4_D276,538: 6,495 / 39 / 43 (526e9c915), bothfinal 300/300 identical, R22218 passed, 0 failed of 218. D27 (the first batch onunit_call_counts): 37 of 39 K&R causes now carry the count and its header ([0] (in shared/ov/func_8016D848.h, …)); the 2 left at[]were a plainif (func_80161B18() != 0) {— the counter's "definition head" test skipped any match whose LINE held a later{. Now a head is) {(whitespace only) or a K&R head () int a; {); known-true[0]on that TU, negative controls (an ANSI definition + calls →[2], a K&R definition →[]), selftest 54/54. -
2026-09-12 — T4 batch
t4_D28(.run/P37/restruct/run_t4_D28.log,batch_t4_D28.json):restruct: batch t4_D28 rung D — 300 files (TUs; 2805 drawable) · 6325 declaration units: 6316 canonical / 0 promoted / 2 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 9 kept · compiles 695 in 116 s wall · final 300/300 identical · written 295 files→ R22 (.run/P37/baseline/r22_t4_D28.log)check-all: 218 passed, 0 failed of 218(wall=82.61 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D29(.run/P37/restruct/run_t4_D29.log,batch_t4_D29.json):restruct: batch t4_D29 rung D — 300 files (TUs; 2513 drawable) · 5566 declaration units: 4976 canonical / 0 promoted / 255 K&R marked / 14 aliases typed / 0 __builtin_abs → abs / 576 kept · compiles 4212 in 152 s wall · final 300/300 identical · written 282 files→ R22 (.run/P37/baseline/r22_t4_D29.log)check-all: 218 passed, 0 failed of 218(wall=86.99 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D30(.run/P37/restruct/run_t4_D30.log,batch_t4_D30.json):restruct: batch t4_D30 rung D — 300 files (TUs; 2242 drawable) · 4485 declaration units: 4185 canonical / 0 promoted / 4 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 300 kept · compiles 5154 in 205 s wall · final 300/300 identical · written 280 files→ R22 (.run/P37/baseline/r22_t4_D30.log)check-all: 218 passed, 0 failed of 218(wall=83.00 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D31(.run/P37/restruct/run_t4_D31.log,batch_t4_D31.json):restruct: batch t4_D31 rung D — 300 files (TUs; 1966 drawable) · 4203 declaration units: 3734 canonical / 0 promoted / 6 K&R marked / 127 aliases typed / 0 __builtin_abs → abs / 342 kept · compiles 4878 in 220 s wall · final 300/300 identical · written 273 files→ R22 (.run/P37/baseline/r22_t4_D31.log)check-all: 218 passed, 0 failed of 218(wall=82.52 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D32(.run/P37/restruct/run_t4_D32.log,batch_t4_D32.json):restruct: batch t4_D32 rung D — 300 files (TUs; 1701 drawable) · 3273 declaration units: 2962 canonical / 0 promoted / 4 K&R marked / 126 aliases typed / 1 __builtin_abs → abs / 184 kept · compiles 1933 in 215 s wall · final 300/300 identical · written 268 files→ R22 (.run/P37/baseline/r22_t4_D32.log)check-all: 218 passed, 0 failed of 218(wall=81.95 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D33(.run/P37/restruct/run_t4_D33.log,batch_t4_D33.json):restruct: batch t4_D33 rung D — 300 files (TUs; 1438 drawable) · 2723 declaration units: 2630 canonical / 0 promoted / 0 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 93 kept · compiles 1552 in 168 s wall · final 300/300 identical · written 263 files→ R22 (.run/P37/baseline/r22_t4_D33.log)check-all: 218 passed, 0 failed of 218(wall=83.68 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D34(.run/P37/restruct/run_t4_D34.log,batch_t4_D34.json):restruct: batch t4_D34 rung D — 300 files (TUs; 1175 drawable) · 2076 declaration units: 1633 canonical / 0 promoted / 1 K&R marked / 3 aliases typed / 127 __builtin_abs → abs / 313 kept · compiles 2032 in 212 s wall · final 300/300 identical · written 204 files→ R22 (.run/P37/baseline/r22_t4_D34.log)check-all: 218 passed, 0 failed of 218(wall=83.66 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D35(.run/P37/restruct/run_t4_D35.log,batch_t4_D35.json):restruct: batch t4_D35 rung D — 300 files (TUs; 1099 drawable) · 168 declaration units: 81 canonical / 0 promoted / 13 K&R marked / 1 aliases typed / 4 __builtin_abs → abs / 82 kept · compiles 189 in 173 s wall · final 300/300 identical · written 27 files→ R22 (.run/P37/baseline/r22_t4_D35.log)check-all: 218 passed, 0 failed of 218(wall=81.20 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D36(.run/P37/restruct/run_t4_D36.log,batch_t4_D36.json):restruct: batch t4_D36 rung D — 300 files (TUs; 1088 drawable) · 27 declaration units: 16 canonical / 0 promoted / 0 K&R marked / 0 aliases typed / 1 __builtin_abs → abs / 10 kept · compiles 25 in 176 s wall · final 300/300 identical · written 6 files→ R22 (.run/P37/baseline/r22_t4_D36.log)check-all: 218 passed, 0 failed of 218(wall=82.92 s) → census(census skipped). -
S108 — the D cycle
t4_D22–t4_D36DONE (step (a)); stopped at the D37 boundary. Batches D28–D36 (7efa3eafa3e7172e455fe100dee1b23b17af69bd934de8f1a9619ed680022d90695fb78c79c6e935b): 6,316 / 4,976 / 4,185 / 3,734 / 2,962 / 2,630 / 1,633 / 81 / 16 canonical, eachfinal 300/300 identical+ R22check-all: 218 passed, 0 failed of 218. D29's 576 kept reconciled against the ledger (R41): 255 K&R + 1conflicting types+ 320ALIAS-KEPT"second typed view" (T6's aggregate class by design:D_800B9A02s16 vs u16 ×177,D_80115188s32 vsE4[]×127). The cycle's total (the ledger, D22–D36): 76,075 declarations canonical · 1,269 K&R sites marked · 277 data aliases typed · 133__builtin_abs→abs· 1,436 DECL-KEPT · 1,675 ALIAS-KEPT · 10,365 DECL-NONE, in 3,686 files, 15 batches. Drawable TUs 3,877 → 1,088 and flat from D35 (REDRAW=DECL-NONEkeeps the genuinely external pairs drawable; D35/D36 yielded 81/16 units for ~3 min each) → the cycle's shells killed at the D37 boundary, the D37 judgekill -INTduring planning and WAITED for (exit in 6 s; nothing in flight;git diff srcempty). T4's latest-row-per-unit totals now: 93,391 canonical · 2,958 DECL-KEPT (K&R + causes) · 484 aliases typed · 1,723 alias-kept · 143 abs · 1 promoted · 2,667 DECL-NONE (external callees + the 29 still-aliased functions' callers; step (b) next). -
S108 — step (b):
t4_ua10(the 29 kept alias functions,--apply --unalias … --label t4_ua10; the checkpoint's command lacked--apply):29 alias-defined functions: 0 back under their real name / 29 kept · 0 files written. Bucketed from the run log (R117): 10 DIFFERS (a pure caller differs under every prototype form — the jr-merge class:func_80146A6Cfunc_8014C4AC(ov_MAIN_012_jr_801458E0),func_8014F6F4(ov_SC01_009_after),func_801848DC,func_80185EEC,func_8018A224,func_8018A860,func_8018AFD0,func_8018B1DC,func_8018CB18— the file-layout phase's, as the checkpoint predicted); **10 "func_X' redeclared as different kind of symbol"** — read on the tree:extern s32 func_8017C078;nine lines above the alias-defined body, a DATA declaration of the real name written by a drafter whose caller passes the function's address as a plain pointer (func_80174684(&func_8017C078)); **5too few arguments** at a shared BODY the TU includes (shared/ov/func_80164DB0.h:5…) — the ladder marked the header()(it holds no declaration) three times and gave up; **4conflicting types**. Two ladder gaps closed inunalias_function: (1) a data-typed declaration of the real name (extern real;) becomes the unit's prototype (the&realuse is a function designator's address — the same relocation); (2) a header-side arity error marks the INCLUDING TUs in the unit K&R, not the header. **t4_ua11(the 10 redeclared):9 back under their real name / 1 kept · 11 files written** — each IDENTICAL on every recipe; the kept one isextern char func_801804D4[];(the empty-array spelling, excluded by the first regex). R22 (.run/P37/baseline/r22_t4_ua11.log): **check-all: 218 passed, 0 failed of 218** (wall=80.82 s`, exit 0). Alias-defined functions: 129 of 149 back / 20 kept. -
S108 —
t4_ua12(the last 10 kept):1 back under their real name / 9 kept · 4 files written(func_801804D4—extern char func_801804D4[];, the empty-array form of the data declaration, now in the regex) → R22 (r22_t4_ua12.log)check-all: 218 passed, 0 failed of 218(wall=89.17 s). Alias-defined functions: 130 of 149 back / 19 kept = 10 jr-merge DIFFERS (the file-layout phase's) + 5 arity- 4
conflicting types. The arity trace read (func_80162CCC, defined in the shared headerfunc_80162CCC.h, called short fromfunc_80164DB0.h:5): the same header raised the same error three times and the ladder never escalated — its "second arity caller" test counts DISTINCT files (sum(1 for (f, k) in tried …)over a Counter's keys), so one file's repeated error never reaches "every declaration()" nor the K&R-style definition, which is what this shape needs (the definition's own prototype is in scope before the short call). The 4conflicting typesare a return-type lie (func_80150480: definedvoid (void), a shared body declaress32 (s32)and USES the result) — a definition-side signature question for step (d)'s--callee … --body, not the unalias ladder's.
- 4
-
S108 —
t4_ua13(the 5 arity functions, after the escalation fix — attempts counted, not distinct files):3 back under their real name / 2 kept · 169 files written—func_80162CCC(IDENTICAL on 288 objects, 145 files),func_8016F0E4(296 objects, 20 files),func_8017EF54(4 objects), each landed as a K&R-style DEFINITION after "every declaration()" (the shape: the definition in a shared header whose prototype is in scope before a short call in another shared body). Kept:func_80161208—void value not ignored as it ought to be×3 (the callers USE avoiddefinition's result: the return-type lie, step (d)'s class) andfunc_8016BF50(a short call infunc_8016BCC0__04061c8b.h:9plus aconflicting typesin the same TU even K&R-style). R22 (r22_t4_ua13.log)check-all: 218 passed, 0 failed of 218(wall=86.17 s). Step (b) DONE: alias-defined functions 133 of 149 back / 16 kept = 10 jr-merge DIFFERS (the file-layout phase's) + 5 return-type lies for step (d) (func_80161208,func_801376E8,func_80150480,func_8017E3F0,func_801843E0) +func_8016BF50. -
2026-09-12 — T4 batch
t4_HD1(.run/P37/restruct/run_t4_HD1.log,batch_t4_HD1.json):restruct: batch t4_HD1 rung D — 20 files (headers; 276 drawable) · 30 declaration units: 27 canonical / 0 promoted / 0 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 3 kept · compiles 1327 in 72 s wall · final 20/20 identical · written 7 files→ R22 (.run/P37/baseline/r22_t4_HD1.log)check-all: 218 passed, 0 failed of 218(wall=86.24 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_HD2(.run/P37/restruct/run_t4_HD2.log,batch_t4_HD2.json):restruct: batch t4_HD2 rung D — 20 files (headers; 256 drawable) · 1 declaration units: 0 canonical / 0 promoted / 0 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 1 kept · compiles 134 in 12 s wall · final 20/20 identical · written 0 files→ R22 (.run/P37/baseline/r22_t4_HD2.log)check-all: 218 passed, 0 failed of 218(wall=82.54 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_HD3(.run/P37/restruct/run_t4_HD3.log,batch_t4_HD3.json):restruct: batch t4_HD3 rung D — 20 files (headers; 236 drawable) · 0 declaration units: 0 canonical / 0 promoted / 0 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 0 kept · compiles 0 in 6 s wall · final 20/20 identical · written 0 files→ R22 (.run/P37/baseline/r22_t4_HD3.log)check-all: 218 passed, 0 failed of 218(wall=88.39 s) → census(census skipped). -
S108 — step (c) DONE: the shared headers (
HEADERS=1 LABEL_PREFIX=t4_H … restruct_cycle.sh 1 16 20 D,cycle_t4h.log).t4_HD120 headers · 30 units: 27 canonical / 3 kept · 7 files (436cfd8a1) ·t4_HD21 unit / 1 kept / 0 files (1e996c609) ·t4_HD30 units (bc16e5994) — each R22check-all: 218 passed, 0 failed of 218; the cycle stopped at the HD3/HD4 boundary (a 90-s R22 per 0-file batch is waste — the cycle now skips the fleet run whengit status srcis clean after a batch) and the remaining headers settled in ONE direct run **t4_HD4: 216 headers · 9 units: 4 canonical / 1 K&R marked / 2 aliases typed / 3 kept · compiles 989 in 44 s · final 216/216 identical · written 6 files** → R22 (r22_t4_HD4.log) **check-all: 218 passed, 0 failed of 218** (wall=84.80 s). Re-plan:restruct --plan D: 0 of 0 TUs with lying declarations · 0 calleesfor--headers— the header population is exhausted. (Slip on the way, not repeated:pgrep -fwith a literal my own command line contained killed my shell — exit 144, R79 in read form; the bracketed patternrestruct_cycl[e]` is the safe spelling.) -
2026-09-12 — T4 step (d)
t4_sig1(restruct --apply --rung D --callee func_800385C0 --body $A/main__func_800385C0/body.c;.run/P37/restruct/run_t4_sig1.log):restruct: signature func_800385C0 — IDENTICAL · 2 files written→ R22 (.run/P37/baseline/r22_t4_sig1.log)check-all: 218 passed, 0 failed of 218(wall=85.91 s). -
2026-09-12 — T4 step (d)
t4_sig2(restruct --apply --rung D --callee func_80029D3C --body $A/main__func_80029D3C/scratch/patch_signature.c;.run/P37/restruct/run_t4_sig2.log):restruct: signature func_80029D3C — COMPILE-ERROR · 0 files written— (no src change) · cause:signature func_80029D3C: COMPILE-ERROR src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c:8778: too few arguments to functionfunc_80029D3C'`. -
2026-09-12 — T4 step (d)
t4_sig3(restruct --apply --rung D --callee func_80035210 --body $A/main__func_80035210/body.c;.run/P37/restruct/run_t4_sig3.log):restruct: signature func_80035210 — IDENTICAL · 1 files written→ R22 (.run/P37/baseline/r22_t4_sig3.log)check-all: 218 passed, 0 failed of 218(wall=84.96 s). -
2026-09-12 — T4 step (d)
t4_sig4(restruct --apply --rung D --callee func_800384A8 --body $A/main__func_800384A8/body.c;.run/P37/restruct/run_t4_sig4.log):restruct: signature func_800384A8 — IDENTICAL · 2 files written→ R22 (.run/P37/baseline/r22_t4_sig4.log)check-all: 218 passed, 0 failed of 218(wall=83.14 s). -
2026-09-12 — T4 step (d)
t4_sig5(restruct --apply --rung D --callee func_80183CC4 --body $A/ov_SC03_094__func_80183CC4/body.c --all-defs;.run/P37/restruct/run_t4_sig5.log):restruct: signature func_80183CC4 — COMPILE-ERROR · 0 files written— (no src change) · cause:signature func_80183CC4: COMPILE-ERROR src/ov_SC03_006/ov_SC03_006_jr_8017AE2C.c:8227:D_801AE958' undeclared (first use this function)`. -
2026-09-12 — T4 step (d)
t4_sig6(restruct --apply --rung D --callee func_80185578 --body $A/ov_SC06_022__func_80185578/body.c --tu src/ov_SC06_022/ov_SC06_022_jr_80184A28.c;.run/P37/restruct/run_t4_sig6.log):restruct: signature func_80185578 — IDENTICAL · 3 files written→ R22 (.run/P37/baseline/r22_t4_sig6.log)check-all: 218 passed, 0 failed of 218(wall=83.33 s). -
2026-09-12 — T4 step (d)
t4_sig7(restruct --apply --rung D --callee func_80188DF4 --body $A/ov_SC03_091__func_80188DF4/body.c --all-defs;.run/P37/restruct/run_t4_sig7.log):restruct: signature func_80188DF4 — COMPILE-ERROR · 0 files written— (no src change) · cause:signature func_80188DF4: COMPILE-ERROR src/ov_SC02_011/ov_SC02_011_jr_80183178.c:4225: too many arguments to functionfunc_80188DF4'`. -
2026-09-12 — T4 step (d)
t4_sig8(restruct --apply --rung D --callee func_80188A30 --body $A/ov_SC04_011__func_80188A30/body_free.c;.run/P37/restruct/run_t4_sig8.log):restruct: signature func_80188A30 — DIFFERS · 0 files written— (no src change) · cause:signature func_80188A30: DIFFERS [build/src/ov_SC04_011/ov_SC04_011_jr_8017D494.o] — nothing written. -
2026-09-12 — T4 step (d)
t4_sig9(restruct --apply --rung D --callee func_801A1E94 --body $A/md_SC07_004__func_801A1E94/body.c;.run/P37/restruct/run_t4_sig9.log):restruct: signature func_801A1E94 — COMPILE-ERROR · 0 files written— (no src change) · cause:signature func_801A1E94: COMPILE-ERROR src/md_SC07_004/md_SC07_004.c:4396: too few arguments to functionfunc_801A1E94'`. -
2026-09-12 — T4 step (d)
t4_sig10(restruct --apply --rung D --callee func_801A5C44 --body $A/md_SC07_004__func_801A5C44/body.c;.run/P37/restruct/run_t4_sig10.log):restruct: signature func_801A5C44 — COMPILE-ERROR · 0 files written— (no src change) · cause:signature func_801A5C44: COMPILE-ERROR src/md_SC07_004/md_SC07_004.c:4200: too few arguments to functionfunc_801A5C44'`. -
2026-09-12 — T4 step (d)
t4_sig11(restruct --apply --rung D --callee func_8017FC5C --body $A/ov_SC03_115__func_8017FC5C/body.c --all-defs;.run/P37/restruct/run_t4_sig11.log):restruct: signature func_8017FC5C — COMPILE-ERROR · 0 files written— (no src change) · cause:signature func_8017FC5C: COMPILE-ERROR src/ov_SC04_002/ov_SC04_002_jr_8017BEBC.c:4875: too few arguments to functionfunc_8017FC5C'`. -
2026-09-12 — T4 step (d)
t4_sig12(restruct --apply --rung D --callee func_80157D20 --body $A/ov_SC04_011__func_80157D20/body.c --all-defs;.run/P37/restruct/run_t4_sig12.log):restruct: signature func_80157D20 — DIFFERS · 0 files written— (no src change) · cause:signature func_80157D20: DIFFERS linked: mipsel-linux-gnu-ld: /home/musashi/bfm-decomp/.run/P36/delever/obj/src__ov_MAIN_012__ov_MAIN_012_jr_801555F4.sig108d39.lnk.o: in functionfunc_80157D20':`. -
2026-09-12 — T4 step (d)
t4_sig12b(restruct --apply --rung D --callee func_80157D20 --body $A/ov_SC04_011__func_80157D20/body.c --all-defs --map-data;.run/P37/restruct/run_t4_sig12b.log):restruct: signature func_80157D20 — COMPILE-ERROR · 0 files written— (no src change) · cause:signature func_80157D20: COMPILE-ERROR src/ov_SC03_126/../shared/ov/func_80157D20__99380536.h:4: conflicting types forfunc_80157D20'`. -
2026-09-12 — T4 step (d)
t4_sig2b(restruct --apply --rung D --callee func_80029D3C --body $A/main__func_80029D3C/scratch/patch_signature.c --with src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c=.run/P37/restruct/with_ov_SC07_002_jr_8017C8D0.c;.run/P37/restruct/run_t4_sig2b.log):restruct: signature func_80029D3C — COMPILE-ERROR · 0 files written— (no src change) · cause:signature func_80029D3C: COMPILE-ERROR src/ov_MAIN_012/../shared/ov/func_8015126C.h:117: too few arguments to functionfunc_80029D3C'`. -
2026-09-12 — T4 step (d)
t4_sig8b(restruct --apply --rung D --callee func_80188A30 --body .run/P37/restruct/body_func_80188A30_s32.c;.run/P37/restruct/run_t4_sig8b.log):restruct: signature func_80188A30 — IDENTICAL · 1 files written→ R22 (.run/P37/baseline/r22_t4_sig8b.log)check-all: 218 passed, 0 failed of 218(wall=99.65 s). -
2026-09-12 — T4 step (d)
t4_sig7b(restruct --apply --rung D --callee func_80188DF4 --body $A/ov_SC03_091__func_80188DF4/body.c --tu src/ov_SC03_091/ov_SC03_091_jr_8018326C.c;.run/P37/restruct/run_t4_sig7b.log):restruct: signature func_80188DF4 — IDENTICAL · 1 files written→ R22 (.run/P37/baseline/r22_t4_sig7b.log)check-all: 218 passed, 0 failed of 218(wall=93.00 s). -
2026-09-12 — T4 step (d)
t4_sig11b(restruct --apply --rung D --callee func_8017FC5C --body $A/ov_SC03_115__func_8017FC5C/body.c --tu src/ov_SC03_115/ov_SC03_115_jr_8017BEBC.c;.run/P37/restruct/run_t4_sig11b.log):restruct: signature func_8017FC5C — IDENTICAL · 1 files written→ R22 (.run/P37/baseline/r22_t4_sig11b.log)check-all: 218 passed, 0 failed of 218(wall=88.01 s). -
2026-09-12 — T4 step (d)
t4_sig2c(restruct --apply --rung D --callee func_80029D3C --body $A/main__func_80029D3C/scratch/patch_signature.c --with src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c=.run/P37/restruct/with_ov_SC07_002_jr_8017C8D0.c --with src/shared/ov/func_8015126C.h=.run/P37/restruct/with_shared_ov_func_8015126C.h;.run/P37/restruct/run_t4_sig2c.log):restruct: signature func_80029D3C — COMPILE-ERROR · 0 files written— (no src change) · cause:signature func_80029D3C: COMPILE-ERROR src/ov_MAIN_012/../shared/ov/func_80151780.h:24: too few arguments to functionfunc_80029D3C'`. -
2026-09-12 — T4 step (d)
t4_sig12c(restruct --apply --rung D --callee func_80157D20 --body $A/ov_SC04_011__func_80157D20/body.c --all-defs --map-data;.run/P37/restruct/run_t4_sig12c.log):restruct: signature func_80157D20 — IDENTICAL · 2105 files written→ R22 (.run/P37/baseline/r22_t4_sig12c.log)check-all: 218 passed, 0 failed of 218(wall=86.11 s). -
2026-09-12 — T4 step (d)
t4_sig2d(restruct --apply --rung D --callee func_80029D3C --body $A/main__func_80029D3C/scratch/patch_signature.c --with src/ov_SC07_002/ov_SC07_002_jr_8017C8D0.c=.run/P37/restruct/with_ov_SC07_002_jr_8017C8D0.c --with src/shared/ov/func_8015126C.h=.run/P37/restruct/with_shared_ov_func_8015126C.h --with src/shared/ov/func_80151780.h=.run/P37/restruct/with_shared_ov_func_80151780.h;.run/P37/restruct/run_t4_sig2d.log):restruct: signature func_80029D3C — IDENTICAL · 2177 files written→ R22 (.run/P37/baseline/r22_t4_sig2d.log)check-all: 218 passed, 0 failed of 218(wall=89.72 s). -
2026-09-12 — T4 step (d)
t4_sig5b(restruct --apply --rung D --callee func_80183CC4 --body $A/ov_SC03_094__func_80183CC4/body.c --tu src/ov_SC03_094/ov_SC03_094_jr_8017BEBC.c;.run/P37/restruct/run_t4_sig5b.log):restruct: signature func_80183CC4 — IDENTICAL · 1 files written→ R22 (.run/P37/baseline/r22_t4_sig5b.log)check-all: 218 passed, 0 failed of 218(wall=83.66 s). -
S108 — step (d) DONE (the parked signature bodies; the driver
.run/P37/restruct/sig_cycle.sh, one judged unit per function, R22 per landing — every entry's exact command is in its own log line above). Landed 10 of the 12 packs:func_800385C0(623069579),func_80035210(ee3419ff0),func_800384A8(145d6a7cb),func_80185578(--tu,754916997),func_80188A30(void→s32— reorg's delay-slot fill, §162f1; the pack'sbody_free.cwith ans32head,32e170941),func_80188DF4(--tu,f4ac36ccf),func_8017FC5C(--tu,6b19f8941),func_80157D20(132 copies,--all-defs --map-data: the pack body'sD_80192768renamed to each copy's own datum by order of first appearance; the variant header__99380536.hand its 3 binaries left as is; IDENTICAL on every recipe, 2,105 files,062467aab),func_80029D3C(--with×3: the definition(void)→(s32 n)AND its three zero-argument callers —ov_SC07_002_jr_8017C8D0.c, the shared bodiesfunc_8015126C.handfunc_80151780.h— each a$4pin that WAS the missing argument, rewritten to pass it; 2,177 files,5016a185d),func_80183CC4(--tu,f0c9b96b6). Not landed, by name for T7:func_801A1E94/func_801A5C44(md_SC07_004: a zero-argument callerfunc_801A6A18(void) { func_801A1E94(); }passes its OWN incoming$a0through — the fix cascades one caller up); the other same-address copies offunc_80185578(ov_SC03_014),func_80188DF4(ov_SC02_011 — a caller passes more arguments; ov_SC03_104),func_8017FC5C(ov_SC04_002 — a short caller),func_80183CC4(ov_SC03_006/029/090 — per-overlay data, 1/0/4 symbols vs the pack's 1). Three tool extensions this step, each with its command in the log:--tufallback in the driver (the pack's own copy when copies differ),--with REL=FILE(a caller-body edit inside the same judged unit),--map-data(per-copy data renames; a count mismatch REFUSES); a header-borne definition is excluded from--all-defsbody replacement (a variant is another function). -
S108 — step (e) DONE: the "carried decl layer" banner comments.
.run/P37/restruct/strip_banners.py(refuses an unknown banner form; prose mentions inside other comments kept):3546 files · 3547 openers + 3543 closers removed(4 openers had no one-line closer — the opener alone went; 142 prose mentions kept),git diff --stat src: 3,546 files changed, 0 insertions, 21,274 deletions, every removed line a comment line → R22 (.run/P37/baseline/r22_t4_banners.log)check-all: 218 passed, 0 failed of 218(wall=92.04 s, exit 0). -
S108 — step (f), first pass: the census + series.
type_census -j 16 --sites→8830 lying declarations / 950 callees (+5002 K&R sites apart) · controls 4/4(from 98,648 / 1,609 at T1; K&R-empty 2,997 / narrow 5,833). The K&R accounting built first:argcheck.scanrows gainkr_marked(the// K&R:marker read from the RAW line — the mask blanks comments),type_censusandreadability_progresscount those APART (kr_sites/kr_calleescolumns; the rendered table's last column) and exclude them from "lying" — the census had lumped the 5,020 marked sites into "K&R-empty".lever_census --check: 3,730 pin/asm sites, 3,730 marked, 0 UNMARKED — OK(from 4,010; −280 = func_80157D20's 264 + func_80029D3C's 4 + func_80183CC4's 4 + …);lever_progress --snapshot(80 milestones) +--check OK;readability_progress --snapshot t4→8830 lying … (+5002 K&R sites apart) … 13 in 10 pinned bodies+--check OK;progress.py --json --readme+--checkfresh. The 8,830 bucketed by their ledger verdict (R117) — T4 is NOT closable yet: 3,700 no ledger row (never judged: themd_*module TUs and others — they were inside the 1,088 "drawable" TUs when I stopped the D cycle on two low-yield batches; an inference, not a measurement — R14); 2,379DECL-NONE "already canonical"+ 453DECL-CANONthat argcheck still calls lying (two instruments resolve the callee to different definitions — 6,419 names carry >1 body; R34, to read on one case each); 1,120DECL-KEPT parse error(T5's types →--redraw DECL-KEPTafter T5); 723DECL-NONE no visible definition(cross-binary callees: a module calling an overlay-region function — a fleet-unique-signature fallback would judge them); 415conflicting types; 21 assorted. Next: the D cycle again WITHOUTREDRAW(draws only the never-judged pairs), the disagreement read, the fallback. -
2026-09-12 — T4 batch
t4_D40(.run/P37/restruct/run_t4_D40.log,batch_t4_D40.json):restruct: batch t4_D40 rung D — 300 files (TUs; 2367 drawable) · 619 declaration units: 547 canonical / 0 promoted / 8 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 72 kept · compiles 756 in 154 s wall · final 300/300 identical · written 286 files→ R22 (.run/P37/baseline/r22_t4_D40.log)check-all: 218 passed, 0 failed of 218(wall=90.49 s) → census(census skipped). -
S108 — the R34 disagreement read (2,379 + 453 "already canonical / DECL-CANON but argcheck says lying"):
func_800CB8A4isvoid (void)in md_MAIN_026,void (s32 a0)in md_MAIN_022,void (void *a0)in md_MAIN_025 — a same-address DIFFERENT-BODY function;argcheck.definitions()kept ONE signature per bare name (setdefault, file order — R48) and called md_MAIN_026's correct declaration a lie. The engine (per-binary scope) was right. Fixed inargcheck: every definition per name kept (_ALL),resolve_definition(name, tu)— one fleet-wide signature → it; else the declaring TU's own binary's definition; else main's/resident's; elsecross_binary=True(the fleet disagrees and this binary has no definition — counted APART, never a lie);type_censusandreadability_progresscountcross_binaryapart likekr_marked. Known-true: md_MAIN_026 → its own(void); md_MAIN_013 (no own definition) → cross-binary; a unique name → its definition. The engine's counterpart:defs_visiblegained a third level — a callee no member TU, main or resident defines takes the fleet's ONE signature when every definition of the name agrees (_fleet_unique_defs; the 723 "no visible definition" rows: e.g. md_MAIN_013'sfunc_80128EA8→ the shared header'svoid (s32, s32, s32)); a name with two bodies stays unresolved (the caller's binary decides).--selftest 54/54. The D cycle again, withoutREDRAW(cycle_t4g.log, batches 40–60):t4_D40619 units: 547 canonical / 8 K&R / 72 kept · 286 files (25c70a009, R22218 passed, 0 failed of 218) — the "1,088 non-actionable" TUs of the earlier stop were 2,367 TUs with work in them. -
2026-09-12 — T4 batch
t4_D41(.run/P37/restruct/run_t4_D41.log,batch_t4_D41.json):restruct: batch t4_D41 rung D — 300 files (TUs; 2085 drawable) · 724 declaration units: 648 canonical / 0 promoted / 8 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 76 kept · compiles 823 in 61 s wall · final 300/300 identical · written 300 files→ R22 (.run/P37/baseline/r22_t4_D41.log)check-all: 218 passed, 0 failed of 218(wall=84.50 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D42(.run/P37/restruct/run_t4_D42.log,batch_t4_D42.json):restruct: batch t4_D42 rung D — 300 files (TUs; 1785 drawable) · 602 declaration units: 577 canonical / 0 promoted / 2 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 25 kept · compiles 670 in 57 s wall · final 300/300 identical · written 298 files→ R22 (.run/P37/baseline/r22_t4_D42.log)check-all: 218 passed, 0 failed of 218(wall=88.44 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D43(.run/P37/restruct/run_t4_D43.log,batch_t4_D43.json):restruct: batch t4_D43 rung D — 300 files (TUs; 1485 drawable) · 606 declaration units: 570 canonical / 0 promoted / 4 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 36 kept · compiles 705 in 57 s wall · final 300/300 identical · written 297 files→ R22 (.run/P37/baseline/r22_t4_D43.log)check-all: 218 passed, 0 failed of 218(wall=82.19 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D44(.run/P37/restruct/run_t4_D44.log,batch_t4_D44.json):restruct: batch t4_D44 rung D — 300 files (TUs; 1185 drawable) · 418 declaration units: 372 canonical / 0 promoted / 12 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 46 kept · compiles 660 in 118 s wall · final 300/300 identical · written 269 files→ R22 (.run/P37/baseline/r22_t4_D44.log)check-all: 218 passed, 0 failed of 218(wall=82.49 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D45(.run/P37/restruct/run_t4_D45.log,batch_t4_D45.json):restruct: batch t4_D45 rung D — 300 files (TUs; 885 drawable) · 265 declaration units: 262 canonical / 0 promoted / 1 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 3 kept · compiles 544 in 47 s wall · final 300/300 identical · written 263 files→ R22 (.run/P37/baseline/r22_t4_D45.log)check-all: 218 passed, 0 failed of 218(wall=80.08 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D46(.run/P37/restruct/run_t4_D46.log,batch_t4_D46.json):restruct: batch t4_D46 rung D — 300 files (TUs; 585 drawable) · 266 declaration units: 263 canonical / 0 promoted / 0 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 3 kept · compiles 560 in 47 s wall · final 300/300 identical · written 263 files→ R22 (.run/P37/baseline/r22_t4_D46.log)check-all: 218 passed, 0 failed of 218(wall=84.36 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D47(.run/P37/restruct/run_t4_D47.log,batch_t4_D47.json):restruct: batch t4_D47 rung D — 285 files (TUs; 285 drawable) · 279 declaration units: 250 canonical / 0 promoted / 1 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 29 kept · compiles 553 in 46 s wall · final 285/285 identical · written 251 files→ R22 (.run/P37/baseline/r22_t4_D47.log)check-all: 218 passed, 0 failed of 218(wall=83.08 s) → census(census skipped). -
S108 — the D cycle
t4_D40–t4_D47DONE (no REDRAW;cycle_t4g.log; "nothing drawable at t4_D48"): 619 / 724 / 602 / 606 / 418 / 265 / 266 / 279 units → 3,489 canonical / 36 K&R marked / 290 kept in 2,264 files (25c70a0096cb5731731464eb4ced2e43e4c3f5c7c1809265f2bcecb9a7791fe2391ee628), eachfinal N/N identical, R22check-all: 218 passed, 0 failed of 218. Census after it (census_t4b.log):2367 lying declarations / 256 callees (+5082 K&R sites, +511 cross-binary apart) · controls 4/4— from 98,648 / 1,609 at T1. The 2,367 bucketed by ledger verdict (R117), every one with a cause: 1,120parse error (type unknown to TU)(T5's canonical types, then--redraw DECL-KEPT), 667no visible definition(settled BEFOREdefs_visible's fleet-unique level — redrawn next), 417conflicting types(T5/T7), 116 "already canonical" (read:func_80189888is defined INDENTED at file scope in ov_SC02_000 —argcheck'sDEFanchored at column 0 missed it and compared against ov_SC06_024's 6-parameter body; fixed: leading blanks allowed, and the K&R loop now feeds_ALLregardless ofoutso BOTH binaries resolve to their own), 13 syntax errors in800.c, 8+2 arity, 8 DECL-CANON, 2+2 compile, 2 bytes, 2 still-aliased.--redrawkeys gained theVERDICT:cause-substringform (DECL-NONE:visible) so a redraw lifts only the rows it means. -
2026-09-12 — T4 batch
t4_D49(.run/P37/restruct/run_t4_D49.log,batch_t4_D49.json):restruct: batch t4_D49 rung D — 203 files (TUs; 203 drawable) · 90 declaration units: 55 canonical / 0 promoted / 0 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 35 kept · compiles 162 in 141 s wall · final 203/203 identical · written 55 files→ R22 (.run/P37/baseline/r22_t4_D49.log)check-all: 218 passed, 0 failed of 218(wall=83.00 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D50(.run/P37/restruct/run_t4_D50.log,batch_t4_D50.json):restruct: batch t4_D50 rung D — 400 files (TUs; 2247 drawable) · 2802 declaration units: 2791 canonical / 0 promoted / 1 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 11 kept · compiles 930 in 229 s wall · final 400/400 identical · written 398 files→ R22 (.run/P37/baseline/r22_t4_D50.log)check-all: 218 passed, 0 failed of 218(wall=87.67 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D51(.run/P37/restruct/run_t4_D51.log,batch_t4_D51.json):restruct: batch t4_D51 rung D — 400 files (TUs; 1903 drawable) · 2802 declaration units: 2778 canonical / 0 promoted / 0 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 24 kept · compiles 900 in 142 s wall · final 400/400 identical · written 398 files→ R22 (.run/P37/baseline/r22_t4_D51.log)check-all: 218 passed, 0 failed of 218(wall=87.20 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D52(.run/P37/restruct/run_t4_D52.log,batch_t4_D52.json):restruct: batch t4_D52 rung D — 400 files (TUs; 1507 drawable) · 1659 declaration units: 1639 canonical / 0 promoted / 1 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 20 kept · compiles 815 in 120 s wall · final 400/400 identical · written 375 files→ R22 (.run/P37/baseline/r22_t4_D52.log)check-all: 218 passed, 0 failed of 218(wall=83.77 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_HD5(.run/P37/restruct/run_t4_HD5.log,batch_t4_HD5.json):restruct: batch t4_HD5 rung D — 281 files (headers; 281 drawable) · 24 declaration units: 20 canonical / 0 promoted / 4 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 4 kept · compiles 2828 in 69 s wall · final 281/281 identical · written 12 files→ R22 (.run/P37/baseline/r22_t4_HD5.log)check-all: 218 passed, 0 failed of 218(wall=83.35 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_HD6(.run/P37/restruct/run_t4_HD6.log,batch_t4_HD6.json):restruct: batch t4_HD6 rung D — 271 files (headers; 271 drawable) · 0 declaration units: 0 canonical / 0 promoted / 0 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 0 kept · compiles 0 in 16 s wall · final 271/271 identical · written 0 files→ R22 (.run/P37/baseline/r22_t4_HD6.log)(no src change — the previous R22 stands)(``) → census(census skipped). -
S108 — the targeted redraw + the indented-definition class (
cycle_t4i.log,REDRAW=DECL-NONE:visible):t4_D49203 TUs · 90 units: 55 canonical / 35 kept (f76538941); then the argcheck cache rebuilt on the fixedDEFand 2,247 TUs became drawable — callers of INDENTED file-scope definitions had never been rows:t4_D502,802 units: 2,791 canonical (a0c26f587) ·t4_D512,802: 2,778 (6d822ff2c) ·t4_D521,659: 1,639 (f74d1e077); headerst4_HD5281: 24 units, 20 canonical / 4 K&R (3d9c8aed1) ·t4_HD60 units (8a84409a1, no src change — the cycle's new skip); every gated batchcheck-all: 218 passed, 0 failed of 218. Chained:cycle_t4j.logbatches 53–62 for the ~1,500 drawable TUs left. The record banked (R30): accelerators P37 S108 (ten entries: the five blind spots, the kill/restore race, the flat-yield stop,--map-data,--with, the K&R-style definition), decision log P37 S108 (the census's four steps were instrument repairs; the stop rule is the bucketed remainder; a signature change is a unit of definition + callers + declarations), cookbook §459 (the declaration layer's byte facts: the K&R-style definition on 288 objects, the local homed in$a0, the return type in a delay slot, the per-overlay data map, what a prototype cannot hide), SETUP §P37 S108 (every option and gotcha), the cookbook index (1,177 sections). -
2026-09-12 — T4 batch
t4_D53(.run/P37/restruct/run_t4_D53.log,batch_t4_D53.json):restruct: batch t4_D53 rung D — 400 files (TUs; 1007 drawable) · 1014 declaration units: 1014 canonical / 0 promoted / 0 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 0 kept · compiles 836 in 71 s wall · final 400/400 identical · written 400 files→ R22 (.run/P37/baseline/r22_t4_D53.log)check-all: 218 passed, 0 failed of 218(wall=84.03 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D54(.run/P37/restruct/run_t4_D54.log,batch_t4_D54.json):restruct: batch t4_D54 rung D — 400 files (TUs; 607 drawable) · 800 declaration units: 800 canonical / 0 promoted / 0 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 0 kept · compiles 836 in 61 s wall · final 400/400 identical · written 400 files→ R22 (.run/P37/baseline/r22_t4_D54.log)check-all: 218 passed, 0 failed of 218(wall=93.99 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D55(.run/P37/restruct/run_t4_D55.log,batch_t4_D55.json):restruct: batch t4_D55 rung D — 207 files (TUs; 207 drawable) · 412 declaration units: 411 canonical / 0 promoted / 1 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 1 kept · compiles 414 in 38 s wall · final 207/207 identical · written 207 files→ R22 (.run/P37/baseline/r22_t4_D55.log)check-all: 218 passed, 0 failed of 218(wall=84.48 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D56(.run/P37/restruct/run_t4_D56.log,batch_t4_D56.json):restruct: batch t4_D56 rung D — 145 files (TUs; 145 drawable) · 32 declaration units: 0 canonical / 0 promoted / 0 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 32 kept · compiles 50 in 140 s wall · final 145/145 identical · written 0 files→ R22 (.run/P37/baseline/r22_t4_D56.log)(no src change — the previous R22 stands)(``) → census(census skipped). -
2026-09-12 — T4 batch
t4_D57(.run/P37/restruct/run_t4_D57.log,batch_t4_D57.json):restruct: batch t4_D57 rung D — 145 files (TUs; 145 drawable) · 0 declaration units: 0 canonical / 0 promoted / 0 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 0 kept · compiles 0 in 133 s wall · final 145/145 identical · written 0 files→ R22 (.run/P37/baseline/r22_t4_D57.log)(no src change — the previous R22 stands)(``) → census(census skipped). -
2026-09-12 — T4 batch
t4_D58(.run/P37/restruct/run_t4_D58.log,batch_t4_D58.json):restruct: batch t4_D58 rung D — 145 files (TUs; 145 drawable) · 50 declaration units: 14 canonical / 0 promoted / 36 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 36 kept · compiles 128 in 131 s wall · final 145/145 identical · written 32 files→ R22 (.run/P37/baseline/r22_t4_D58.log)check-all: 218 passed, 0 failed of 218(wall=83.89 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_D59(.run/P37/restruct/run_t4_D59.log,batch_t4_D59.json):restruct: batch t4_D59 rung D — 115 files (TUs; 115 drawable) · 1 declaration units: 0 canonical / 0 promoted / 0 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 1 kept · compiles 1 in 129 s wall · final 115/115 identical · written 0 files→ R22 (.run/P37/baseline/r22_t4_D59.log)(no src change — the previous R22 stands)(``) → census(census skipped). -
2026-09-12 — T4 batch
t4_HD7(.run/P37/restruct/run_t4_HD7.log,batch_t4_HD7.json):restruct: batch t4_HD7 rung D — 271 files (headers; 271 drawable) · 289 declaration units: 182 canonical / 0 promoted / 91 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 107 kept · compiles 41375 in 1381 s wall · final 271/271 identical · written 159 files→ R22 (.run/P37/baseline/r22_t4_HD7.log)check-all: 218 passed, 0 failed of 218(wall=83.80 s) → census(census skipped). -
2026-09-12 — T4 batch
t4_HD8(.run/P37/restruct/run_t4_HD8.log,batch_t4_HD8.json):restruct: batch t4_HD8 rung D — 57 files (headers; 57 drawable) · 0 declaration units: 0 canonical / 0 promoted / 0 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 0 kept · compiles 0 in 12 s wall · final 57/57 identical · written 0 files→ R22 (.run/P37/baseline/r22_t4_HD8.log)(no src change — the previous R22 stands)(``) → census(census skipped). -
S108 (continued on Drew's "continue") — item (h) read and closed; the disk; item (g)'s tool. The 593 "no visible definition" rows were STALE VERDICTS, not a disagreement: the engine resolves every one now (
defs_visible('src/md_MAIN_013/md_MAIN_013.c')['func_80128EA8']→ the shared header), but the firstDECL-NONE:visibleredraw had drawn its TUs and skipped every unit as done —apply_batchlifted the engine'sdoneset by VERDICT only (latest.get(k[:3]) not in set(a.redraw)), so theVERDICT:causekey lifted the planner's filter and not the engine's ("rows 0" in D49/D56/D57). Fixed at the cause (the same key logic on both sides); the redraw again:t4_D5850 units: 14 canonical / 36 K&R marked · 32 files (22915a697, R22218 passed, 0 failed of 218) ·t4_D591 kept ·t4_HD7271 headers · 289 units: 182 canonical / 91 K&R marked / 107 kept · 159 files · 41,375 compiles in 1,381 s (1e876b0ec, R22 218/218) ·t4_HD80. Of the 593, 133 were the alias NAMESaF…of the 16 still-aliased functions (T7's). Census (census_t4d.log):1796 lying declarations / 76 callees (+5262 K&R sites, +418 cross-binary apart) · controls 4/4. The disk (Drew asked): 254 MB free of 73 GB —.run/was 50 GB, 22 GB of it gcc pass dumps (.sched2 .lreg .flow .greg .combine .cse …fromcc1_dumps_tu.sh) under.run/P36/agents/'s packs; the dump files deleted (every.c/.md/.txtkept — step (d) read bodies fromscratch/), the 45k stale judge objects in.run/P36/delever/objtoo,sudo fstrim /→ 10 GiB back to the host; 22 GB free (70 %); still prunable, same class:.run/P32/6.6 GB, the rest of.run/P36/6.5 GB. Item (g)'s tool:share_body --retry-excepted(a ledgered class re-enters the plan; before registration its old row is dropped — a share leaves no row, a rejection re-ledgers with the fresh diagnostic);--plan --retry-excepted: extend 50 classes · new 1 class (0 / 0 without the flag). -
S108 — item (g), the extend bucket:
share_body --apply --bucket extend --retry-excepted --batch 60 --label t4_ret1(run_t4_ret1.log, 104 s):gated 141/141 binaries green · registered 0 groups · extended 17 members · rejected classes 44— 6 of the 50 ledgered classes share now (their rows dropped: the ledger 63 → 57 lines;config/dedup.us.yamlextended by 17 members; one private copy deleted fromov_MAIN_012_jr_8013F350.c), 44 re-ledgered with today's diagnostics (conflicting types for ApplyMatrixSV/D_800AE620/D_80126CC4/D_800A651C— a late-onboarded TU declares a Sony function or a datum another way, T5's canonical layer;too few arguments to func_8014A51C / func_80146C3C / func_801483E8 / func_8016EDECinside shared bodies — the header's short call compiles only where the includer's declaration is the K&R();redefinition of tail_8012F274;conflicting types for func_80173B4C). R22 (r22_t4_ret1.log)check-all: 218 passed, 0 failed of 218(wall=82.36 s);share_census --check --strict-macros --strict-text→S1 … 10,180 satisfied (3,507 twin-covered, 45 excepted, 3,801 deferred cross-address), 0 VIOLATION(S) — OK. -
S108 — item (g), the new bucket:
share_body --apply --bucket new --retry-excepted --label t4_ret2— the one ledgered class (0x8017D0FC, 2 instances)REJECTED — ov_SC04_006: func_8017D0FC__250070c4.h:4: D_80126954 undeclared(a datum declared in one member TU only — T5's canonical data declarations);gated 2/2 binaries green, nothing written, its row refreshed. Item (g) DONE: the 51 TU-CONFLICT rows → 45 (6 shared), every survivor carrying today's compiler line. T4's remainder is now entirely ledgered by cause and owned by T5/T7.
🛑 SESSION CHECKPOINT — S108 (2026-09-12, FINAL — written for a FRESH session; the session's last commit follows this): gate 1 APPROVED, T0 ☑ T1 ☑ T2 ☑ T3 ☑ — T4 IN PROGRESS (☐): steps (a)–(f) DONE, two owed items left — 🛑 T4 NEXT: (g) the 51 TU-CONFLICT rows retried through share_body (needs a --retry-excepted flag), (h) the 593 "no visible definition" rows read on one example; then the T4 ☑ line, the P6 rules check, T5 (Max for the head types); xHigh | R22 check-all: 218 passed, 0 failed of 218 at 06615fe89 (every one of the session's ~40 gated commits carries its own) | HEAD after this commit is the checkpoint's commit; tree clean; nothing pushed after 79b2f6f15 (Drew pushes, R6) | last batch t4_HD8 on 1e876b0ec: 57 files (headers; 57 drawable) · 0 declaration units: 0 canonical / 0 promoted / 0 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 0 kept · compiles 0 i
Replay this block into the chat at the next session start (R64); it is the ONLY in-phase context the next session inherits. Everything below
is what S108 knew and the next session must not re-derive. The checkpoint procedure (every session end, Drew 2026-09-12): bank the
record (cookbook / decision log / accelerators / SETUP / stale assertions), advance the post-100 % story — docs/story.md §10 and
docs/retrospective.md §7 from the session's decision-log entry — and regenerate tools/timeline.py, then rewrite this block, commit, recap (R18).
-
Where we are — and T4's exact resume. Phase 37 (structs) opened 2026-09-11 (S106, gate 1: grind to zero on raw casts / lying declarations / levers; placeholders + cited evidence; T7 = the P36 agent lane on Drew's word; the full canonical declaration layer; R107–R117 ratified; no tags at closes). S107 built T3 (the engine) and started T4; **S108 (this session, ~10 h, ~60 commits, xHigh) ran T4's six checkpoint steps to their floor: (a) the D cycle —
t4_D22–t4_D36,t4_D40–t4_D47,t4_D49–t4_D55(≈90,000 declarations canonical in total, 5,092 K&R sites marked); (b) the alias-defined functions — 133 of 149 back under their real names, 16 kept by cause; (c) the shared headers — the header plan is EMPTY (0 of 0); (d) the parked signature bodies — 10 of 12 landed (func_80157D20×132 via--map-data,func_80029D3C+ its 3 callers via--with,func_80188A30void→s32, seven more), themd_SC07_004pair and the other same-address copies of four functions named for T7; (e) the 3,546 "carried decl layer" banner comment blocks removed (21,274 comment lines, 0 insertions); (f) the census- series published.** Every gated commit
check-all: 218 passed, 0 failed of 218. The day's real story was FIVE instrument blind spots, each repaired at its cause (item 5 below; accelerators P37 S108). T4's two owed items, in order: (g) the 51 TU-CONFLICT rows ofconfig/dedup_exceptions.tsv(P35's ledger — declaration-environment conflicts the D work may have dissolved:D_800B9A02 undeclared,conflicting types for func_80146C3C, …):share_body --planreports0 classesfor both buckets becauseplan_classesskipsc["excepted"](tools/share_body.py:173) — add a--retry-exceptedflag (the excepted classes re-enter the plan; the ledger row is deleted only when the gate accepts the share), thentools/share_body_cycle.sh(unattended: batch → exit code → log → commit → periodic clean fleet run) on--bucket extendthennew; the rows the gate still rejects keep their (refreshed) diagnostic. (h) the 593DECL-NONE "no visible definition"rows that survive the fleet-unique fallback — read ONE on the tree (R14): take a row from the bucketing script in the "final census" log entry (e.g. a.cTU, not a header), runrestruct.defs_visible(tu).get(callee)andargcheck.resolve_definition(callee, tu, …)side by side; the disagreement is one of: a name with 2+ bodies where argcheck picked the TU's binary's definition but the engine's_files_in_dirdid not see it (an indented definition? a_jr_file outside the alias dir?), or a twin dir (corpus.src_dir). Fix at the cause, re-run--redraw DECL-NONE:visible(TUs thenHEADERS=1), re-census. Then: the T4 ☑ line (its verify lines: the final census line,lever_census --check, the bucketed remainder), the P6 rules check (the plan asks for one after T4), and T5 (Max for the head types) — struct unification from the map (--write-types --top 6previews;--audit-types's 26 legacypad<SIZE>names; the 1,120parse errordeclarations close with--redraw DECL-KEPToncePos800D20C0-class types are canonical).
- series published.** Every gated commit
-
The counters at this checkpoint (
.run/P37/census/type_census.txt,census_t4c.log; controls 4/4).2171 lying declarations / 189 callees (+5092 K&R sites, +418 cross-binary apart)— from 98,648 / 1,609 at T1 (S107's end: ≈81,000 by the ledger; S108's census steps 13,832 → 8,830 → 2,367 → 2,171, each an instrument repair). Definitions 7,255 (527 layouts, 206 duplicate classes, 40 variant camps); cast sites 503,013 in 69,497 bodies (four forms + A; unchanged — T6's). Leverslever_census --check: 3,730 pin/asm sites, 3,730 marked, 0 UNMARKED(from 4,010;--strictstill FAIL by design: the 6,717 direct GTE statements + 314 per-TU asm macros are T6/T7's). The remainder of 2,171, by its ledger verdict (every row has one): 1,120DECL-KEPT parse error (type unknown to TU)→ T5; 593DECL-NONE no visible definition→ item (h); 417DECL-KEPT conflicting types elsewhere in TU→ T5/T7; 13syntax errorin800.c; 12void value not ignored(avoiddefinition whose callers use$v0— the return-type lie:func_80161208,func_801376E8,func_80150480,func_8017E3F0,func_801843E0, … a definition-side--callee --bodyeach, judged as one unit); 8+2 arity; 2 bytes; 2 DECL-CANON; 2 still-aliased. K&R sites apart: 5,092 over 155 callees (// K&R: n of m args (P37 …)on each line); cross-binary apart: 418 over 147 callees. Alias-defined functions: 133 / 149 back; the 16 kept = 10 jr-merge DIFFERS (func_80146A6Cfunc_8014C4ACfunc_8014F6F4func_801848DCfunc_80185EECfunc_8018A224func_8018A860func_8018AFD0func_8018B1DCfunc_8018CB18— the file-layout phase's) + 5 return-type lies (above) +func_8016BF50. Series:docs/levers.md(80 milestones,lever_progress --check OK),docs/readability.md(t4row: 8,830 at274223396— re-snapshot after (g)/(h) with the 2,171 line),progress.json/README fresh at the last publish (progress.py --check). -
What T2 proved on the bytes (the design inputs for T3; the full tables are the T2 log entry and
.run/P37/probe/*.md). (a) Rung 1 (body-local((P37S_<hash> *)base)->unk<HEX>with the type from the cluster layout; misaligned layout entries skipped; pointer fields only where the site's pointee equals the field's; sign-mismatch loads stay casts; the typedef inserted at file scope before the function) is byte-neutral on 126/139 judged bodies (90.6 %), 716 sites moved; 226 of 942 candidate sites (24 %) were skipped because the cluster layout cannot hold them (no-field 133, sign 44, width 33, index 13, negative 3) — T5's type-authoring residue. (b) The 13 DIFFERS are the/sasymmetry (COUNT/ORDER residuals, never REG): a converted store carriesMEM_IN_STRUCT_P, the body's bare fixed globals do not,sched.c:837's escape hoists a fixed load over it. Byte-read onfunc_801814AC(ov_SC05_010 :3030): fiveD_801C7E30sites as members + the+0x34store as a cast → IDENTICAL; the pointer global itself as a member fixes that store and moves ali v0,10elsewhere. The/sflag is a per-ACCESS dial (cookbook §458, §351). (c) Rung S2 (leave-one-out, then cumulative revert in source order, then minimise) closes 13/13 keeping 27 of 716 sites as casts — ≤2n+1 compiles, no agent. (d) S+A (levers stripped too) closed 0/5 lever bodies — unmeasured at this size; T6 measures it on all 1,980 lever bodies. (e) Declarations: the definition's ANSI signature written into a callee's lying declarations is IDENTICAL for 4,473/4,828 (TU, callee) pairs (92.6 %), 0 DIFFERS; 355 compile refusals = 136 arity contradictions (too few/many arguments→ the K&R sites), 121 conflicting declarations elsewhere in the TU (a repair must replace EVERY declaration of the callee in the TU), 98 unread causes (main'sAt top level:22; a#define NULLcontext line 14) — T3's solver reads full messages (R103). (f) Definition fold (typedef <Canon> <Local>;for a same-layout tier-1/2 duplicate): 12/20 TUs IDENTICAL, 8 COMPILE-ERRORstructure has no member named a/f0/v— an opaque-tier fold renames members, so the fold must rewrite the TU's member accesses too. (g) The layout engine agrees with cc1 on 5,283 file-scope definitions / 29,248 named fields (0 rejected, 0 unresolved) —restruct --audit-layouts; on the way two engine gaps were fixed (nested-paren__attribute__((aligned(4))), per-fieldaligned(N)) and 27 dead#ifndef BFM_ENGINE_TYPES_Hstandalone blocks (21 TUs) are now blanked by the census. (h) The oracle: the f3 control (func_801A4258in md_SC07_004 withs16 *p = &D_801F8870; p[1]…) is whole-object DIFFERS andmake build BINARY=md_SC07_004BYTE-IDENTICAL (87ac0de3…) — relocation SPELLING differs, linked bytes do not → T3's linked-relocation mode is required for global blocks/arrays;engine_types.hfan-out = 3,818 TUs / 3,975 objects in 35 s wall at -j16 (0.141 s/object), with 26 TRANSIENT compile errors at 16 threads (0 on re-run: retry a fan-out failure once). Oracle tags must contain no spaces (the scratch object path lands in the pipeline).judge_textwrites the file IN PLACE and restores it — two workers must never own one file; header judgements compile other workers' TUs, so headers run serially after the.cbodies. (i) Pricing (R41): T4 ≈ 1 unattended session (94k pairs, ~93 % mechanical, ~6.6k to the solver); T5 ≈ 1 session (5,995 in-.cdefinitions, ~60 % by alias, the rest with member renames; header batches of dozens per 35-s fan-out); T6 ≈ 1–2 sessions (69,497 bodies × 2 s + S2 on ~10 %; expected floor after S2 ≈ 4 % of converted sites kept + the 24 % the types cannot hold yet); T7 open-ended by decision 1. -
T3's engine — what exists and how it is used (the reference is
tools/restruct.py's docstring + SETUP §P37 S107).- Rungs: S (every typed base of a body →
((Unkstruct_X *)base)->unkK, orbase->unkK/D_x.unkKwhen the base is already declared with the type; CANONICAL types only under--apply, T2's localP37S_type under--try/--try-file; a site the type cannot hold is SKIPPED and counted: no-field / width / sign / index / negative / pointee / overlap / aggregate-field), S2 (the minimal kept-cast set: leave-one-out → cumulative revert → minimise), S+A (delever's ladder — rung A strip-all, rung B greedy — on the struct-spelled text; survivors' markers(P37 S+A <label>); a removed_mGTE lever's stale marker scrubbed; the lever row also appended to delever's ledger), X (pass_hint: SCHED-ALIAS / SCHED-ORDER / CSE-KILL / WIDTH / ADDRESS-FOLD / ALIGNMENT / REGALLOC / COUNT-OTHER / OTHER — a hint, never a verdict), R (the registryRECIPES: R1 the pointer global read as a struct member (§458), R2extern T X[](a18), R3 the walked pointer (f3; reloc-flagged); each returns candidates the oracle judges; a hit is adopted), D (every declaration of a callee in the TU → the definition's ANSI signature > the width-promoted form (s16 a→s32 a, what a K&R call passes) > every declaration()+// K&R: <n> of <m> args (P37 rung D <label>)when the TU's calls pass another count and the all-()form is IDENTICAL; ladder per TU = all callees at once then cumulative greedy; the definitions index = the TU's own file, its binary's dir, its headers, then main/resident (REFUSES when two definitions disagree); a K&R-marked unit is settled;--callee F --signature "ret F(params)"= a definition-side change judged on the definition's TU + every declaring TU as ONE unit), L (a file-scope duplicate of a canonical type → deleted when same-named identical text, elsetypedef <Canon> <Local>;+ member renames by the offset map; REFUSED when a renamed member name is also a field of another type visible in the TU). - The oracle:
judge_files({rel: text}, tag, reloc=)— every recipe of every file (a header's includers) compiled in place, whole-object equality against the snapshot; a DIFFERS falls tojudge_linkedwhen the job is reloc-flagged orreloc_only_diffsays the.textwords agree modulo relocation operands (the linked mode = the build's ownld/objcopy/trimon the candidate object against the snapshot's other objects, SHA1 vsconfig/check.<alias>.sha; ~10 ms); a fan-out COMPILE-ERROR retried once. The snapshot (--snapshot-baseline) REFUSES an object that does not reproduce from an untouched compile — run it only after a green clean fleet run; it also carries every binary's link inputs (_link/<alias>/,links.json).--linked-control(md_SC07_004func_801A4258) is the known-true + negative. - The ledger
.run/P37/restruct/ledger.jsonl: one row per unit (rung, tu, unit = fn |decl:<callee>|def:<callee>|fold:<name>@<line>,nhash_before/after, verdict, per-site rows MEMBER / KEPT(hint) / REFUSED / SKIPPED,bases,skips,residual,hint,levers,recipes,cause,needs_types); "done" = (rung, tu, unit, current hash) ∈ the latest rows' DONE verdicts;--redraw VERDICT…draws settled units again (e.g.DECL-KEPTafter T5's types exist);inflight.jsonis the only restore (--restoredrops the killed batch's rows). - The measured causes of a kept declaration (t3d1/t3d2, 16 of 258): 7×
func_800D20C0— its prototype namesPos800D20C0, a type local to the resident TU the overlay cannot see (needs_types; T5 makes it canonical, then--redraw DECL-KEPT); 1×conflicting types for func_800D2318 … prev: shared/ov/func_80168BDC.h:3— a per-function SHARED HEADER carries the lying spelling (rung D--headersmode judges the header on every includer); 8× K&R sites marked (too few arguments: the original's calling convention). T4's plan: rung D over the fleet by symbol space in cycles (tools/restruct_cycle.sh 1 N 50 D, detached),--headersbatches for the shared headers (serial, ~35 s per judgement on 141 includers), then the definition-side changes (--callee/--signature) from.run/P37/census/parked.tsv's 13 signature patches (e.g.func_800385C0:s16 a0→s32 a0, the patch text in.run/P36/agents/main__func_800385C0/scratch/signature.patch) with R22 per change; the 51 TU-CONFLICT rows ofconfig/dedup_exceptions.tsv; class E aliases (extern u16 aD_x __asm__("D_x")→ one typed declaration) and__builtin_abs→absare NOT yet generators in the engine — T4 adds them as rung-D sub-rewrites (the census records them: 5,749 aliases / 225 names; 144__builtin_abs). Pricing (T2, R41): ≈94k (TU, callee) pairs × 0.15–0.8 s ≈ 1 unattended session, ~93 % mechanical; the t3d1 batch measured 27 TUs / 258 units / 223 compiles in 31 s wall at -j12. - Known-true controls to re-run after any engine change:
restruct --selftest(48) ·--selftest --real(53: + calibration, the tree's own text IDENTICAL, a nop DIFFERS, the linked control, the macro proof) ·--try src/ov_SC05_010/ov_SC05_010_jr_80180F84.c func_801814AC --base global:D_801C7E30 --recipes→ DIFFERS · S2 kept 1 (+0x34) · R1 IDENTICAL ·--try-file src/ov_SC06_008/ov_SC06_008_jr_8017C294.c func_8017E830→ S IDENTICAL (2 members) · S+A 6 levers off (nothing written). - For T6 (noted S107): the 6
gte_rtv0tr_mlevers of func_8017E830 come off with or without the struct today — a P36 T5 leftover class; a targeted regen over the 450 GTE_mvariants (delever's rung A per body, orgte_consolidate --sweepon the current tree) is cheaper than meeting them one S+A body at a time.--write-types --top 6previews the two big types:Unkstruct_800B5CB890 fields / 44 overlaps,Unkstruct_80126B58146 fields / 28 overlaps + 1 misaligned — the overlaps are the map's width conflicts (T5: union vs split per offset).--audit-typeson the legacy header: 26 violations, all legacypad<SIZE>names → T5's rename list.
- Rungs: S (every typed base of a body →
-
The instruments changed this session (all committed; SETUP §P37 S108 has every option).
tools/restruct.py:defs_visible(+ the sibling TUs' shared headers — the 10,495-row blindness; + the fleet-unique third level_fleet_unique_defs),unit_call_counts(arity from the TU AND its included bodies; the definition-head test),--unalias(data-typed declaration of the real name → the prototype, incl.extern char f[];; a header-side arity error marks the INCLUDING TUs; escalation counts attempts),--callee --body+--with REL=FILE(caller-body edits in the same unit) +--map-data(per-copyD_renames; count mismatch refuses) + header-borne definitions excluded from--all-defs,--redraw VERDICT[:cause].tools/argcheck.py:_ALL+resolve_definition(per declaring binary;cross_binary),kr_marked,DEFwith leading blanks, the K&R loop always feeds_ALL.tools/type_census.py+tools/readability_progress.py: K&R and cross-binary counted APART (kr_sites/cross_binary+ callees; two TSV columns).tools/delever_oracle.py --snapshot-baseline: REFUSES an empty/shrunkenbuild/.tools/restruct_cycle.sh: no fleet run whensrc/is unchanged after a batch. One-off drivers (ignored, commands in the log):.run/P37/restruct/sig_cycle.sh(entries list at its top;--tufallback),strip_banners.py. Known-true controls to re-run after any engine change:restruct --selftest(54) ·--selftest --real·type_census --selftest(21) ·defs_visible('src/ov_SC05_000/ov_SC05_000_jr_8017BEBC.c') ['func_80147514']→ the shared header ·defs_visible('src/md_MAIN_013/md_MAIN_013.c')['func_80128EA8']→ the fleet-unique header ·argcheck.resolve_definition('func_800CB8A4', 'src/md_MAIN_026/md_MAIN_026.c', …)→ its own(void)·unit_call_countson ov_SC01_077_jr_8015C32C.c / func_801483E8 →([0], ['src/shared/ov/func_80161124.h'])·call_arg_countson ov_SC07_007_jr_8015B950.c / func_80161B18 →[0]. -
Files and artifacts. Evidence (tracked):
.run/P37/restruct/{ledger.jsonl, batch_*.json, apply_*.log, run_*.log, cycle_t4[e-j].log, cycle_t4sig*.log, kept_ua*.txt, with_*.c/.h, body_func_80188A30_s32.c},.run/P37/baseline/r22_*.log(every gate),.run/P37/census/ census_t4*.log+type_census.{json,txt}. Ignored:argcheck_cache.json,sig_cycle.sh,strip_banners.py, the snapshot.run/P36/delever/baseline/(7,428 objects +_link/; at the last batch's tree — refresh after the next green R22 with--snapshot-baseline, then--calibrate ov_SC04_011 ov_SC03_015 md_SC07_004 main -j 16;--applyrefuses on a stale one). Docs this session: accelerators P37 S108 (ten), decision log P37 S108, cookbook §459, SETUP §P37 S108, cookbook index (1,177), story §10 + retrospective §7 advanced, the timeline regenerated (78 rows). Still owed at T9:docs/actor-struct.md(+0x108/+0x10C are 4-byte), the §396(a) correction, atools-healthrun (not re-run this session; the kit corpus will needmake kit-corpusafter the SETUP/cookbook edits — atool_census --check/kit_coveragered is expected until then), the dictionary rows for the new options (restruct/argcheck rows exist; no new tools). -
Environment, commands and the gotchas of this session.
~/bfm-decompon ext4;.venv/bin/python; every buildJOBS=16/-j. Ghidra MCP not needed until T8. R22:make clean && make extract-all JOBS=16 && make check-all JOBS=16(≈90 s; read the exit code). Cycle:setsid nohup bash -c 'LABEL_PREFIX=t4_ TASK=T4 CENSUS=0 tools/restruct_cycle.sh START END 400 D; echo "cycle exit=$?"' > .run/P37/restruct/cycle_<x>.log 2>&1 &(+REDRAW="DECL-NONE:visible"/HEADERS=1 LABEL_PREFIX=t4_H); it refreshes the snapshot + calibration itself when HEAD moved and stops on "nothing drawable". Unalias:--apply --unalias NAMES --label L -j 12(--applyis required). Signature:--apply --rung D --callee F --body FILE [--all-defs [--map-data]] [--tu TU] [--with REL=FILE …] --label L -j 12. Gotchas: (1) stop a judge withkill -INT <pid>and WAIT for its exit (ps; ~2 min — it finishes its in-flight units) BEFORE--restore; a restore run early consumesinflight.jsonand the judge's later writes have no tool-side restore (S108: 6 files reverted by hand, 197 orphan rows dropped). (2)pgrep -f/pkill -fnever with a literal your own command line contains (exit 144 — twice this session); bracket a character:restruct_cycl[e]. (3) Never editCURRENT_PHASE.mdwhile a cycle is between its R22 and its commit (its python rewrites the file); checkpsformakefirst. (4) A--snapshot-baselineonly after a GREEN clean fleet run (build/ is the tree's); it now refuses an empty build/. (5)DECL-NONEis a DONE verdict: a settled row is redrawn only with--redraw— use theVERDICT:causekey, never bareDECL-NONE(it redraws every "already canonical"/external pair: the t4_D21–D36 cost). (6) A "flat yield" is not "nothing drawable": bucket the remainder by ledger verdict before stopping a cycle (themd_*modules were 3,700 never-judged pairs). (7) A pack's "one caller" is a claim:grep -rnE '\bfunc_X\s*\(\s*\)' srcbefore a signature unit. -
T4's residue, by name, for T5/T7 (each with its cause in the ledger). T7: the
md_SC07_004pairfunc_801A1E94/func_801A5C44(the zero-argument callerfunc_801A6A18(void) { func_801A1E94(); }passes its OWN incoming$a0— re-sign the caller one level up in the same--withunit); the other same-address copies offunc_80185578(ov_SC03_014),func_80188DF4(ov_SC02_011 — a caller passes MORE arguments; ov_SC03_104),func_8017FC5C(ov_SC04_002 — a short caller),func_80183CC4(ov_SC03_006/029/090 — per-overlay data with 1/0/4 symbols vs the pack's 1: per-copy bodies read against their bytes); the 5 return-type lies (--callee F --bodywith thes32head, callers in the unit);func_8016BF50; the 10 jr-merge functions (the file-layout phase's, not T7's). T5: the 1,120parse errordeclarations (types the TU cannot see — canonical types, then--redraw DECL-KEPT); the 417conflicting types(a second declaration elsewhere in the TU — most will fall to the canonical files). T6: 1,723ALIAS-KEPT "second typed view"data aliases (aggregates), 253 kept from S107.
Approved plan (verbatim, gate 1 — 2026-09-11)
Phase 37 — the structs phase: the original's types back into the matched C (v2.2.0 → v2.3.0) — gate-1 plan
Gate 1, 2026-09-11, plan mode at Max (Tier 1). Drew's Gen3 order: dedup (P35) → pins (P36) → structs → names. Owner decisions recorded at the end. On approval: T0 writes this plan verbatim into
phase-ends/CURRENT_PHASE.md, builds the harness task list (R28), and execution is one task at a time (P3–P5). Precondition: Drew's Phase-36 close commit + thev2.2.0tag (the block inPhaseEnd_Phase36.md§🛑) — the close artifacts are still staged/uncommitted in the tree (git status:R CURRENT_PHASE.md -> logs/Phase36.md,?? PhaseEnd_Phase36.md,M DIGEST.md…); T0 refuses to start on a tree that still carries them.
Context — why this phase, and what it is really about
The Gen3 charter (docs/gen3-standards.md §2 rule 4, §4 step 3; docs/gen3-handoff.md §2 item 1, §2.1) says: types come from the code,
names from observation — unify the drafter-invented struct definitions into one per shape, turn raw address casts into declared, typed
data, and do it before any field is named. R95 (the S91-b doctrine) is the binding rule: types are a banking lever and a width lever;
a canonical type file; widths proven by the bytes; no duplicate definition or raw address cast.
Phase 36 changed what this phase is. It took the compiler-forcing levers from 53,234 to 4,010 and found that the last third of the residue
is not codegen the pin lane can read its way out of — it is wrong signatures (a (void) function that reads $a0; a void one that
returns $v0; an s16 parameter the bytes use as s32), missing struct types (the compiler's own alias tests decide by
MEM_IN_STRUCT_P), carved data a struct copy would address in one relocation, and one GTE spelling. Its evidence is byte-proven:
d10's register union (ov_SC05_001__func_8017EF88: three pins + two keep-alives → 0 with a union { struct { s16 x, y; } v; s32 sxy; }),
a18's extern u16 X[] (the MEM_IN_STRUCT alias escape, sched.c:837-839), f10's body-local structs (ov_SC06_006__func_80180AE8/FE8:
"the aggregate-vs-scalar MEM flag is the whole lever"), f3's s16[3] arrays (identical after linking), func_80186CE0's 20-byte struct
copy over five carved word symbols.
The fact the plan is built on: struct spelling is not byte-neutral in gcc 2.7.2. *(T*)(p+k) gets no /s; p->f, q[k], *(Blk*)p
get it; the scheduler's alias escape (sched.c:830-865) and cse's kill table read that flag (docs/gcc-2.7.2-map/cse_expr.md §4;
cookbook §30/§351/§379/§456/§469). So this campaign is gated exactly like a match — object oracle per TU, R22 per batch — and its
residue is informative: a site where the member spelling moves bytes is a site where the original's shape was different, and the
marked lever that survives beside it is the P36 residue this phase is meant to close. Phase 17's "types are byte-neutral" (0/10/2 on a
structural-miss sample) measured m2c drafting, not member-vs-cast spelling in a matched body (docs/struct-core-pivot.md, its caveats).
Nothing in this phase invents a name. Struct and field names are placeholders (owner decision 2) or citations of recorded evidence
(docs/memory-map.md §3.4, docs/actor-struct.md); meaning-naming is Phase 38.
The population, measured at gate 1 (grep/scan census, 2026-09-11 — T1 re-derives it with a self-asserting tool, R32/R37)
| Unit | What | Count | Where / command | Notes |
|---|---|---|---|---|
| U1 definitions | struct/union bodies in src/shared/engine_types.h |
~1,180 (1,089 typedef struct + 90 tags + 1 union; the charter's 1,232 counts 53 forward decls) |
grep -cE '^typedef struct' src/shared/engine_types.h |
103 exact-duplicate groups cover 919 of 1,162 names; 91 layout groups cover 946 (s32 w[8] ×68 names, u16 x,y,z,w ×99, s16 v[4] ×56, SVECTOR ×50); 467 double-suffixed Name_ADDR_ADDR; 123 dead names |
struct/union bodies inside .c files |
5,547 (3,990 file-scope, 1,557 block-scope) in 1,725 of 4,121 TUs | grep -rhoE '^\s*(typedef\s+)?(struct|union)\s*\w*\s*\{' --include='*.c' src | wc -l |
1,900 distinct names; Prim_8016E7C8 defined in 1,192 files, Ent 394, Blk8 314 (the "carried decl layer" banner in 3,546 TUs); 32 names with >1 body; lift_types.py scans only src/ov_*/*.c |
|
in per-function shared headers / *_shared.h / include/ |
52 / 24 / 2 | |||
| U2 cast sites | *(T *)(…) (the readability regex) |
411,850 | tools/readability_progress.py |
+ 26,279 *(T *)ident, 14,491 ((T *)e)[i], 19,542 M2C_FIELD( — uncounted today (R32 gap); struct member reads 177,902 |
| by base | first parameter a0/param_1/arg0 188,844 (46 %) on 289 offsets (+0x20 pointer 18,215; +0x2, +0x1C, +0x2C, +0xE, +0xA, +0x6, +0x34, +0x234 …); (s32)matrix + k 53,797; D_/&D_ bases 47,178 over 6,040 symbols; nested 18,282 |
one entity type owns half the debt; the player block is 64 bare D_80078Exx globals (D_80078E78 6,792 mentions) with a documented field table and no struct in src/ |
||
absolute-address casts *(T *)0x80… |
138 | grep -rhoE '\*\)\s*0x80[0-9A-Fa-f]{6}' src | wc -l |
the charter's low-hanging fruit | |
| U3 declarations | extern function declarations | 4.28 M (4.24 M file-scope) per-function blocks; 12,120 declared names; 3,894 callees with >1 parameter-list spelling | python line scan | no canonical header exists; the Phase-16 global header broke matches (struct-core-pivot.md) |
| lying call declarations | 98,648 over 1,609 callees (91,357 (), 7,291 (void)/narrow; 33 in pinned bodies) |
tools/argcheck.py |
decl_repair.py repaired 16,759 free (S102); PROMOTE_PROTOTYPES (mips.h:1153): callee bytes depend on the DEFINITION's widths, caller bytes on arity |
|
| ledgered TU-CONFLICT classes | 51 (16 int-from-pointer, 19 conflicting types for a function, 3 for a D_, 4 undeclared, 4 too few args, 1 redefinition) |
config/dedup_exceptions.tsv |
the S1 ledger's types-phase inheritance | |
h_text groups (bytes vary per binary through the TU's declarations) |
38 | config/dedup.us.yaml |
gate every member | |
| U4 P36 residue | marked pin/asm sites | 4,010 = 1,637 drawable RESIDUE + 1,080 minimum-lever banks in PARK + 593 parked RESIDUE + 450 GTE clobber variants + 94 arg-only pins + 83 whose latest ledger row is a failed attempt + 24 minimum-lever not in PARK + 18 + 13 asm-body + 10 drawn + 8 file-scope | tools/lever_census.py --check; the ledger .run/P36/delever/ledger.jsonl |
24 parked classes / 453 bodies (6 with patch files, 8 more with whole-TU scratch copies, func_80180200 inside ov_SC03_115__func_8017FC5C/); heads func_8013CF68 ×134 (la), func_80178970 ×134 ($2); the five S103 head classes 933 sites; func_8013D9B0's 268 markers are gte-unsigned, OUTSIDE the 4,010 (a census inconsistency T1 resolves); the gte_stORGB respelling (include/gte_inline.h:237; sotn's header adds 7 project-local GTE macros) |
| U5 P36-deferred classes | E asm-label aliases extern u16 aD800B9A02 __asm__("D_800B9A02"); / F __builtin_memcpy 302 + __builtin_abs 297 / G __attribute__((packed/aligned)) 76 |
8,331 (6,196 file-scope) / 599 / 76 | the P36 gate-1 table | E = a second typed view of one symbol (a union/array/struct in truth — a18, f3); F memcpy = a struct assignment (expand_block_move, §391 alignment); G = a wrong layout |
| U6 instruments | delever_oracle.py (object oracle, header-capable via delever.includers(); engine_types.h reaches 3,818 TUs ≈ 3,900 objects at 0.08–0.14 s each), delever.py's engine pattern, cdecl.py, pycparser 2.23, argcheck/decl_repair, lift_types/uniquify_type/build_engine_types, canon_sig_reconcile, conform_decls, decl_prior, ram_probe.py, ExportAnnotations.java (type rows supported: struct/union/enum/typedef/fndef with fields — 0 tracked today) |
nothing exists that infers a layout from base+offset+width evidence, rewrites a cast to a member, or merges same-layout names |
The reference read (R106, X2 — data): sotn-decomp holds 479 typedef structs for a whole game, 26 raw scalar casts and 2,335
LOH/LOW-style reinterpret macros, one Entity (0xBC) + a 367-arm Ext union, /* 0xNN */ offset comments, unk<HEX> fields,
anonymous bit-field padding, Unkstruct_<addr> for the unknown, SYNC_FIELD offset asserts; its declarations are per-overlay headers
(src/dra/dra.h: 194 prototypes + 152 externs, placeholders typed), no per-TU extern lists.
The oracle and the invariant
- Inner oracle (per candidate, 0.1–1 s):
tools/delever_oracle.py— the TU compiled IN PLACE through the build's own rule against the snapshot baseline (--snapshot-baselineat T0; whole-object equality; calibration 100 % untouched + a positive control before any verdict, R39/R56/R57). A header edit is judged on EVERY includer (delever.includers()), serialized; twins on both objects; the 38 h_text bodies on every member;-O0TUs and main's pad stage through the same recipes. - Outer gate (per batch, ≈90 s):
make clean && make extract-all JOBS=16 && make check-all JOBS=16→check-all: 218 passed, 0 failed of 218, read by exit code withpipefail(R22, R97); commit the moment it is green with the log line and the 🛑 headline (R42, R101). - The type invariant (new, asserted from T1 on): every struct definition in the canonical type files has a computed layout; no two
definitions share a layout under different names (VARIANT camps are DIFFERENT types under different names, §64a); every converted site's
(base type, offset, width, signedness)is a field of its type (theSYNC_FIELDequivalent, run by the census, not by the PC build); every raw cast that remains is counted and, in a lever-bearing body, ledgered with its pass. - The declaration invariant: a function has one canonical prototype, derived from its DEFINITION; a TU's in-scope declaration equals it wherever the object is unchanged; where the bytes refuse, the site keeps its local declaration with its cause named in the ledger and the count published — never a silent lie (the P36 doctrine: ban the silence, not the lever).
The ladder (deterministic first; tokens last)
| Rung | What | Cost | Who |
|---|---|---|---|
| L layout | parse every definition (canonical header + every .c), compute o32 layouts, hash; fold exact/layout duplicates onto one canonical name (majority body; address-suffixed placeholder where the purpose is unknown); strip local copies where what becomes visible is layout-identical (lift_types' three laws, extended to .c file-scope and block-scope, main and md_*) |
compiles only | tool |
| D declarations | per TU: the canonical prototype (K&R-read from the definition) replaces each per-function extern where the object is unchanged; the free decl_repair set; asm-label aliases replaced by one typed declaration; __builtin_abs → abs; the 24 parked signature patches (definition-side fixes: s16→s32, (void)→(s32), void→void *) with their callers |
compiles only | tool |
| S struct spelling | per body, per base with a type: *(T*)(base + k) → base->unkK (nested, address-of, strides); M2C_FIELD → members; ((T*)x)->f → typed base; __builtin_memcpy(&a,&b,N) → a = b; carved word runs → one record table (func_80186CE0, f3); the 138 absolute casts → declared symbols; oracle per object |
1 compile per body | tool |
| S+A the struct hypothesis | for a lever-bearing body: rung S with the body's marked levers stripped, then greedy (P36's rung B) — the levers come off where the struct was the missing piece | ≤ sites+1 compiles | tool |
| X classify | a body whose member spelling moves bytes: the residual classified by pass (sched alias escape / cse kill / width / other — delever_search.py's classifier) and ledgered; the plain cast kept MID-CAMPAIGN, counted, and queued for R then E — decision 1 says it does not stay |
0 | tool |
| R recipes | the shapes the record already names (u16 X[] vs scalar, the s16[3] array, the register union, the cast-at-the-shift, p = &tbl[i] to drop /s, the one-struct-pointer rule §357) tried mechanically per X site; the rung grows after every agent landing (harvest → toolify) |
compiles only | tool |
| E agents | what R leaves, if owner decision 3 allows: one agent per TU batch with the pack (body, target listing, the ledger's X sites, alloc_table/cc1_dumps_tu, the /s model, METHOD_S103 steps 1–25, §454–§457, a known-true run on the start text at every landing — P36 candidate (c)); deliverables early (R67); the tool judges; harvest → toolify → regen before the next draw |
tokens | agents (Agent tool; Drew's cap; his word to start) |
| M mark/ledger | every remaining raw cast in a lever-bearing body and every kept local declaration carries its ledger row; the census asserts 0 UNLEDGERED; lever_census --check keeps 0 UNMARKED, and --strict is asserted the day it passes |
0 | tool |
Tasks (plan order; one commit each; ☐ → ☑ with the verify line quoted in the log)
- T0 — Precondition, baseline and the phase file (xHigh; low for bookkeeping). Refuse to start until the P36 close commit and
v2.2.0are ingit log/git tag; R22 clean fleet at the open (.run/P37/baseline/r22_t0.log);delever_oracle --snapshot-baselinere-taken on that tree +--calibrateon two overlays + main + one module;.gitignoreP37 evidence allowlist (.run/P37/{baseline,census,probe, restruct,decls,agents}/, text only, by-contents form R84);phase-ends/CURRENT_PHASE.mdfrom this plan; harness task list (R28). Verify: the R22 line; the calibration line;git statusclean after the commit. - T1 — The type census
tools/type_census.py(xHigh; its layout/cluster model reviewed at Max). Derived fromshare_census's instance records (R33); a comment/string-aware site parser (thelever_censusapproach; pycparser where a whole declaration must be understood,cdecl.pyfor declarators); (a) definitions: every struct/union/typedef fleet-wide with its o32 layout hash, duplicate classes, VARIANT camps, dead names, shadowing (.cnames that also exist in the header); (b) cast sites: all four forms +M2C_FIELD, base class (parameter / local /D_/&D_/ absolute / nested / member), offset, width, signedness, load/store, address-of; per-base offset maps across functions (the clustering input); (c) declarations: every function's definition signature (K&R-read), the in-scope declaration per TU, the lying set (argcheckas a library), the 3,894 multi-spelled callees, the asm-label aliases, builtins, attributes; (d) the P36 inheritance: the 24 parked classes with their reasons in ONE file (.run/P37/census/parked.tsv: fn, alias, copies, sites, what it needs, the patch path) — the record has no such list; the func_8013D9B0gte-unsignedinconsistency resolved (counted or the markers dropped, on the bytes); coverage (R32): sites found == the raw regex totals for each form, else FAIL; controls: the player block's live-verified fields (+0x8C s32,+0xB2/+0xB4/+0xB6/+0xB8 u16,+0x108/+0x10C s16) recovered from theD_80078Exxaccesses;MATRIX(32) vsMATRIX_L48(48) as two layouts; one TU-CONFLICT row's diagnostic reproduced. Output.run/P37/census/*.json/.txt;progress.pypublishes atypesblock (definitions, distinct layouts, duplicate classes, cast sites by form, lying declarations, aliases) + the README sentence (R75);readability_progress.pygains the uncounted forms (a datedcorrectionsentry). Dictionary + SETUP rows (R87, R21);lever_census's three stale controls re-keyed (R85). Verify:type_census: <D> definitions (<L> layouts, <C> duplicate classes, <V> variant camps) · <S> cast sites in <B> bodies over <K> bases (<F> forms, coverage OK) · <Y> lying declarations / <Q> callees · controls 4/4. - T2 — The probe (R37) (Max). Three stratified probes on the calibrated oracle, each with denominators: (i) struct spelling — ~150
bodies over the top bases (the first-parameter entity type, the player block,
(s32)matrixMATRIX/SVECTOR bases, threeD_record tables, the shared headers): % identical after rung S, % differing, of the differing how many close under S+A (levers off), the residual classes by pass; (ii) declarations —decl_repair-style judgement of the canonical prototype per TU on ~300 TUs across spaces: free / byte-changing / refused, causes histogram ((void)truncation, width, arity, K&R); the 24 parked patches applied and gated as the probe's known-true set; (iii) definitions — the fold of the 103 exact + 91 layout duplicate groups and the.cfile-scope copies on 20 TUs: textual fold / layout fold / VARIANT; seconds per object; objects per header edit. Prices T4–T7 with denominators (R41) and fixes the rewrite table. Evidence.run/P37/probe/. Verify: the probe table in the log with its commands. - T3 — The tools (Max design; xHigh finish).
tools/restruct.py(rungs L/D/S/S+A/X/R; thedelever.pypattern: positional token-exact rewrites with REFUSAL on mismatch (R43), the file as the write unit,--plan/--apply/--class/--only <base|tu|type>/--batch/--batches 1/--label, workers own whole TUs, header edits serialized and judged on every includer,inflight.jsonthe only restore (R102), the ledger.run/P37/restruct/ledger.jsonlkeyed alias+tu+function+body-hash (R48) with per-site verdicts MEMBER / KEPT(pass) / REFUSED(reason) / DECL-CANON / DECL-KEPT(cause), progress logs (R55), selftest fixtures for every form + a known-true no-op run (a body already spelled with members), negative controls (R39));tools/struct_layout.py(the o32 layout computer + the field assertion, shared with the census); the canonical type files' writer (offset comments in hex,unk<HEX>fields,// size = 0x.., the PsyQ ground-truth block preserved, one file per symbol space —src/shared/engine_types.hstays theov/resident file;src/shared/main/types.h,src/shared/<slot>/types.hadded; main's and the modules' TUs gain the include); the named reinterpret macros ininclude/common.h(sotn'sLOH/LOW/…form, each proven byte-identical to the cast it replaces);tools/restruct_cycle.sh(batch → exit code → log entry → commit → R22 every N batches; DETACHED with a progress log, never a harness background task — R115). The Plan agent's stress-test lands here as design notes. Verify: selftest; the calibration line; one batch on one overlay end-to-end with R22 green. - T4 — The declaration layer (xHigh; unattended cycles). Rung D over the fleet by symbol space: the canonical prototype per TU where
free; the 16,759-style free repairs; the 24 parked signature changes landed with their callers (definition-side fixes, then the fleet's
declarations, gated — their levers come off: the first P36 residue bucket falls); the 51 TU-CONFLICT rows resolved (a shared header
re-exemplared or a declaration conformed) or re-ledgered with the byte cause; class E aliases → one typed declaration where free (a symbol
needing two widths is an aggregate → T6);
__builtin_abs→abs; the byte-proven K&R sites marked and counted apart; the byte-changing remainder ledgered with its cause (definition-side fixes queued for T6/T7) and published; the 3,546 TUs' "carried decl layer" banner blocks deleted as their contents become canonical. Batches < 10 min; R22 every 2 batches; one commit per batch with the census line. Rules check (P6) after T4. Verify per batch:restruct D: batch <k> — <n> declarations canonical / <m> kept (<causes>) in <t> TUs; gated <x>/<x> identical; R22218 passed. - T5 — Struct unification (Max for the head types' layouts and the naming of the canonical files; xHigh to run). Rung L: the 103 exact
- 91 layout duplicate groups in the header and the 5,547 in-
.cdefinitions folded to one canonical definition per layout, written in the final style (owner decision 2), the VARIANT camps uniquified (§64a), the 123 dead names deleted, the PsyQ-identical layouts under Sony's names (MATRIX/SVECTOR/VECTOR/POLY_*),MATRIX_L48kept as documented; the entity type behind the first parameter and the player block's struct authored from the census's evidence (fields typed by width, namedunk<HEX>or by the cited record); main andmd_*TUs onboarded to their canonical file. Every step oracle-gated; R22 per batch. Verify:type_census: 0 duplicate definitions (<L> layouts = <D> definitions, <V> variant camps named apart); 0 dead names; controls 4/4; R22218 passed.
- 91 layout duplicate groups in the header and the 5,547 in-
- T6 — The cast campaign (xHigh; unattended cycles; largest leverage first: shared headers → the first-parameter entity type → the player
block and the top
D_record tables → MATRIX/SVECTOR bases → the rest). Rungs S / S+A / X / R over the population; the 138 absolute casts → declared symbols;M2C_FIELD→ members;__builtin_memcpy→ struct assignment; carved word runs → record tables (carve-state edits under R60:interleave_check+pads_audit); the lever count falls with the struct hypothesis and is attributed per site ((P37 rung S+A)). Batches < 10 min; R22 every 2 batches; the readability series and the lever series fall per commit. Rules check (P6) every 4 batches' worth of tasks. Verify per batch:restruct S: batch <k> — <n> sites → members / <m> kept (<pass histogram>) in <b> bodies; levers −<l>; gated <x>/<x> identical; R22. - T7 — The residue lane (owner decision 3; the coordinator at Max, agents at Drew's cap, NO Ultracode wave without his direct approval —
the S98 rule). Rung E over the X residue and the P36 heads, TU-batched cheapest-residual-first; the harvest → toolify →
regengate between draws (the recipe rung R grows; a mechanical shape sweeps the residue for free); the residue re-bucketed by what it needs at every landing (P36 candidate (k)); the stop rule per owner decision 1. Verify per landing: the agent's verdict on the bytes, the known-true run of every registered recipe on the start text,lever_census --check0 UNMARKED, R22 per bank. - T8 — The gates and the Ghidra mirror (xHigh).
type_census --checkinmake tools-healthnext tolever_census(0 duplicate definitions; every converted site a field of its type; 0 UNLEDGERED kept casts in lever-bearing bodies; the parked list empty or re-ledgered) + P36'sattribution_checkfolded intolever_census --check(every marker names its instrument — candidate (g));progress.py/readability_progress/lever_progresspublish the close snapshot (R75); the canonical types into Ghidra: a headless step that authors the canonical struct definitions into the tracked programs (from the C headers viacdecl/struct_layout→ theExportAnnotationstyperow form), exported toconfig/ghidra/*.jsonl,tools/ghidra_rebuild.sh --proofPASS (R9; MCP stopped, R23). Verify:tools-health: OKwith the new rung;--proofPASS for the programs that gained types. - T9 — The record (xHigh). Cookbook § (the
/scampaign's byte findings by pass; the declaration causes; the shapes the lane produced; the §396(a) correction with its bytes — the refuting body is recorded inov_SC03_110__func_801800F0/mechanism.md:64-70, owed since S104); decision log P37 (R31); accelerators; SETUP rows for every tool (R21); the wiki (a "The type layer" page;Where-the-project-goes-nextitem 3 + the table row;Verification-and-progress; the how-to's integration chapter);gen3-standards.md§4 step 3 +gen3-handoff.mddated snapshots;docs/levers.mdanddocs/readability.mdrendered;docs/tool-index.md+ the kit corpus regenerated (tool_census --check,kit_lint,kit_coveragewith the R107–R117 dispositions);doc_links --strict0/0;make tools-healthOK. - T10 — Close (Max; fresh session or Drew's call). R22 218/218 from clean; tools-health OK; PhaseEnd_Phase37.md + DIGEST §0/§2/§3 + the log archived (R19) + kit corpus; left uncommitted for Drew's close commit (R6); v2.3.0.
What "zero" means, counter by counter (owner decision 1 = grind to zero; each definition is honest AND reachable)
- Raw casts → 0. No
*(T *)(…),*(T *)ident,((T *)e)[i]orM2C_FIELD(insrc/(all four forms the census counts). Every base+offset access is a member of a typed base; every genuine REINTERPRETATION (the original reading a word as two halves, a struct as bytes) is a union field or one of a small set of named macros (sotn'sLOH/LOW/LOHU/…form, defined once ininclude/common.h), which the census counts apart as "reinterpret sites" and lists per macro — never a bare pointer cast on a sum. - Lying declarations → 0. Every call site's in-scope declaration is the callee's canonical prototype. A byte-proven K&R call (the matched
caller passes fewer arguments than the definition takes and every spelling of a prototype moves its bytes) is not a lie about the callee — it
is the original's calling convention: it keeps a
()declaration carrying// K&R: <n> of <m> args (P37 rung D, <TU>), is counted apart ("K&R sites") and published. A definition proven wrong by its own bytes (a(void)that reads$a0, avoidthat returns$v0, ans16the bytes treat ass32) is FIXED at the definition (the P36 parking signals, §456). Width rule (verified intools/reference/gcc-2.7.2/ c-typeck.c:1740andfunction.c:3664-3676): underPROMOTE_PROTOTYPESa prototyped narrow parameter is converted in the CALLER (a possibleandi/sll-sra) and narrowed again at the callee's ENTRY — so the callee's entry code is the oracle for the definition's width (no entry narrowing ⇒ the parameter iss32, fix the definition), and a caller whose bytes lack the prototype's conversion while the callee narrows is a K&R site, not a lie. - Levers → 0.
lever_census --check --strict: 0 register pins, 0 asm statements outsideinclude/gte_inline.h, 0 per-TU asm macro definitions. A GTE variant that is a legitimate coprocessor sequence (a three-op load, a respelled store —gte_stORGB) becomes a project-local macro in the one GTE header under a Sony-style name (Drew's S104 ruling (b); sotn'slibgte.hadds seven such); a clobber-only_msteer is a lever and is closed by the shape (the struct hypothesis) — it may not be re-homed as a macro. - A function is identified by its DEFINITION, not its address. Same-address different-body overlay functions are different functions with their own prototypes (the 38 h_text bodies prove the original overlays' declaration environments differed); the canonical prototype is keyed by (symbol space or binary, address, body) and the fleet-wide form applies only to shared/resident/main definitions.
- The phase does not close while any counter is above zero (Drew, gate 1). T7 is therefore open-ended; every landing re-prices it with denominators, the residue is re-bucketed by what it needs (R117), and Drew may amend the rule as he did at P36 S104 — the plan follows his latest word and records it.
Milestone (gate 2 — what Drew confirms, each with its literal output)
- 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. - Casts:
type_census --check→ 0 raw cast sites in all four forms; reinterpret sites counted apart by macro; the player block and the first-parameter entity type are structs insrc/; the counts published in the readability series with the dated snapshot (R75). - 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.
- 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 --strictunchanged (the 1998 routines untouched). make clean && make extract-all JOBS=16 && make check-all JOBS=16→check-all: 218 passed, 0 failed of 218(R22);make tools-healthOK with the new rung;ghidra_rebuild --proofPASS with the types; the record (T9), this PhaseEnd, the DIGEST append, the log archived; v2.3.0.
Rules at gate 1 (P10) — Drew accepts, modifies or rejects (ratified by the plan approval unless vetoed)
PhaseEnd_Phase36's candidates (a)–(k), operated through P36, proposed as R107–R117: (a) ban the silence, not the lever — a lever is allowed only marked, ledgered and published from the first bank, with a one-compile bank-time trial without it; (b) a generator ships with a negative-control corpus and a regen pass reports its refusal reasons as a histogram; (c) at every landing run every registered family on the agent's START text before banking; (d) a scorer's target is the tree's own bytes compiled by the build's own tail, never a disassembly — a known-true case before any campaign; (e) scratch is keyed by the unit of work, never by a worker tag or a file; (f) a gate's baseline is a snapshot, not the build directory; (g) a lever's marker names its PASS and its INSTRUMENT, asserted by an attribution check at the close; (h) a ledger's "done" is per body (unit, function, after-hash), never by text alone; (i) a long unattended run is DETACHED with a progress log, never a harness background task; (j) a marked ordinary-C fake is counted apart from levers and never an orphan; an invented condition, dead store or dummy reassignment is never banked; (k) a "stalling?" question is answered with the residue bucketed by what each bucket needs before any plan is proposed.
Effort / sessions / budget (R41)
Effort per task (R7): Max for T2, T3's design, T5's head-type layouts, T10; xHigh for T0, T1, T3's finish, T4, T6, T8, T9; T7 per
owner decision 3 (agents at Drew's cap; the coordinator at Max; Ultracode never without his direct approval, R27 + the S98 rule). Max is
session-only — re-apply each session. Sessions: T0–T2 one; T3 one; T4 one (compute-bound cycles); T5 one; T6 one to two (a 400k-site
campaign at ~0.1 s per object is compute, not tokens — the header fan-out is the cost: ~3,900 objects ≈ 6 min per engine_types.h edit at
-j16, so header edits are batched); T8–T10 one. Mechanical floor 6–7 sessions; T7 is open-ended by decision 1 (to zero) — priced by T2
(X residue × measured tokens per close; P36 measured ≈3.5 M tokens per 56 classes at S105) and re-priced at every landing with denominators.
P36 was priced 3 + open-ended and took 9 sessions / 575 commits / ~15–20 M agent tokens; this population is larger (412k casts vs 53k
levers) but the mechanical fraction is expected higher (member spelling on a base with no fixed-symbol interplay is byte-neutral) — T2
measures it before T4 starts.
Evidence and docs
.run/P37/baseline/ (R22 + tools-health + calibration logs) · census/ (json/txt, parked.tsv) · probe/ (the three probe tables) ·
restruct/ (ledger.jsonl, batch records, apply logs) · decls/ (the per-TU declaration judgements) · agents/ (packs, mechanism.md). Text
only, nothing ROM-derived (R74).
Deferred by name (recorded, not owed this phase)
Meaning-names for functions, data, structs and fields (Phase 38 — names with evidence); the _jr_ carve-split file layout regrouped by
system and clang-format (the formatting phase); the 3,801 cross-address classes' parameterized form and the 20 trampoline families (names
phase); the kit split; xsig v2; the 11 still-RESIDUE UNSTRIPPABLE packs (one-off instructions, multi-output/macro-carried launders) unless
the struct hypothesis closes them; a refusal-reason histogram for delever_regen and a "local vs global" column for alloc_table (built
only if T7 draws).
Owner decisions at gate 1 (Drew, 2026-09-11, in order)
- 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. (The three "zero" definitions above make it honest and reachable; Drew may amend, as at P36 S104 — the plan follows his latest word.)
- Naming: placeholders + cited evidence. Unknown-purpose types
Unkstruct_<addr>(the address of a canonical instance where one exists — the player blockUnkstruct_80078E00; else the exemplar function's address, sotn'sET_<addr>precedent), the SDK's name where the layout equals a PsyQ type; fieldsunk<HEX>with/* 0xNN */hex offset comments and// size = 0x..; a field is NAMED only where the record already cites evidence (docs/memory-map.md§3.4,docs/actor-struct.md), with the citation in the header comment. Every other name is Phase 38's. - T7 runs as the P36 lane: the Agent tool, one agent per TU batch, cheapest-residual-first, at a concurrency cap Drew sets and retunes; the
harvest → toolify →
regengate between draws; it STARTS only on Drew's word in the session that runs it (the S98 rule); never an Ultracode wave without his direct approval (R27). - The declaration layer is the full canonical layer: one canonical prototype per definition, applied per TU where the object is unchanged (per-TU and byte-arbitrated — not the Phase-16 header forced on every TU); the 24 parked patches; the 51 TU-CONFLICT rows; classes E/F/G; the byte-proven K&R sites counted apart and marked.