phase-37: T1 ☑ — tools/type_census.py + the struct map: 7,261 struct definitions (525 layouts, 206 duplicate classes / 2,789 names, 39 VARIANT), 503,016 raw pointer-cast dereferences in four forms (coverage OK; + 18,912 address-of, 36,681 typed cast-member), 98,648 lying declarations / 1,609 callees, 18,760 evidence-clustered types explaining 99.2 % of sites, 24 parked P36 classes in parked.tsv, controls 4/4; lever_census controls re-keyed and --strict made literal (6,717 direct GTE statements in bodies); progress.py types block + README sentence + 2 corrections; the readability series read by column name with 16 census columns; docs/struct-map.md; SETUP §P37 S106; dictionary row; kit corpus | 🛑 T2 NEXT (the probe, Max)

This commit is contained in:
Drew T
2026-09-11 23:54:15 -06:00
parent 23fc5d2159
commit da26c05d67
29 changed files with 11919 additions and 121 deletions
+1
View File
@@ -542,6 +542,7 @@ unsloth_compiled_cache/
!/.run/P37/census/
/.run/P37/census/*
!/.run/P37/census/*.json
/.run/P37/census/struct_map.json
!/.run/P37/census/*.txt
!/.run/P37/census/*.md
!/.run/P37/census/*.tsv
+10 -10
View File
@@ -219,25 +219,25 @@
},
"controls": [
{
"expected": 45,
"expected": 14,
"got": 14,
"name": "src/800.c func_800226C0 pins",
"ok": true,
"status": "N-A"
"status": "OK"
},
{
"expected": 26,
"expected": 8,
"got": 8,
"name": "src/shared/ov/func_80178004.h pins",
"ok": true,
"status": "N-A"
"status": "OK"
},
{
"expected": 3,
"got": 0,
"name": "ov_SC03_006 func_80184034 bare-name pins",
"expected": 2,
"got": 2,
"name": "ov_SC03_006 func_801896EC bare-name pins",
"ok": true,
"status": "N-A"
"status": "OK"
},
{
"expected": 0,
@@ -280,7 +280,7 @@
}
},
"coverage_ok": true,
"elapsed_s": 22.5,
"elapsed_s": 21.8,
"generated": "2026-09-11",
"gte_levers": {
"direct": 356,
@@ -291,7 +291,7 @@
"via_macro": 94,
"what": "GTE ops whose clobbers exceed the canonical macro's (a scheduling steer): class-B levers INSIDE the headline number since T5 (2026-09-09), marked, 0 at the close"
},
"head": "60c4bb1cc",
"head": "23fc5d215",
"headers": 3181,
"levers_AB": {
"asm": 1869,
+5 -5
View File
@@ -12,7 +12,7 @@ lever_census: 218 binaries · 4,121 TUs + 3,181 headers · coverage OK · unclas
E asm-label 7802 1370 6432 1100 161 2090 0 7802 {'asm-label': 7802}
F builtin 445 445 0 428 27 302 0 445 {'builtin': 445}
G attribute 76 1 75 1 1 40 0 76 {'attribute': 76}
UNION A–D: 5,746 bodies · 1,007 distinct (addresses normalized) · 110 multi-copy classes holding 4,849 bodies · by kind {'ov': 5352, 'shared': 159, 'main': 124, 'md': 105, 'resident': 6}
UNION A–D: 5,746 bodies · 1,007 distinct (addresses normalized) · 110 multi-copy classes holding 4,849 bodies · by kind {'ov': 5352, 'main': 124, 'md': 105, 'shared': 159, 'resident': 6}
THE PHASE'S NUMBER (pins + asm statements, GTE excluded): 4,010 sites in 1,980 bodies (674 distinct) · marked !FAKE 4,010 · UNMARKED 0
orphan !FAKE markers (no pin/asm site on the line nor below): 0
marked ordinary-C fakes kept by Drew's S104 ruling (a) (`do { } while (0)`, dead initialisers; NOT levers): 53
@@ -25,8 +25,8 @@ lever_census: 218 binaries · 4,121 TUs + 3,181 headers · coverage OK · unclas
gte mnemonics: {'gte_ldv0': 768, 'gte_stlvnl': 593, 'gte_stsxy': 457, 'gte_rtps': 448, 'gte_stflg': 433, 'gte_rtpt': 361, 'gte_SetRotMatrix': 253, 'gte_stsxy3': 245, 'gte_SetTransMatrix': 231, 'gte_rtv0tr': 229, 'gte_ldv3': 186, 'gte_ldv3c': 184, 'gte_stsv': 161, 'lwc2': 158, 'gte_stsz4': 149, 'gte_stsz3': 147, 'gte_stszotz': 134, 'gte_dpcl': 134, 'gte_stclmv': 114, 'gte_stsxy3_f3': 111, 'gte_nclip': 108, 'gte_stopz': 108, 'gte_stsxy3c': 108, 'gte_rtir': 81, 'gte_stsxy3_ft3': 79, 'gte_ldclmv': 78, 'gte_avsz4': 65, 'gte_stotz': 61, 'gte_ldrgb': 30, 'gte_nccs': 25}
asm-bearing macro definitions: 314 (20 names, 3 with >1 text) kinds {'gte': 150, 'launder': 154, 'instruction': 9, 'barrier': 1}
controls (R39):
src/800.c func_800226C0 pins got 14 expected 45 N-A
src/shared/ov/func_80178004.h pins got 8 expected 26 N-A
ov_SC03_006 func_80184034 bare-name pins got 0 expected 3 N-A
src/800.c func_800226C0 pins got 14 expected 14 OK
src/shared/ov/func_80178004.h pins got 8 expected 8 OK
ov_SC03_006 func_801896EC bare-name pins got 2 expected 2 OK
engine_prelude.h asm sites (a macro definition only) got 0 expected 0 OK
elapsed 22.5 s
elapsed 21.8 s
+30
View File
@@ -0,0 +1,30 @@
# .run/P37/census/parked.tsv — the Phase-36 parked classes, in one file with their reasons (type_census.write_parked; generated).
# A RESIDUE class of the P36 ledger whose exemplar is in .run/P36/s105/pick.py's PARK set; `needs` is read from the pack's mechanism.md headline
# (signature | carve | gte | struct | irreducible | ?); `patches` lists the ready patch files. The second block lists PARK names whose latest
# ledger verdict is LEVER-FREE (a minimum-lever bank — its surviving marked sites are counted by lever_census, not here).
fn alias tu copies sites needed_per_copy kinds regs needs pack patches headline
func_80157D20 ov_SC04_011 src/ov_SC04_011/ov_SC04_011_jr_80154C24.c 132 264 2 pin $4 $5 signature .run/P36/agents/ov_SC04_011__func_80157D20 **Final score: 0 (BYTE-IDENTICAL, 21/21 words + relocs) — but NOT body-only.**
func_8013CF68 ov_SC04_011 src/ov_SC04_011/ov_SC04_011_jr_8013C98C.c 134 134 1 instruction signature .run/P36/agents/ov_SC04_011__func_8013CF68 **Result: NOT closed.** The best score is still **10** (ORDER, 63/63). `PACK/body.c` is c9's `h2.c`, unchanged,
func_80178970 ov_SC04_011 src/ov_SC04_011/ov_SC04_011_jr_801734BC.c 127 127 1 pin $2 struct .run/P36/agents/ov_SC04_011__func_80178970 **Final score: 2, NOT closed.** `PACK/body.c` is the S102 agent's early-return body. I re-scored it (score 2, 14 vs 15
func_80180324 ov_SC04_007 src/ov_SC04_007/ov_SC04_007_jr_8017BEBC.c 7 56 8 cast,keepalive,pin $0 ? .run/P36/agents/ov_SC04_007__func_80180324 **Result: `--try` score 0 (328/328), on this function AND all ten other members of its family (table:
func_80181D1C ov_SC04_004 src/ov_SC04_004/ov_SC04_004_jr_8017AE2C.c 4 20 5 barrier,keepalive,pin $2 $3 ?
func_8017FC5C ov_SC03_115 src/ov_SC03_115/ov_SC03_115_jr_8017BEBC.c 9 18 2 keepalive,pin $2 signature .run/P36/agents/ov_SC03_115__func_8017FC5C .run/P36/agents/ov_SC03_115__func_8017FC5C/scratch/tu_d5.diff;.run/P36/agents/ov_SC03_115__func_8017FC5C/scratch/tu_p1.diff **Result: score 0, lever-free, whole object byte-identical** — but it is NOT a `--body`-only change: the function has to
func_80168828 ov_SC01_077 src/ov_SC01_077/ov_SC01_077_jr_8015C32C.c 8 16 2 pin $3 $4 ? .run/P36/agents/ov_SC01_077__func_80168828
func_80183CC4 ov_SC03_094 src/ov_SC03_094/ov_SC03_094_jr_8017BEBC.c 3 12 4 keepalive,pin $16 $2 $3 signature .run/P36/agents/ov_SC03_094__func_80183CC4 **Result: score 0, ZERO levers, plain C. SIGNATURE CHANGE: `void` → `s32`** (parked for the structs phase per Drew S104 (d),
func_80185578 ov_SC06_022 src/ov_SC06_022/ov_SC06_022_jr_80184A28.c 6 12 2 instruction,keepalive signature .run/P36/agents/ov_SC06_022__func_80185578 **Result: score 0, and the whole object is byte-identical (`objdump -drz -s` diff empty), BUT THE CLOSE NEEDS A CHANGE
func_80178970 ov_MAIN_012 src/ov_MAIN_012/ov_MAIN_012_jr_80171B4C.c 7 7 1 pin $2 ? .run/P36/agents/ov_MAIN_012__func_80178970
func_80015608 main src/800.c 1 4 4 pin $20 $22 $3 signature .run/P36/agents/main__func_80015608 Best body: `body.c` (= scratch/b0/v1.c tidied). Residual: ONE register — `y0`'s `subu` and its `sll s8,…,16` use
func_8001BBBC main src/800.c 1 4 4 launder,pin $2 $3 $8 struct .run/P36/agents/main__func_8001BBBC Best body: `body.c` (= scratch/f6.c): plain field stores in the target's order, then the addPrim tail spelled with
func_801834A4 ov_SC03_105 src/ov_SC03_105/ov_SC03_105_jr_80181C84.c 1 3 3 launder,pin $2 struct .run/P36/agents/ov_SC03_105__func_801834A4 `body.c` (= `body_minlever.c` = `scratch/n1.c` + marks): `--try` score 0 (106/106).
func_80188DF4 ov_SC03_091 src/ov_SC03_091/ov_SC03_091_jr_8018326C.c 3 3 1 keepalive signature .run/P36/agents/ov_SC03_091__func_80188DF4 **Result: score 0, ZERO levers, plain C.** Six TUs checked (the brief said 3 copies share the text; the other three have the
func_80157D20 ov_SC01_077 src/ov_SC01_077/ov_SC01_077_jr_80154C24.c 1 2 2 pin $4 $5 signature .run/P36/agents/ov_SC04_011__func_80157D20 **Final score: 0 (BYTE-IDENTICAL, 21/21 words + relocs) — but NOT body-only.**
func_80035210 main src/800_b_2.c 1 1 1 pin $3 signature .run/P36/agents/main__func_80035210 Score 4, REG-caller, 24 vs 24: the post-`SpuWrite` read-modify-write of `D_80076218` (`lw; addu ..,s1; sw`) lives in `$v0`
func_80037144 main src/800_c.c 1 1 1 barrier struct .run/P36/agents/main__func_80037144 **Result.** No levers: `body.c` is byte-identical ONCE LINKED; `--try` scores it **2**, and both points are relocation
func_800384A8 main src/800_c.c 1 1 1 pin $4 signature .run/P36/agents/main__func_800384A8 Two instructions: the target indexes `D_800B9CD8` with the raw `$a0` (`sll v0,a0,7; subu v0,v0,a0`), the lever-free body
func_801805EC ov_SC02_027 src/ov_SC02_027/ov_SC02_027_jr_8017D898.c 1 1 1 barrier struct .run/P36/agents/ov_SC02_027__func_801805EC (a) Residual: score 7 (COUNT, 67 vs 68) — after the u16 store `obj->0x14 += a0->0x2A - cam->0x12` the target RELOADS
func_80185D44 ov_SC06_029 src/ov_SC06_029/ov_SC06_029_jr_8017C954.c 1 1 1 launder struct .run/P36/agents/ov_SC06_029__func_80185D44 **Result: score 0 with ONE marked lever (the tree's launder, re-marked in the step-9 format). Levers 1 -> 1.
func_80188A30 ov_SC04_011 src/ov_SC04_011/ov_SC04_011_jr_8017D494.c 1 1 1 barrier signature .run/P36/agents/ov_SC04_011__func_80188A30 **Result: score 0 in plain C with a SIGNATURE change — PARKED.** The return type is `s32` instead of `void`, the body is the
func_801A1E94 md_SC07_004 src/md_SC07_004/md_SC07_004.c 1 1 1 pin $4 signature .run/P36/agents/md_SC07_004__func_801A1E94 .run/P36/agents/md_SC07_004__func_801A1E94/signature.diff (a) Residual: body_free.c is 41 ins vs 42 — the target's `move s0,a0` in the prologue is missing and `$s0/$s1` are swapped.
func_801A5094 md_SC07_004 src/md_SC07_004/md_SC07_004.c 1 1 1 barrier struct .run/P36/agents/md_SC07_004__func_801A5094 (a) Residual: same 64 instructions; the word load `lui v1; lw v1,D_801F8744` is scheduled ABOVE `li v0,1; sb v0,D_801F8747`
func_801A5C44 md_SC07_004 src/md_SC07_004/md_SC07_004.c 1 1 1 pin $4 signature .run/P36/agents/md_SC07_004__func_801A5C44 .run/P36/agents/md_SC07_004__func_801A5C44/signature.diff (a) Residual: body_free.c is 40 ins vs 41 — the target's `sw s0,16(sp); move s0,a0` parameter copy is missing and the
# minimum-lever banks in PARK (LEVER-FREE in the ledger): func_80015D4C func_80029D3C func_8002FF0C func_800301C8 func_800385C0 func_8012E364 func_80136824 func_8013D9B0 func_8013F350 func_80140958 func_80177B5C func_8017DFB8 func_8017EF50 func_8017F0EC func_80180200 func_80180A54 func_80180FA4 func_80181F4C func_80182614 func_80186CE0 func_8018C14C func_801ADF5C
1 # .run/P37/census/parked.tsv — the Phase-36 parked classes, in one file with their reasons (type_census.write_parked; generated).
2 # A RESIDUE class of the P36 ledger whose exemplar is in .run/P36/s105/pick.py's PARK set; `needs` is read from the pack's mechanism.md headline
3 # (signature | carve | gte | struct | irreducible | ?); `patches` lists the ready patch files. The second block lists PARK names whose latest
4 # ledger verdict is LEVER-FREE (a minimum-lever bank — its surviving marked sites are counted by lever_census, not here).
5 fn alias tu copies sites needed_per_copy kinds regs needs pack patches headline
6 func_80157D20 ov_SC04_011 src/ov_SC04_011/ov_SC04_011_jr_80154C24.c 132 264 2 pin $4 $5 signature .run/P36/agents/ov_SC04_011__func_80157D20 **Final score: 0 (BYTE-IDENTICAL, 21/21 words + relocs) — but NOT body-only.**
7 func_8013CF68 ov_SC04_011 src/ov_SC04_011/ov_SC04_011_jr_8013C98C.c 134 134 1 instruction signature .run/P36/agents/ov_SC04_011__func_8013CF68 **Result: NOT closed.** The best score is still **10** (ORDER, 63/63). `PACK/body.c` is c9's `h2.c`, unchanged,
8 func_80178970 ov_SC04_011 src/ov_SC04_011/ov_SC04_011_jr_801734BC.c 127 127 1 pin $2 struct .run/P36/agents/ov_SC04_011__func_80178970 **Final score: 2, NOT closed.** `PACK/body.c` is the S102 agent's early-return body. I re-scored it (score 2, 14 vs 15
9 func_80180324 ov_SC04_007 src/ov_SC04_007/ov_SC04_007_jr_8017BEBC.c 7 56 8 cast,keepalive,pin $0 ? .run/P36/agents/ov_SC04_007__func_80180324 **Result: `--try` score 0 (328/328), on this function AND all ten other members of its family (table:
10 func_80181D1C ov_SC04_004 src/ov_SC04_004/ov_SC04_004_jr_8017AE2C.c 4 20 5 barrier,keepalive,pin $2 $3 ?
11 func_8017FC5C ov_SC03_115 src/ov_SC03_115/ov_SC03_115_jr_8017BEBC.c 9 18 2 keepalive,pin $2 signature .run/P36/agents/ov_SC03_115__func_8017FC5C .run/P36/agents/ov_SC03_115__func_8017FC5C/scratch/tu_d5.diff;.run/P36/agents/ov_SC03_115__func_8017FC5C/scratch/tu_p1.diff **Result: score 0, lever-free, whole object byte-identical** — but it is NOT a `--body`-only change: the function has to
12 func_80168828 ov_SC01_077 src/ov_SC01_077/ov_SC01_077_jr_8015C32C.c 8 16 2 pin $3 $4 ? .run/P36/agents/ov_SC01_077__func_80168828
13 func_80183CC4 ov_SC03_094 src/ov_SC03_094/ov_SC03_094_jr_8017BEBC.c 3 12 4 keepalive,pin $16 $2 $3 signature .run/P36/agents/ov_SC03_094__func_80183CC4 **Result: score 0, ZERO levers, plain C. SIGNATURE CHANGE: `void` → `s32`** (parked for the structs phase per Drew S104 (d),
14 func_80185578 ov_SC06_022 src/ov_SC06_022/ov_SC06_022_jr_80184A28.c 6 12 2 instruction,keepalive signature .run/P36/agents/ov_SC06_022__func_80185578 **Result: score 0, and the whole object is byte-identical (`objdump -drz -s` diff empty), BUT THE CLOSE NEEDS A CHANGE
15 func_80178970 ov_MAIN_012 src/ov_MAIN_012/ov_MAIN_012_jr_80171B4C.c 7 7 1 pin $2 ? .run/P36/agents/ov_MAIN_012__func_80178970
16 func_80015608 main src/800.c 1 4 4 pin $20 $22 $3 signature .run/P36/agents/main__func_80015608 Best body: `body.c` (= scratch/b0/v1.c tidied). Residual: ONE register — `y0`'s `subu` and its `sll s8,…,16` use
17 func_8001BBBC main src/800.c 1 4 4 launder,pin $2 $3 $8 struct .run/P36/agents/main__func_8001BBBC Best body: `body.c` (= scratch/f6.c): plain field stores in the target's order, then the addPrim tail spelled with
18 func_801834A4 ov_SC03_105 src/ov_SC03_105/ov_SC03_105_jr_80181C84.c 1 3 3 launder,pin $2 struct .run/P36/agents/ov_SC03_105__func_801834A4 `body.c` (= `body_minlever.c` = `scratch/n1.c` + marks): `--try` score 0 (106/106).
19 func_80188DF4 ov_SC03_091 src/ov_SC03_091/ov_SC03_091_jr_8018326C.c 3 3 1 keepalive signature .run/P36/agents/ov_SC03_091__func_80188DF4 **Result: score 0, ZERO levers, plain C.** Six TUs checked (the brief said 3 copies share the text; the other three have the
20 func_80157D20 ov_SC01_077 src/ov_SC01_077/ov_SC01_077_jr_80154C24.c 1 2 2 pin $4 $5 signature .run/P36/agents/ov_SC04_011__func_80157D20 **Final score: 0 (BYTE-IDENTICAL, 21/21 words + relocs) — but NOT body-only.**
21 func_80035210 main src/800_b_2.c 1 1 1 pin $3 signature .run/P36/agents/main__func_80035210 Score 4, REG-caller, 24 vs 24: the post-`SpuWrite` read-modify-write of `D_80076218` (`lw; addu ..,s1; sw`) lives in `$v0`
22 func_80037144 main src/800_c.c 1 1 1 barrier struct .run/P36/agents/main__func_80037144 **Result.** No levers: `body.c` is byte-identical ONCE LINKED; `--try` scores it **2**, and both points are relocation
23 func_800384A8 main src/800_c.c 1 1 1 pin $4 signature .run/P36/agents/main__func_800384A8 Two instructions: the target indexes `D_800B9CD8` with the raw `$a0` (`sll v0,a0,7; subu v0,v0,a0`), the lever-free body
24 func_801805EC ov_SC02_027 src/ov_SC02_027/ov_SC02_027_jr_8017D898.c 1 1 1 barrier struct .run/P36/agents/ov_SC02_027__func_801805EC (a) Residual: score 7 (COUNT, 67 vs 68) — after the u16 store `obj->0x14 += a0->0x2A - cam->0x12` the target RELOADS
25 func_80185D44 ov_SC06_029 src/ov_SC06_029/ov_SC06_029_jr_8017C954.c 1 1 1 launder struct .run/P36/agents/ov_SC06_029__func_80185D44 **Result: score 0 with ONE marked lever (the tree's launder, re-marked in the step-9 format). Levers 1 -> 1.
26 func_80188A30 ov_SC04_011 src/ov_SC04_011/ov_SC04_011_jr_8017D494.c 1 1 1 barrier signature .run/P36/agents/ov_SC04_011__func_80188A30 **Result: score 0 in plain C with a SIGNATURE change — PARKED.** The return type is `s32` instead of `void`, the body is the
27 func_801A1E94 md_SC07_004 src/md_SC07_004/md_SC07_004.c 1 1 1 pin $4 signature .run/P36/agents/md_SC07_004__func_801A1E94 .run/P36/agents/md_SC07_004__func_801A1E94/signature.diff (a) Residual: body_free.c is 41 ins vs 42 — the target's `move s0,a0` in the prologue is missing and `$s0/$s1` are swapped.
28 func_801A5094 md_SC07_004 src/md_SC07_004/md_SC07_004.c 1 1 1 barrier struct .run/P36/agents/md_SC07_004__func_801A5094 (a) Residual: same 64 instructions; the word load `lui v1; lw v1,D_801F8744` is scheduled ABOVE `li v0,1; sb v0,D_801F8747`
29 func_801A5C44 md_SC07_004 src/md_SC07_004/md_SC07_004.c 1 1 1 pin $4 signature .run/P36/agents/md_SC07_004__func_801A5C44 .run/P36/agents/md_SC07_004__func_801A5C44/signature.diff (a) Residual: body_free.c is 40 ins vs 41 — the target's `sw s0,16(sp); move s0,a0` parameter copy is missing and the
30 # minimum-lever banks in PARK (LEVER-FREE in the ledger): func_80015D4C func_80029D3C func_8002FF0C func_800301C8 func_800385C0 func_8012E364 func_80136824 func_8013D9B0 func_8013F350 func_80140958 func_80177B5C func_8017DFB8 func_8017EF50 func_8017F0EC func_80180200 func_80180A54 func_80180FA4 func_80181F4C func_80182614 func_80186CE0 func_8018C14C func_801ADF5C
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
+33
View File
@@ -0,0 +1,33 @@
type_census — 2026-09-12T05:44:31Z at 23fc5d215 (src stamp ab7aba1c21c89889, tool da30900472); 7305 files (4121 TUs + 3181 headers), 99130 function definitions; walk 59.9 s, total 198.8 s
DEFINITIONS 7261 struct/union bodies (+0 enums): canonical header 1179 · .c file-scope 4091 · .c block-scope 1904 · per-function shared headers 63 · other headers 24 · include/ 0
3109 distinct names · 525 distinct layouts (2 unresolved) · 206 duplicate classes covering 2789 names (tier 1 122 same-named, tier 2 84 opaque; 46 layout-twin classes / 1844 names kept apart) · 588 exact-text classes / 4469 copies · 39 VARIANT names (>1 layout) · 141 dead canonical names · 75 canonical names redefined in .c · 1781 scalar/alias typedefs · 157 forward decls
CAST SITES deref 503016 = P 409007 + I 60666 + X 13800 + M 19543 (+ A address-of 18912; + C typed cast-member 36681) in 69497 bodies · coverage OK (raw {'P': 409007, 'I': 60666, 'X': 13800, 'A': 18912, 'C': 36681, 'M': 19543}) · refused 0 · absolute 0 · readability regex over raw text 411850
by base: param 276860 · local 149915 · gaddr 40122 · nested 24076 · global 8860 · other 1678 · addr-of 1349 · ident 156
by width: s4 145167 · u2 142775 · s2 131818 · u1 43174 · agg 13472 · p4 12016 · u4 11165 · s1 3429
top bases: a0(param) 92255 · param_1(param) 81595 · arg0(param) 67704 · p(local) 18043 · p(param) 11784 · s0(local) 10368 · cach(local) 8246 · s1(local) 7137 · buf(local) 7067 · flag(local) 5453 · *(s32 *)(a0 + 0x20)(nested) 5215 · iVar2(local) 5160 · dst(local) 4874 · iVar1(local) 4836 · iVar3(local) 4693 · e(local) 3918
DECLARATIONS 99130 function definitions (1889 K&R) · 4279365 extern function declarations over 12139 names (3870 spelled >1 way) · 6415 names with >1 body text · 1078837 data externs over 55569 symbols (18442 typed >1 way) · asm-label aliases 5749 (225 names) · builtins {'memcpy': 301, 'abs': 144} · attributes {'packed': 64, 'aligned': 12}
lying declarations 98648 over 1609 callees {'K&R-empty': 91357, 'narrow': 7291}
STRUCT MAP 18760 types explain 498896/503016 deref sites (99.2 %); unassigned 4120; 4054 types span ≥2 bodies (441056 sites), 14706 single-body; types with conflicts 729, suspect 11
merges by evidence {'param': 36550, 'assign': 14717, 'ret-of': 3410, 'arg': 10176, 'return': 1523, 'assign&': 1051, 'arg&': 270, 'field': 9623}; vetoed {'arg-conduit': 115291, 'ret-of-multisource': 6651, 'assign-multisource': 34545, 'arg&-conduit': 14516, 'field-multisource': 7008, 'ret-of': 683, 'assign&-multisource': 12499, 'arg&-no-overlap': 3455, 'assign': 347, 'arg-no-overlap': 43018, 'assign&': 69, 'arg': 182, 'return': 12, 'field': 3220}
Unkstruct_800B5CB8 sites 107598 bodies 11186 fields 134 size≥0x10c width-conflicts 50 sign-mixed 55 merges {'param': 9464, 'assign': 7396, 'arg': 6960, 'field': 2617} at D_800B5CB8,D_800D3888,D_80181448 ptr D_8006386C,D_80074778,D_80074780
Unkstruct_80126B58 sites 65397 bodies 17047 fields 175 size≥0x24c width-conflicts 50 sign-mixed 60 merges {'param': 2100, 'arg': 1086, 'assign&': 106, 'field': 51} at D_80126B58 ptr D_80126B58
Unkstruct_8018E71C sites 6745 bodies 396 fields 7 size≥0x10 width-conflicts 0 sign-mixed 0 merges {'param': 18, 'arg': 15, 'assign&': 2} at D_8018E71C
Unkstruct_dac960ce sites 4464 bodies 124 fields 13 size≥0x24c width-conflicts 0 sign-mixed 2 merges {'param': 2}
Unkstruct_0caecd54 sites 4340 bodies 124 fields 23 size≥0xfe width-conflicts 0 sign-mixed 1 merges {'param': 2, 'assign': 1, 'return': 1}
Unkstruct_f8ed2b9f sites 4061 bodies 4061 fields 1 size≥0x217 width-conflicts 0 sign-mixed 0 merges {'param': 2}
Unkstruct_a32b99a1 sites 3936 bodies 123 fields 8 size≥0x4b width-conflicts 0 sign-mixed 1 merges {}
Unkstruct_8e3dbe51 sites 3930 bodies 131 fields 5 size≥0x4c width-conflicts 0 sign-mixed 1 merges {}
Unkstruct_8014A1B0 sites 3778 bodies 542 fields 13 size≥0xfe width-conflicts 0 sign-mixed 1 merges {'field': 13, 'arg': 10, 'param': 10, 'return': 1}
Unkstruct_80128EA8 sites 3311 bodies 632 fields 18 size≥0x38 width-conflicts 0 sign-mixed 13 merges {'arg': 23, 'ret-of': 19, 'field': 7, 'param': 2}
Unkstruct_ade2e8a0 sites 3271 bodies 196 fields 26 size≥0xa4 width-conflicts 3 sign-mixed 9 merges {'param': 268, 'arg': 133}
Unkstruct_1fa9e810 sites 3144 bodies 131 fields 3 size≥0x49 width-conflicts 0 sign-mixed 0 merges {}
GLOBAL BLOCKS 2123 runs of ≥4 adjacent scalar D_ symbols (14251 symbols): 0x800cf10c+0x34 ×29 (D_800CF10C..D_800CF13C) · 0x800a6580+0x3a ×27 (D_800A6580..D_800A65B8) · 0x801998a4+0x57 ×24 (D_801998A4..D_801998FA) · 0x80199840+0x56 ×23 (D_80199840..D_80199895) · 0x801a9608+0x50 ×22 (D_801A9608..D_801A9654) · 0x801ab708+0x54 ×21 (D_801AB708..D_801AB758) · 0x801b0df0+0x4b ×21 (D_801B0DF0..D_801B0E3A) · 0x801b83a0+0x4e ×21 (D_801B83A0..D_801B83ED)
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: player_block_widths OK (D_80078E8C:4/4 D_80078EB2:2/2 D_80078EB4:2/2 D_80078EB6:2/2 D_80078EB8:2/2 [doc-disputed D_80078F08: code 4 vs actor-struct.md 2] [doc-disputed D_80078F0C: code 4 vs actor-struct.md 2]) · matrix_layouts OK (MATRIX=32 MATRIX_L48=48) · prim_layout_class OK (defs in 1192 files, 2 spellings, 1192/1192 in one layout (64 B)) · tu_conflict_D_800A651C OK (s32:1202 | OtBlk[]:9 | OtBlk_80016450[]:8 | u8[]:8 | s32[][5]:6)
duplicate-layout classes (top 12): 8B×293 names (488 defs): GTESVec, GVec8, SIn_8017E95C, SV… | 8B×202 names (0 defs): Blk8L, Blk8S16, Blk8U, Blk8_80126940… | 32B×170 names (278 defs): M32_8017F154, M32_80188094, MATRIX, MATRIX2… | 8B×152 names (341 defs): Blk8_801807DC, Blk8_8018453C, COL_8001EFE0, MoveT… | 32B×129 names (0 defs): B20, Blk20, Blk20_800CB68C, Blk20_8016DF5C… | 4B×102 names (0 defs): B4, B4_8017F154, B4_80181970, B4_80181ABC… | 64B×91 names (1428 defs): Prim_8016E7C8, Prim_8016E7C8_8016B6BC, Prim_8016E7C8_8016B9F8, Prim_8016E7C8_8016C2C4… | 8B×72 names (0 defs): B8, B8_17F474, B8_801AEB04, B8_CB578… | 8B×63 names (211 defs): Ang_8017E95C, DVEC_80183534, SOut_8017E95C, SVEC… | 4B×60 names (68 defs): PTAG_85910, PTag, PTag293C, PTag_1412A8… | 8B×58 names (0 defs): CdFileLoc, Cmd_801805C8, M8_8016B6BC, Packed8… | 16B×54 names (0 defs): B16, B16_8017CDE4, B16_80183ED8, B16_801841C8…
VARIANT names (top 12): Prim×5, Rec×4, St×4, S×4, V8×4, Blk8×3, Vec8×3, Obj×3, Ent×3, Blk16×2, CdReq×2, Blk4×2
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
+2
View File
@@ -29,6 +29,8 @@ One source per unique function (Phase 35): 103,015 function bodies written once
Levers off (Phase 36, snapshot 2026-09-11): 2,141 register pins and 1,869 asm statements remain in 1,980 functions (674 distinct bodies), 4,010 of them marked `// !FAKE:`; 1,589 volatile qualifiers and 50 bare `register` keywords are censused; 6,447 GTE coprocessor operations and 22 whole-body assembly routines kept inside C shells (2,682 sites; the original's scratchpad stack-switch trampolines, one copy per overlay, listed in the verbatim manifest) are not levers and are excluded.
Types (Phase 37, snapshot 2026-09-12): 503,016 raw pointer-cast dereferences remain in 69,497 functions (four forms; 36,681 typed cast-member accesses and 18,912 address-of casts counted apart); 7,261 struct definitions (1,179 in the canonical header, 5,995 inside `.c` files) over 525 distinct layouts, 206 duplicate classes covering 2,789 names; 98,648 call declarations narrower than their callee's definition over 1,609 callees; the struct map clusters the cast sites into 18,760 types by evidence (99.2 % of sites assigned).
_Generated by `tools/progress.py --readme` from `docs/progress.json` — numbers are never typed by hand._
<!-- progress:end -->
+1
View File
@@ -318,6 +318,7 @@ tools/treelock.sh P8 ADAPT hold one mutex over tree-writing campaigns, with stat
tools/triage_ladder.py P8 ADAPT decide before and after drafting whether a target needs an agent at all Zero-token pass deciding whether a target needs an agent at all, before and after drafting repo scratch paths LIVE
tools/twin_rescan.py P6 ADAPT report which open stubs became mechanical remaps the moment one was banked After a bank, reports which open stubs just became mechanical remaps instead of drafts repo signature files STILL-NEEDED report which open stubs became mechanical remaps the moment one was banked
tools/twin_sweep.py P6 ADAPT bank every open stub that already has a banked structural twin Banks every open stub that has an already-banked structural twin, for near-zero tokens repo signature files LIVE
tools/type_census.py P10 ADAPT census every struct definition, raw pointer-cast dereference and function declaration in the C, and cluster the cast sites into the types the tree needs (the struct map) The Phase-37 type census: struct/union/typedef definitions fleet-wide with o32 layouts (duplicate classes by layout+member evidence, VARIANT camps, dead and shadowed canonical names), every cast site in six forms (P *(T*)(…), I *(T*)ident, X ((T*)e)[i], M M2C_FIELD, A address-of, C typed cast-member) with base class/offset/width/sign/access and a per-form coverage assertion against an independent raw regex, the declaration layer (definitions K&R-read, extern spellings per name, multi-body names, asm-label aliases, builtins, attributes, argcheck's lying set), global blocks (runs of adjacent scalar D_ symbols), four known-true controls, and the struct map — union-find over evidence edges only (same global, argument flow into a parameter the callee dereferences with shared offsets, single-source assignment/return flow, pointer-field flow, body-hash identity) with a width-conflict veto; writes type_census.json/txt, struct_map(.top).json, sites.jsonl (--sites), parked.tsv (the P36 parked classes with reasons) and docs/struct-map.md; --check is the T8 gate; --selftest repo paths, the shared-body scanner, argcheck, the P36 ledger (parked.tsv) LIVE
tools/uniquify_type.py P10 ADAPT give each conflicting camp of a same-named type its own name Gives each conflicting camp of a same-named type its own name so every camp becomes liftable repo src layout STILL-NEEDED give each conflicting camp of a same-named type its own name so both become liftable
tools/validate_targets.py P8 ADAPT gate every target list for validity before agents are spawned The validity gate every target list must pass before agents are spawned repo scratch paths LIVE
tools/verbatim_check.py P10 ADAPT guard that every inline-assembly body still reproduces its target bytes Regression guard that every inline-assembly body still reproduces its target bytes repo src layout LIVE
1 path phase portability need what adapts status successor_or_product
318 tools/triage_ladder.py P8 ADAPT decide before and after drafting whether a target needs an agent at all Zero-token pass deciding whether a target needs an agent at all, before and after drafting repo scratch paths LIVE
319 tools/twin_rescan.py P6 ADAPT report which open stubs became mechanical remaps the moment one was banked After a bank, reports which open stubs just became mechanical remaps instead of drafts repo signature files STILL-NEEDED report which open stubs became mechanical remaps the moment one was banked
320 tools/twin_sweep.py P6 ADAPT bank every open stub that already has a banked structural twin Banks every open stub that has an already-banked structural twin, for near-zero tokens repo signature files LIVE
321 tools/type_census.py P10 ADAPT census every struct definition, raw pointer-cast dereference and function declaration in the C, and cluster the cast sites into the types the tree needs (the struct map) The Phase-37 type census: struct/union/typedef definitions fleet-wide with o32 layouts (duplicate classes by layout+member evidence, VARIANT camps, dead and shadowed canonical names), every cast site in six forms (P *(T*)(…), I *(T*)ident, X ((T*)e)[i], M M2C_FIELD, A address-of, C typed cast-member) with base class/offset/width/sign/access and a per-form coverage assertion against an independent raw regex, the declaration layer (definitions K&R-read, extern spellings per name, multi-body names, asm-label aliases, builtins, attributes, argcheck's lying set), global blocks (runs of adjacent scalar D_ symbols), four known-true controls, and the struct map — union-find over evidence edges only (same global, argument flow into a parameter the callee dereferences with shared offsets, single-source assignment/return flow, pointer-field flow, body-hash identity) with a width-conflict veto; writes type_census.json/txt, struct_map(.top).json, sites.jsonl (--sites), parked.tsv (the P36 parked classes with reasons) and docs/struct-map.md; --check is the T8 gate; --selftest repo paths, the shared-body scanner, argcheck, the P36 ledger (parked.tsv) LIVE
322 tools/uniquify_type.py P10 ADAPT give each conflicting camp of a same-named type its own name Gives each conflicting camp of a same-named type its own name so every camp becomes liftable repo src layout STILL-NEEDED give each conflicting camp of a same-named type its own name so both become liftable
323 tools/validate_targets.py P8 ADAPT gate every target list for validity before agents are spawned The validity gate every target list must pass before agents are spawned repo scratch paths LIVE
324 tools/verbatim_check.py P10 ADAPT guard that every inline-assembly body still reproduces its target bytes Regression guard that every inline-assembly body still reproduces its target bytes repo src layout LIVE
+3 -2
View File
@@ -8,8 +8,8 @@
> its platform SDK need the marked adaptation. The last table lists the tools that are project-only in code (their *shape* is a task;
> their code does not transfer). *TODO(platform): the MIPS and PlayStation SDK hard-codes are the ones another platform replaces first.*
>
> **Coverage:** 309 tool files in scope (submodules, vendored and downloaded code excluded), of which 309 live rows
> below; per phase: P1 2 · P2 26 · P3 17 · P4 9 · P5 26 · P6 51 · P7 20 · P8 86 · P9 27 · P10 29 · PROJECT-ONLY 16. Superseded tools appear only as pointers to their successor (30 pointer rows); one-offs are omitted. Table rows in all: 339 (the installer checks its copy against this figure).
> **Coverage:** 310 tool files in scope (submodules, vendored and downloaded code excluded), of which 310 live rows
> below; per phase: P1 2 · P2 26 · P3 17 · P4 9 · P5 26 · P6 51 · P7 20 · P8 86 · P9 27 · P10 30 · PROJECT-ONLY 16. Superseded tools appear only as pointers to their successor (30 pointer rows); one-offs are omitted. Table rows in all: 340 (the installer checks its copy against this figure).
## P1 — extraction + manifest
@@ -328,6 +328,7 @@
| `ghidra_scripts/ApplySymbols.java` | apply curated names and signatures inside the analysis tool and save | The in-tool half of that mirror: apply curated names and signatures, save on exit | none |
| `delever_pack.py` | build the pack one agent needs to read and crack one residue exemplar, without touching the tree | The Phase-36 T7 pack builder (one agent at a time): per residue exemplar of ≥N copies a directory under .run/P36/agents/ with the TU path, the body as the tree has it, the lever-free body (the seed), the residual as mnemonic blocks from delever_search --try (a scratch compile, no tree write), the ledger's NEEDED sites, and every engine attempt with its best moves; ORDER.tsv ranks the exemplars by the best distance reached, then copies. PROMPT.md beside them is the agent's brief. | repo scratch paths; the engine's outcomes and traces |
| `lever_census.py` | census every compiler-forcing construct in the C and gate the levers-off phase | The Phase-36 census of lever sites (register pins, asm statements by kind, volatile levers, bare register, asm-label aliases, builtins, attributes; the whole-body hand-asm routines and the GTE ops set apart) derived from the shared-body scanner with a per-token coverage assertion against the raw text, four known-true controls, the !FAKE marker split, --check (0 unmarked pins/asm, 0 orphan markers) and --strict (0 pins, 0 asm) gates, --sites for the delever ledger, a fixture self-test | repo paths, the shared-body scanner |
| `type_census.py` | census every struct definition, raw pointer-cast dereference and function declaration in the C, and cluster the cast sites into the types the tree needs (the struct map) | The Phase-37 type census: struct/union/typedef definitions fleet-wide with o32 layouts (duplicate classes by layout+member evidence, VARIANT camps, dead and shadowed canonical names), every cast site in six forms (P *(T*)(…), I *(T*)ident, X ((T*)e)[i], M M2C_FIELD, A address-of, C typed cast-member) with base class/offset/width/sign/access and a per-form coverage assertion against an independent raw regex, the declaration layer (definitions K&R-read, extern spellings per name, multi-body names, asm-label aliases, builtins, attributes, argcheck's lying set), global blocks (runs of adjacent scalar D_ symbols), four known-true controls, and the struct map — union-find over evidence edges only (same global, argument flow into a parameter the callee dereferences with shared offsets, single-source assignment/return flow, pointer-field flow, body-hash identity) with a width-conflict veto; writes type_census.json/txt, struct_map(.top).json, sites.jsonl (--sites), parked.tsv (the P36 parked classes with reasons) and docs/struct-map.md; --check is the T8 gate; --selftest | repo paths, the shared-body scanner, argcheck, the P36 ledger (parked.tsv) |
| `gte_consolidate.py` | consolidate the GTE coprocessor inline-asm macros under Sony's names in one header and sweep dead lever macros | The Phase-36 T5 tool: every asm-bearing macro definition and direct GTE statement SIGNED by the build's own maspsx→as tail (template bytes with operands bound to fixed registers, operand counts, clobbers); one canonical text per signature named by PsyQ's inline_c.h convention (Sony's file supplies names and clobber lists, never opcode words) written to include/gte_inline.h; per file the canonical duplicates deleted, private names renamed, a variant with extra clobbers tried as canonical and kept as a marked <name>_m lever only when the object differs, direct statements rewritten into canonical calls (a concatenation of two included); every file judged through every recipe; --sweep deletes dead asm-bearing macros and drops a compound macro's inner asm when byte-neutral | Sony's inline_c.h path, the census sites, the oracle |
| `macro_to_header.py` | convert a shared-body macro header into per-function plain-C headers included at each site | The Phase-35 converter: every DEFINE_ macro body becomes a plain-C header under src/shared/<space>/ included at its site, the legacy name-parameterized headers converted, the registry text-edited, the macro header deleted; --plan / --apply / --finalize / --verify | the macro form is this project's; a kit-born project shares headers from its first bank |
| `asm_verbatim.py` | emit a function's target assembly as an inline-assembly body | Emits the file-scope inline-assembly body form from a disassembly file | repo asm layout |
@@ -978,10 +978,13 @@ def run_census(jobs, use_cache=True, out_dir=OUT_DIR_DEFAULT, want_sites=False,
# the known-true bodies as they were at T1 (commit 357f8a1ed): a control holds only while the body's normalized text is the one the
# count was made on — the campaign removes pins byte-identically, and a control that kept expecting them would fail on its own
# staleness (batch tus7 of T4 removed func_80184034's three bare-name pins; the census then refused a correct tree)
# re-keyed at P37 T1 (S106, 2026-09-12; R85): the P36 campaign changed all three bodies — counted again independently with the
# gate-1 grep (`register [^;/]*__asm__\("\$?[a-z0-9]+"\)` over the masked body): 45 → 14, 26 → 8, and the bare-name control moved to
# func_801896EC (2 bare-name pins; func_80184034's are gone). A control returns N-A the day its body changes again.
CONTROL_NHASH = {
("src/800.c", "func_800226C0"): "47f1042f0dda6f163009793a11ef16f405c29af1",
("src/shared/ov/func_80178004.h", None): "90d67fb489780cf0ef81f1a7b4b4f74dfe3c782b",
("src/ov_SC03_006/ov_SC03_006_jr_8017AE2C.c", "func_80184034"): "2dce73f8716c32324b1b3517f11bd03a4e9966af",
("src/800.c", "func_800226C0"): "902372b4e3bf845f39f0b4d4bab7f2ab8ce47121",
("src/shared/ov/func_80178004.h", None): "27524a8bf23911718b4082cd5cca7d971d8c9090",
("src/ov_SC03_006/ov_SC03_006_jr_8017AE2C.c", "func_801896EC"): "140f5b7e434d93ebaaea89dbe65c1a702d233020",
}
@@ -998,11 +1001,11 @@ def controls(sites, defs):
return "OK" if got == want else "MISMATCH"
out = []
n = sum(1 for s in sites if s["tu"] == "src/800.c" and s["fn"] == "func_800226C0" and s["cls"] == "A")
out.append(("src/800.c func_800226C0 pins", n, 45, status(("src/800.c", "func_800226C0"), n, 45)))
out.append(("src/800.c func_800226C0 pins", n, 14, status(("src/800.c", "func_800226C0"), n, 14)))
n = sum(1 for s in sites if s["tu"] == "src/shared/ov/func_80178004.h" and s["cls"] == "A")
out.append(("src/shared/ov/func_80178004.h pins", n, 26, status(("src/shared/ov/func_80178004.h", None), n, 26)))
n = sum(1 for s in sites if s["tu"] == "src/ov_SC03_006/ov_SC03_006_jr_8017AE2C.c" and s["fn"] == "func_80184034" and s["cls"] == "A")
out.append(("ov_SC03_006 func_80184034 bare-name pins", n, 3, status(("src/ov_SC03_006/ov_SC03_006_jr_8017AE2C.c", "func_80184034"), n, 3)))
out.append(("src/shared/ov/func_80178004.h pins", n, 8, status(("src/shared/ov/func_80178004.h", None), n, 8)))
n = sum(1 for s in sites if s["tu"] == "src/ov_SC03_006/ov_SC03_006_jr_8017AE2C.c" and s["fn"] == "func_801896EC" and s["cls"] == "A")
out.append(("ov_SC03_006 func_801896EC bare-name pins", n, 2, status(("src/ov_SC03_006/ov_SC03_006_jr_8017AE2C.c", "func_801896EC"), n, 2)))
n = sum(1 for s in sites if s["tu"] == "src/shared/engine_prelude.h" and s["cls"] == "B")
out.append(("engine_prelude.h asm sites (a macro definition only)", n, 0, "OK" if n == 0 else "MISMATCH"))
return out
@@ -1185,13 +1188,18 @@ def main():
ab = [x for x in sites if x["cls"] in "AB" and x["kind"] not in NON_LEVER_KINDS and x["tu"] != a.gte_header]
un = [x for x in ab if not x["marked"]]
if a.strict:
# P37 (S106): --strict reads its own words — "0 asm statements outside the GTE header" — so a DIRECT GTE statement in a body
# (kind gte / gte-unsigned: Sony's idiom spelled inline instead of as the header's macro call) is a violation here, while the
# --check headline keeps the P36 definition (the series' continuity). verbatim-body stays excluded by the manifest.
direct_gte = [x for x in sites if x["cls"] == "B" and x["kind"] in ("gte", "gte-unsigned") and x["tu"] != a.gte_header]
pt = s.get("per_tu_asm_macro_definitions", {}).get("total", 0)
gl = s.get("gte_levers", {}).get("sites", 0)
print(f"lever_census --check --strict: pins {s['pins']['sites']}, asm {sum(1 for x in ab if x['cls'] == 'B' and x['kind'] != GTE_LEVER_KIND)}, "
f"gte-levers {gl}, per-TU asm macro definitions {pt}, volatile-needed {s['classes']['C']['sites']}, register-needed {s['classes']['D']['sites']} — "
f"{'OK' if not ab and not pt else 'FAIL'}")
if ab or pt:
for x in ab[:10]:
f"gte-levers {gl}, direct GTE statements in bodies {len(direct_gte)}, per-TU asm macro definitions {pt}, "
f"volatile-needed {s['classes']['C']['sites']}, register-needed {s['classes']['D']['sites']} — "
f"{'OK' if not ab and not pt and not direct_gte else 'FAIL'}")
if ab or pt or direct_gte:
for x in (ab + direct_gte)[:10]:
print(f" {x['tu']}:{x['line']} {x['fn']} {x['cls']}/{x['kind']} {x['detail']}")
rc = 1
else:
@@ -43,31 +43,68 @@ def counts():
casts += len(CAST.findall(t))
members += len(MEMBER.findall(t))
pinned = [r for r in rows if r["argpin"]]
return dict(definitions=len(defs), narrow_decls=len(rows),
callees=len({r["callee"] for r in rows}),
kr_empty=sum(1 for r in rows if r["kind"] == "K&R-empty"),
narrow=sum(1 for r in rows if r["kind"] == "narrow"),
pinned_rows=len(pinned), pinned_bodies=len({(r["tu"], r["in_fn"]) for r in pinned}),
raw_casts=casts, struct_members=members)
out = dict(definitions=len(defs), narrow_decls=len(rows),
callees=len({r["callee"] for r in rows}),
kr_empty=sum(1 for r in rows if r["kind"] == "K&R-empty"),
narrow=sum(1 for r in rows if r["kind"] == "narrow"),
pinned_rows=len(pinned), pinned_bodies=len({(r["tu"], r["in_fn"]) for r in pinned}),
raw_casts=casts, struct_members=members)
# Phase 37 T1 (2026-09-12): the type census's columns — the four dereference forms (the CAST regex above sees one of them, over raw
# text), the typed cast-member accesses (the MEMBER regex counts these as members — they are the rewrite's rung 1, not finished
# members), the struct definitions and their duplicate classes, the struct map. A snapshot REFUSES a stale census (R43/R51).
cj = REPO / ".run/P37/census/type_census.json"
head = subprocess.run(["git", "rev-parse", "HEAD"], cwd=REPO, capture_output=True, text=True).stdout.strip()
if not cj.exists():
sys.exit("readability_progress: no type census — run `tools/type_census.py -j 16` first (its columns are part of the row)")
ts = json.loads(cj.read_text())["summary"]
if not head.startswith(ts.get("head", "?")):
sys.exit(f"readability_progress: the type census is STALE (census {ts.get('head')} vs HEAD {head[:9]}) — rerun tools/type_census.py")
c, d, sm = ts["casts"], ts["definitions"], ts["struct_map"]
out.update(deref_all=c["deref_total"], form_P=c["by_form"].get("P", 0), form_I=c["by_form"].get("I", 0), form_X=c["by_form"].get("X", 0),
form_M=c["by_form"].get("M", 0), addr_form=c["addr_form"], typed_cast_member=c["typed_cast_member"],
struct_defs=d["total"], canon_defs=d["canon"], in_c_defs=d["in_c_file_scope"] + d["in_c_block_scope"],
distinct_layouts=d["distinct_layouts"], dup_classes=d["dup_layout_classes"], dup_names=d["dup_layout_names"],
map_types=sm["types"], map_pct=sm["explained_pct"])
return out
HEAD = ("date\tlabel\tcommit\tdefinitions\tnarrow_decls\tcallees\tkr_empty\tnarrow\tpinned_rows\tpinned_bodies"
"\traw_casts\tstruct_members\n")
COLS = ["date", "label", "commit", "definitions", "narrow_decls", "callees", "kr_empty", "narrow", "pinned_rows", "pinned_bodies",
"raw_casts", "struct_members",
# P37 columns (appended 2026-09-12; older rows carry blanks — the renderer reads by name, never by position)
"deref_all", "form_P", "form_I", "form_X", "form_M", "addr_form", "typed_cast_member", "struct_defs", "canon_defs", "in_c_defs",
"distinct_layouts", "dup_classes", "dup_names", "map_types", "map_pct"]
HEAD = "\t".join(COLS) + "\n"
def _rows():
lines = [l for l in TSV.read_text().splitlines() if l.strip()]
cols = lines[0].split("\t")
rows = []
for l in lines[1:]:
vals = l.rstrip("\n").split("\t")
rows.append({c: (vals[i] if i < len(vals) else "") for i, c in enumerate(cols)})
return rows
def render():
rows = [l.rstrip("\n").split("\t") for l in TSV.read_text().splitlines()[1:] if l.strip()]
rows = _rows()
g = lambda r, k: r.get(k, "") or "—"
out = ["# Readability of the matched C — the Gen3 series",
"",
"> **Generated by `tools/readability_progress.py --snapshot`; never typed (R75).** Companion to",
"> `docs/levers.md`, which counts the compiler-forcing levers. This one counts the two things that are wrong",
"> with the source even where no lever remains: call declarations that are FALSE, and memory read through raw",
"> pointer casts where the original had a struct.",
"> pointer casts where the original had a struct. From Phase 37 the row carries the type census's columns",
"> (`tools/type_census.py`): all four dereference forms, the typed cast-member intermediate, the definitions and the map.",
"",
"| date | label | commit | lying declarations | of which `()` | of which `(void)` | in a pinned body | raw cast derefs | struct member reads |",
"|---|---|---|---:|---:|---:|---:|---:|---:|"]
"| date | label | commit | lying declarations | of which `()` | of which `(void)` | in a pinned body | raw cast derefs (one form, raw text) | struct member reads | **raw derefs, four forms** | typed cast-member | struct defs (canonical / in .c) | layouts | duplicate classes / names | map types (% sites) |",
"|---|---|---|---:|---:|---:|---:|---:|---:|---:|---:|---|---:|---|---|"]
for r in rows:
out.append(f"| {r[0]} | {r[1]} | `{r[2][:9]}` | {r[4]} | {r[6]} | {r[7]} | {r[8]} | {r[10]} | {r[11]} |")
defs = f"{g(r,'struct_defs')} ({g(r,'canon_defs')} / {g(r,'in_c_defs')})" if r.get("struct_defs") else "—"
dups = f"{g(r,'dup_classes')} / {g(r,'dup_names')}" if r.get("dup_classes") else "—"
mp = f"{g(r,'map_types')} ({g(r,'map_pct')} %)" if r.get("map_types") else "—"
out.append(f"| {r['date']} | {r['label']} | `{r['commit'][:9]}` | {r['narrow_decls']} | {r['kr_empty']} | {r['narrow']} | {r['pinned_rows']} | "
f"{r['raw_casts']} | {r['struct_members']} | **{g(r,'deref_all')}** | {g(r,'typed_cast_member')} | {defs} | {g(r,'distinct_layouts')} | {dups} | {mp} |")
out += ["",
"**How to read it.** A *lying declaration* is a call site whose in-scope declaration names fewer parameters",
"than the callee's own definition. It is not a style problem: on this processor an argument travels in a",
@@ -97,17 +134,17 @@ def main():
print(__doc__)
return 2
c = counts()
if not TSV.exists():
TSV.write_text(HEAD)
with TSV.open("a") as fh:
fh.write("\t".join([datetime.date.today().isoformat(), a.snapshot, head, str(c["definitions"]),
str(c["narrow_decls"]), str(c["callees"]), str(c["kr_empty"]), str(c["narrow"]),
str(c["pinned_rows"]), str(c["pinned_bodies"]), str(c["raw_casts"]),
str(c["struct_members"])]) + "\n")
c.update(date=datetime.date.today().isoformat(), label=a.snapshot, commit=head)
# the header row is rewritten to the current column list; older rows keep their positions (the new columns are appended)
old = [l for l in TSV.read_text().splitlines()[1:] if l.strip()] if TSV.exists() else []
TSV.write_text(HEAD + "".join(l + "\n" for l in old) + "\t".join(str(c.get(k, "")) for k in COLS) + "\n")
render()
print(f"readability_progress: {a.snapshot} — {c['narrow_decls']} lying declaration(s) over {c['callees']} callee(s) "
f"({c['kr_empty']} `()`, {c['narrow']} `(void)`), {c['pinned_rows']} in {c['pinned_bodies']} pinned bodies; "
f"{c['raw_casts']} raw cast deref(s), {c['struct_members']} struct member read(s), at {head[:9]}")
f"{c['raw_casts']} raw cast deref(s) by the one-form regex, {c['deref_all']} by the census's four forms (+{c['typed_cast_member']} typed "
f"cast-member, +{c['addr_form']} address-of), {c['struct_members']} struct member read(s); {c['struct_defs']} struct definitions over "
f"{c['distinct_layouts']} layouts ({c['dup_classes']} duplicate classes / {c['dup_names']} names); the map: {c['map_types']} types "
f"({c['map_pct']} % of sites), at {head[:9]}")
return 0
File diff suppressed because it is too large Load Diff
+34 -3
View File
@@ -1173,6 +1173,26 @@ def fleet():
"hand_asm_routines_in_c_shells": _vb.get("routines"), "hand_asm_routine_sites": _vb.get("sites")}
except Exception:
_lev = None
# Phase 37 T1: the type census (tools/type_census.py) — the struct debt, the declaration debt and the struct map, published until 0 (R75)
_typ = None
try:
import json as _jt
_tj = ROOT / ".run/P37/census/type_census.json"
if _tj.exists():
_ts = _jt.loads(_tj.read_text())["summary"]
_d, _c, _dc, _sm = _ts["definitions"], _ts["casts"], _ts["decls"], _ts["struct_map"]
_typ = {"date": _ts.get("when", "")[:10], "head": _ts.get("head"),
"what": "the structs phase's counters: raw pointer-cast dereferences in four forms (P *(T*)(…), I *(T*)ident, X ((T*)e)[i], M M2C_FIELD), "
"struct definitions and their duplicate classes, lying call declarations, and the struct map's types (Phase 37 drives the first three to 0)",
"raw_cast_sites": _c["deref_total"], "raw_cast_forms": _c["by_form"], "raw_cast_bodies": _c["bodies"],
"address_of_sites": _c["addr_form"], "typed_cast_member_sites": _c["typed_cast_member"], "absolute_address_casts": _c["abs_casts"],
"struct_definitions": _d["total"], "canonical_definitions": _d["canon"], "definitions_in_c_files": _d["in_c_file_scope"] + _d["in_c_block_scope"],
"distinct_layouts": _d["distinct_layouts"], "duplicate_classes": _d["dup_layout_classes"], "duplicate_names": _d["dup_layout_names"],
"variant_names": _d["variant_names"], "dead_canonical_names": _d["dead_canon_names"],
"lying_declarations": _dc["lying"], "lying_callees": _dc["lying_callees"], "asm_label_aliases": _dc["asm_label_aliases"],
"multi_spelled_callees": _dc["multi_spelled_callees"], "struct_map_types": _sm["types"], "struct_map_explained_pct": _sm["explained_pct"]}
except Exception:
_typ = None
# Phase 35 T5b: the TEXT tier — groups keyed by one normalized text at one address whose bytes vary per binary (verbose members)
_tg = [g for g in gs if g.get("tier") == "h_text"]
return {
@@ -1201,7 +1221,7 @@ def fleet():
"text_tier_groups": len(_tg), "text_tier_instances": sum(len(g.get("members") or []) for g in _tg),
"deferred_same_address_texts": (_census.get("deferred_texts") or {}).get("texts"),
"deferred_same_address_copies": (_census.get("deferred_texts") or {}).get("sites"),
"levers": _lev},
"levers": _lev, "types": _typ},
"corrections": [ # dated snapshots of published-number moves with their cause and the command that shows them (R75)
{"date": "2026-09-08", "phase": "P35 T2", "metric": "fn_count.total", "delta": 7,
"cause": "seven overlays including the whale header but never registered were counted by neither classify nor the registry fold", "command": "tools/progress.py --fleet"},
@@ -1210,7 +1230,11 @@ def fleet():
{"date": "2026-09-08", "phase": "P35 T6", "metric": "counts.real_c_functions", "delta": -10211,
"cause": "empty-bodied shared functions were folded into REAL under the macro form; the include form classifies them EMPTY (the instruction-weighted metrics are unchanged)", "command": "tools/progress.py --fleet"},
{"date": "2026-09-09", "phase": "P36 T1b", "metric": "counts.verbatim_asm_bodies", "delta": 22,
"cause": "the §265 lane's IN-FUNCTION form (a whole routine as one __asm__ statement inside a C shell) was invisible to the file-scope detector behind the manifest: 22 scratchpad stack-switch trampolines (one private copy per overlay, 2,682 sites) are hand asm and are listed PERMANENT-VERBATIM; a 23rd asm-body is -O0 compiler output and is listed DECOMPILE-NOW", "command": "tools/lever_census.py; tools/verbatim_check.py"}],
"cause": "the §265 lane's IN-FUNCTION form (a whole routine as one __asm__ statement inside a C shell) was invisible to the file-scope detector behind the manifest: 22 scratchpad stack-switch trampolines (one private copy per overlay, 2,682 sites) are hand asm and are listed PERMANENT-VERBATIM; a 23rd asm-body is -O0 compiler output and is listed DECOMPILE-NOW", "command": "tools/lever_census.py; tools/verbatim_check.py"},
{"date": "2026-09-12", "phase": "P37 T1", "metric": "counts.types.raw_cast_sites", "delta": 91166,
"cause": "the readability series' regex counted one cast form (`*(T *)(`: 411,850 over raw text); the type census counts four dereference forms over comment-masked text — P 409,007 + I 60,666 (`*(T *)ident`, `*(T *)&D_x`) + X 13,800 (`((T *)e)[i]`) + M 19,543 (`M2C_FIELD`) = 503,016 — with a coverage assertion per form; 18,912 address-of casts and 36,681 typed cast-member accesses are counted apart", "command": "tools/type_census.py"},
{"date": "2026-09-12", "phase": "P37 T1", "metric": "counts.levers (--strict)", "delta": 6717,
"cause": "lever_census --strict now reads its own words: 6,717 direct GTE coprocessor asm statements in function bodies (Sony's idiom spelled inline instead of as the header's macro call; kinds gte/gte-unsigned, incl. func_8013D9B0's 268 unsigned respellings) are asm statements outside the GTE header — the P36 headline (--check, 4,010) keeps its definition for the series' continuity", "command": "tools/lever_census.py --check --strict"}],
"per_binary": [{"binary": r['binary'], "real": r['real'], "shared": r['shared'], "linked": r['linked'],
"byte_identical": r['byteident'], "matchable": r['matchable'],
"instr_matched": (wm['per_bin'].get(r['binary'], [None, None])[0] if wm else None),
@@ -1282,7 +1306,14 @@ def readme_block(d):
f"{c['levers']['register_keyword_sites']:,} bare `register` keywords are censused; {c['levers']['gte_sites']:,} GTE coprocessor "
f"operations and {c['levers']['hand_asm_routines_in_c_shells']} whole-body assembly routines kept inside C shells "
f"({c['levers']['hand_asm_routine_sites']:,} sites; the original's scratchpad stack-switch trampolines, one copy per "
f"overlay, listed in the verbatim manifest) are not levers and are excluded."] if c.get("levers") else []) + [
f"overlay, listed in the verbatim manifest) are not levers and are excluded."] if c.get("levers") else []) + ([f"", f"Types (Phase 37, snapshot {c['types']['date']}): {c['types']['raw_cast_sites']:,} raw pointer-cast dereferences remain in "
f"{c['types']['raw_cast_bodies']:,} functions (four forms; {c['types']['typed_cast_member_sites']:,} typed cast-member accesses and "
f"{c['types']['address_of_sites']:,} address-of casts counted apart); {c['types']['struct_definitions']:,} struct definitions "
f"({c['types']['canonical_definitions']:,} in the canonical header, {c['types']['definitions_in_c_files']:,} inside `.c` files) over "
f"{c['types']['distinct_layouts']:,} distinct layouts, {c['types']['duplicate_classes']:,} duplicate classes covering "
f"{c['types']['duplicate_names']:,} names; {c['types']['lying_declarations']:,} call declarations narrower than their callee's "
f"definition over {c['types']['lying_callees']:,} callees; the struct map clusters the cast sites into {c['types']['struct_map_types']:,} "
f"types by evidence ({c['types']['struct_map_explained_pct']} % of sites assigned)."] if c.get("types") else []) + [
"", f"_Generated by `tools/progress.py --readme` from `docs/progress.json` — numbers are never typed by hand._",
README_END]
return "\n".join(out)
+3 -2
View File
@@ -8,8 +8,8 @@
> its platform SDK need the marked adaptation. The last table lists the tools that are project-only in code (their *shape* is a task;
> their code does not transfer). *TODO(platform): the MIPS and PlayStation SDK hard-codes are the ones another platform replaces first.*
>
> **Coverage:** 309 tool files in scope (submodules, vendored and downloaded code excluded), of which 309 live rows
> below; per phase: P1 2 · P2 26 · P3 17 · P4 9 · P5 26 · P6 51 · P7 20 · P8 86 · P9 27 · P10 29 · PROJECT-ONLY 16. Superseded tools appear only as pointers to their successor (30 pointer rows); one-offs are omitted. Table rows in all: 339 (the installer checks its copy against this figure).
> **Coverage:** 310 tool files in scope (submodules, vendored and downloaded code excluded), of which 310 live rows
> below; per phase: P1 2 · P2 26 · P3 17 · P4 9 · P5 26 · P6 51 · P7 20 · P8 86 · P9 27 · P10 30 · PROJECT-ONLY 16. Superseded tools appear only as pointers to their successor (30 pointer rows); one-offs are omitted. Table rows in all: 340 (the installer checks its copy against this figure).
## P1 — extraction + manifest
@@ -328,6 +328,7 @@
| `ghidra_scripts/ApplySymbols.java` | apply curated names and signatures inside the analysis tool and save | The in-tool half of that mirror: apply curated names and signatures, save on exit | none |
| `delever_pack.py` | build the pack one agent needs to read and crack one residue exemplar, without touching the tree | The Phase-36 T7 pack builder (one agent at a time): per residue exemplar of ≥N copies a directory under .run/P36/agents/ with the TU path, the body as the tree has it, the lever-free body (the seed), the residual as mnemonic blocks from delever_search --try (a scratch compile, no tree write), the ledger's NEEDED sites, and every engine attempt with its best moves; ORDER.tsv ranks the exemplars by the best distance reached, then copies. PROMPT.md beside them is the agent's brief. | repo scratch paths; the engine's outcomes and traces |
| `lever_census.py` | census every compiler-forcing construct in the C and gate the levers-off phase | The Phase-36 census of lever sites (register pins, asm statements by kind, volatile levers, bare register, asm-label aliases, builtins, attributes; the whole-body hand-asm routines and the GTE ops set apart) derived from the shared-body scanner with a per-token coverage assertion against the raw text, four known-true controls, the !FAKE marker split, --check (0 unmarked pins/asm, 0 orphan markers) and --strict (0 pins, 0 asm) gates, --sites for the delever ledger, a fixture self-test | repo paths, the shared-body scanner |
| `type_census.py` | census every struct definition, raw pointer-cast dereference and function declaration in the C, and cluster the cast sites into the types the tree needs (the struct map) | The Phase-37 type census: struct/union/typedef definitions fleet-wide with o32 layouts (duplicate classes by layout+member evidence, VARIANT camps, dead and shadowed canonical names), every cast site in six forms (P *(T*)(…), I *(T*)ident, X ((T*)e)[i], M M2C_FIELD, A address-of, C typed cast-member) with base class/offset/width/sign/access and a per-form coverage assertion against an independent raw regex, the declaration layer (definitions K&R-read, extern spellings per name, multi-body names, asm-label aliases, builtins, attributes, argcheck's lying set), global blocks (runs of adjacent scalar D_ symbols), four known-true controls, and the struct map — union-find over evidence edges only (same global, argument flow into a parameter the callee dereferences with shared offsets, single-source assignment/return flow, pointer-field flow, body-hash identity) with a width-conflict veto; writes type_census.json/txt, struct_map(.top).json, sites.jsonl (--sites), parked.tsv (the P36 parked classes with reasons) and docs/struct-map.md; --check is the T8 gate; --selftest | repo paths, the shared-body scanner, argcheck, the P36 ledger (parked.tsv) |
| `gte_consolidate.py` | consolidate the GTE coprocessor inline-asm macros under Sony's names in one header and sweep dead lever macros | The Phase-36 T5 tool: every asm-bearing macro definition and direct GTE statement SIGNED by the build's own maspsx→as tail (template bytes with operands bound to fixed registers, operand counts, clobbers); one canonical text per signature named by PsyQ's inline_c.h convention (Sony's file supplies names and clobber lists, never opcode words) written to include/gte_inline.h; per file the canonical duplicates deleted, private names renamed, a variant with extra clobbers tried as canonical and kept as a marked <name>_m lever only when the object differs, direct statements rewritten into canonical calls (a concatenation of two included); every file judged through every recipe; --sweep deletes dead asm-bearing macros and drops a compound macro's inner asm when byte-neutral | Sony's inline_c.h path, the census sites, the oracle |
| `macro_to_header.py` | convert a shared-body macro header into per-function plain-C headers included at each site | The Phase-35 converter: every DEFINE_ macro body becomes a plain-C header under src/shared/<space>/ included at its site, the legacy name-parameterized headers converted, the registry text-edited, the macro header deleted; --plan / --apply / --finalize / --verify | the macro form is this project's; a kit-born project shares headers from its first bank |
| `asm_verbatim.py` | emit a function's target assembly as an inline-assembly body | Emits the file-scope inline-assembly body form from a disassembly file | repo asm layout |
+40
View File
@@ -1678,6 +1678,46 @@ fills fast). Nothing is leaking — but the host does not get the memory back on
length / priority / hard reg (global.c `allocno_compare`); the callee-saved bank is that order (§501-R).
- `tools/cc1_dumps.sh` now also writes the `.loop` dump (`-dL`): the "not desirable"/"moved to"/"matches" lines (§501-R).
### §P37 S106 — 2026-09-12: the type census and the struct map (Phase 37 T1)
- **`tools/type_census.py [-j N] [--sites] [--check] [--selftest] [--out-dir .run/P37/census]`** — the structs phase's instrument.
One walker per file (worker processes; `share_census.mask_text`/`scan_text` for the masking and the function spans; a per-file cache
keyed by mtime/size/tool stamp under `.run/P37/census/cache/`, ~1 GB, ignored) returns: every struct/union/typedef **definition** with
its o32 layout (`Resolver`: scalars, pointers, arrays, nested aggregates, unions, bit-fields, `packed`; a TU's own definitions first, then
the canonical header, then the SDK sizes) and its layout hash — duplicate classes in three tiers (1 identical meaningful member names,
2 opaque copy blocks, 3 layout twins with different meaningful names — NOT duplicates, reported), VARIANT camps (one name, several
layouts — §64a), dead canonical names, canonical names redefined in `.c`; every **cast site** in six forms — P `*(T *)(…)`, I
`*(T *)ident` / `*(T *)&D_x` / `*(T *)0x80…`, X `((T *)e)[i]`, M `M2C_FIELD(…)`, A `(T *)(base + k)` (address-of, no deref), C
`((T *)e)->f` (typed cast-member, already a COMPONENT_REF — the rewrite's rung 1) — each with base class (param / local / global by
value `PTR:` / global by address `AT:` / abs / nested / other), offset, accessed width and sign, load/store/rmw, stride; **coverage
(R32)**: per form, sites recorded == an independent raw regex over the same masked text, else exit 1 (the readability regex's
raw-text count is reported beside it for continuity: 411,850 vs 409,007 masked); the **declaration layer** (definitions K&R-read,
4.28 M extern function declarations over 12,139 names, 3,870 spelled >1 way, 6,415 names with >1 body text, data externs typed >1
way, asm-label aliases, builtins, attributes, `argcheck`'s lying set); **global blocks** (runs of ≥4 address-adjacent scalar `D_`
symbols by declared width); **the struct map** — union-find over EVIDENCE edges only: a parameter's positional and named nodes; an
argument into a callee parameter ONLY when the callee dereferences it (`typed_params`) AND, when both sides carry offsets, the
callee's map is structured (≥2 offsets) and shares ≥1 offset of equal width with the caller's; single-source locals only (a local
assigned from two sources is a reused temp and carries nothing); `&D_x` → `AT:D_x`; `x = f()` / `return v` through `R:<f>`; pointer-field
reads through `FLD:<cluster>:<off>` to a fixpoint; a **width-conflict veto** on every merge (a bare global's declared type seeds its
node); a function's identity is its body hash (`H:<shared header>` / `F:<nhash>` / `X:<space>:<name>`), never its name. Per type:
members, sites, bodies, layout from the sites, width conflicts vs same-width sign mixes (a store's signedness leaves no byte), the
evidence mix that built it, a `suspect` flag. Four **controls** (R39): the player block's agreed widths (+ the doc-disputed
`D_80078F08/0C`: the code says 4, `actor-struct.md` says 2), MATRIX 32 vs MATRIX_L48 48, `Prim_8016E7C8` 1,192/1,192 in one layout (two
spellings), the `D_800A651C` TU-CONFLICT row. Writes `type_census.json/.txt`, `struct_map.json` (full, ignored) + `struct_map_top.json`
(300 types, tracked), `sites.jsonl` (`--sites`, 213 MB, ignored), **`parked.tsv`** (the 24 P36 parked classes with copies/sites/kinds,
a `needs` class read from each pack's `mechanism.md`, the patch paths) and **`docs/struct-map.md`** (generated, R75). `--check` is
T8's gate (0 duplicate classes, 0 definitions outside the canonical files, 0 raw casts, 0 lying declarations). Fleet run ≈ 3.5 min at
`-j 16` (walk 49 s). Selftest 21/21 on a fixture with every form.
- **`tools/lever_census.py --check --strict` reads its own words** (S106): a DIRECT GTE coprocessor asm statement in a function body
(kinds `gte` / `gte-unsigned` — Sony's idiom spelled inline instead of as `include/gte_inline.h`'s macro call; 6,717 today, incl.
`func_8013D9B0`'s 268 unsigned respellings) is an asm statement outside the GTE header and FAILS `--strict`; the `--check` headline keeps
the P36 definition (4,010) for the series' continuity. The three stale known-true controls were re-keyed (R85): `func_800226C0` 14 pins,
`func_80178004.h` 8, the bare-name control moved to `func_801896EC` (2) — each counted independently with the gate-1 grep.
- **`tools/readability_progress.py --snapshot`** now REFUSES a stale type census (its `head` must be HEAD) and appends the census's
columns (the four dereference forms, the typed cast-member intermediate, definitions/layouts/duplicate classes, the map); the TSV is
read by column NAME (older rows carry blanks). **`tools/progress.py`** publishes `counts.types` and a "Types (Phase 37, …)" README
sentence, with two dated `corrections` entries (the four-form count vs the one-form regex; `--strict`'s direct GTE statements).
## Retired tools (`tools/sunset/`, Phase 33.5)
*The rows below were moved out of the tool tables above when their tools were retired under the owner's criterion (superseded by a named
+1
View File
@@ -77,3 +77,4 @@ date milestone head sites_AB pins asm bodies_AB distinct_AB marked unmarked gte_
2026-09-11 S105 f10 (4) ff22c1fba 4026 2152 1874 1985 679 4026 0 450 314 1589 50 7802 445 76
2026-09-11 S105 f11 (4 + 4 copies) — T7 ENDS 31cf8695f 4010 2141 1869 1980 674 4010 0 450 314 1589 50 7802 445 76
2026-09-11 P36 close (T8/T9 done; the @unstuck retag) 60c4bb1cc 4010 2141 1869 1980 674 4010 0 450 314 1589 50 7802 445 76
2026-09-11 P37 T1 — the lever census re-keyed (controls) and --strict made literal; 4,010 unchanged 23fc5d215 4010 2141 1869 1980 674 4010 0 450 314 1589 50 7802 445 76
1 date milestone head sites_AB pins asm bodies_AB distinct_AB marked unmarked gte_levers per_tu_asm_macros class_C class_D class_E class_F class_G
77 2026-09-11 S105 f10 (4) ff22c1fba 4026 2152 1874 1985 679 4026 0 450 314 1589 50 7802 445 76
78 2026-09-11 S105 f11 (4 + 4 copies) — T7 ENDS 31cf8695f 4010 2141 1869 1980 674 4010 0 450 314 1589 50 7802 445 76
79 2026-09-11 P36 close (T8/T9 done; the @unstuck retag) 60c4bb1cc 4010 2141 1869 1980 674 4010 0 450 314 1589 50 7802 445 76
80 2026-09-11 P37 T1 — the lever census re-keyed (controls) and --strict made literal; 4,010 unchanged 23fc5d215 4010 2141 1869 1980 674 4010 0 450 314 1589 50 7802 445 76
+1
View File
@@ -123,6 +123,7 @@ counted, not marked). E, F and G belong to the canonical type layer and are the
| 2026-09-11 | S105 f10 (4) | 2152 | 1874 | **4026** | 1985 | 679 | 450 | 314 | 1589 | 50 | 7802 | 445 | 76 | `ff22c1fba` |
| 2026-09-11 | S105 f11 (4 + 4 copies) — T7 ENDS | 2141 | 1869 | **4010** | 1980 | 674 | 450 | 314 | 1589 | 50 | 7802 | 445 | 76 | `31cf8695f` |
| 2026-09-11 | P36 close (T8/T9 done; the @unstuck retag) | 2141 | 1869 | **4010** | 1980 | 674 | 450 | 314 | 1589 | 50 | 7802 | 445 | 76 | `60c4bb1cc` |
| 2026-09-11 | P37 T1 — the lever census re-keyed (controls) and --strict made literal; 4,010 unchanged | 2141 | 1869 | **4010** | 1980 | 674 | 450 | 314 | 1589 | 50 | 7802 | 445 | 76 | `23fc5d215` |
### The campaign — every batch, from the ledger (derived on every render)
+48
View File
@@ -63,6 +63,38 @@
"gte_sites": 6447,
"hand_asm_routines_in_c_shells": 22,
"hand_asm_routine_sites": 2682
},
"types": {
"date": "2026-09-12",
"head": "23fc5d215",
"what": "the structs phase's counters: raw pointer-cast dereferences in four forms (P *(T*)(\u2026), I *(T*)ident, X ((T*)e)[i], M M2C_FIELD), struct definitions and their duplicate classes, lying call declarations, and the struct map's types (Phase 37 drives the first three to 0)",
"raw_cast_sites": 503016,
"raw_cast_forms": {
"P": 409007,
"I": 60666,
"X": 13800,
"A": 18912,
"C": 36681,
"M": 19543
},
"raw_cast_bodies": 69497,
"address_of_sites": 18912,
"typed_cast_member_sites": 36681,
"absolute_address_casts": 0,
"struct_definitions": 7261,
"canonical_definitions": 1179,
"definitions_in_c_files": 5995,
"distinct_layouts": 525,
"duplicate_classes": 206,
"duplicate_names": 2789,
"variant_names": 39,
"dead_canonical_names": 141,
"lying_declarations": 98648,
"lying_callees": 1609,
"asm_label_aliases": 5749,
"multi_spelled_callees": 3870,
"struct_map_types": 18760,
"struct_map_explained_pct": 99.2
}
},
"corrections": [
@@ -97,6 +129,22 @@
"delta": 22,
"cause": "the \u00a7265 lane's IN-FUNCTION form (a whole routine as one __asm__ statement inside a C shell) was invisible to the file-scope detector behind the manifest: 22 scratchpad stack-switch trampolines (one private copy per overlay, 2,682 sites) are hand asm and are listed PERMANENT-VERBATIM; a 23rd asm-body is -O0 compiler output and is listed DECOMPILE-NOW",
"command": "tools/lever_census.py; tools/verbatim_check.py"
},
{
"date": "2026-09-12",
"phase": "P37 T1",
"metric": "counts.types.raw_cast_sites",
"delta": 91166,
"cause": "the readability series' regex counted one cast form (`*(T *)(`: 411,850 over raw text); the type census counts four dereference forms over comment-masked text \u2014 P 409,007 + I 60,666 (`*(T *)ident`, `*(T *)&D_x`) + X 13,800 (`((T *)e)[i]`) + M 19,543 (`M2C_FIELD`) = 503,016 \u2014 with a coverage assertion per form; 18,912 address-of casts and 36,681 typed cast-member accesses are counted apart",
"command": "tools/type_census.py"
},
{
"date": "2026-09-12",
"phase": "P37 T1",
"metric": "counts.levers (--strict)",
"delta": 6717,
"cause": "lever_census --strict now reads its own words: 6,717 direct GTE coprocessor asm statements in function bodies (Sony's idiom spelled inline instead of as the header's macro call; kinds gte/gte-unsigned, incl. func_8013D9B0's 268 unsigned respellings) are asm statements outside the GTE header \u2014 the P36 headline (--check, 4,010) keeps its definition for the series' continuity",
"command": "tools/lever_census.py --check --strict"
}
],
"per_binary": [
+2 -1
View File
@@ -1,3 +1,4 @@
date label commit definitions narrow_decls callees kr_empty narrow pinned_rows pinned_bodies raw_casts struct_members
date label commit definitions narrow_decls callees kr_empty narrow pinned_rows pinned_bodies raw_casts struct_members deref_all form_P form_I form_X form_M addr_form typed_cast_member struct_defs canon_defs in_c_defs distinct_layouts dup_classes dup_names map_types map_pct
2026-09-10 P36 S102 — after the 16,759 free declaration repairs 51028a78d377b0ff8e0a12a86500ed2ae1f2346d 15626 94001 1564 86701 7300 461 314 414148 173286
2026-09-11 P36 close 7a7f78e255ec3661992d12b5ceb1bd2ec2c1d680 15726 98648 1609 91357 7291 33 25 411850 177902
2026-09-11 P37 T1 — the type census (four forms, definitions, the map) 23fc5d21592452084c7ae11fed1e98e0a40913a7 15726 98648 1609 91357 7291 33 25 411850 177902 503016 409007 60666 13800 19543 18912 36681 7261 1179 5995 525 206 2789 18760 99.2
1 date label commit definitions narrow_decls callees kr_empty narrow pinned_rows pinned_bodies raw_casts struct_members deref_all form_P form_I form_X form_M addr_form typed_cast_member struct_defs canon_defs in_c_defs distinct_layouts dup_classes dup_names map_types map_pct
2 2026-09-10 P36 S102 — after the 16,759 free declaration repairs 51028a78d377b0ff8e0a12a86500ed2ae1f2346d 15626 94001 1564 86701 7300 461 314 414148 173286
3 2026-09-11 P36 close 7a7f78e255ec3661992d12b5ceb1bd2ec2c1d680 15726 98648 1609 91357 7291 33 25 411850 177902
4 2026-09-11 P37 T1 — the type census (four forms, definitions, the map) 23fc5d21592452084c7ae11fed1e98e0a40913a7 15726 98648 1609 91357 7291 33 25 411850 177902 503016 409007 60666 13800 19543 18912 36681 7261 1179 5995 525 206 2789 18760 99.2
+7 -5
View File
@@ -3,12 +3,14 @@
> **Generated by `tools/readability_progress.py --snapshot`; never typed (R75).** Companion to
> `docs/levers.md`, which counts the compiler-forcing levers. This one counts the two things that are wrong
> with the source even where no lever remains: call declarations that are FALSE, and memory read through raw
> pointer casts where the original had a struct.
> pointer casts where the original had a struct. From Phase 37 the row carries the type census's columns
> (`tools/type_census.py`): all four dereference forms, the typed cast-member intermediate, the definitions and the map.
| date | label | commit | lying declarations | of which `()` | of which `(void)` | in a pinned body | raw cast derefs | struct member reads |
|---|---|---|---:|---:|---:|---:|---:|---:|
| 2026-09-10 | P36 S102 — after the 16,759 free declaration repairs | `51028a78d` | 94001 | 86701 | 7300 | 461 | 414148 | 173286 |
| 2026-09-11 | P36 close | `7a7f78e25` | 98648 | 91357 | 7291 | 33 | 411850 | 177902 |
| date | label | commit | lying declarations | of which `()` | of which `(void)` | in a pinned body | raw cast derefs (one form, raw text) | struct member reads | **raw derefs, four forms** | typed cast-member | struct defs (canonical / in .c) | layouts | duplicate classes / names | map types (% sites) |
|---|---|---|---:|---:|---:|---:|---:|---:|---:|---:|---|---:|---|---|
| 2026-09-10 | P36 S102 — after the 16,759 free declaration repairs | `51028a78d` | 94001 | 86701 | 7300 | 461 | 414148 | 173286 | **—** | — | — | — | — | — |
| 2026-09-11 | P36 close | `7a7f78e25` | 98648 | 91357 | 7291 | 33 | 411850 | 177902 | **—** | — | — | — | — | — |
| 2026-09-11 | P37 T1 — the type census (four forms, definitions, the map) | `23fc5d215` | 98648 | 91357 | 7291 | 33 | 411850 | 177902 | **503016** | 36681 | 7261 (1179 / 5995) | 525 | 206 / 2789 | 18760 (99.2 %) |
**How to read it.** A *lying declaration* is a call site whose in-scope declaration names fewer parameters
than the callee's own definition. It is not a style problem: on this processor an argument travels in a
+210
View File
@@ -0,0 +1,210 @@
# The struct map — the types the fleet's cast sites need (Phase 37 T1)
> **Generated by `tools/type_census.py` at `23fc5d215` (2026-09-12T05:44:31Z); never typed (R75).** Every raw pointer-cast dereference in `src/` was assigned to a base (a parameter, a local, a global by value or by address, an absolute address) and the bases were clustered by EVIDENCE only — the same global symbol, an argument passed to a callee's parameter, an assignment or return, a pointer field read, a shared body's fleet-wide identity — never by a similar offset signature. Each cluster is one type the tree needs. Names are placeholders (`Unkstruct_<addr>`: the lowest global instance's address, else the lowest member function's); fields are placeholders (`unk<HEX>`) until Phase 38 cites evidence.
**18760 types explain 498896 of 503016 dereference sites (99.2 %); 4120 sites have a base the census could not classify; 729 types carry a width conflict.** Merges by evidence: param 36550, assign 14717, arg 10176, field 9623, ret-of 3410, return 1523, assign& 1051, arg& 270.
| # | type | sites | bodies | fields | size ≥ | width conflicts (+sign mixes) | instance globals | pointer globals |
|---:|---|---:|---:|---:|---:|---:|---|---|
| 1 | `Unkstruct_800B5CB8` | 107598 | 11186 | 134 | 0x10c | 50 (+55 sign) | D_800B5CB8, D_800D3888, D_80181448, D_80181538… | D_8006386C, D_80074778, D_80074780, D_80074784… |
| 2 | `Unkstruct_80126B58` | 65397 | 17047 | 175 | 0x24c | 50 (+60 sign) | D_80126B58 | D_80126B58 |
| 3 | `Unkstruct_8018E71C` | 6745 | 396 | 7 | 0x10 | 0 (+0 sign) | D_8018E71C | |
| 4 | `Unkstruct_dac960ce` | 4464 | 124 | 13 | 0x24c | 0 (+2 sign) | | |
| 5 | `Unkstruct_0caecd54` | 4340 | 124 | 23 | 0xfe | 0 (+1 sign) | | |
| 6 | `Unkstruct_f8ed2b9f` | 4061 | 4061 | 1 | 0x217 | 0 (+0 sign) | | |
| 7 | `Unkstruct_a32b99a1` | 3936 | 123 | 8 | 0x4b | 0 (+1 sign) | | |
| 8 | `Unkstruct_8e3dbe51` | 3930 | 131 | 5 | 0x4c | 0 (+1 sign) | | |
| 9 | `Unkstruct_8014A1B0` | 3778 | 542 | 13 | 0xfe | 0 (+1 sign) | | |
| 10 | `Unkstruct_80128EA8` | 3311 | 632 | 18 | 0x38 | 0 (+13 sign) | | |
| 11 | `Unkstruct_ade2e8a0` | 3271 | 196 | 26 | 0xa4 | 3 (+9 sign) | | |
| 12 | `Unkstruct_1fa9e810` | 3144 | 131 | 3 | 0x49 | 0 (+0 sign) | | |
| 13 | `Unkstruct_30b21035` | 3100 | 124 | 13 | 0x54 | 0 (+0 sign) | | |
| 14 | `Unkstruct_80126948` | 2986 | 832 | 34 | 0xa4 | 0 (+10 sign) | D_80126948, D_80126E60 | D_80114EE8, D_801151D4, D_80126948, D_80126E60… |
| 15 | `Unkstruct_adc0bee4` | 2646 | 126 | 8 | 0x34 | 0 (+3 sign) | | |
| 16 | `Unkstruct_198fc7cc` | 2580 | 129 | 16 | 0x38 | 3 (+1 sign) | | |
| 17 | `Unkstruct_801439FC` | 2489 | 981 | 57 | 0x10c | 9 (+22 sign) | | |
| 18 | `Unkstruct_80130D48` | 2382 | 587 | 25 | 0x64 | 6 (+3 sign) | | D_80072C84, D_80078E78 |
| 19 | `Unkstruct_ed8f1335` | 2356 | 124 | 18 | 0x24 | 0 (+0 sign) | | |
| 20 | `Unkstruct_8016B4F8` | 2140 | 535 | 5 | 0x30 | 0 (+0 sign) | | |
| 21 | `Unkstruct_80139C7C` | 2111 | 265 | 14 | 0x44 | 0 (+3 sign) | | |
| 22 | `Unkstruct_b047cdf2` | 2108 | 124 | 6 | 0x20 | 0 (+0 sign) | | |
| 23 | `Unkstruct_2729e670` | 2091 | 123 | 6 | 0x4b | 0 (+0 sign) | | |
| 24 | `Unkstruct_dd542e54` | 2016 | 126 | 7 | 0x18 | 0 (+0 sign) | | |
| 25 | `Unkstruct_f49880fd` | 2000 | 125 | 6 | 0x54 | 0 (+1 sign) | | |
| 26 | `Unkstruct_a8d34bce` | 1948 | 1948 | 1 | 0x215 | 0 (+0 sign) | | |
| 27 | `Unkstruct_568f7bda` | 1875 | 125 | 9 | 0x38 | 0 (+0 sign) | | |
| 28 | `Unkstruct_8016DF5C` | 1791 | 131 | 9 | 0x38 | 0 (+3 sign) | | |
| 29 | `Unkstruct_f1f49381` | 1764 | 126 | 10 | 0x38 | 0 (+0 sign) | | |
| 30 | `Unkstruct_8011F7A8` | 1746 | 271 | 7 | 0x11e | 0 (+0 sign) | D_8011F7A8 | |
| 31 | `Unkstruct_84612d18` | 1722 | 123 | 8 | 0x4b | 0 (+0 sign) | | |
| 32 | `Unkstruct_57db4d07` | 1664 | 128 | 13 | 0x0 | 13 (+0 sign) | | |
| 33 | `Unkstruct_4692fc17` | 1612 | 124 | 4 | 0x1e | 0 (+3 sign) | | |
| 34 | `Unkstruct_eda88e53` | 1596 | 133 | 6 | 0x54 | 6 (+0 sign) | | |
| 35 | `Unkstruct_8012D3B4` | 1588 | 183 | 23 | 0x24 | 16 (+9 sign) | | D_80074808, D_800A5E60 |
| 36 | `Unkstruct_4e09b6d9` | 1572 | 131 | 9 | 0x32 | 0 (+1 sign) | | |
| 37 | `Unkstruct_23e45db5` | 1512 | 126 | 11 | 0x16 | 0 (+0 sign) | | |
| 38 | `Unkstruct_47470ce3` | 1488 | 124 | 6 | 0x1e | 0 (+0 sign) | | |
| 39 | `Unkstruct_b5c0372a` | 1441 | 131 | 9 | 0x58 | 0 (+0 sign) | | |
| 40 | `Unkstruct_0980b9f0` | 1441 | 131 | 4 | 0x49 | 0 (+0 sign) | | |
| 41 | `Unkstruct_ba6e2e9f` | 1439 | 1439 | 1 | 0x4 | 0 (+0 sign) | | |
| 42 | `Unkstruct_a68f6d03` | 1364 | 124 | 9 | 0x14 | 0 (+0 sign) | | |
| 43 | `Unkstruct_8fdd92d1` | 1300 | 130 | 4 | 0x24 | 2 (+0 sign) | | |
| 44 | `Unkstruct_110cf29e` | 1250 | 125 | 7 | 0x2c | 0 (+0 sign) | | |
| 45 | `Unkstruct_4db8cec8` | 1240 | 124 | 8 | 0x36 | 0 (+0 sign) | | |
| 46 | `Unkstruct_f0bc3b7a` | 1240 | 124 | 7 | 0x100 | 0 (+0 sign) | | |
| 47 | `Unkstruct_297e7547` | 1240 | 124 | 10 | 0x58 | 0 (+0 sign) | | |
| 48 | `Unkstruct_dd59c999` | 1240 | 124 | 6 | 0x38 | 0 (+2 sign) | | |
| 49 | `Unkstruct_919ca3ea` | 1230 | 123 | 6 | 0x10 | 0 (+0 sign) | | |
| 50 | `Unkstruct_a459e3e5` | 1220 | 122 | 6 | 0x34 | 0 (+0 sign) | | |
| 51 | `Unkstruct_8014CA00` | 1219 | 407 | 4 | 0x2e | 0 (+3 sign) | | |
| 52 | `Unkstruct_74787850` | 1206 | 1073 | 1 | 0x2 | 0 (+1 sign) | | D_801152A8 |
| 53 | `Unkstruct_f9a7989e` | 1179 | 131 | 3 | 0x36 | 0 (+1 sign) | | |
| 54 | `Unkstruct_0b30043d` | 1128 | 376 | 3 | 0x5e | 0 (+0 sign) | | |
| 55 | `Unkstruct_301381d4` | 1116 | 124 | 3 | 0x36 | 0 (+1 sign) | | |
| 56 | `Unkstruct_0ced46e2` | 1116 | 124 | 5 | 0xfe | 0 (+0 sign) | | |
| 57 | `Unkstruct_f153f338` | 1107 | 123 | 5 | 0x34 | 0 (+0 sign) | | |
| 58 | `Unkstruct_50a3f6b4` | 1040 | 130 | 3 | 0x36 | 0 (+0 sign) | | |
| 59 | `Unkstruct_800B9A02` | 992 | 434 | 1 | 0x2 | 0 (+0 sign) | D_800B9A02 | |
| 60 | `Unkstruct_f74e3af7` | 992 | 124 | 5 | 0xfe | 0 (+0 sign) | | |
| 61 | `Unkstruct_6b138cb0` | 931 | 133 | 7 | 0x20 | 1 (+0 sign) | | |
| 62 | `Unkstruct_b774eeeb` | 917 | 131 | 4 | 0x41 | 0 (+0 sign) | | |
| 63 | `Unkstruct_6d856e9d` | 917 | 131 | 5 | 0x1e | 3 (+1 sign) | | |
| 64 | `Unkstruct_d0c6cce6` | 917 | 131 | 4 | 0x38 | 0 (+0 sign) | | |
| 65 | `Unkstruct_859b4fab` | 910 | 130 | 4 | 0xb0 | 0 (+0 sign) | | |
| 66 | `Unkstruct_801463A0` | 907 | 210 | 13 | 0x54 | 0 (+1 sign) | | D_80126B78 |
| 67 | `Unkstruct_6d3f3f5d` | 889 | 127 | 6 | 0x38 | 0 (+0 sign) | | |
| 68 | `Unkstruct_1e86c313` | 882 | 126 | 4 | 0x8 | 0 (+0 sign) | | |
| 69 | `Unkstruct_a41ec127` | 882 | 126 | 6 | 0x38 | 0 (+0 sign) | | |
| 70 | `Unkstruct_3f697924` | 875 | 125 | 5 | 0x38 | 0 (+0 sign) | | |
| 71 | `Unkstruct_e505dcd3` | 868 | 124 | 4 | 0x8 | 0 (+0 sign) | | |
| 72 | `Unkstruct_fe02110c` | 868 | 124 | 3 | 0x10 | 0 (+2 sign) | | |
| 73 | `Unkstruct_92677d11` | 861 | 123 | 5 | 0x240 | 0 (+0 sign) | | |
| 74 | `Unkstruct_86465c2c` | 861 | 123 | 7 | 0x20 | 0 (+0 sign) | | |
| 75 | `Unkstruct_ffd2397c` | 854 | 122 | 5 | 0x34 | 0 (+0 sign) | | |
| 76 | `Unkstruct_17738e2c` | 821 | 30 | 32 | 0xa4 | 12 (+5 sign) | | |
| 77 | `Unkstruct_801270C0` | 821 | 820 | 1 | 0x2 | 0 (+0 sign) | D_801270C0 | |
| 78 | `Unkstruct_2932a0a7` | 798 | 133 | 6 | 0x12 | 5 (+0 sign) | | |
| 79 | `Unkstruct_0a8f505b` | 790 | 83 | 14 | 0x10c | 0 (+5 sign) | | |
| 80 | `Unkstruct_12f4cee2` | 786 | 131 | 5 | 0x28 | 0 (+0 sign) | | |
| 81 | `Unkstruct_d2490774` | 786 | 131 | 3 | 0xb0 | 0 (+0 sign) | | |
| 82 | `Unkstruct_80135260` | 780 | 130 | 3 | 0x54 | 0 (+0 sign) | | |
| 83 | `Unkstruct_b196f9c0` | 768 | 128 | 5 | 0x14 | 1 (+0 sign) | | |
| 84 | `Unkstruct_36c327cf` | 762 | 127 | 2 | 0x18 | 0 (+0 sign) | | |
| 85 | `Unkstruct_6cd0e445` | 756 | 126 | 2 | 0x10 | 0 (+0 sign) | | |
| 86 | `Unkstruct_c0b9c5d5` | 750 | 125 | 6 | 0x10 | 0 (+0 sign) | | |
| 87 | `Unkstruct_64375b18` | 744 | 124 | 5 | 0xa0 | 0 (+0 sign) | | |
| 88 | `Unkstruct_438adcd1` | 744 | 124 | 5 | 0x14 | 0 (+0 sign) | | |
| 89 | `Unkstruct_97b6f459` | 744 | 124 | 5 | 0x28 | 0 (+0 sign) | | |
| 90 | `Unkstruct_38975874` | 744 | 124 | 4 | 0x84 | 0 (+0 sign) | | |
| 91 | `Unkstruct_76b1caf3` | 744 | 124 | 2 | 0x3 | 0 (+0 sign) | | |
| 92 | `Unkstruct_8016BBE0` | 690 | 139 | 9 | 0x38 | 0 (+0 sign) | | |
| 93 | `Unkstruct_80146A6C` | 680 | 137 | 7 | 0x2c | 0 (+0 sign) | | |
| 94 | `Unkstruct_800AF630` | 671 | 537 | 3 | 0xa3dc | 0 (+0 sign) | D_800AF630 | |
| 95 | `Unkstruct_8012C284` | 668 | 533 | 1 | 0x2 | 0 (+1 sign) | | D_80126720 |
| 96 | `Unkstruct_80115128` | 667 | 534 | 1 | 0x2 | 0 (+0 sign) | D_80115128 | |
| 97 | `Unkstruct_3271c3cc` | 665 | 133 | 3 | 0x5e | 0 (+0 sign) | | |
| 98 | `Unkstruct_61789347` | 665 | 133 | 0 | 0x0 | 0 (+0 sign) | | |
| 99 | `Unkstruct_05fa9429` | 665 | 133 | 0 | 0x0 | 0 (+0 sign) | | |
| 100 | `Unkstruct_801345F8` | 665 | 133 | 0 | 0x0 | 0 (+0 sign) | | |
| 101 | `Unkstruct_801345F8` | 665 | 133 | 0 | 0x0 | 0 (+0 sign) | | |
| 102 | `Unkstruct_801152A0` | 665 | 399 | 1 | 0x2 | 0 (+0 sign) | D_801152A0 | |
| 103 | `Unkstruct_89230a8b` | 665 | 133 | 5 | 0x1c | 0 (+0 sign) | | |
| 104 | `Unkstruct_fdd04bae` | 650 | 130 | 3 | 0x38 | 0 (+0 sign) | | |
| 105 | `Unkstruct_eb8b6fbf` | 645 | 129 | 5 | 0xfe | 0 (+0 sign) | | |
| 106 | `Unkstruct_90d0825c` | 645 | 129 | 5 | 0x1c | 1 (+0 sign) | | |
| 107 | `Unkstruct_27c177f1` | 645 | 129 | 4 | 0x34 | 0 (+0 sign) | | |
| 108 | `Unkstruct_4f9f60b8` | 630 | 126 | 4 | 0x78 | 0 (+0 sign) | | |
| 109 | `Unkstruct_7a31a22f` | 630 | 126 | 2 | 0x19c | 0 (+0 sign) | | |
| 110 | `Unkstruct_187abeff` | 630 | 126 | 5 | 0x68 | 0 (+0 sign) | | |
| 111 | `Unkstruct_dafba7ce` | 630 | 126 | 4 | 0x20 | 0 (+0 sign) | | |
| 112 | `Unkstruct_20d4328b` | 630 | 126 | 4 | 0x38 | 0 (+0 sign) | | |
| 113 | `Unkstruct_d94ab931` | 625 | 125 | 4 | 0x6 | 2 (+1 sign) | | |
| 114 | `Unkstruct_7ef9c9ef` | 625 | 125 | 4 | 0x6 | 2 (+1 sign) | | |
| 115 | `Unkstruct_8ce68494` | 625 | 125 | 2 | 0x1a | 0 (+0 sign) | | |
| 116 | `Unkstruct_57ae03d1` | 620 | 124 | 2 | 0x2c | 0 (+0 sign) | | |
| 117 | `Unkstruct_af1e9d57` | 620 | 248 | 4 | 0x64 | 0 (+0 sign) | | |
| 118 | `Unkstruct_172cbd29` | 620 | 124 | 2 | 0x1fc | 0 (+0 sign) | | |
| 119 | `Unkstruct_2c2c1d2e` | 620 | 124 | 4 | 0x24 | 0 (+0 sign) | | |
| 120 | `Unkstruct_aaf4c4dd` | 615 | 615 | 1 | 0x16 | 0 (+0 sign) | | |
| 121 | `Unkstruct_293d71dc` | 600 | 75 | 0 | 0x0 | 0 (+0 sign) | | |
| 122 | `Unkstruct_78eaa73c` | 553 | 7 | 15 | 0x10a | 0 (+7 sign) | | |
| 123 | `Unkstruct_8011512E` | 532 | 133 | 1 | 0x2 | 0 (+0 sign) | D_8011512E | |
| 124 | `Unkstruct_8016BFA8` | 532 | 133 | 4 | 0x24 | 0 (+0 sign) | | |
| 125 | `Unkstruct_30befa8c` | 520 | 130 | 3 | 0xfe | 0 (+0 sign) | | |
| 126 | `Unkstruct_00ddc7c9` | 520 | 130 | 1 | 0x2 | 1 (+0 sign) | | |
| 127 | `Unkstruct_01082f7a` | 520 | 520 | 1 | 0x4 | 0 (+0 sign) | | |
| 128 | `Unkstruct_db0ee441` | 516 | 129 | 4 | 0x38 | 0 (+0 sign) | | |
| 129 | `Unkstruct_7476116e` | 516 | 129 | 1 | 0x4 | 0 (+0 sign) | | |
| 130 | `Unkstruct_290ce261` | 504 | 126 | 3 | 0xfe | 0 (+0 sign) | | |
| 131 | `Unkstruct_d6100faa` | 504 | 126 | 3 | 0x20 | 0 (+0 sign) | | |
| 132 | `Unkstruct_5ebcbddc` | 504 | 126 | 3 | 0xe | 0 (+0 sign) | | |
| 133 | `Unkstruct_7cb40b10` | 500 | 500 | 1 | 0x4 | 0 (+0 sign) | | |
| 134 | `Unkstruct_4e078af8` | 496 | 124 | 2 | 0x4 | 0 (+2 sign) | | |
| 135 | `Unkstruct_494cef68` | 496 | 124 | 2 | 0x188 | 0 (+0 sign) | | |
| 136 | `Unkstruct_93df0322` | 496 | 124 | 4 | 0x38 | 0 (+0 sign) | | |
| 137 | `Unkstruct_3b2b6e45` | 496 | 124 | 4 | 0x38 | 0 (+0 sign) | | |
| 138 | `Unkstruct_31283f15` | 492 | 123 | 3 | 0x6 | 0 (+0 sign) | | |
| 139 | `Unkstruct_a05973fa` | 492 | 123 | 3 | 0x2c | 0 (+0 sign) | | |
| 140 | `Unkstruct_48c11385` | 441 | 21 | 5 | 0x68 | 0 (+0 sign) | | |
| 141 | `Unkstruct_a55a221e` | 428 | 428 | 1 | 0x215 | 0 (+0 sign) | | |
| 142 | `Unkstruct_02864986` | 420 | 420 | 1 | 0x2 | 0 (+1 sign) | | D_80115158 |
| 143 | `Unkstruct_80131B14` | 404 | 383 | 5 | 0x32 | 0 (+0 sign) | | |
| 144 | `Unkstruct_8011511A` | 404 | 146 | 1 | 0x2 | 0 (+1 sign) | D_8011511A | |
| 145 | `Unkstruct_8016B5C0` | 399 | 133 | 2 | 0x1c | 0 (+0 sign) | | |
| 146 | `Unkstruct_8016BFA8` | 399 | 133 | 3 | 0x6 | 0 (+0 sign) | | |
| 147 | `Unkstruct_8011F7F0` | 399 | 133 | 3 | 0x42 | 0 (+0 sign) | D_8011F7F0 | |
| 148 | `Unkstruct_2552224c` | 393 | 131 | 3 | 0x10 | 0 (+0 sign) | | |
| 149 | `Unkstruct_1649b9a7` | 392 | 28 | 8 | 0x38 | 0 (+2 sign) | | |
| 150 | `Unkstruct_ea5ed765` | 390 | 130 | 1 | 0xdb | 0 (+0 sign) | | |
| 151 | `Unkstruct_80135260` | 390 | 130 | 3 | 0x6 | 0 (+0 sign) | | |
| 152 | `Unkstruct_a472a6ba` | 387 | 129 | 3 | 0x1c | 0 (+0 sign) | | |
| 153 | `Unkstruct_630777a3` | 387 | 258 | 2 | 0x5 | 0 (+0 sign) | | |
| 154 | `Unkstruct_f2440762` | 384 | 128 | 1 | 0x4 | 0 (+0 sign) | | |
| 155 | `Unkstruct_80164BDC` | 384 | 128 | 5 | 0x64 | 0 (+1 sign) | | |
| 156 | `Unkstruct_8c2ab96e` | 384 | 128 | 3 | 0x8 | 0 (+0 sign) | | |
| 157 | `Unkstruct_d448adea` | 384 | 48 | 0 | 0x0 | 0 (+0 sign) | | |
| 158 | `Unkstruct_e79a0730` | 378 | 126 | 2 | 0x24 | 0 (+0 sign) | | |
| 159 | `Unkstruct_1a8e907f` | 378 | 126 | 1 | 0x4 | 0 (+0 sign) | | |
| 160 | `Unkstruct_e1c73ac0` | 378 | 126 | 3 | 0x6 | 0 (+0 sign) | | |
| 161 | `Unkstruct_8ba4da0a` | 378 | 126 | 3 | 0x1c | 0 (+0 sign) | | |
| 162 | `Unkstruct_93e44aed` | 378 | 126 | 2 | 0x1c | 0 (+0 sign) | | |
| 163 | `Unkstruct_24687968` | 378 | 126 | 3 | 0xe | 0 (+0 sign) | | |
| 164 | `Unkstruct_89684c99` | 375 | 125 | 3 | 0x6 | 0 (+0 sign) | | |
| 165 | `Unkstruct_831a2d3a` | 375 | 125 | 2 | 0x24 | 0 (+0 sign) | | |
| 166 | `Unkstruct_89f82b52` | 372 | 124 | 3 | 0x1ca | 0 (+0 sign) | | |
| 167 | `Unkstruct_924d03d6` | 372 | 124 | 3 | 0x6 | 0 (+0 sign) | | |
| 168 | `Unkstruct_7fd6458b` | 372 | 124 | 1 | 0x40 | 0 (+0 sign) | | |
| 169 | `Unkstruct_92a372de` | 372 | 124 | 2 | 0x24 | 0 (+0 sign) | | |
| 170 | `Unkstruct_4a31f01c` | 372 | 124 | 3 | 0x1c | 0 (+0 sign) | | |
| 171 | `Unkstruct_39de3511` | 372 | 124 | 3 | 0x12 | 0 (+0 sign) | | |
| 172 | `Unkstruct_1b4331f0` | 369 | 123 | 3 | 0x5e | 0 (+0 sign) | | |
| 173 | `Unkstruct_75e9a6af` | 369 | 123 | 3 | 0x10 | 0 (+0 sign) | | |
| 174 | `Unkstruct_b39064df` | 366 | 14 | 24 | 0xa2 | 3 (+3 sign) | | |
| 175 | `Unkstruct_5c635b4b` | 364 | 14 | 13 | 0x34 | 0 (+0 sign) | | |
| 176 | `Unkstruct_800AE620` | 325 | 322 | 0 | 0x0 | 0 (+0 sign) | D_800AE620 | |
| 177 | `Unkstruct_814e4d87` | 300 | 75 | 0 | 0x0 | 0 (+0 sign) | | |
| 178 | `Unkstruct_09b02bee` | 300 | 75 | 2 | 0x4 | 0 (+0 sign) | | |
| 179 | `Unkstruct_1ef3b11b` | 280 | 10 | 7 | 0x10c | 0 (+1 sign) | | |
| 180 | `Unkstruct_80115188` | 274 | 270 | 1 | 0x4 | 0 (+0 sign) | D_80115188 | |
| 181 | `Unkstruct_80129CF8` | 273 | 90 | 33 | 0xa435 | 0 (+5 sign) | | D_800AF630 |
| 182 | `Unkstruct_a2d6c72b` | 273 | 21 | 4 | 0x100 | 0 (+0 sign) | | |
| 183 | `Unkstruct_80078EB4` | 270 | 137 | 1 | 0x2 | 0 (+0 sign) | D_80078EB4 | |
| 184 | `Unkstruct_80115118` | 268 | 265 | 1 | 0x2 | 0 (+1 sign) | D_80115118 | |
| 185 | `Unkstruct_801152B0` | 268 | 268 | 0 | 0x0 | 0 (+0 sign) | D_801152B0 | |
| 186 | `Unkstruct_801269F4` | 267 | 134 | 1 | 0x2 | 0 (+0 sign) | D_801269F4 | |
| 187 | `Unkstruct_8012C1DC` | 267 | 134 | 3 | 0x1c | 0 (+0 sign) | | |
| 188 | `Unkstruct_8011515C` | 267 | 267 | 1 | 0x2 | 0 (+1 sign) | D_8011515C | |
| 189 | `Unkstruct_640f8122` | 266 | 133 | 1 | 0x2e | 0 (+0 sign) | | |
| 190 | `Unkstruct_02495693` | 266 | 133 | 2 | 0x1e | 0 (+0 sign) | | |
| 191 | `Unkstruct_3f149285` | 266 | 133 | 1 | 0x2 | 0 (+0 sign) | | |
| 192 | `Unkstruct_a310cf42` | 266 | 133 | 1 | 0x4 | 0 (+0 sign) | | |
| 193 | `Unkstruct_80115124` | 266 | 266 | 1 | 0x2 | 0 (+0 sign) | D_80115124 | |
| 194 | `Unkstruct_800D4BE0` | 266 | 133 | 1 | 0x4 | 0 (+0 sign) | D_800D4BE0 | |
| 195 | `Unkstruct_800D4F8C` | 266 | 133 | 1 | 0x4 | 0 (+0 sign) | D_800D4F8C | |
| 196 | `Unkstruct_8016BFA8` | 266 | 133 | 0 | 0x0 | 0 (+0 sign) | | |
| 197 | `Unkstruct_8016BFA8` | 266 | 133 | 0 | 0x0 | 0 (+0 sign) | | |
| 198 | `Unkstruct_80176734` | 266 | 133 | 1 | 0x2c | 0 (+0 sign) | | D_8011F7B0 |
| 199 | `Unkstruct_80126B62` | 265 | 252 | 2 | 0xe | 0 (+1 sign) | D_80126B62 | |
| 200 | `Unkstruct_76f4299b` | 262 | 131 | 1 | 0x4a | 0 (+0 sign) | | |
*18760 types in all; the table shows the 200 largest by site count. The full map with every type's layout (offset, width, sign, site count per field) and conflicts is `.run/P37/census/struct_map.json`.*
+8 -7
View File
@@ -5,7 +5,7 @@ freshness). The derived columns come from the tree on every run; the authored on
dictionary, whose coverage is asserted both ways. Read it by NEED: find the phrase that matches what you are trying to do, then the tool,
then what proved it. The same data generates the day-one kit's manifest and its verbatim tool corpus.*
**Coverage:** 309 tool files in scope (submodules, vendored and downloaded code excluded; `find` and `git ls-files` agree) + 38 retired under `tools/sunset/`. Classes: LIVE 244 (a runtime consumer), REFERENCED 31 (a SETUP row only), ORPHAN 34 (neither) — of 309. Portability: PORTABLE 23, ADAPT 269, PROJECT-ONLY 17.
**Coverage:** 310 tool files in scope (submodules, vendored and downloaded code excluded; `find` and `git ls-files` agree) + 38 retired under `tools/sunset/`. Classes: LIVE 246 (a runtime consumer), REFERENCED 31 (a SETUP row only), ORPHAN 33 (neither) — of 310. Portability: PORTABLE 23, ADAPT 270, PROJECT-ONLY 17.
## P1 — extraction + manifest
@@ -295,7 +295,7 @@ then what proved it. The same data generates the day-one kit's manifest and its
| build a progress timeline from the repository's own committed digests | `timeline.py` | Builds a progress timeline from the repository's own committed digests, with a self-check | Makefile | repo doc paths | LIVE |
| check that every relative link in the public docs resolves | `doc_links.py` | Checks that every relative link in the public docs resolves and the link policy holds | Makefile, wiki_render.py, wiki_sync.sh | repo doc paths | LIVE |
| compile every eligible translation unit with the pinned toolchain, using no derived bytes | `compile_only.py` | Compiles every eligible translation unit with the pinned toolchain, without any game bytes | .github/workflows/no-rom.yml, delever_oracle.py, lever_census.py, macro_to_header.py (+1) | compiler triple, repo makefile parsing | LIVE |
| compute and publish progress metrics as report, machine data and per-binary breakdowns | `progress.py` | Computes and publishes the progress metrics as report, JSON and per-binary breakdowns | Makefile, docs/wave-playbook.md, api_agent.py, atlas.py (+35) | repo src/config layout | LIVE |
| compute and publish progress metrics as report, machine data and per-binary breakdowns | `progress.py` | Computes and publishes the progress metrics as report, JSON and per-binary breakdowns | Makefile, docs/wave-playbook.md, api_agent.py, atlas.py (+36) | repo src/config layout | LIVE |
| convert progress metrics into an external progress-report schema | `objdiff_report.py` | Converts the progress JSON into the external progress-report schema | .github/workflows/progress.yml | external report schema | LIVE |
| emit the public ordinal-to-hash map and the private old-to-new map | `public_rewrite/build_commit_map.py` | Emits the public ordinal-to-new-hash map and the private old-to-new map | probe_github.sh, resolve_tokens.py | repo doc/scratch paths | LIVE |
| gate a first push: prove no derived bytes among tracked files | `audit_public.py` | The first-push gate: no derived bytes among tracked files, four independent checks | .github/workflows/no-rom.yml, gate_scan.py | repo purge-set and path lists (the kit's template reads `config/firewall.txt` instead) | LIVE |
@@ -323,19 +323,20 @@ then what proved it. The same data generates the day-one kit's manifest and its
| add per-site function-pointer casts so a draft can call a differently typed callee | `cast_call_sites.py` | Adds per-site function-pointer casts so a draft can call a differently typed callee | canon_sig_reconcile.py, cast_self_callers.py, family_sweep.py, gate_stage.py (+4) | repo src layout | LIVE |
| apply curated names and signatures inside the analysis tool and save | `ghidra_scripts/ApplySymbols.java` | The in-tool half of that mirror: apply curated names and signatures, save on exit | ghidra_apply_symbols.sh, ghidra_export_annotations.sh, ghidra_rebuild.sh, ExportAnnotations.java (+1) | none | LIVE |
| build the pack one agent needs to read and crack one residue exemplar, without touching the tree | `delever_pack.py` | The Phase-36 T7 pack builder (one agent at a time): per residue exemplar of ≥N copies a directory under .run/P36/agents/ with the TU path, the body as the tree has it, the lever-free body (the seed), the residual as mnemonic blocks from delever_search --try (a scratch compile, no tree write), the ledger's NEEDED sites, and every engine attempt with its best moves; ORDER.tsv ranks the exemplars by the best distance reached, then copies. PROMPT.md beside them is the agent's brief. | — | repo scratch paths; the engine's outcomes and traces | REFERENCED |
| census every compiler-forcing construct in the C and gate the levers-off phase | `lever_census.py` | The Phase-36 census of lever sites (register pins, asm statements by kind, volatile levers, bare register, asm-label aliases, builtins, attributes; the whole-body hand-asm routines and the GTE ops set apart) derived from the shared-body scanner with a per-token coverage assertion against the raw text, four known-true controls, the !FAKE marker split, --check (0 unmarked pins/asm, 0 orphan markers) and --strict (0 pins, 0 asm) gates, --sites for the delever ledger, a fixture self-test | Makefile, argcheck.py, delever.py, delever_cycle.sh (+6) | repo paths, the shared-body scanner | LIVE |
| census every compiler-forcing construct in the C and gate the levers-off phase | `lever_census.py` | The Phase-36 census of lever sites (register pins, asm statements by kind, volatile levers, bare register, asm-label aliases, builtins, attributes; the whole-body hand-asm routines and the GTE ops set apart) derived from the shared-body scanner with a per-token coverage assertion against the raw text, four known-true controls, the !FAKE marker split, --check (0 unmarked pins/asm, 0 orphan markers) and --strict (0 pins, 0 asm) gates, --sites for the delever ledger, a fixture self-test | Makefile, argcheck.py, delever.py, delever_cycle.sh (+7) | repo paths, the shared-body scanner | LIVE |
| census every struct definition, raw pointer-cast dereference and function declaration in the C, and cluster the cast sites into the types the tree needs (the struct map) | `type_census.py` | The Phase-37 type census: struct/union/typedef definitions fleet-wide with o32 layouts (duplicate classes by layout+member evidence, VARIANT camps, dead and shadowed canonical names), every cast site in six forms (P *(T*)(…), I *(T*)ident, X ((T*)e)[i], M M2C_FIELD, A address-of, C typed cast-member) with base class/offset/width/sign/access and a per-form coverage assertion against an independent raw regex, the declaration layer (definitions K&R-read, extern spellings per name, multi-body names, asm-label aliases, builtins, attributes, argcheck's lying set), global blocks (runs of adjacent scalar D_ symbols), four known-true controls, and the struct map — union-find over evidence edges only (same global, argument flow into a parameter the callee dereferences with shared offsets, single-source assignment/return flow, pointer-field flow, body-hash identity) with a width-conflict veto; writes type_census.json/txt, struct_map(.top).json, sites.jsonl (--sites), parked.tsv (the P36 parked classes with reasons) and docs/struct-map.md; --check is the T8 gate; --selftest | progress.py, readability_progress.py | repo paths, the shared-body scanner, argcheck, the P36 ledger (parked.tsv) | LIVE |
| consolidate the GTE coprocessor inline-asm macros under Sony's names in one header and sweep dead lever macros | `gte_consolidate.py` | The Phase-36 T5 tool: every asm-bearing macro definition and direct GTE statement SIGNED by the build's own maspsx→as tail (template bytes with operands bound to fixed registers, operand counts, clobbers); one canonical text per signature named by PsyQ's inline_c.h convention (Sony's file supplies names and clobber lists, never opcode words) written to include/gte_inline.h; per file the canonical duplicates deleted, private names renamed, a variant with extra clobbers tried as canonical and kept as a marked <name>_m lever only when the object differs, direct statements rewritten into canonical calls (a concatenation of two included); every file judged through every recipe; --sweep deletes dead asm-bearing macros and drops a compound macro's inner asm when byte-neutral | delever.py, delever_cycle.sh, delever_permute.py, lever_census.py | Sony's inline_c.h path, the census sites, the oracle | LIVE |
| convert a shared-body macro header into per-function plain-C headers included at each site | `macro_to_header.py` | The Phase-35 converter: every DEFINE_ macro body becomes a plain-C header under src/shared/<space>/ included at its site, the legacy name-parameterized headers converted, the registry text-edited, the macro header deleted; --plan / --apply / --finalize / --verify | share_body.py, tool_census.py | the macro form is this project's; a kit-born project shares headers from its first bank | LIVE |
| emit a function's target assembly as an inline-assembly body | `asm_verbatim.py` | Emits the file-scope inline-assembly body form from a disassembly file | docs/wave-playbook.md, draft_prechecks.py, gate_main.py, recover_route.py | repo asm layout | LIVE |
| extract inline-defined types and typedefs from a source file into a shared header | `build_engine_types.py` | Extracts inline-defined named types and typedefs from a source file into a shared header | inject_capped_externs.py, lift_types.py, uniquify_type.py | repo shared-header path | LIVE |
| find a lever-free spelling of a body by a guided search on the byte distance, not a blind test | `delever_search.py` | The Phase-36 rung G: the same shape generators as rung R (declaration order/move, initializer split, commutative swap, temp inlined/introduced/hoisted, block wrap/unwrap, adjacent swap) and the same per-TU oracle, but every candidate SCORED — the function's instructions read out of the scratch object and compared, reloc-masked, with the fleet run's baseline object, as an edit distance — the residual CLASSIFIED (REG caller/callee, COUNT, ORDER, MIXED) to choose the move families, and a beam search composing two and three moves under a compile budget; a score-0 verified on every recipe and banked through delever --apply-body, then --propagate to the class. Controls: the tree's own text must score 0 (per body), --positive-control perturbs a matching body and requires the way back, --selftest. | delever.py, delever_pack.py, delever_regen.py | repo scratch paths; the recipe oracle | LIVE |
| find every call site whose in-scope declaration is narrower than the callee real definition | `argcheck.py` | The static filter for the missing-argument class: six T7 agents independently reached score 0 by restoring an argument the decompiled source had dropped (m2c drops them at unprototyped and indirect call sites), and no candidate generator can reach it because every family rewrites statements and declarations while this changes a call ARITY. Reads the real arity from the DEFINITION wherever it lives (a .c under src/ or a shared body header) and reports each narrower declaration with the scope that says which fix is available: the cast route is body-only at either scope, widening the declaration itself needs block scope. Known blind spot, stated in the docstring: it cannot see a definition that is uniformly wrong. | decl_repair.py, delever.py, readability_progress.py | repo paths; the census walk | LIVE |
| find a lever-free spelling of a body by a guided search on the byte distance, not a blind test | `delever_search.py` | The Phase-36 rung G: the same shape generators as rung R (declaration order/move, initializer split, commutative swap, temp inlined/introduced/hoisted, block wrap/unwrap, adjacent swap) and the same per-TU oracle, but every candidate SCORED — the function's instructions read out of the scratch object and compared, reloc-masked, with the fleet run's baseline object, as an edit distance — the residual CLASSIFIED (REG caller/callee, COUNT, ORDER, MIXED) to choose the move families, and a beam search composing two and three moves under a compile budget; a score-0 verified on every recipe and banked through delever --apply-body, then --propagate to the class. Controls: the tree's own text must score 0 (per body), --positive-control perturbs a matching body and requires the way back, --selftest. | delever.py, delever_pack.py, delever_regen.py, type_census.py | repo scratch paths; the recipe oracle | LIVE |
| find every call site whose in-scope declaration is narrower than the callee real definition | `argcheck.py` | The static filter for the missing-argument class: six T7 agents independently reached score 0 by restoring an argument the decompiled source had dropped (m2c drops them at unprototyped and indirect call sites), and no candidate generator can reach it because every family rewrites statements and declarations while this changes a call ARITY. Reads the real arity from the DEFINITION wherever it lives (a .c under src/ or a shared body header) and reports each narrower declaration with the scope that says which fix is available: the cast route is body-only at either scope, widening the declaration itself needs block scope. Known blind spot, stated in the docstring: it cannot see a definition that is uniformly wrong. | decl_repair.py, delever.py, readability_progress.py, type_census.py | repo paths; the census walk | LIVE |
| flag address-named references whose address now has a curated name | `lint_symbol_refs.py` | Flags address-named references in committed sources whose address now has a curated name | .github/workflows/no-rom.yml, Makefile | repo symbol/src paths | LIVE |
| give each conflicting camp of a same-named type its own name | `uniquify_type.py` | Gives each conflicting camp of a same-named type its own name so every camp becomes liftable | — | repo src layout | REFERENCED |
| guard that every inline-assembly body still reproduces its target bytes | `verbatim_check.py` | Regression guard that every inline-assembly body still reproduces its target bytes | .github/workflows/no-rom.yml, Makefile, lever_census.py, progress.py (+2) | repo src layout | LIVE |
| judge one translation-unit edit by the bytes of its object in under a second | `delever_oracle.py` | The Phase-36 fast byte oracle: every object's exact build command captured once via make -n -W (the Makefile's own recipe, pad stage and -O0 overrides included), a candidate compiled in place with -o/-MF redirected to scratch and compared with the fleet run's object; --calibrate proves 100 % equality untouched, twin == primary and a positive control before any verdict is trusted | delever.py, delever_cycle.sh, delever_permute.py, delever_search.py (+1) | the Makefile's object rules, the twin rule | LIVE |
| keep the lever count as a series a chart and a story can be drawn from | `lever_progress.py` | The Phase-36 lever series: a milestone row appended per census snapshot (its totals by class with the tree's HEAD, since a census is a moment that cannot be recovered later) plus the campaign table derived from the de-lever ledger on every render — per batch the rungs used, the bodies first judged, the sites removed and rewritten, and, scored as a transition against what that body's previous row left, the sites a later rung closed and the bodies it made lever-free; renders both into docs/levers.md's generated block and --check refuses a series that is not this tree's | readability_progress.py | the census json, the delever ledger | LIVE |
| measure duplicate function bodies across the fleet and assert one source per unique function | `share_census.py` | The census of byte-identical function classes across every binary with their source forms and verdicts, plus the S1 invariant check with its exception ledger and a fixture self-test | Makefile, audit_binaries.py, dedup_integrate.py, delever.py (+11) | repo paths, the registry and signature schemas | LIVE |
| measure duplicate function bodies across the fleet and assert one source per unique function | `share_census.py` | The census of byte-identical function classes across every binary with their source forms and verdicts, plus the S1 invariant check with its exception ledger and a fixture self-test | Makefile, audit_binaries.py, dedup_integrate.py, delever.py (+12) | repo paths, the registry and signature schemas | LIVE |
| mirror the curated symbol file into the analysis database with a real save | `ghidra_apply_symbols.sh` | Mirrors the curated symbol file into the analysis program headlessly, with a real save | — | repo symbol path, project name | REFERENCED |
| re-run newly harvested generator families over the whole residue and bank what closes, without re-sweeping | `delever_regen.py` | The Phase-36 regen pass (S103): for every residue class, the lever-free body and the engine's best text are fed to delever.recipe_candidates with ONLY the named generator families (the two newest by default) and every candidate is scored read-only through delever_search --try --body, one worker per class; a TSV under .run/P36/regen/ lists each class's best; --bank re-scores each score-0 row on the current tree, then apply_body_core + --propagate (the one writer). Built because no search ever revisits a residue class after a new generator lands. | — | repo scratch paths, the delever generator registry | ORPHAN |
| refuse, from one place, the command line of a tool the project has frozen | `frozen.py` | The one refusal a FROZEN tool prints from its main(): the tool, the successor and why; imports never exit (libraries stay usable) | aprop_autodraft.py, blocker_probe.py, canon_sig_reconcile.py, conform_decls.py (+10) | nothing | LIVE |
@@ -346,7 +347,7 @@ then what proved it. The same data generates the day-one kit's manifest and its
| see which register local-alloc gives each value inside one basic block, and why, before trying a register move | `localalloc_sim.py` | Simulates gcc 2.7.2's block_alloc for the block containing a given insn from a .lreg dump: quantity births/deaths, ties (combine_regs), copy suggestions, qty_compare_1 priority, find_free_reg — and prints the simulated hard register beside the one the dump records (0 mismatches over 150 validated block simulations, S103). Complements alloc_table.py, which shows global allocation only. | — | the cc1 dump format | ORPHAN |
| share one byte-identical function class across its binaries through an include-at-site header, gated per binary | `share_body.py` | The Phase-35 successor of dedup_propagate + dedup_extend for the include-at-site form: exemplar by majority text, the header written once, every private copy replaced by the include at its position, per-binary byte gate with object comparison, bisect on red, the registry appended or extended by text, the exception ledger on refusal; --plan / --apply --bucket extend|new | aprop_autodraft.py, audit_binaries.py, auto_driver.py, blocker_probe.py (+18) | repo paths, the registry and signature schemas | LIVE |
| take register pins, asm statements, volatile and register levers out of matched C, byte-gated per site | `delever.py` | The Phase-36 de-lever engine and campaign tool: positional rewrites per lever class (pin -> plain declaration, barrier/keep-alive deleted, a launder deleted or turned into the assignment it is, a hand-placed instruction -> its C, the zero-register variable -> 0, a macro-carried site deleted/valued/refused by its macro's shape, volatile/register dropped); per body replay -> rung A strip-all -> rung B greedy through delever_oracle; the file is the write unit and its final compile through every recipe the proof; --plan/--apply batches (TUs parallel, exemplar files first; headers serial, includers parallel), the ledger keyed by tu+fn+addr with the body's nhash before/after, !FAKE markers on class A/B survivors, --redraw for bodies refused by an older tool, --restore from inflight.json, --scrub for orphan markers, --apply-body for T6/T7, --recipes (rung R: the byte-neutral shape recipes — the formerly-pinned declarations permuted, one moved through the declaration run, an initializer split — each judged by the oracle, with an identity control on both the splice and the oracle), --selftest with a stub oracle, --probe (T2) | delever_cycle.sh, delever_pack.py, delever_permute.py, delever_regen.py (+3) | the census site records, the oracle | LIVE |
| track how honest and how readable the matched C is over time, as a generated series | `readability_progress.py` | The Gen3 companion to docs/levers.md: levers are only one way the source is untrue. Counts lying call declarations (a call site whose in-scope declaration names fewer parameters than the callee definition, split by the K&R-empty and (void) forms, and how many sit in a body that still holds an argument-register pin) and raw cast dereferences against struct member reads, which is the struct debt. Appends a dated row carrying its commit to docs/readability-progress.tsv and renders docs/readability.md; --check asserts the last row is this tree. | — | repo paths | ORPHAN |
| track how honest and how readable the matched C is over time, as a generated series | `readability_progress.py` | The Gen3 companion to docs/levers.md: levers are only one way the source is untrue. Counts lying call declarations (a call site whose in-scope declaration names fewer parameters than the callee definition, split by the K&R-empty and (void) forms, and how many sit in a body that still holds an argument-register pin) and raw cast dereferences against struct member reads, which is the struct debt. Appends a dated row carrying its commit to docs/readability-progress.tsv and renders docs/readability.md; --check asserts the last row is this tree. | type_census.py | repo paths | LIVE |
| turn an inline-assembly body back into a stub the toolchain can reach | `verbatim_to_stub.py` | Turns an inline-assembly body back into an include-assembly stub | — | repo src/asm layout | REFERENCED |
| widen every call declaration that lies, and measure on the bytes which repairs are free | `decl_repair.py` | The free-correctness half of the missing-argument class: a declaration is repaired only when every call to that function in the unit ALREADY passes the arguments, so the code is right and only the promise is wrong. Each candidate is compiled from a scratch copy through the unit own recipe and compared on .text/.rodata/.data (never whole-object: the object records its own source path, which made the first fleet run return 0 free of 3,634 units). Every unit is negative-controlled by compiling it UNCHANGED first, and a unit whose control fails is reported as a harness failure rather than a result. --apply writes only the units this run judged identical. | — | repo paths; the recipe oracle | ORPHAN |
+1
View File
@@ -41,6 +41,7 @@ in the Archive index, not here. The conventions behind this page: [Docs and scra
| [`levers.md`](../levers.md) | The register pins and compiler hints: the taxonomy, the generated count over time (the post-100% chart's data), how they got in, how each rung takes them out, and the argument on whether to refuse them from the first bank or clean them up at the end. | Read whole; §2's tables are generated. | authored + a generated block (`tools/lever_progress.py`), the series in `lever-progress.tsv` |
| [`lever-progress.tsv`](../lever-progress.tsv) | The lever series' data: one row per milestone (date, task, HEAD, sites by class, marked/unmarked, GTE variants, per-TU asm macros) appended by `tools/lever_progress.py --snapshot` — a census is a moment and cannot be recovered later. | Read as a table; the chart source. | generated (`tools/lever_progress.py`), never edited |
| [`readability.md`](../readability.md) | The other Gen3 series beside the levers: lying call declarations (split `()` / `(void)`, how many sit in a pinned body) and raw cast dereferences against struct member reads — the struct debt the structs phase inherits. | Read whole; the block is generated. | authored + a generated block (`tools/readability_progress.py`), the series in `readability-progress.tsv` |
| [`struct-map.md`](../struct-map.md) | The struct map (Phase 37): every raw pointer-cast dereference in `src/` assigned to a base and the bases clustered by evidence into the types the tree needs — the 200 largest with sites, bodies, fields, size, width conflicts and instance/pointer globals; the input the structs phase authors its canonical types from. | Read the table; the full map with every type's layout is `.run/P37/census/struct_map_top.json` (regenerate with `tools/type_census.py`). | generated (`tools/type_census.py`), never edited |
| [`readability-progress.tsv`](../readability-progress.tsv) | The readability series' data: one dated row per snapshot with its commit (declarations, pinned-body declarations, raw casts, struct member reads). | Read as a table. | generated (`tools/readability_progress.py`), never edited |
| [`accelerators.md`](../accelerators.md) | What was learned late that a future project should know on day one: each entry with when it was found, when it could have been, what it would have saved. | Read whole; the entries are short. | authored |
| [`generic-decomp-package.md`](../generic-decomp-package.md) | The thesis for the next project: what it inherits and does before cracking — the knowledge base seeded from the compiler's source and sibling projects, the structural tooling, the similarity join as a band not a point, the differential-oracle harness, the widening review. | Read whole. | authored |
+88 -19
View File
@@ -50,7 +50,7 @@
untouched; twin checks 0 (0 mismatch); positive control DIFFERS on build/src/800.o; 2.3 s — OK` (main 0.108 s/object, ov 0.15–0.16,
md_SC07_004 0.504) (`.run/P37/baseline/oracle_t0.log`); `.gitignore` P37 allowlist (by-contents, R84; `git check-ignore` verified: logs
and `.tsv` tracked, `.o` ignored); this file. Verify at the commit: `git status` clean.
- ☐ **T1** (xHigh; the layout/cluster model reviewed at Max) — `tools/type_census.py` + **the struct map** (added after T0 — Drew asked, Claude recommended,
- ☑ **T1** (S106; the commit carrying this line) — `tools/type_census.py` + **the struct map** (added after T0 — Drew asked, Claude recommended,
Drew approved "Yes — T1 delivers the map"; P5d): definitions with o32 layouts + duplicate classes +
VARIANT camps + dead names; cast sites in all four forms + `M2C_FIELD` with base class/offset/width/sign/load-store; the declaration
layer (definitions K&R-read, in-scope declarations per TU, the lying set, multi-spelled callees, aliases, builtins, attributes); the P36
@@ -161,33 +161,101 @@ bucketed by what each bucket needs before any plan is proposed. **Candidates for
- **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.
## 🛑 SESSION CHECKPOINT — S106 (2026-09-11/12, LIVE — refreshed at every task close): gate 1 APPROVED, **T0 ☑** (baseline + oracle + allowlist + this file, committed) — 🛑 **T1 NEXT (the type census, xHigh; its layout/cluster model at Max)** | R22 `check-all: 218 passed, 0 failed of 218` at `db212f167` | the P36 close `79b2f6f15` is committed AND PUSHED (`origin/main`); no tag (Drew: no tags/releases at closes); T0 `0a55cb0fd` local
- **S106 — T1 design (X1).** One walker per file in worker processes (the masking and the function spans from `share_census`, the
cache/coverage pattern from `lever_census`) → definitions with o32 layouts (`Resolver`), six cast-site forms with base/offset/width/
sign/access, the declaration records, the flow edges; the parent computes duplicate tiers, coverage, controls, global blocks and the
struct map (union-find over evidence only). **The Plan agent's stress-test landed** (322k tokens; its design goes into T3's notes) and
corrected four premises before the fleet run: (1) a whole-object oracle says DIFFERS on a correct global-block edit because the
RELOCATION SPELLING changes (`D_80078EB4` → `g.hp`) while the linked bytes are identical — T3 needs a resolved-relocation mode
(control: `md_SC07_004`'s `D_801F8870[1]`) and a committed linker fragment for every new base symbol; (2) function identity is never
the bare name (6,415 names carry >1 body text) — the map keys a function by its body hash; (3) a sixth site form exists, `((T *)p)->f`
(36,681 sites: a COMPONENT_REF already, the readability MEMBER regex counts it as a member — it is the rewrite's rung 1, not a finished
member); (4) "one definition per layout" is too strong — `{s16 ×4}` carries 177 names, some genuinely different types (`Rect` vs
`SVECTOR`): a duplicate is same layout AND (identical meaningful member names | an opaque copy block | flow evidence); layout twins
without evidence are reported, not merged — **milestone item 1's "per layout" reads "per type" from here (a clarification for Drew,
not a scope change)**. Also from the agent: caller bytes DO depend on a narrow prototype's widths in both directions (the return axis
too: `extern u8 f(void)` makes the caller mask eagerly), and rung 1 (body-local `((Unk *)a0)->f`, no signature change, the same `/s`)
decouples the byte question from the declaration question — rung 2 (the typed signature) follows the declaration solver.
- **S106 — T1 built.** `tools/type_census.py` (selftest 21/21 on a fixture with every form); five fleet runs to converge the map: run 1
a mega-cluster of 297,668 sites (Steensgaard's classic over-merge through untyped conduit parameters) and A/C sites counted against a
deref denominator (105 %); run 2 typed-use parameters + a width-conflict veto + nested bases → 173,025; run 3 the single-source rule
for locals + declared-type seeding of `AT:` nodes → 166,789 (the entity type: max offset 0x24C = `actor-struct.md`'s record size);
run 4 positive shared evidence required on inter-function edges (the callee's map structured ≥2 offsets, ≥1 offset in common) →
two large types (107,598 sites / 0x10C spanning 9,753 pointer globals — the cross-address copies of per-overlay globals, still partly
fused at low offsets; 65,397 sites / 0x24C with one instance global `D_80126B58`), their conflicts mostly same-width sign mixes (a
store's signedness leaves no byte), now counted apart from width conflicts; run 5 = the final numbers. **The map is a model with
stated rules and reported conflicts; T2 tests it on bytes, T5 refines it.**
- **S106 — T1 verify lines (HEAD `23fc5d215`, 3 m 20 s at -j16).** `type_census: 7261 definitions (525 layouts, 206 duplicate classes,
39 variant camps) · 503016 cast sites in 69497 bodies over 8 base classes (4 forms + A, coverage OK) · 98648 lying declarations / 1609
callees · controls 4/4` · `struct_map: 18760 types over 18760 clusters explain 498896/503016 sites (99.2 %); 4120 unassigned sites; 729
types with conflicts`. DEFINITIONS: canonical header 1,179 · `.c` file-scope 4,091 · `.c` block-scope 1,904 · per-function shared headers
63 · other headers 24; 3,109 distinct names; duplicate tiers: 122 same-named + 84 opaque classes (2,789 names), 46 layout-twin classes /
1,844 names kept apart; 588 exact-text classes / 4,469 copies; 39 VARIANT names; 141 dead canonical names; 75 canonical names redefined
in `.c`. CAST SITES: **deref 503,016 = P 409,007 + I 60,666 + X 13,800 + M 19,543** (+ A 18,912 address-of; + C 36,681 typed cast-member)
in 69,497 bodies; coverage OK on all six forms; refused 0; the readability regex over raw text 411,850 (the 2,843 difference = casts
inside comments/strings/macro blocks); by base: param 276,860 · local 149,915 · gaddr 40,122 · nested 24,076 · global 8,860 · other 1,678;
by width: s4 145,167 · u2 142,775 · s2 131,818 · u1 43,174 · agg 13,472 · p4 12,016 · u4 11,165 · s1 3,429; top bases a0 92,255 ·
param_1 81,595 · arg0 67,704 (the first parameter 241,554 = 48 %). DECLARATIONS: 99,130 definitions (1,889 K&R) · 4,279,365 extern
function declarations over 12,139 names (3,870 spelled >1 way) · 6,415 names with >1 body text · 1,078,837 data externs over 55,569
symbols (18,442 typed >1 way) · asm-label aliases 5,749 (225 names) · builtins memcpy 301 / abs 144 · attributes packed 64 / aligned 12 ·
lying 98,648 / 1,609 callees (K&R-empty 91,357, narrow 7,291). GLOBAL BLOCKS: 2,123 runs of ≥4 adjacent scalar `D_` symbols (14,251
symbols). PARKED (P36): **24 classes / 453 bodies / 691 needed sites → `.run/P37/census/parked.tsv`**, needs {signature 13, struct 7,
? 4}; 22 PARK names are minimum-lever banks. CONTROLS 4/4 (the doc dispute reported: `D_80078F08/0C` code 4 vs `actor-struct.md` 2 —
a T9 correction; the bytes side with the code). `lever_census`: controls re-keyed (14 / 8 / `func_801896EC` 2, each counted
independently) → 4/4 OK; `--check: 4,010 … 0 UNMARKED — OK`; **`--check --strict: pins 2141, asm 1419, gte-levers 450, direct GTE
statements in bodies 6717, per-TU asm macro definitions 314 … FAIL`** — `--strict` now reads its own words: a direct GTE coprocessor
statement in a body is an asm statement outside the GTE header (the P36 close excluded 6,447 `gte` + 270 `gte-unsigned` as Sony's
idiom; under decision 1 they are work — macro calls from the one header; `func_8013D9B0`'s 268 are among them, resolved this way).
Published (R75): `progress.py --json --readme` → `counts.types` + the README "Types (Phase 37, snapshot 2026-09-12)" sentence + two
dated `corrections` (the four-form count; `--strict`'s direct GTE statements); `progress.py --check` fresh; `readability_progress
--snapshot` (the TSV now read by column NAME; 16 census columns appended) → `503016 by the census's four forms (+36681 typed
cast-member, +18912 address-of) … 7261 struct definitions over 525 layouts (206 duplicate classes / 2789 names); the map: 18760 types
(99.2 % of sites)`; `lever_progress --snapshot` (79 milestones, 4,010 unchanged) → `--check OK`; `docs/struct-map.md` generated (200
types) + its Reference-index row; dictionary row + SETUP §P37 S106 (R87/R21); `make kit-corpus` → `tool_census --check: OK`;
`doc_links --strict: OK`; `kit_lint: OK`; `kit_coverage: OK`. Files: `.run/P37/census/{type_census.json,type_census.txt,struct_map_top.json,
parked.tsv}` tracked; `struct_map.json` (6.4 MB) and `sites.jsonl` (213 MB) regenerable, ignored.
## 🛑 SESSION CHECKPOINT — S106 (2026-09-11/12, LIVE — refreshed at every task close): gate 1 APPROVED, **T0 ☑ T1 ☑** (the type census + the struct map, committed) — 🛑 **T2 NEXT (the probe, Max)** | R22 `check-all: 218 passed, 0 failed of 218` at `db212f167` | the P36 close `79b2f6f15` is committed AND PUSHED (`origin/main`); no tag (Drew: no tags/releases at closes); T0 `0a55cb0fd` local
**Replay this block into the chat at the next session start (R64); it is the ONLY in-phase context the next session inherits.**
1. **Where we are.** Phase 37 (the structs phase) opened 2026-09-11 in S106 at Max. Gate 1 approved with Drew's four decisions: **grind to
zero** (raw casts, lying declarations, levers — the plan's §"What zero means" defines each honestly); **placeholders + cited evidence**
for every type/field name; **T7 = the P36 agent lane at Drew's cap, started only on his word**; **the full canonical declaration layer**.
R107–R117 ratified. T0's baseline and oracle calibration are done (the log entry above has every verify line). T0 is committed (this file, `.gitignore`, `.run/P37/baseline/*.log`, the recalibrated `.run/P36/delever/calibration.json`).
NEXT = **T1 — the type census `tools/type_census.py` + THE STRUCT MAP** (`.run/P37/census/struct_map.json` + `docs/struct-map.md`)
at xHigh (its layout/cluster model at Max) — added to T1 on Drew's word after T0 (P5d); T4's prototypes carry the map's parameter types.
2. **What the next session must know before T1.** (a) The population table in the approved plan below is a gate-1 grep census — T1
re-derives every number with a self-asserting tool (R32/R37) and its verify line is the plan's. (b) The four cast forms: `*(T *)(…)`
(411,850, the readability regex `tools/readability_progress.py:31`), `*(T *)ident` (26,279), `((T *)e)[i]` (14,491), `M2C_FIELD(`
(19,542) — the last three are UNCOUNTED by the series today (R32 gap; T1 adds them with a dated `corrections` entry). (c) The 24 parked
P36 classes have NO list with reasons anywhere — the reasons are split across `phase-ends/logs/Phase36.md:2261-2267` and `:2197-2199`,
the bank lists' MSG column (`.run/P36/s105/banks_*.txt`), and each pack's `mechanism.md` headline; `.run/P36/s105/pick.py`'s PARK set (44
names) mixes parked classes with minimum-lever banks; patch files exist for 6 (`main__func_800385C0/scratch/signature.patch`,
R107–R117 ratified. T0 (baseline, oracle calibration, allowlist, this file) and T1 (the type census + the struct map; every verify
line in the log above) are committed. **NEXT = T2 — the probe (Max):** three stratified probes on the calibrated oracle — (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 + the 24 parked patches (`.run/P37/census/parked.tsv`) as the known-true set, (iii) the definition fold on 20 TUs —
plus the Plan agent's two probes: the layout engine audited against cc1 (the negative-array-size offsetof idiom over every definition;
0 errors) and the linked-relocation oracle mode's control (`md_SC07_004`'s `D_801F8870[1]`: IDENTICAL linked, DIFFERS whole-object).
T2 prices T4–T7 with denominators (R41). The probe drives a `restruct --try` for rung 1 only (body-local `((Unk *)a0)->unkK`) — the
Plan agent's "build first" order: layout engine + cc1 audit → linked oracle mode → census (done) → `--try`.
2. **What the next session must know (T1's findings, for T2–T5).** (a) The phase's counters, re-derived by `tools/type_census.py` (coverage OK, controls 4/4): **503,016 raw dereferences** (P 409,007 +
I 60,666 + X 13,800 + M 19,543) in 69,497 bodies + 18,912 address-of + 36,681 typed cast-member (rung 1's form, counted apart);
7,261 struct definitions (1,179 canonical, 5,995 inside `.c`), 525 layouts, 206 duplicate classes (2,789 names; 46 layout-twin classes /
1,844 names are NOT duplicates without flow evidence), 39 VARIANT names, 141 dead canonical names; 98,648 lying declarations / 1,609
callees; 6,415 names with >1 body text (identity = body hash, never the name); **the lever finish line is 4,010 marked sites + 6,717
direct GTE statements in bodies + 314 per-TU asm macro definitions** (`lever_census --check --strict`, now literal). (b) The struct map
(`.run/P37/census/struct_map_top.json`, `docs/struct-map.md`): 18,760 types explain 99.2 % of the sites; the two largest — 107,598 sites /
0x10C over 9,753 pointer globals (partly fused at low offsets) and 65,397 sites / 0x24C with the instance global `D_80126B58` (the
actor record) — carry width conflicts the map reports; the map's merge rules are in SETUP §P37 S106; it is a MODEL — T2 tests it on
bytes (does the member spelling hold?) before T5 authors anything from it. (c) The Plan agent's four corrections (the log entry "T1
design"): the relocation-spelling oracle mode + linker fragment for base symbols (T3), body-hash identity (done), form C (done),
duplicates = layout + evidence (done; milestone item 1 reads "per type"). (d) Two doc corrections owed at T9: `actor-struct.md`'s
`s16` at +0x108/+0x10C (the code declares 4-byte fields; the bytes decide), and `include/common.h:28-30`'s "identical codegen to
`p->field`" for `M2C_FIELD` (false — the `/s` flag differs; `gen3-handoff.md:161-164` says the same). (e) The 24 parked
P36 classes are now ONE file, `.run/P37/census/parked.tsv` (fn, alias, tu, copies, sites, kinds, regs, needs {signature 13, struct 7, ? 4},
pack, patches, headline; 453 bodies / 691 needed sites; 22 more PARK names are minimum-lever banks) — generated by the census from the
P36 ledger + `pick.py`'s PARK set + each pack's `mechanism.md`; patch files exist for 6 (`main__func_800385C0/scratch/signature.patch`,
`main__func_80029D3C/scratch/patch_signature.c`, `ov_SC07_007__func_80180FA4/scratch/signature_3args.patch`,
`ov_SC02_027__func_80180A54/scratch/signature.patch`, `md_SC07_004__func_801A1E94/signature.diff`, `…__func_801A5C44/signature.diff`),
whole-TU scratch copies for 8 more; `func_80180200` has no pack (it lives in `ov_SC03_115__func_8017FC5C/`). (d) `func_8013D9B0`'s 268
markers are kind `gte-unsigned` (NON_LEVER) — OUTSIDE the 4,010 headline though the PhaseEnd lists it among the residue heads; T1 resolves
this on the bytes. (e) `lever_census`'s known-true controls: three of four return N-A (their T1 body hashes are stale) — re-key them (R85).
(f) The 4,010 reconcile exactly against the ledger: 1,637 drawable RESIDUE + 1,080 minimum-lever banks in PARK + 593 parked RESIDUE +
whole-TU scratch copies for 8 more; `func_80180200` has no pack (it lives in `ov_SC03_115__func_8017FC5C/`). (f) `func_8013D9B0`'s 268
markers (kind `gte-unsigned`) are now inside `--strict`'s direct-GTE count (resolved: they are asm statements outside the header, to
become macro calls). `lever_census`'s controls are re-keyed and 4/4 OK. (g) The 4,010 reconcile exactly against the ledger: 1,637 drawable RESIDUE + 1,080 minimum-lever banks in PARK + 593 parked RESIDUE +
450 GTE clobber variants (`gte-lever`; 64 per-TU `_m` macro definitions, `gte_rt_m` 55) + 94 arg-only pins (83 classes) + 83 whose latest
ledger row is a failed attempt (invisible to `pick.py`; `delever.py --redraw`) + 24 + 18 + 13 asm-body + 10 drawn + 8 file-scope.
(g) The §396(a) refuting body IS recorded: `.run/P36/agents/ov_SC03_110__func_801800F0/mechanism.md:64-70` (d11) — T9 writes the correction.
(h) The type tools' reach: `lift_types.py` scans only `src/ov_*/*.c` (line 49); `engine_types.h` is included by 3,818 TUs via
(h) The §396(a) refuting body IS recorded: `.run/P36/agents/ov_SC03_110__func_801800F0/mechanism.md:64-70` (d11) — T9 writes the correction.
(i) The type tools' reach: `lift_types.py` scans only `src/ov_*/*.c` (line 49); `engine_types.h` is included by 3,818 TUs via
`engine_prelude.h` but by 0 of the 85 root `.c` and 12 of 87 `md_*`; `decl_repair.py` compares `.text/.rodata/.data` sections (the scratch
path lands in the object) while `delever_oracle` compares whole objects compiled in place.
3. **Environment.** `~/bfm-decomp` on ext4; `.venv/bin/python`; every build with `JOBS=16`/`-j`; the headless Ghidra MCP was started by
@@ -195,7 +263,8 @@ bucketed by what each bucket needs before any plan is proposed. **Candidates for
`ghidra/` (nothing does until T8; R23). The oracle's snapshot baseline: `.run/P36/delever/baseline/` (7,428 objects at `db212f167`, taken
after the green R22 — R112). The Plan agent (tool design stress-test) may still be running or have reported: its report goes into T3's
design notes; if it is lost, T3's design at Max re-derives it from the plan's §B questions.
4. **Commands that work.** R22: `make clean && make extract-all JOBS=16 && make check-all JOBS=16` (≈86 s; read the exit code with
4. **Commands that work.** Census: `.venv/bin/python tools/type_census.py -j 16 [--sites]` (≈3.5 min; `--selftest` 21/21; outputs under
`.run/P37/census/`; `docs/struct-map.md` regenerated). R22: `make clean && make extract-all JOBS=16 && make check-all JOBS=16` (≈86 s; read the exit code with
`pipefail`). Oracle: `.venv/bin/python tools/delever_oracle.py --calibrate <aliases> -j 16` (147/147 in 2.3 s). Census (P36's, for the
lever side): `.venv/bin/python tools/lever_census.py --check -j 16`. Series: `tools/readability_progress.py --snapshot <label>`,
`tools/lever_progress.py --check`. Tools-health (foreground, ~8–15 min): `make tools-health`.
+19 -11
View File
@@ -978,10 +978,13 @@ def run_census(jobs, use_cache=True, out_dir=OUT_DIR_DEFAULT, want_sites=False,
# the known-true bodies as they were at T1 (commit 357f8a1ed): a control holds only while the body's normalized text is the one the
# count was made on — the campaign removes pins byte-identically, and a control that kept expecting them would fail on its own
# staleness (batch tus7 of T4 removed func_80184034's three bare-name pins; the census then refused a correct tree)
# re-keyed at P37 T1 (S106, 2026-09-12; R85): the P36 campaign changed all three bodies — counted again independently with the
# gate-1 grep (`register [^;/]*__asm__\("\$?[a-z0-9]+"\)` over the masked body): 45 → 14, 26 → 8, and the bare-name control moved to
# func_801896EC (2 bare-name pins; func_80184034's are gone). A control returns N-A the day its body changes again.
CONTROL_NHASH = {
("src/800.c", "func_800226C0"): "47f1042f0dda6f163009793a11ef16f405c29af1",
("src/shared/ov/func_80178004.h", None): "90d67fb489780cf0ef81f1a7b4b4f74dfe3c782b",
("src/ov_SC03_006/ov_SC03_006_jr_8017AE2C.c", "func_80184034"): "2dce73f8716c32324b1b3517f11bd03a4e9966af",
("src/800.c", "func_800226C0"): "902372b4e3bf845f39f0b4d4bab7f2ab8ce47121",
("src/shared/ov/func_80178004.h", None): "27524a8bf23911718b4082cd5cca7d971d8c9090",
("src/ov_SC03_006/ov_SC03_006_jr_8017AE2C.c", "func_801896EC"): "140f5b7e434d93ebaaea89dbe65c1a702d233020",
}
@@ -998,11 +1001,11 @@ def controls(sites, defs):
return "OK" if got == want else "MISMATCH"
out = []
n = sum(1 for s in sites if s["tu"] == "src/800.c" and s["fn"] == "func_800226C0" and s["cls"] == "A")
out.append(("src/800.c func_800226C0 pins", n, 45, status(("src/800.c", "func_800226C0"), n, 45)))
out.append(("src/800.c func_800226C0 pins", n, 14, status(("src/800.c", "func_800226C0"), n, 14)))
n = sum(1 for s in sites if s["tu"] == "src/shared/ov/func_80178004.h" and s["cls"] == "A")
out.append(("src/shared/ov/func_80178004.h pins", n, 26, status(("src/shared/ov/func_80178004.h", None), n, 26)))
n = sum(1 for s in sites if s["tu"] == "src/ov_SC03_006/ov_SC03_006_jr_8017AE2C.c" and s["fn"] == "func_80184034" and s["cls"] == "A")
out.append(("ov_SC03_006 func_80184034 bare-name pins", n, 3, status(("src/ov_SC03_006/ov_SC03_006_jr_8017AE2C.c", "func_80184034"), n, 3)))
out.append(("src/shared/ov/func_80178004.h pins", n, 8, status(("src/shared/ov/func_80178004.h", None), n, 8)))
n = sum(1 for s in sites if s["tu"] == "src/ov_SC03_006/ov_SC03_006_jr_8017AE2C.c" and s["fn"] == "func_801896EC" and s["cls"] == "A")
out.append(("ov_SC03_006 func_801896EC bare-name pins", n, 2, status(("src/ov_SC03_006/ov_SC03_006_jr_8017AE2C.c", "func_801896EC"), n, 2)))
n = sum(1 for s in sites if s["tu"] == "src/shared/engine_prelude.h" and s["cls"] == "B")
out.append(("engine_prelude.h asm sites (a macro definition only)", n, 0, "OK" if n == 0 else "MISMATCH"))
return out
@@ -1185,13 +1188,18 @@ def main():
ab = [x for x in sites if x["cls"] in "AB" and x["kind"] not in NON_LEVER_KINDS and x["tu"] != a.gte_header]
un = [x for x in ab if not x["marked"]]
if a.strict:
# P37 (S106): --strict reads its own words — "0 asm statements outside the GTE header" — so a DIRECT GTE statement in a body
# (kind gte / gte-unsigned: Sony's idiom spelled inline instead of as the header's macro call) is a violation here, while the
# --check headline keeps the P36 definition (the series' continuity). verbatim-body stays excluded by the manifest.
direct_gte = [x for x in sites if x["cls"] == "B" and x["kind"] in ("gte", "gte-unsigned") and x["tu"] != a.gte_header]
pt = s.get("per_tu_asm_macro_definitions", {}).get("total", 0)
gl = s.get("gte_levers", {}).get("sites", 0)
print(f"lever_census --check --strict: pins {s['pins']['sites']}, asm {sum(1 for x in ab if x['cls'] == 'B' and x['kind'] != GTE_LEVER_KIND)}, "
f"gte-levers {gl}, per-TU asm macro definitions {pt}, volatile-needed {s['classes']['C']['sites']}, register-needed {s['classes']['D']['sites']} — "
f"{'OK' if not ab and not pt else 'FAIL'}")
if ab or pt:
for x in ab[:10]:
f"gte-levers {gl}, direct GTE statements in bodies {len(direct_gte)}, per-TU asm macro definitions {pt}, "
f"volatile-needed {s['classes']['C']['sites']}, register-needed {s['classes']['D']['sites']} — "
f"{'OK' if not ab and not pt and not direct_gte else 'FAIL'}")
if ab or pt or direct_gte:
for x in (ab + direct_gte)[:10]:
print(f" {x['tu']}:{x['line']} {x['fn']} {x['cls']}/{x['kind']} {x['detail']}")
rc = 1
else:
+34 -3
View File
@@ -1173,6 +1173,26 @@ def fleet():
"hand_asm_routines_in_c_shells": _vb.get("routines"), "hand_asm_routine_sites": _vb.get("sites")}
except Exception:
_lev = None
# Phase 37 T1: the type census (tools/type_census.py) — the struct debt, the declaration debt and the struct map, published until 0 (R75)
_typ = None
try:
import json as _jt
_tj = ROOT / ".run/P37/census/type_census.json"
if _tj.exists():
_ts = _jt.loads(_tj.read_text())["summary"]
_d, _c, _dc, _sm = _ts["definitions"], _ts["casts"], _ts["decls"], _ts["struct_map"]
_typ = {"date": _ts.get("when", "")[:10], "head": _ts.get("head"),
"what": "the structs phase's counters: raw pointer-cast dereferences in four forms (P *(T*)(…), I *(T*)ident, X ((T*)e)[i], M M2C_FIELD), "
"struct definitions and their duplicate classes, lying call declarations, and the struct map's types (Phase 37 drives the first three to 0)",
"raw_cast_sites": _c["deref_total"], "raw_cast_forms": _c["by_form"], "raw_cast_bodies": _c["bodies"],
"address_of_sites": _c["addr_form"], "typed_cast_member_sites": _c["typed_cast_member"], "absolute_address_casts": _c["abs_casts"],
"struct_definitions": _d["total"], "canonical_definitions": _d["canon"], "definitions_in_c_files": _d["in_c_file_scope"] + _d["in_c_block_scope"],
"distinct_layouts": _d["distinct_layouts"], "duplicate_classes": _d["dup_layout_classes"], "duplicate_names": _d["dup_layout_names"],
"variant_names": _d["variant_names"], "dead_canonical_names": _d["dead_canon_names"],
"lying_declarations": _dc["lying"], "lying_callees": _dc["lying_callees"], "asm_label_aliases": _dc["asm_label_aliases"],
"multi_spelled_callees": _dc["multi_spelled_callees"], "struct_map_types": _sm["types"], "struct_map_explained_pct": _sm["explained_pct"]}
except Exception:
_typ = None
# Phase 35 T5b: the TEXT tier — groups keyed by one normalized text at one address whose bytes vary per binary (verbose members)
_tg = [g for g in gs if g.get("tier") == "h_text"]
return {
@@ -1201,7 +1221,7 @@ def fleet():
"text_tier_groups": len(_tg), "text_tier_instances": sum(len(g.get("members") or []) for g in _tg),
"deferred_same_address_texts": (_census.get("deferred_texts") or {}).get("texts"),
"deferred_same_address_copies": (_census.get("deferred_texts") or {}).get("sites"),
"levers": _lev},
"levers": _lev, "types": _typ},
"corrections": [ # dated snapshots of published-number moves with their cause and the command that shows them (R75)
{"date": "2026-09-08", "phase": "P35 T2", "metric": "fn_count.total", "delta": 7,
"cause": "seven overlays including the whale header but never registered were counted by neither classify nor the registry fold", "command": "tools/progress.py --fleet"},
@@ -1210,7 +1230,11 @@ def fleet():
{"date": "2026-09-08", "phase": "P35 T6", "metric": "counts.real_c_functions", "delta": -10211,
"cause": "empty-bodied shared functions were folded into REAL under the macro form; the include form classifies them EMPTY (the instruction-weighted metrics are unchanged)", "command": "tools/progress.py --fleet"},
{"date": "2026-09-09", "phase": "P36 T1b", "metric": "counts.verbatim_asm_bodies", "delta": 22,
"cause": "the §265 lane's IN-FUNCTION form (a whole routine as one __asm__ statement inside a C shell) was invisible to the file-scope detector behind the manifest: 22 scratchpad stack-switch trampolines (one private copy per overlay, 2,682 sites) are hand asm and are listed PERMANENT-VERBATIM; a 23rd asm-body is -O0 compiler output and is listed DECOMPILE-NOW", "command": "tools/lever_census.py; tools/verbatim_check.py"}],
"cause": "the §265 lane's IN-FUNCTION form (a whole routine as one __asm__ statement inside a C shell) was invisible to the file-scope detector behind the manifest: 22 scratchpad stack-switch trampolines (one private copy per overlay, 2,682 sites) are hand asm and are listed PERMANENT-VERBATIM; a 23rd asm-body is -O0 compiler output and is listed DECOMPILE-NOW", "command": "tools/lever_census.py; tools/verbatim_check.py"},
{"date": "2026-09-12", "phase": "P37 T1", "metric": "counts.types.raw_cast_sites", "delta": 91166,
"cause": "the readability series' regex counted one cast form (`*(T *)(`: 411,850 over raw text); the type census counts four dereference forms over comment-masked text — P 409,007 + I 60,666 (`*(T *)ident`, `*(T *)&D_x`) + X 13,800 (`((T *)e)[i]`) + M 19,543 (`M2C_FIELD`) = 503,016 — with a coverage assertion per form; 18,912 address-of casts and 36,681 typed cast-member accesses are counted apart", "command": "tools/type_census.py"},
{"date": "2026-09-12", "phase": "P37 T1", "metric": "counts.levers (--strict)", "delta": 6717,
"cause": "lever_census --strict now reads its own words: 6,717 direct GTE coprocessor asm statements in function bodies (Sony's idiom spelled inline instead of as the header's macro call; kinds gte/gte-unsigned, incl. func_8013D9B0's 268 unsigned respellings) are asm statements outside the GTE header — the P36 headline (--check, 4,010) keeps its definition for the series' continuity", "command": "tools/lever_census.py --check --strict"}],
"per_binary": [{"binary": r['binary'], "real": r['real'], "shared": r['shared'], "linked": r['linked'],
"byte_identical": r['byteident'], "matchable": r['matchable'],
"instr_matched": (wm['per_bin'].get(r['binary'], [None, None])[0] if wm else None),
@@ -1282,7 +1306,14 @@ def readme_block(d):
f"{c['levers']['register_keyword_sites']:,} bare `register` keywords are censused; {c['levers']['gte_sites']:,} GTE coprocessor "
f"operations and {c['levers']['hand_asm_routines_in_c_shells']} whole-body assembly routines kept inside C shells "
f"({c['levers']['hand_asm_routine_sites']:,} sites; the original's scratchpad stack-switch trampolines, one copy per "
f"overlay, listed in the verbatim manifest) are not levers and are excluded."] if c.get("levers") else []) + [
f"overlay, listed in the verbatim manifest) are not levers and are excluded."] if c.get("levers") else []) + ([f"", f"Types (Phase 37, snapshot {c['types']['date']}): {c['types']['raw_cast_sites']:,} raw pointer-cast dereferences remain in "
f"{c['types']['raw_cast_bodies']:,} functions (four forms; {c['types']['typed_cast_member_sites']:,} typed cast-member accesses and "
f"{c['types']['address_of_sites']:,} address-of casts counted apart); {c['types']['struct_definitions']:,} struct definitions "
f"({c['types']['canonical_definitions']:,} in the canonical header, {c['types']['definitions_in_c_files']:,} inside `.c` files) over "
f"{c['types']['distinct_layouts']:,} distinct layouts, {c['types']['duplicate_classes']:,} duplicate classes covering "
f"{c['types']['duplicate_names']:,} names; {c['types']['lying_declarations']:,} call declarations narrower than their callee's "
f"definition over {c['types']['lying_callees']:,} callees; the struct map clusters the cast sites into {c['types']['struct_map_types']:,} "
f"types by evidence ({c['types']['struct_map_explained_pct']} % of sites assigned)."] if c.get("types") else []) + [
"", f"_Generated by `tools/progress.py --readme` from `docs/progress.json` — numbers are never typed by hand._",
README_END]
return "\n".join(out)
+58 -21
View File
@@ -43,31 +43,68 @@ def counts():
casts += len(CAST.findall(t))
members += len(MEMBER.findall(t))
pinned = [r for r in rows if r["argpin"]]
return dict(definitions=len(defs), narrow_decls=len(rows),
callees=len({r["callee"] for r in rows}),
kr_empty=sum(1 for r in rows if r["kind"] == "K&R-empty"),
narrow=sum(1 for r in rows if r["kind"] == "narrow"),
pinned_rows=len(pinned), pinned_bodies=len({(r["tu"], r["in_fn"]) for r in pinned}),
raw_casts=casts, struct_members=members)
out = dict(definitions=len(defs), narrow_decls=len(rows),
callees=len({r["callee"] for r in rows}),
kr_empty=sum(1 for r in rows if r["kind"] == "K&R-empty"),
narrow=sum(1 for r in rows if r["kind"] == "narrow"),
pinned_rows=len(pinned), pinned_bodies=len({(r["tu"], r["in_fn"]) for r in pinned}),
raw_casts=casts, struct_members=members)
# Phase 37 T1 (2026-09-12): the type census's columns — the four dereference forms (the CAST regex above sees one of them, over raw
# text), the typed cast-member accesses (the MEMBER regex counts these as members — they are the rewrite's rung 1, not finished
# members), the struct definitions and their duplicate classes, the struct map. A snapshot REFUSES a stale census (R43/R51).
cj = REPO / ".run/P37/census/type_census.json"
head = subprocess.run(["git", "rev-parse", "HEAD"], cwd=REPO, capture_output=True, text=True).stdout.strip()
if not cj.exists():
sys.exit("readability_progress: no type census — run `tools/type_census.py -j 16` first (its columns are part of the row)")
ts = json.loads(cj.read_text())["summary"]
if not head.startswith(ts.get("head", "?")):
sys.exit(f"readability_progress: the type census is STALE (census {ts.get('head')} vs HEAD {head[:9]}) — rerun tools/type_census.py")
c, d, sm = ts["casts"], ts["definitions"], ts["struct_map"]
out.update(deref_all=c["deref_total"], form_P=c["by_form"].get("P", 0), form_I=c["by_form"].get("I", 0), form_X=c["by_form"].get("X", 0),
form_M=c["by_form"].get("M", 0), addr_form=c["addr_form"], typed_cast_member=c["typed_cast_member"],
struct_defs=d["total"], canon_defs=d["canon"], in_c_defs=d["in_c_file_scope"] + d["in_c_block_scope"],
distinct_layouts=d["distinct_layouts"], dup_classes=d["dup_layout_classes"], dup_names=d["dup_layout_names"],
map_types=sm["types"], map_pct=sm["explained_pct"])
return out
HEAD = ("date\tlabel\tcommit\tdefinitions\tnarrow_decls\tcallees\tkr_empty\tnarrow\tpinned_rows\tpinned_bodies"
"\traw_casts\tstruct_members\n")
COLS = ["date", "label", "commit", "definitions", "narrow_decls", "callees", "kr_empty", "narrow", "pinned_rows", "pinned_bodies",
"raw_casts", "struct_members",
# P37 columns (appended 2026-09-12; older rows carry blanks — the renderer reads by name, never by position)
"deref_all", "form_P", "form_I", "form_X", "form_M", "addr_form", "typed_cast_member", "struct_defs", "canon_defs", "in_c_defs",
"distinct_layouts", "dup_classes", "dup_names", "map_types", "map_pct"]
HEAD = "\t".join(COLS) + "\n"
def _rows():
lines = [l for l in TSV.read_text().splitlines() if l.strip()]
cols = lines[0].split("\t")
rows = []
for l in lines[1:]:
vals = l.rstrip("\n").split("\t")
rows.append({c: (vals[i] if i < len(vals) else "") for i, c in enumerate(cols)})
return rows
def render():
rows = [l.rstrip("\n").split("\t") for l in TSV.read_text().splitlines()[1:] if l.strip()]
rows = _rows()
g = lambda r, k: r.get(k, "") or "—"
out = ["# Readability of the matched C — the Gen3 series",
"",
"> **Generated by `tools/readability_progress.py --snapshot`; never typed (R75).** Companion to",
"> `docs/levers.md`, which counts the compiler-forcing levers. This one counts the two things that are wrong",
"> with the source even where no lever remains: call declarations that are FALSE, and memory read through raw",
"> pointer casts where the original had a struct.",
"> pointer casts where the original had a struct. From Phase 37 the row carries the type census's columns",
"> (`tools/type_census.py`): all four dereference forms, the typed cast-member intermediate, the definitions and the map.",
"",
"| date | label | commit | lying declarations | of which `()` | of which `(void)` | in a pinned body | raw cast derefs | struct member reads |",
"|---|---|---|---:|---:|---:|---:|---:|---:|"]
"| date | label | commit | lying declarations | of which `()` | of which `(void)` | in a pinned body | raw cast derefs (one form, raw text) | struct member reads | **raw derefs, four forms** | typed cast-member | struct defs (canonical / in .c) | layouts | duplicate classes / names | map types (% sites) |",
"|---|---|---|---:|---:|---:|---:|---:|---:|---:|---:|---|---:|---|---|"]
for r in rows:
out.append(f"| {r[0]} | {r[1]} | `{r[2][:9]}` | {r[4]} | {r[6]} | {r[7]} | {r[8]} | {r[10]} | {r[11]} |")
defs = f"{g(r,'struct_defs')} ({g(r,'canon_defs')} / {g(r,'in_c_defs')})" if r.get("struct_defs") else "—"
dups = f"{g(r,'dup_classes')} / {g(r,'dup_names')}" if r.get("dup_classes") else "—"
mp = f"{g(r,'map_types')} ({g(r,'map_pct')} %)" if r.get("map_types") else "—"
out.append(f"| {r['date']} | {r['label']} | `{r['commit'][:9]}` | {r['narrow_decls']} | {r['kr_empty']} | {r['narrow']} | {r['pinned_rows']} | "
f"{r['raw_casts']} | {r['struct_members']} | **{g(r,'deref_all')}** | {g(r,'typed_cast_member')} | {defs} | {g(r,'distinct_layouts')} | {dups} | {mp} |")
out += ["",
"**How to read it.** A *lying declaration* is a call site whose in-scope declaration names fewer parameters",
"than the callee's own definition. It is not a style problem: on this processor an argument travels in a",
@@ -97,17 +134,17 @@ def main():
print(__doc__)
return 2
c = counts()
if not TSV.exists():
TSV.write_text(HEAD)
with TSV.open("a") as fh:
fh.write("\t".join([datetime.date.today().isoformat(), a.snapshot, head, str(c["definitions"]),
str(c["narrow_decls"]), str(c["callees"]), str(c["kr_empty"]), str(c["narrow"]),
str(c["pinned_rows"]), str(c["pinned_bodies"]), str(c["raw_casts"]),
str(c["struct_members"])]) + "\n")
c.update(date=datetime.date.today().isoformat(), label=a.snapshot, commit=head)
# the header row is rewritten to the current column list; older rows keep their positions (the new columns are appended)
old = [l for l in TSV.read_text().splitlines()[1:] if l.strip()] if TSV.exists() else []
TSV.write_text(HEAD + "".join(l + "\n" for l in old) + "\t".join(str(c.get(k, "")) for k in COLS) + "\n")
render()
print(f"readability_progress: {a.snapshot} — {c['narrow_decls']} lying declaration(s) over {c['callees']} callee(s) "
f"({c['kr_empty']} `()`, {c['narrow']} `(void)`), {c['pinned_rows']} in {c['pinned_bodies']} pinned bodies; "
f"{c['raw_casts']} raw cast deref(s), {c['struct_members']} struct member read(s), at {head[:9]}")
f"{c['raw_casts']} raw cast deref(s) by the one-form regex, {c['deref_all']} by the census's four forms (+{c['typed_cast_member']} typed "
f"cast-member, +{c['addr_form']} address-of), {c['struct_members']} struct member read(s); {c['struct_defs']} struct definitions over "
f"{c['distinct_layouts']} layouts ({c['dup_classes']} duplicate classes / {c['dup_names']} names); the map: {c['map_types']} types "
f"({c['map_pct']} % of sites), at {head[:9]}")
return 0
+1885
View File
File diff suppressed because it is too large Load Diff