Commit Graph

972 Commits

Author SHA1 Message Date
Drew T 02f060f607 feat(phase-31): S79 #5 — the libpad 4.2.1 + libapi 4.2 band and the apicard region LINKED from real objects: 13 stubs + 4 TUs + the reorder island gone; main 16 stubs, fleet 38
800c3 (0x8005CE18-0x8005FC68, one contiguous run of 33 interleaved Sony objects) is now four
stub rows — libapi1 (21 BIOS trampolines + COUNTER), libpad1 (PADENTRY + PADMAIN 760), libapi2
(L02/L03), libpad2 (PADCMD PADIF PADPORTD PADSEQD WAITRC2) — fed by two WINDOWED psyq_integrate
calls from the raw .run/obj42/{libapi42,libpad421} dirs (integrate tiles each stub with one
library; every boundary checked against .text SECTION sizes). The apicard region's three
"game code" rows were libapi 4.2's C objects to the byte: 800c2 = FIRST.o (firstfile + the
"no jump table wall" stub func_80062144), 800c2_2 = PAD.o, 800c2_3 = PATCH.o + CHCLRPAD.o ->
apicard5/6/7; make_apicard_used.py sources libapi from 4.2 (the EXE's real libapi; libcard
stays 4.0) into .run/obj42/apicard_used, 26 objects / 7 blocks, no game code left in
0x80061F38-0x80062888. src/800c3.c (129 hand-matched "C", 62 verbatim bodies, 19 stubs incl.
the four §332 %lo-in-a-delay-slot "walls"), src/800c2.c, src/800c2_2.c, src/800c2_3.c removed;
REORDER_TUS is empty (mechanism kept). Cookbook §490.

Two stale instruments fixed: exclude_audit let a pinned WALL outrank LINKED (PopMatrix/
PushMatrix had sat as walls since S68 while living in libgte3, linked since Phase 8) — LINKED
dominates now, config/wave_exclude.txt 13 -> 3; frontier_classify carried a hard-coded 49-name
LINKED set (R51) and reported 337 "stubs" — derived from the Makefile now.

Verified: main 143dbb89f34491258bbc27810d0a12ec8b43a8dd WITH all SDK dirs and WITHOUT them from
a fresh extract; make tools-health OK; R22 fleet extract-all 212/212 + check-all 213/213.
Metrics: main REAL 839->773, LINKED 1,150->1,256, VERBATIM 29->3, stubs 29->16, byte-identical
2,075/2,091 = 99.2%; game-code weighted 93.3% (38,748/41,534), remainder 2,786 = the open-stub
sum; fleet stubs 51->38 (frontier_classify: 39 rows incl. the data word). Verbatim manifest
33 -> 6. Docs: worklist rows + "S79 task #5", SETUP (fresh-clone obj42 commands, Makefile
blocks, exclude_audit), decision-log "S79 addendum 2", accelerators "S79 (2)", CURRENT_PHASE
S79 FINAL refreshed (census, metrics, the task #6 brief).
2026-09-04 17:56:31 -06:00
Drew T 58996ca4f7 feat(phase-31): S79 #13 — FOUND the EXE's libpad 4.2.1 + libapi 4.2 (PsyQ RTL 4.2 archive + the J421PD patch): 46/46 band objects link byte-identical
The bounded hunt succeeded on its first lead. archive.org item
`play-station-programmer-tool-runtime-library-version-4.2.7z` (383 KB) is the PsyQ Runtime
Library 4.2 (LIB/*.LIB + INCLUDE, 1998-01-21) plus LIB/42PATCH/J421PD.ZIP — SCE R&D's
1998-02-26 "Libpad.lib version 4.2.1 for the Analog Controller (DUAL SHOCK)" patch, shipping
LIBPAD.LIB 4.2.1 with LIBAPI.LIB 4.2 and LIBPAD.H/LIBAPI.H/KERNEL.H.

Placed and byte-verified against the EXE (psyq_identify 0x8005CE18-0x800629DC, then
psyq_link.py per object): libpad 4.2.1 7/11 — PADENTRY, PADMAIN (760 ins, the 4.2.1 build,
exact), PADCMD, PADIF, PADPORTD, PADSEQD, WAITRC2 — and libapi 4.2 39/88 — the 21 band
trampolines, COUNTER, L02/L03, and the apicard-region C112/A50/A51/A54/A65/A67/A69/FIRST/A66/
PAD/A18-21/PATCH/CHCLRPAD. All 46 PASS. Neighbours for the record: plain libpad 4.2 and the
4.3 disc (DTL-S2340, 1998-05-18; PADMAIN 832 / PADIF 380 / PADSEQD 292) each place only 4;
4.2.1 is the unique exact match, so the game was built between Feb and May 1998.

Banked (R20): the 7z tracked under tools/psyq/ with sha256 + provenance in CHECKSUMS.sha256;
extracted to gitignored tools/psyq/lib42/ and lib421/ (the 4.2.1 headers are the band's
prototype oracle from now on); ELF in .run/obj42/{libpad421,libapi42}. Docs: psyq-worklist
"S79 task #13", SETUP archive table + §5.1 + S79 tool table, CURRENT_PHASE (#13 log; the S79
FINAL block's §5 records the archive and §6 is the re-scoped task #5 brief: link the whole
0x8005CE18-0x8005FC68 band and re-source the apicard region's libapi from 4.2).
2026-09-04 17:36:03 -06:00
Drew T 757bd82a0f feat(phase-31): S79 #4 — scattered-.bss split at link-prepare (psyq_bss_split): SYS.o→libgpu2, VM_F.o→snd12, GS_001.o→libgs8 LINKED; libgpu_used retired
The §9.1 "scattered .bss commons" exclusion class (Phase 8 → P31) is closed 3/3. New
tools/psyq_bss_split.py (own ELF32 REL reader/writer) cuts an object's packed .bss into
per-base NOBITS pieces: bases derived from the game bytes per HI16/LO16 pair, references
walked in offset order into single-base runs, cuts snapped to symbol starts (the linker
scattered SYMBOLS), symbols moved, a LOCAL section symbol per piece inserted, relocs
retargeted with the addend rewritten in the immediates, self-diffed. It runs inside the one
prepare step shared by psyq_link.link_object / psyq_link_region.build_region /
psyq_integrate.integrate (prepare_object before classify), re-derived every build.

GS_001.o was certified "5 interleaved bases, NOT splittable" by the S77 probe, which grouped
by BASE; by RUN it is six symbol-aligned pieces. All seven cuts across the three objects are
confirmed by the other objects' by-name recoveries (_que 0x800C5510, _svm_sreg_buf
0x800B9B58, PSDBASEX/CLIP2/PSDBASEY/POSITION/GsDRAWENV). R39 negative control: 235 placed
objects across 9 curated dirs, 0 refusals, exactly 3 splits (a libcd .bss+size end pointer
refused the first build → reference problems are fatal only when a split is needed).

Wiring: yaml 800c→libgpu2, sgap_6→sgap_6+snd12, gsgap3→libgs8 (comments rewritten);
LIBGPU_ELF := .run/obj40/libgpu (curated libgpu_used retired); libgs 34 objs/8 blocks
(make_libgs.sh +GS_001); snd 63/12 (make_snd_used.py exclusions 4→3). src/800c.c and
src/gsgap3.c removed (Sony code hand-matched as REAL/verbatim), sgap_6.c keeps only
func_8003FA54; splat-emitted libgpu2.c/libgs8.c/snd12.c stubs for the no-SDK fallback.

Verified: main 143dbb89f34491258bbc27810d0a12ec8b43a8dd WITH the SDK objects and WITHOUT
them from a fresh extract; make tools-health OK; R22 fleet clean extract-all 212/212 +
check-all 213/213. Metrics: main REAL 886→839, LINKED 1,040→1,150, VERBATIM 85→29, stubs 29
(unchanged); game-code weighted 91.1% (40,895/44,870) — both terms lost the 3,667 SDK ins;
the remainder is still exactly the 3,975-ins open-stub sum. Verbatim manifest --update
200→33 rows (subtractive). Docs: cookbook §489 (+index), psyq-worklist rows + "S78 task #4",
SETUP S79 R21 table, decision-log S79 addendum, accelerators S79, CURRENT_PHASE S79 FINAL 🛑.
2026-09-04 17:19:29 -06:00
Drew T 4c32475299 docs(phase-31): S78 FINAL checkpoint — #12 + #3 banked, the census, the three instrument corrections, task #4 design brief (SYS.o/VM_F .bss split), #5/#13 band context 2026-09-04 16:32:43 -06:00
Drew T a85733a487 feat(phase-31): S78 #3 — 13 "game code" subsegs were PsyQ objects: wired LINKED (libgte 70/30, libgs 33/7, snd 62/11); main's game-code metric corrected to 91.8%
- exact tiles, 0 tokens: libgte23-26 (MSC01/02/05/09, SMP_00, FGO_01-06, PATCHGTE), libgte9 re-derived
  as SMP_05 NormalClip (SMP_06 NormalClipS = nested sub-pattern; psyq_integrate now drops nested
  placements), libgte27-30 (the libgs-gap MTX_05/07/11, REG03+REG11), libgs7 (2D_BG0+2D_BG1), snd10
  (VM_NO1), snd11 (VM_NOWON carved off sgap_8). LINKED 959->1040, REAL 912->886 (SDK inline-asm wrappers
  re-provenanced), VERBATIM 146->85, 13 TUs deleted; splat re-emits the stub records.
- main 143dbb89 WITH and WITHOUT the SDK objects. The no-SDK fallback had been red since S7x
  (CdReadyCallback called by its SDK name while the libcd stub carried func_800435B4) — curated
  CdReadyCallback = 0x800435B4, refs unified. R22 clean fleet 213/213; tools-health OK.
- METRIC CORRECTION (R35): progress.py's "MAIN game-code weighted" sig never excluded the LINKED
  objects (its comment said it did) — ~31k linked-SDK ins sat in the denominator as unmatched game
  code. Exclusion now derived LIVE from the Makefile stub lists + yaml ranges: 91.8% (44,562/48,537),
  not 59.8%; the 3,975-ins remainder equals the open-stub sum exactly.
- VM_F.o probed SPLITTABLE at .bss 0x50c (SYS.o's class -> task #4). cookbook §488; worklist S78 #3;
  decision-log + accelerators; SETUP rows.
2026-09-04 16:26:12 -06:00
Drew T a7394f44dc feat(phase-31): S78 #12 — the 800c3 "wall" band is LIBPAD 4.2.1 + LIBAPI 4.2: 46 names applied; integrate wired by subseg range; renames via ApplySymbols
- provenance: the psx loader's per-version PsyQ signature sets place PADENTRY/PADCMD/PADPORTD/
  PADSEQD (4.2), WAITRC2 (4.3), COUNTER/C114/FIRST/PAD/PATCH/CHCLRPAD (libapi 4.2) byte-exact in
  0x8005CE48-0x8005FC68 / 800c2 -> 12 of main's 29 stubs incl. all four §332 walls are Sony's
  DualShock library in reorder mode. 46 names -> symbols.us.txt (count 1081), band TUs, verbatim
  manifest, wave_exclude; firstfile/firstfile2 (4.2 naming); CdGetToc @0x800430B8 (was the Phase-21
  xdedup mislabel DecDCToutCallback). SETUP §5.1 corrected; psyq-worklist S78; cookbook §487;
  decision-log + accelerators S78; CHECKSUMS +Psy-Q_46.zip +PSYQ_SDevTC_v4.5.zip.
- psyq_integrate: --yaml maps stub<->objects by SUBSEG RANGE with an exact-tiling check and PRINTS
  the located-but-unwired residue (libgte: 13 objs / 1,264 ins) — main's LINKED build had been RED
  at HEAD since the S77 psyq_identify fix (22 libgte blocks merged to 3; gate worktrees take the
  stub fallback so it never showed); a library object's exported symbol whose recovered address the
  curated file names differently is --redefine-sym'd (R15; A66 firstfile->firstfile2).
- Ghidra: 47 MCP renames did NOT persist through the sentinel stop (R9 caught it) -> NEW
  tools/ghidra_scripts/ApplySymbols.java + tools/ghidra_apply_symbols.sh mirror the curated file
  headless with a real save: 73 renamed, R9-verified x4. SETUP inventory rows (R21).
- lint_symbol_refs: scans verbatim __asm__ bodies (`.ent\tfunc_X` is invisible to \b and to the
  string-masked scan); negative-controlled (red on the pre-fix TUs, green on the passing tree).
- R22: clean extract-all 212/212 + check-all green on the final config; main rebuilt byte-identical
  143dbb89 after the last src-only fix -> 213/213; tools-health OK.
2026-09-04 15:57:06 -06:00
Drew T ac97233aa9 docs(phase-31): S78 OPEN checkpoint — the census, the libpad-4.2.1 band finding, the confirmed completion order (#1-#13) 2026-09-04 15:26:18 -06:00
Drew T c9dd2fbc76 docs(phase-31): S77 FINAL checkpoint — 31 banked, contract §1.3 closed, the LINKED picture measured 2026-09-03 22:51:28 -06:00
Drew T 75a7169cc2 docs(phase-31): S77 addendum — recover_route + permuter_sweep, and the two self-inflicted defects they exposed 2026-09-03 21:12:21 -06:00
Drew T bfc0f43c92 docs(phase-31): S77 CLOSE — 30 banked, main 57.1%->59.4%, ten instrument defects, R61
S77w wave: 30 workflows, 30/30 reported, 9 banked, 21 NEAR, 0 errors.
R22 clean-fleet 213/213 (fourth run this session). Cookbook §477-§483.
2026-09-03 20:52:15 -06:00
Drew T 90042c111d rules(R61): not-judged is not a verdict; a draft-judging tool must model the real pipeline
Drew ratified in-session after the S77 census: eight instrument defects, all one
shape — a tool asserting about a DRAFT what was true only of the HARNESS.
2026-09-03 20:01:28 -06:00
Drew T 9d15598b5a docs(phase-31): S77 FINAL checkpoint — 21 banked, self_decl_tu closed, the permuter yield curve, eight instrument defects 2026-09-03 19:51:02 -06:00
Drew T b5751c7c1e docs(phase-31): S77 checkpoint — 17 banked, the self_decl_tu lane closed, six instrument defects
T11 4/7, T12 13 banked of a 34-draft pool, T13 R22 213/213 twice (a green
baseline before the overlay banks and again after all 17).

main REAL 895 -> 899, stubs 46 -> 42. Fleet stubs 82 -> 65, distinct-code
99.3% -> 99.4%, MAIN game-code 57.1% -> 57.3%.
2026-09-03 19:25:02 -06:00
Drew T 4069ee43a7 docs(phase-31): S76 FINAL checkpoint — 24 banked, five more instrument defects, four walls refuted
Written for a fresh session: what banked, what did not and WHY (classified by
compiling each stranded draft in its real TU, not guessed), the five tool
defects and their fixes, the four refuted walls and the one proved, and the
five things I got wrong so the next session does not inherit them.

Headline state: REAL 895 (was 882), main game-code 57.1% instruction-weighted
(was 55.8%), 46 open stubs in main and 82 fleet-wide, 143dbb89 byte-identical.
R22 clean-fleet NOT run since the banks.

Next four tasks are logged with their evidence and their traps.
2026-09-03 18:14:08 -06:00
Drew T 163c91e420 docs(phase-31): correct the S75 checkpoint's figures and record the one-line UNPLACED fix
Verified at close rather than asserted: 25 commits, src/config/tools clean, main
green at 143dbb89..., and HEAD genuinely carries the func_8002B0B4 C (0
INCLUDE_ASM for SaveLoadRoutine, 1 real definition). A 47-minute bisection left
several mid-run readings that looked like regressions and were not, so the
figures are now stated from a settled tree.

Adds START HERE item 0: the UNPLACED parse hole is one line --
config/symbols.us.txt:27 still declares SaveLoadRoutine = 0x8002B154 // func, so
splat keeps emitting a .s for a symbol that is now case 0: inside func_8002B0B4.
Delete, re-extract, rebuild. config/wave_exclude.txt lines 14-15 are stale for
the same reason. Left undone only because a gate held main's tree at close.

T10 checklist now carries the S75 line.
2026-09-03 12:26:26 -06:00
Drew T af4912e624 docs(phase-31): S75 FINAL checkpoint — 32 banked, nine instrument defects, the verbatim class mapped
Written for a fresh session. Headline: every codegen wall examined this session
was an instrument defect, and the two largest results came from deleting a
belief rather than writing better C -- SaveLoadRoutine's §434 wall was a splat
symbol boundary (it is case 0 of func_8002B0B4, one function on one frame), and
the '§332/§188 wall' was the reorder island, which banked 20 functions whose
drafts had been on disk since waves m04-m16.

Records what I got wrong so it is not inherited: five regex censuses
(116/112/108/178/199), contiguity mistaken for fragmentation, a build-config gap
called compiler-inexpressible, and two bursts drawn at fragments because the
triage came after the draw instead of before it.

R22 clean-fleet NOT run; the checkpoint says so at the top.
2026-09-03 12:13:02 -06:00
Drew T 8e3ce81a69 docs(phase-31): S75 addendum — the frontier is 154 game functions bigger than reported
tools/asm_in_c.py finds 199 functions that are assembly posing as C (154 game
code, 171 in main). They were in no progress.py bucket, so main's REAL% was
overstated: 45.88% -> 42.15% once counted. Nothing regressed; the denominator
was missing 173 functions of real remaining work.

Also records the counting cautionary tale (five hand counts, 116->112->108->178
->199, each wrong the same way) and the tool design that answers it. Cookbook
§448.
2026-09-03 00:02:02 -06:00
Drew T ac55da69d1 docs(phase-31): S75 checkpoint — 7 banked, seven instrument defects, SaveLoadRoutine is a carve
Full 🛑 block for a fresh session: state, the seven defects (§442-§447), the
measured frontier map, Drew's dedup decision, and the harness lessons.

The headline for whoever picks this up: SaveLoadRoutine (1,165 ins, the §434
wall, 9.2% of all remaining work) has a BYTE-IDENTICAL body and is blocked by a
jump-table carve -- which the verdict tool could not say because that verdict
class was unreachable by construction on main.

R22 clean-fleet is NOT yet run for S75 and the checkpoint says so.
2026-09-02 23:11:35 -06:00
Drew T cb948a6bbc feat(decomp): the ov_SC01 reloc-only cluster + its 5th latent victim — 5 fns, 1,301 ins
S74 handed this forward as "1,116 instructions behind one question": family_remap
on ov_SC01_004/005/006/008 gated DIFF 4/4 against the banked exemplar
ov_SC01_009:func_8017EB08, and the class had been carried as a codegen wall since
S70. The four bodies were byte-identical to the exemplar the entire time.

Word-level classification vs the exemplar, computed independently twice (a Fable
agent's script, then mine from scratch against the retail images), identical:

    nins=279   EQ 213 · RELOC-HI16 23 · RELOC-LO16 24 · INTERNAL-J 19 · CODEGEN 0

Zero register-allocation, instruction-selection or scheduling differences.

ROOT CAUSE — tools/jtbl_carve.py reserved ONE WORD TOO MANY per table:
  * spimdisasm runs an island's LAST `jtbl_` dlabel one word into the following
    NON-ZERO data (string bytes 0x696F760A / 0x000013FF / 0x62647020), so the
    zero-word trim cannot see it; and
  * the over-span clamp that would have caught it was guarded by
    `len(sltiu_bounds) == 1` -- but `sltiu` is ALSO how gcc emits an unsigned
    range check ((u32)(x-lo) < n, I1). These four carry five distinct sltiu
    immediates, so the guard silently disabled itself on precisely the functions
    that needed it.
  0x2C reserved for a 0x28 table => image 4 bytes short => ~850 %lo immediates
  shift => whole-binary DIFF about a function whose own bytes are perfect.
Fixed with a PER-TABLE bound: gcc-2.7.2's dispatch is a fixed idiom, so the
`sltiu` nearest ABOVE that table's own %hi(jtbl_X) is unambiguous whatever else
the function tests. Second defect stacked behind it: a carve span whose
JTBL_PADS line lacks a `tables=` comment lost its existing table's start on
merge and refused "table starts do not fit the span" -- which harvest_verify
then "repaired" with a needless jr_isolate_all that walked back into the first.

THE NEGATIVE CONTROL IS THE STORY. Run over every other open table-bearing stub
fleet-wide, the fixed bound changed exactly one more table: ov_SC06_022/
func_80185B80 (185 ins), a FIFTH victim nobody had drafted against. A guard that
disables itself on a common idiom does not fail once -- it fails quietly across
the whole corpus.

Banked, each with its own byte-gate verdict (--no-propagate, clean re-gate):
  func_8017EB30  ov_SC01_004  279
  func_8017F2D4  ov_SC01_005  279
  func_8017F2D4  ov_SC01_006  279
  func_8017EC68  ov_SC01_008  279
  func_80185B80  ov_SC06_022  185

Also here:
  * dedup_propagate: memoize find_site's mask (lru_cache) -- 54 ms of masking
    per call over the whole source, recomputed though it depends only on the
    text. 2x on that loop (58.3 -> 33.0 ms/call), NC identical on 120 addrs.
    Scoped honestly: that loop is ~2.4 min of a 30-min run; the profiler puts
    43% in family_remap._alias_decl_for, which is NOT fixed here.
  * Makefile: `clean` says out loud that BINARY= is ignored and it is fleet-wide
    (cookbook §445) -- it silently deleted asm/ for all 213 binaries this session.
  * Cookbook §446 (the carve law: when a standalone-MATCH jtbl draft gates DIFF,
    diff the carve extent against 4 x sltiu before touching the body), §445, and
    SETUP rows for both tools (R21).
  * CURRENT_PHASE: the S75 log, incl. the measured fleet dedup-hygiene census
    (~2,073 fns / ~12,116 items, all ALREADY MATCHED -- cleanup, not work) and
    Drew's decision to leave it and gate --no-propagate from here.
2026-09-02 22:15:20 -06:00
Drew T cdd535e45b fix(tools): reconcile_tu's cc1 premise, the &-cast arms, and the worktree sig gap
The S74 checkpoint's "one unfixed defect that is actively costing banks"
(reconcile_tu manufacturing declaration conflicts), run to ground — plus the
harness gap that produced a false carve-corruption verdict.

reconcile_tu.py — three defects, measured against the real gcc-2.7.2 front end
(cdecl._cc1_accepts, the oracle cdecl.compatible was validated with; R33):
  * The premise "a decl BELOW still conflicts" is TRUE at file scope and FALSE
    at block scope. cc1 ACCEPTS a block-scope extern against a TU decl below it
    (pedwarn "type mismatch with previous external decl"); conforming it is
    destructive, because the TU's decl names the TU's TYPE and a type declared
    below the splice point is not in scope AT it -- the emitted result gets
    "syntax error before 'D_x'". Byte-witnessed on resident:func_800D06E8 (344
    ins), whose block-scoped `extern Blk80078E78` became `extern
    Struct80078E78`, typedef 388 lines lower. That construct is what this
    ladder's OWN scope_demote_drafts (§8d) rung emits on purpose, and three
    already-banked functions in that TU use it: one rung undoing another.
  * The cast pass rewrote COMMENT PROSE -- 8 rewrites inside one header comment,
    including inside a quoted cc1 diagnostic. Now matches on cdecl._mask
    (length-preserving, so a mask offset is a source offset) and splices into
    the original.
  * `&sym` emitted `&` applied to a cast: legal for the scalar arm, `invalid
    lvalue in unary '&'` (measured) for the array/fnptr/fnptr_array arms. `&`
    now selects a pointer form and consumes itself -- but ONLY with no trailing
    subscript, because `&sym[i]` is the address of ELEMENT i and the old code
    had that case right. That last clause exists because the R39 negative
    control caught the fold as a regression in the first cut of this fix.

gate_stage.py — `--skip-stages` / `GATE_SKIP_STAGES` (loud when used). Stage 0
gates raw drafts first, so a broken rung can only cost a RECOVERY, which is
exactly what makes it invisible: the function it destroys was already failing,
so its DIFF reads as a fact about the function.

verify_worktree.py / jr_isolate_all.py / parallel_gate.py — provision() now
symlinks every .run/sig.*.jsonl (main clone 259, provisioned worktree 0), the
third member of the class holding extracted/ and .run/obj40. parallel_gate was
fixed for this identical bug in S69: two provisioners, no shared list, found
twice; they now cross-reference each other. jr_isolate_all no longer swallows
the resulting FileNotFoundError into `except: continue` -- that turned a missing
index into a confident carve-CORRUPTION verdict over 2,603 of 2,603 functions
(R54). Adds _assert_scan_covered: attempted == raised means the scan measured
nothing, so its zero is an artifact, not a finding (R32).

Verification:
  * 4 cc1 probes (the table above), each run on the pinned front end.
  * R39 negative control over the stored-draft corpus: 661 adjudicated, 652
    IDENTICAL, 9 CHANGED and every one an intended class. 4,173 of 4,864 drafts
    unadjudicable (filenames that are not func_<ADDR>) -- stated, not hidden.
  * jr_isolate_all ov_SC03_105 --dry-run: unchanged in the main tree.
  * make clean/extract/build BINARY=resident -> 8e17e02f... BYTE-IDENTICAL.

Docs ship with the change (R21): cookbook §442/§443, index regenerated (1,112
sections), 3 docs/SETUP.md rows, CURRENT_PHASE S75 log.
2026-09-02 20:30:22 -06:00
Drew T 7f7e1c7d90 docs(phase-31): refresh the S74 checkpoint — §440/§441 and the doc-state line
The checkpoint listed §435-§439 and was written before the documentation catch-up; a stale
checkpoint is worse than an absent one. Now records that every tool change this session carries a
SETUP row and a cookbook entry, and names the rule the gap taught.
2026-09-02 19:54:10 -06:00
Drew T b24394e732 docs(phase-31): S74 FINAL checkpoint — 50 banked, seven tool defects, R22 213/213
Every reject class this session was an instrument defect, not a codegen wall: 24 already-MATCHed
bodies were sitting behind seven tool bugs, six of which are now fixed. The checkpoint names the
seventh (reconcile_tu manufacturing declaration conflicts) as the first thing to fix next session,
and the harness gap (verify_worktree omits the sig files, and the scan that needs them swallows the
error and reports a false corruption) beside it.

Fleet verified from a clean rebuild AFTER the last bank: check-all 213 passed, 0 failed of 213.
split_indicator 213 OK and now a hard gate. INCLUDE_ASM lines in src/ 1,086 -> 1,036, measured at
both commits — the same 50 the gates reported, counted independently from the source.
2026-09-02 19:40:46 -06:00
Drew T aa302aa050 docs(phase-31): S73 FINAL checkpoint — consolidated, verified, fresh-session ready
Supersedes S73 CLOSE and its addendum. Every number re-verified against the repo:
REAL 880/1,918, MAIN 56.5%, frontier 124 (main 36), main jtbl fns 25 -> 2.
2026-09-02 17:25:57 -06:00
Drew T a0ff94626a docs(phase-31): all 40 actively-misleading audit findings worked, not deferred
Replaces the 'known-remaining' TODO list with what was actually fixed. The four that
were not doc typos: progress.py undercounting REAL by 7 (the #else half of a
NON_MATCHING block is live code and classify() swallowed it), the silently deleted §429,
the false §265 accusation in §434, and memory-map.md:309 claiming a 'verified' extent
that overlaps the new span-B carve.
2026-09-02 17:17:44 -06:00
Drew T 5ae43099e0 docs(phase-31): S73 CLOSE addendum — corrections, and the known-remaining list
Corrects three defects I introduced (deleted §429, a false accusation in §434, an
over-strong SaveLoadRoutine verdict), two wrong numbers in the block above, and records
the SETUP §6.6 gap that was the real answer to 'are the docs up to date'.

Also lists what the audit found and I did NOT fix, with file:line, so a fresh session
inherits the list instead of rediscovering it: jr_isolate/jtbl_rodata_pads/draw_waves
docstrings, several stale playbook census numbers and its step-1 command, memory-map:309,
and the pre-S72 --front/--tail descriptions in the Makefile and ld_interleave.
2026-09-02 17:06:52 -06:00
Drew T 2c1d21bb9d docs(phase-31): S73 CLOSE — R22 213/213, 23 main banked this session, main 56.5%, frontier 124
The jump-table class on main is resolved: 25 -> 2, and both survivors are the §434 frame
pair, provably unmatchable as separate C functions (resegmentation, not drafting).

Wave S73m_1 banked 9 of 9 drafts (2,413 ins). Cookbook entries written this morning
cracked functions this afternoon; two of mine were refuted by later MATCHes and rewritten.
2026-09-02 16:34:13 -06:00
Drew T ab0bbd257b docs(phase-31): S72 addendum 2 — exclude list regenerated, draw refuses a stale one
88 of 107 entries were stale one day after the list was written; 46 of them were
12,750 instructions of open drawable work including SaveLoadRoutine. Canonical list is
now config/wave_exclude.txt (19 entries), and draw_waves --exclude-file audits it as a
prerequisite.
2026-09-02 14:39:55 -06:00
Drew T 27c81ed0c2 docs(phase-31): S72 addendum — split_indicator found 4 more binaries (16 fns / 3,613 ins)
18% of the non-main frontier, all already in the exclude list as if unmatchable rather
than 'needs a subseg split'. Plus: 28 of that list's 107 entries are already banked, so
regenerate it before the next draw.
2026-09-02 14:10:20 -06:00
Drew T 09886be66b docs(phase-31): S72 FINAL — R22 213/213, 14 main banked, main 52.6%, frontier 133
The carve + the src/800.c split at the original TU boundaries. 7 of the 14 banks were
span B/C — impossible before the split. Next session starts with 11 functions /
4,479 instructions that are now merely undrafted rather than unbankable.
2026-09-02 13:54:16 -06:00
Drew T f0148e6822 docs(phase-31): S72 CLOSE — R22 green 213/213, 7 main banked, main past 51.8%, frontier 140
The 11 'PROVEN gate-rejects' were one missing rodata carve, not bad bodies. Next
session starts at the span B/C carve: 18 jtbl functions left in main's frontier holding
most of its remaining instruction mass, blocked on splitting src/800.c at 0x8002B0B4
and 0x80035270 — the original TU boundaries the jtbl spans reveal.
2026-09-02 12:58:44 -06:00
Drew T 8edd0f61e0 docs(phase-31): S72 progress — main's jtbl carve debugged, fixed, 3 banked; span B/C is the next lever 2026-09-02 12:09:06 -06:00
Drew T 6c904ebd0c docs: close the S71 documentation gaps - SETUP tools table, playbook steps, decision log, gate ledger
Audit found real gaps rather than assumed coverage:
* SETUP.md (R21) had NONE of the five tools written this session. Added a table for
  journal_notes / launch_check / gate_triage / restage_matching / weave_sweep, each with
  when you need it, plus the two gating rules now enforced in code (parallel_gate refuses
  main; gate_main refuses a no-op draft and counts banks from the source).
* wave-playbook: launch_check as step 4c (payloads go stale while gates run - 3 of 27
  wave-2 targets were already banked) and gate_triage as step 6b with the measured
  blocker census.
* decision-log (R31) held only the §406 pivot. Added the two strategic entries this
  session actually turned on: gating main with a tool documented as unable to gate it
  (false PASS, caught only by R22), and the drafting pool running dry while the lever
  was an exclude list nobody re-probed after a tool fix.
* CURRENT_PHASE: the per-gate ledger for all 14 cycles plus the carve/rebase/main gates.
* Two memories: gate-main-only-with-gate-main, reprobe-exclude-lists-after-tool-fixes.
2026-09-02 11:19:49 -06:00
Drew T 9631949339 docs(phase-31): S71 CLOSE — R22 green 213/213, frontier 147, 63 banked, main past 50% 2026-09-02 11:15:21 -06:00
Drew T 225f7d4ee9 docs(phase-31): frontier 150, 60 banked; main lane reopened; two gate_main defects fixed 2026-09-02 10:15:20 -06:00
Drew T 11862e3c22 docs(phase-31): gate 10 (+3), frontier 162, 48 banked; §420-§423 harvested 2026-09-02 05:51:08 -06:00
Drew T 1c932c61b8 docs(phase-31): +4 via multi-cluster symbol rebase; frontier 165, 45 banked 2026-09-02 05:38:45 -06:00
Drew T f31f56ef17 docs(phase-31): the drafting pool emptied; the carve lane replaced it (+5, frontier 169)
Wave 3 drew 1 target - 0 left in pool. Of 174 open: 64 main, and of 110 non-main, 41
drafted this session, 68 excluded, 2 walls, ZERO undrawn. Re-probing the 68 with
jtbl_carve --probe found 17 now reporting `tail`, because tonight's jr_isolate_all
fixes changed their overlays. All 17 already had drafts; 10 scored closeness 0 with no
drafting. The gate banked 5, and they are exactly the five overlays jr-isolated tonight.

An exclude list is a snapshot of what the TOOLING could not do and goes stale the moment
the tooling improves - re-probe it after every tool fix.
2026-09-02 05:34:38 -06:00
Drew T 9bb43dd426 docs(phase-31): S71 gate 9 (+2, frontier 174, 36 banked); §419 density lever recorded 2026-09-02 05:19:10 -06:00
Drew T 49d1e06632 docs(phase-31): S71 gate 8 (+2, frontier 176, 34 banked); two proven walls recorded
Two functions recorded as walls with their refutation lists rather than redrafted:
ov_SC03_105/func_801834A4 (loop.c movable ordering, closeness 6) and
ov_SC06_022/func_8017DF28 (expand_block_move's copy_addr_to_reg pseudo reused by cse,
closeness 2, seven levers measured inert). One MATCH blocked purely on carve state with
its exact prescription queued in .run/S71_carve_todo.txt.
2026-09-02 05:02:09 -06:00
Drew T 8709798738 docs(phase-31): S71 gate 7 (+3, frontier 178, 32 banked) + the measured blocker census
Blocker census read off the 37 gate verdicts on disk: DIFF 18, CARVE 7, PARSE 3,
NO-DIAG 3, CONFLICT 2, ARITY 2, UNDEF 2. I had called carve the dominant remaining
class mid-session on the strength of the last two agents I'd read; it is not. What
remains is mostly genuine codegen, the opposite of the integration-dominated picture
this session opened with.

Also recorded rather than redrafted: ov_SC03_105/func_801834A4 as a proven loop.c
movable-ordering wall (closeness 6, two measured-inert levers), and
ov_SC01_004/func_8017EB30 as MATCH-279/279 blocked purely on §8e carve state.
2026-09-02 04:46:02 -06:00
Drew T 072607df7b docs(phase-31): S71 gate 6 (+4, frontier 181) and cookbook §416
Four new byte-proven levers from the overnight lane, none previously in the cookbook:
re-read the store instead of passing the value (CSE store-forwarding), (&SYM)[3] vs a
pointer local as an ADDRESSING choice, one biv with +0/+2/+4 for combine_givs, and a
local's width choosing lh vs lhu+sll/sra.

Also recorded: the same-address twin hint was false three times tonight (ov_SC06_000,
ov_SC01_080, ov_SC03_030) while the same-TU neighbour was the real fuel in every case.

Three of the night's five post-limit MATCHes recovered a body off disk rather than
re-deriving it - func_80181A60 in 2 minutes instead of 16.
2026-09-02 04:32:08 -06:00
Drew T ab46791e06 docs(phase-31): S71 resumed at 04:11 after the session-limit reset
All five in-flight agents died on the 5-hour limit and returned NO-DRAFT; that is a
harness kill, not a verdict about the targets (R40), so they relaunch unchanged.
Gate 5 banked 2 (commit:3614). launch_check.py added after a stale card burned an agent.
2026-09-02 04:12:25 -06:00
Drew T 4d7c297b12 docs(phase-31): S71 CHECKPOINT — fleet R22 GREEN 213/213, honest frontier 187 (23 banked), main incident recorded 2026-09-02 01:50:33 -06:00
Drew T 0e4c98dc97 docs(phase-31): S71 gate cycle 4 — frontier 210 -> 176, 34 banked; residual-class routing + the R48 name-key exposure 2026-09-02 01:31:57 -06:00
Drew T fecbfac5f8 docs(phase-31): §412 — §323 carve blocker 2 was a regex blind to __attribute__; 5 of 6 carve overlays cleared 2026-09-02 01:25:56 -06:00
Drew T 6c4391abb9 docs(phase-31): S71 gate cycle 3 — 29 banked; journal-notes made permanent; jr_isolate_all unblocked 2026-09-02 01:17:47 -06:00
Drew T 89c3cf831b docs(phase-31): S71 wave 1 — journal-fuelled packs, 100% first-pass MATCH; cookbook 1078
* Every pack carried PAST ATTEMPTS ON THIS EXACT FUNCTION, mined per-function from the
  historical agent journals (52 of 60 targets, 131 notes). Every landed agent returned
  MATCH at closeness 0 on the hardest frontier we have.
* §409 — the wave and the nine laws it produced. Law 1: a relocation-stream
  TRANSPOSITION is invisible to match_one, the permuter scorer and every similarity
  tier (HI16/LO16 masking; the §195-D blind spot for a different reloc class), and it
  retroactively explains "MATCH but the gate rejected it" verdicts.
* §410 — COPY THEN ACCUMULATE ON THE COPY: satisfies the $s2 in-place destination and
  the sched1 birthing boost at once, with the agent's measured refutation list.
2026-09-02 01:04:27 -06:00
Drew T 137c418bc7 docs(phase-31): S71 — the 64 standalone matches priced honestly; 12 banked, 52 in four named lanes
* gate 1 (all 64 across 33 binaries): 12 banked — main 11 + ov_SC07_006 1.
* gate 2 tested "a bad draft kills its binary's good ones" by re-staging only the 25
  that recover_integration --probe-only called MATCH in their real TU: 0 banked.
  An honest null — that probe compiles and diffs bytes but never LINKS or CARVES,
  so it is a third oracle with its own blind spot.
* triage (25/25 accounted): CARVE-REFUSED 10, undefined-reference 4, DIFF 3,
  CC1-FAIL-no-diagnostic 2, PARSE 1; gate 1 adds 7 func-decl / 4 data-decl /
  6 type-decl conflicts.
* R37 probe of the carve class: 6 of 8 are one refusal — a subseg would host
  NON-CONTIGUOUS .rodata carves — whose named remedy is jr_isolate_all (§8b).

tools/restage_matching.py — rebuild a gate plan from probe verdicts.
tools/gate_triage.py — route a gate's verdicts to the lane each one names (R47).
2026-09-02 00:39:18 -06:00
Drew T 8cf0104386 fix(cards): defect 5 — an expired BASELINE-RED claim, without discarding any measurement
The S70 patch was refused by its own adversarial review for sorting rows by recency:
a pair's ledger rows are several PROBES about one draft, alternating between
`closeness 4` and `won't compile standalone`, so max(ts) serves whichever probe ran
last — often the least informative. This form keeps both.

* the ts-newest verdict is still selected (file order made the per-binary bulk ledger
  always win regardless of age: 25 pairs mis-selected),
* AND the best measurement ever taken on the pair rides alongside it, so a later
  uninformative probe can no longer erase an earlier residual: 981 of 2,605 pairs
  gain a line they were previously denied.
* BASELINE-RED is a fact about a binary at a moment (R51), frozen into an append-only
  ledger and replayed forever — 2,676 rows all stamped 2026-08-26. gate_feedback now
  reads the same live red union gate_stage consults, so a pack and the next gate run
  cannot disagree: 173 expired claims retired, 0 binaries currently red.

R39 control 3/3 (expired-when-green, harness-line-when-red, measurement-survives).
2026-09-02 00:32:20 -06:00
Drew T 13a16a15c6 fix(pgate): the merge scope missed main entirely — 11 byte-proven banks were dropped silently
* `git status --porcelain -- src/<binary>/` finds nothing for main, whose TUs are
  src/800.c, src/boot.c, ... — so a main worker returned `files: {}` while the bank
  oracle (the stub disappeared) still counted the banks. parallel_gate printed
  "12 banked across 2 binaries" and committed one of them.
* src_scope() takes the scope from the binary's own stub rows (each names its TU),
  captured BEFORE the gate because a bank deletes the stub that names it, and keeps
  the directory prefix for overlays that have one.
  Negative control: main 0 -> 54 TUs, ov_SC07_006 1 -> 3 (superset, no regression).
* A reused worktree kept the previous job's .run/harvest_failed*.classified.txt, so
  verdicts surfaced under the wrong binary; the worker clears them first.
* tools/gate_triage.py — routes a gate's verdicts to the repair lane each names (R47),
  with the staged-draft denominator asserted (R32/R41).

Re-gated main: 11 banked (commit:3586), main real frontier 64 -> 53.
2026-09-02 00:27:52 -06:00