docs(phase-37): S108 record — accelerators P37 S108 (ten), decision log P37 S108, cookbook §459 (the declaration layer's byte facts), SETUP §P37 S108, cookbook index; the redraw + indented-definition class: D49–D52 + HD5–HD6 (7,283 canonical) | 🛑 T4 in progress (S108)

This commit is contained in:
Drew T
2026-09-12 21:04:56 -06:00
parent 8a84409a18
commit aa4e8de21d
7 changed files with 127 additions and 4 deletions
+22
View File
@@ -1969,3 +1969,25 @@ CLAIM, not a fact — two were refuted on bytes on 2026-09-10.**
24-class probe closed 4 at the first candidate, all by `reloc`. Known limits: a same-name donor that is a DIFFERENT
function scores high (the ranking is by line count only); a pair whose REL addends differ cannot match (MIPS REL: the
addend is in the instruction, the object comparison sees the symbol name).
### §P37 S108 — 2026-09-12: the declaration layer run to its floor (Phase 37 T4)
- **`tools/restruct.py`** (rung D) — `defs_visible` indexes the shared headers each SIBLING TU includes (a binary's own shared bodies were
"external") and, as a third level, a callee's fleet-unique signature when no member/main/resident TU defines it; `unit_call_counts` (the K&R
arity read from the TU AND its included bodies; a definition head is `) {` or a K&R head); `--unalias`: a data-typed declaration of the real
name (`extern s32 f;` / `extern char f[];`) becomes the prototype, a header-side arity error marks the INCLUDING TUs, escalation counts
attempts; `--callee F --body FILE` gained **`--with REL=FILE`** (a caller-body edit inside the same judged unit, repeatable), **`--map-data`**
(with `--all-defs`: the body's `D_` symbols renamed to each copy's own by order of first appearance; a count mismatch REFUSES), header-borne
definitions excluded from `--all-defs` (a variant is another function); **`--redraw VERDICT[:cause-substring]`** (`DECL-NONE:visible`).
`--unalias` runs under `--apply` (the S107 checkpoint's line lacked it). Selftest 54/54.
- **`tools/argcheck.py`** — every definition per name kept (`_ALL`), `resolve_definition(name, tu)`: one fleet-wide signature → it; else the
declaring TU's own binary's; else main/resident; else `cross_binary=True`; rows carry `kr_marked` (the `// K&R:` marker read from the RAW
line); `DEF` allows leading blanks (indented file-scope definitions); the K&R loop feeds `_ALL` regardless of `out`.
- **`tools/type_census.py` / `tools/readability_progress.py`** — lying declarations exclude `kr_marked` and `cross_binary` rows, which are
published APART (`kr_sites`/`kr_callees`, `cross_binary`/`cross_callees`; two new TSV columns, read by name).
- **`tools/delever_oracle.py --snapshot-baseline`** — REFUSES an empty or shrunken `build/` before writing (it had stamped "HEAD, 0 objects").
- **`tools/restruct_cycle.sh`** — skips the fleet run when `git status src` is clean after a batch (the previous R22 stands).
- One-off drivers under `.run/P37/restruct/` (ignored; every command line is in the phase log): `sig_cycle.sh` (the parked signature bodies:
oracle refresh → `--callee … --body` → R22 → log → commit; a `--tu` fallback when copies differ), `strip_banners.py` (the §8b banner comments).
- **Gotchas:** after `kill -INT` on a judge WAIT for its exit (`ps`) before `--restore`; `pgrep -f`/`pkill -f` never with a literal your own
command line contains (`restruct_cycl[e]`).
+30
View File
@@ -998,3 +998,33 @@ cross-address copies produce IDENTICAL probe bodies, and a hash-keyed scratch fi
`pkill -f` with a literal from your own command line kills your own shell (R79, hit again at 14:20).
8. **A fallback ladder that re-judges hundreds of objects per step needs an escalation rule** (a second caller of the same kind → all
callers), or a 20-file chain costs 20 × 20 s per unit.
## P37 S108 (2026-09-12) — the declaration layer's day of instrument findings: five ways a census was blind to its own population
The session ran rung D over the fleet for ~9 h and landed ≈90,000 declarations canonical — and almost every jump came from finding a
class the instruments could not see, not from the engine getting better. Each of these would have paid on day one of T4:
1. **A definitions index must follow the sibling TUs' includes.** Since Phase 35 every shared body is a header included by ONE member TU;
an index that reads the sibling `.c` files but not the headers they include sees a binary's own shared functions as "external".
`t4_D21` drew 300 TUs for 0 units on exactly this; the fix was one loop, and the next batch put 10,123 declarations canonical.
2. **A function's identity is (binary, definition), never the bare name (R48, again).** `argcheck.definitions()` kept one signature per
name with `setdefault`; 6,419 names carry more than one body; 2,832 correct declarations read as lies for two sessions. Resolve per
declaring binary: one fleet-wide signature → it; else the TU's own binary's; else main/resident; else "cross-binary", counted apart.
3. **A `^`-anchored definition regex misses INDENTED file-scope definitions** — 116 "disagreements" were this, and the fix (leading blanks
allowed) surfaced ~2,200 more drawable TUs whose lying declarations had never been rows at all: the census's denominator grew by
~10,000 after the instrument was repaired (`t4_D50`–`D52`: 7,208 canonical in three batches).
4. **A call-arity counter must read the included bodies too, and "a `{` later on the line" is not a definition head.** 306 K&R markers read
`? of N args` for a known count (the short call sat in a shared body the TU includes), two read `[]` for `if (f() != 0) {`.
5. **An empty or shrunken `build/` is a refusal, not a snapshot (R68).** The snapshot tool stamped "HEAD, 0 objects" over 7,428 objects of
another tree; a stopped R22 (`make clean` done, fleet run not) is the ordinary way to get there.
6. **After `kill -INT` on a judge, WAIT for its exit before `--restore`** — it honours the signal only after its in-flight units (~2 min);
a restore run 8 s later consumed `inflight.json` and left six files with no tool-side restore. And `pgrep -f`/`pkill -f` with a literal
your own command line contains kills your own shell (R79 — hit twice more; the safe spelling brackets a character: `restruct_cycl[e]`).
7. **A flat-yield stop is an inference; bucket the remainder by ledger verdict before stopping.** Two low-yield batches read as "the rest is
non-actionable" while 3,700 (TU, callee) pairs had never been judged — they were the `md_*` modules, ranked low by the planner.
8. **Same code over per-overlay data is one body with a symbol map, not 133 bodies.** `--map-data` (the pack body's `D_` symbols renamed to each
copy's own, by order of first appearance; a count mismatch refuses) landed the 132-copy class in one judged unit — 264 pins.
9. **"The pin was the missing argument" needs the CALLERS in the same judged unit as the definition** (`--with REL=FILE`): a declaration change
alone is `too few arguments` at every zero-argument caller, and the pack's "one caller" was three once the fleet was grepped.
10. **A definition in a shared header whose short callers sit in other shared bodies lands as a K&R-style DEFINITION** — no per-TU `()`
declaration can hide a prototype that is in scope before the call; the ladder must count ATTEMPTS to escalate there (it counted files).
+7 -3
View File
@@ -2,7 +2,7 @@
> **Generated by `tools/cookbook_index.py` — do not hand-edit** (R33). Regenerate after adding a cookbook section.
>
> `docs/matching-cookbook.md` is ~716 KB / 1176 sections. Grepping it blind is how three P30 wave-1 agents each "discovered" an idiom that was already written down. **Start here, then read the section.** A section appears under every symptom it addresses.
> `docs/matching-cookbook.md` is ~716 KB / 1177 sections. Grepping it blind is how three P30 wave-1 agents each "discovered" an idiom that was already written down. **Start here, then read the section.** A section appears under every symptom it addresses.
**How to use:** name what you SEE in the diff (a stolen delay slot, an extra `la`, a swapped register pair, a `conflicting types` error), find that symptom below, read those sections first. If nothing fits, THEN grind — and add a section when you win.
@@ -551,7 +551,7 @@
- **§497** — ★ — A BODILESS `typedef struct Tag Alias;` DEFINES THE ALIAS, NOT THE TAG: THE CARRIER'S FALSE "CONFLICTING BODIES" REFUSAL (P32 T1b; ov_SC02_017 `func_80186C64` isolation) <sub>L36705</sub>
- **§458** — Struct spelling is a per-access dial: the T2 probe's byte evidence (Phase 37 S106) <sub>L37886</sub>
### types, signedness & load/store width (98)
### types, signedness & load/store width (99)
- **§3-I1** — Unsigned range check: `(x - lo) < (hi-lo)` → `addiu`+`sltiu` <sub>L41</sub>
- **§3-I2** — Byte mask forces `andi` even after `lbu` <sub>L47</sub>
@@ -651,8 +651,9 @@
- **§481** — ★★★ — `conflicting types` IS A SAME-SCOPE ERROR; ACROSS SCOPES IT IS ONLY A WARNING (P31 S77, `main:func_8001FC08`, 400 ins) <sub>L35911</sub>
- **§496** — ★★ — A CARRIED-TYPE TEST THAT ASSUMES THE OVERLAY INCLUDE SET SILENTLY DROPS A RESIDENT TYPEDEF (P32 T1a; byte-proven, resident `func_800D128C` isolation) <sub>L36671</sub>
- **§497** — ★ — A BODILESS `typedef struct Tag Alias;` DEFINES THE ALIAS, NOT THE TAG: THE CARRIER'S FALSE "CONFLICTING BODIES" REFUSAL (P32 T1b; ov_SC02_017 `func_80186C64` isolation) <sub>L36705</sub>
- **§459** — The declaration layer's byte facts (Phase 37 T4, S107–S108): what a prototype spelling can and cannot hide <sub>L37912</sub>
### declarations, prototypes & K&R (122)
### declarations, prototypes & K&R (123)
- **§3-T4** — Branch polarity: invert the source condition to flip gcc's chosen branch <sub>L90</sub>
- **§8c** — Splitting a TU means rebuilding its DECLARATION ENVIRONMENT, not moving text (Phase 26 session 6) <sub>L456</sub>
@@ -776,6 +777,7 @@
- **§481** — ★★★ — `conflicting types` IS A SAME-SCOPE ERROR; ACROSS SCOPES IT IS ONLY A WARNING (P31 S77, `main:func_8001FC08`, 400 ins) <sub>L35911</sub>
- **§487** — ★★★ — THE PSX LOADER'S PER-VERSION SIGNATURE SETS ARE A FREE PROVENANCE ORACLE: main's "WALL" BAND IS LIBPAD 4.2.1 (P31 S78) <sub>L36160</sub>
- **§495** — ★★★ — THE VERBATIM END-STATE (P31 S80 #10): TWO DEF-SIDE DECLARATION WALLS, A "BANK" THAT WAS THE ASSEMBLY, AND A GATE THAT DROPPED A BANK ON EXIT 0 <sub>L36630</sub>
- **§459** — The declaration layer's byte facts (Phase 37 T4, S107–S108): what a prototype spelling can and cannot hide <sub>L37912</sub>
### jump tables & switches (72)
@@ -2988,6 +2990,7 @@
- **§456** — The lever-removal move catalog: what the S104 agents found under ~205 pins, barriers and launders (Phase 36 T7) <sub>L37765</sub>
- **§457** — The lever-removal move catalog, S105: eight TU batches, 42 of 42 at 0 (Phase 36 T7) <sub>L37814</sub>
- **§458** — Struct spelling is a per-access dial: the T2 probe's byte evidence (Phase 37 S106) <sub>L37886</sub>
- **§459** — The declaration layer's byte facts (Phase 37 T4, S107–S108): what a prototype spelling can and cannot hide <sub>L37912</sub>
---
@@ -4176,3 +4179,4 @@ Notes routinely quote that as a section id. This table resolves it. Grep bait: `
| L37765 | §456 | The lever-removal move catalog: what the S104 agents found under ~205 pins, barriers and l |
| L37814 | §457 | The lever-removal move catalog, S105: eight TU batches, 42 of 42 at 0 (Phase 36 T7) |
| L37886 | §458 | Struct spelling is a per-access dial: the T2 probe's byte evidence (Phase 37 S106) |
| L37912 | §459 | The declaration layer's byte facts (Phase 37 T4, S107–S108): what a prototype spelling can |
+24
View File
@@ -3901,3 +3901,27 @@ For those, no single-TU spelling exists; the file-layout phase's split is the fi
**What it cost.** ~4 h of the session in five unalias passes and two planner corrections; 120 of 149 landed; 29 named. **Sooner:** read
the census's "lying declaration" rows against the DEFINITIONS' names before pricing — a definition under another name is a hole in the
denominator, and the planner should have counted only rows the engine can act on from the first batch (`DECL-NONE` now settles them).
## P37 S108 (2026-09-12) — T4 run to its measured floor: the declaration layer's instruments were the campaign
**Context and belief.** The checkpoint priced T4's remainder as six mechanical steps (the D cycle again, 29 alias functions, the headers,
13 parked signature bodies, the banners, the census). The D cycle had put ≈17,300 declarations canonical in S107 and its first batch of
S108 was "the test of the DECL-NONE settling".
**What happened.** That batch drew 300 TUs for 0 units — and the reason was the engine's definitions index, not the population: it never
looked inside the shared headers a SIBLING TU includes, so every binary's own shared functions were "external". One loop fixed it and the
next fifteen batches put 76,075 declarations canonical. The same day, four more blind spots each moved the number by thousands: argcheck
keyed definitions by bare name (2,832 false lies — a same-address function with three bodies), its `DEF` regex missed indented definitions
(a whole class of callers never became rows; 7,208 canonical in three batches after the fix), the arity counter never read included bodies,
and the "flat yield" stop I made at D36 left 3,700 never-judged pairs in the `md_*` modules. **The census went 98,648 → 13,832 → 8,830 →
2,367 lying declarations, each step an instrument repair, not a new rung.**
**The pivots.** (1) The planner's rows must be rows the engine can act on, and the stop rule is the remainder bucketed by ledger verdict
(R117) — never a yield curve. (2) Lying declarations are counted per binary (a function is identified by its definition — the plan's own
rule, now the instrument's), with two populations counted APART: byte-proven K&R sites (5,082, each marked with its cause) and cross-binary
declarations (511: the fleet's definitions disagree and the binary has none). (3) The parked signature bodies are not "apply the patch":
`func_80157D20`'s 132 copies needed a per-copy data-symbol map (`--map-data`), `func_80029D3C` needed its three zero-argument callers in the
same judged unit (`--with`), `func_80188A30` needed only its return type (`void` → `s32`, reorg's delay-slot fill), and the `md_SC07_004`
pair needs a caller one level up re-signed too — the definition-side change is a UNIT of definition + callers + declarations, judged once.
**What it cost.** ~9 h of one session, 60 commits, ~35 fleet gates (every one 218/218); one self-inflicted race (a restore run against a
judge still unwinding) and two shell kills by `pgrep -f`. **Sooner:** the five instrument checks above are each a one-line control against
a known case (a shared-header callee; a three-body name; an indented definition; a short call in an included body; an empty `build/`) —
they belong in `type_census --selftest` and `restruct --selftest` from the day the census exists, not in the campaign's log.
+32
View File
@@ -37908,3 +37908,35 @@ member, the site's own cast kept: `*(u16 *)((((struct { s32 p; } *)&D_801C7E30)-
the body closes with members everywhere but that one site, and that site with both sides `/s`. The same recipe on the ORIGINAL text (every
site a cast) is also IDENTICAL: the pointer read's `/s` is what the scheduler's escape needed, whichever side the store took. R1 is the first
entry of the engine's recipe registry (R2 = a18's `extern T X[]`, R3 = f3's walked pointer); T6 runs the registry on every kept cast.
## §459 — The declaration layer's byte facts (Phase 37 T4, S107–S108): what a prototype spelling can and cannot hide
Rung D put ≈90,000 call declarations canonical (the definition's ANSI signature) byte-identically, judged per object; the residue and the
signature-side landings are the byte facts worth keeping (every one gated `check-all: 218 passed, 0 failed of 218`).
1. **A byte-proven K&R site is a per-TU fact, but a definition in a shared header makes it a per-DEFINITION fact.** A TU whose calls pass
fewer arguments than the definition takes keeps `extern ret f(); // K&R: n of m args (…)` — 5,082 such sites over 155 callees, counted
apart from the lies. When the DEFINITION sits in a shared header (`func_80162CCC.h`) and the short call sits in another shared body
(`func_80164DB0.h:5`), no per-TU `()` can hide the prototype already in scope: the definition itself is spelled K&R-style (`void
func_80162CCC(a0) u8 *a0; {`) — **IDENTICAL on 288 objects, 145 files** (`t4_ua13`; same shape `func_8016F0E4` 296 objects, `func_80131CA8`
202 in S107). gcc 2.7.2's K&R head changes nothing in the callee's bytes when the parameter types are the byte-true ones.
2. **"The pin was the missing argument" is a UNIT of definition + callers.** `func_80029D3C`'s pins (P36) faked `$4`; the truth is `s32
func_80029D3C(s32 n)` — and every zero-argument caller then passes the value its pin had loaded: `s0 = func_80029D3C(D_8011DB1A);`
(ov_SC07_002), and in two shared bodies a local compared then passed — `s16 cmp79; if (... (cmp79 = *(s16 *)(p + 0x79)) != 1000) angle =
func_80029D3C(cmp79);` — **IDENTICAL on every recipe (2,177 files)**: local-alloc homes a local that dies at the call in `$a0`, exactly where
the pin had put it. A declaration change alone is `too few arguments` at each such caller; grep the fleet for `f()` before trusting a
pack's "one caller" (it was three).
3. **A return type is observable in a delay slot (§162f1 operated).** `func_80188A30`: `void` → `s32` with the body unchanged (no `return`; the
function falls off the end) — reorg's `fill_slots_from_thread` refuses to steal `li v0,24` into the `beqz` slot once `$v0` is live at the
epilogue (`reorg.c:4274`); the `"memory"` barrier that had faked the `nop` comes off. IDENTICAL, 1 file.
4. **Same code over per-overlay data is one body plus a symbol map.** `func_80157D20` in 132 overlays: the pack body names `D_80192768`
(ov_SC04_011's table); each copy's own definition names its own (`D_801806BC` in ov_MAIN_012, …) at the same site. Renaming the pack's `D_`
symbols to each copy's by ORDER OF FIRST APPEARANCE (`--map-data`; a count mismatch refuses) landed all 132 as `void func_80157D20(void
*param_1, s32 param_2)` — **IDENTICAL, 2,105 files, 264 `$4/$5` pins gone**. The 133rd "definition" was a variant header (`__99380536.h`,
different bytes for 3 overlays): a variant is another function, left with its includers' declarations.
5. **What a prototype cannot hide (the residue's causes, each a ledger row):** a caller in one jr-merged TU whose bytes disagree with the
definition's head (the original was separate translation units — the file-layout phase's; 10 functions); a `void` definition whose
callers USE `$v0` (`void value not ignored` — the definition's return type is the lie: a definition-side change, 5 functions); a prototype
naming a type the TU cannot see (`Pos800D20C0`; 1,120 rows — T5's canonical types); `conflicting types` from a second declaration
elsewhere in the TU (417); a zero-argument caller that passes its OWN incoming `$a0` through (`func_801A6A18(void) { func_801A1E94(); }`) —
the fix re-signs the caller too, one level up.
+1 -1
View File
File diff suppressed because one or more lines are too long
+11
View File
@@ -716,6 +716,17 @@ bucketed by what each bucket needs before any plan is proposed. **Candidates for
- **2026-09-12 — T4 batch `t4_HD6`** (`.run/P37/restruct/run_t4_HD6.log`, `batch_t4_HD6.json`): `restruct: batch t4_HD6 rung D — 271 files (headers; 271 drawable) · 0 declaration units: 0 canonical / 0 promoted / 0 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 0 kept · compiles 0 in 16 s wall · final 271/271 identical · written 0 files` → R22 (`.run/P37/baseline/r22_t4_HD6.log`) **`(no src change — the previous R22 stands)`** (``) → census `(census skipped)`.
- **S108 — the targeted redraw + the indented-definition class (`cycle_t4i.log`, `REDRAW=DECL-NONE:visible`):** `t4_D49` 203 TUs · 90 units: 55
canonical / 35 kept (`f76538941`); then the argcheck cache rebuilt on the fixed `DEF` and **2,247 TUs became drawable** — callers of INDENTED
file-scope definitions had never been rows: `t4_D50` 2,802 units: 2,791 canonical (`a0c26f587`) · `t4_D51` 2,802: 2,778 (`6d822ff2c`) ·
`t4_D52` 1,659: 1,639 (`f74d1e077`); headers `t4_HD5` 281: 24 units, 20 canonical / 4 K&R (`3d9c8aed1`) · `t4_HD6` 0 units (`8a84409a1`, no
src change — the cycle's new skip); every gated batch `check-all: 218 passed, 0 failed of 218`. Chained: `cycle_t4j.log` batches 53–62 for the
~1,500 drawable TUs left. **The record banked (R30):** accelerators **P37 S108** (ten entries: the five blind spots, the kill/restore race,
the flat-yield stop, `--map-data`, `--with`, the K&R-style definition), decision log **P37 S108** (the census's four steps were instrument
repairs; the stop rule is the bucketed remainder; a signature change is a unit of definition + callers + declarations), cookbook **§459**
(the declaration layer's byte facts: the K&R-style definition on 288 objects, the local homed in `$a0`, the return type in a delay slot, the
per-overlay data map, what a prototype cannot hide), SETUP **§P37 S108** (every option and gotcha), the cookbook index (1,177 sections).
## 🛑 SESSION CHECKPOINT — S107 (2026-09-12, FINAL — written for a FRESH session at 84 % context; the session's last commit follows this): gate 1 APPROVED, **T0 ☑ T1 ☑ T2 ☑ T3 ☑ — T4 IN PROGRESS (☐)** — 🛑 **T4 NEXT: resume the declaration layer where the cycle stopped (below, §1 "T4 — where it stands and the exact next commands"); xHigh** | R22 `check-all: 218 passed, 0 failed of 218` at `f2b58011e` (every one of the 21 T4 commits carries its own) | HEAD after this commit is the checkpoint's commit; tree clean; nothing pushed after `79b2f6f15` (Drew pushes, R6) | last batch `t4_HD6` on 3d9c8aed1: 271 files (headers; 271 drawable) · 0 declaration units: 0 canonical / 0 promoted / 0 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 0 kept · compiles 0
**Replay this block into the chat at the next session start (R64); it is the ONLY in-phase context the next session inherits. Everything below