Commit Graph

1622 Commits

Author SHA1 Message Date
Drew T c824c19a3d feat(phase-30 S48-T6): propagate func_80185F58 to its zero-crack siblings 2026-08-11 18:35:20 -06:00
Drew T 65204c205a feat(phase-30 S48-T6): propagate func_80186270 to its zero-crack siblings 2026-08-11 18:34:44 -06:00
Drew T 0c5d6fa909 docs(phase-30 S48): §162 — the wave-1 idiom harvest, deduped by a skeptic pass
17 candidates from the 12 crack agents, each audited against the whole
cookbook by an independent agent before being written: NEW 3, SHARPENS 13,
COVERED 0 (one agent died mid-response — its entry, §162c, is written by the
orchestrator and labelled as the least-audited one).

The three genuinely new laws:
- §162e  LICM: uniform loop-variable indexing is what makes a symbol address a
         MOVABLE at all (a literal index leaves a constant, no base pseudo, no
         hoist), and preheader order is body order.
- §162g  cross-jump DIRECTION is a source-shape oracle: do_cross_jump always
         keeps the LATER copy, so a BACKWARD jump into an earlier block can
         never be cross-jumping — it is a source `goto`.
- §162n  a conditionally-assigned alias pointer kills a spurious giv
         (loop.c cant_derive).

Two in-place CORRECTIONS, because a reader who lands there first must not be
taught the superseded rule:
- §161a's "diagnostic tell (family-wide)" reads as a complete test on entry[0]
  and actively teaches skipping the upper edge. Amended: check BOTH edges.
  The maxval symptom is the OPPOSITE of the minval one — it shifts nothing and
  costs two bytes, so it is functionally invisible.
- §25's triage rule prescribes pins for a symptom whose sibling mechanism
  (local-alloc optimize_reg_copy_1) pins provably cannot reach, because
  SMALL_REGISTER_CLASSES is never defined in config/mips/mips.h. Amended to
  point at §162j.

The skeptic pass also caught two errors in MY submitted evidence: I had copied
§161a's minval symptom onto the maxval case, and I described func_8017F2D4 as
a verified MATCH when the whole-binary gate had refused it (it is still
INCLUDE_ASM). Both corrected in the entries.

cookbook_index.py: 495 sections, 14 symptom buckets.
2026-08-11 18:31:18 -06:00
Drew T b83babbff5 feat(phase-30 S48-T6): Stage-1 probe wave — 8 exemplars banked, R22 213/213
Probe-12 wave (workflow wf_45e34026-aed, 21 agents, 3.36M tok, 70 min):
12 top-weight zero-crack sibling families cracked against match_one, every
claimed MATCH re-gated by an independent adversarial verifier.

  crack-agent MATCH   9/12 (75%)   adversarially refuted 0
  whole-binary gate   8/12 (67%)   NEAR 3, FAIL 0

Banked (exemplars, 1,941 ins; ~10k templatable ins across 42 member slots):
  ov_SC06_018  func_80186270 x6  func_80185F58 x6  func_80187AEC x6
  ov_MAIN_012  func_8017D730 x5  func_8017D2A4 x5  func_8017CF3C x5
               func_8017CBC8 x5
  ov_SC04_018  func_80188E1C x5

NOT banked, ledgered:
  func_8017F2D4 (ov_SC01_005) — match_one MATCH, verifier confirmed, and the
    WHOLE-BINARY gate still classifies DIFF. The §52b gap made concrete: the
    per-function gate is a candidate filter, the binary gate is the arbiter.
  func_8017C294 (x16, the largest single item on the board) NEAR 18 ins
  func_8017C3BC NEAR 17 ins · func_80189540 NEAR +2 ins / 4 sites

R22 clean-fleet after banking: 213 passed / 0 failed of 213.
2026-08-11 18:09:02 -06:00
Drew T 0498fc3627 chore(phase-30 S48): stage 0b closed — 91 banked (stub oracle 13,345 -> 13,254), R22 213/213 clean 2026-08-11 16:13:31 -06:00
Drew T 4913ac6a2c feat(phase-30 S48-0b): jtbl family func_8017A4AC — 1/1 blocked-binary siblings banked 2026-08-11 16:09:43 -06:00
Drew T 58b1d7aeea feat(phase-30 S48-0b): jtbl family func_8015C32C — 2/2 blocked-binary siblings banked 2026-08-11 16:09:34 -06:00
Drew T 19fee49f56 feat(phase-30 S48-0b): jtbl family func_8015B950 — 2/2 blocked-binary siblings banked 2026-08-11 16:09:23 -06:00
Drew T ef31c895b6 feat(phase-30 S48-0b): jtbl family func_8015AE2C — 2/2 blocked-binary siblings banked 2026-08-11 16:09:08 -06:00
Drew T d84e4f84ae feat(phase-30 S48-0b): jtbl family func_801734BC — 3/3 blocked-binary siblings banked 2026-08-11 16:08:57 -06:00
Drew T f0ecebd81f feat(phase-30 S48-0b): jtbl family func_80159A20 — 3/3 blocked-binary siblings banked 2026-08-11 16:08:39 -06:00
Drew T d8b84b75de feat(phase-30 S48-0b): jtbl family func_80171B4C — 3/3 blocked-binary siblings banked 2026-08-11 16:08:19 -06:00
Drew T c679a406b0 feat(phase-30 S48-0b): jtbl family func_801594E8 — 3/3 blocked-binary siblings banked 2026-08-11 16:07:30 -06:00
Drew T 63aa207c15 feat(phase-30 S48-0b): jtbl family func_8016AE5C — 3/3 blocked-binary siblings banked 2026-08-11 16:06:41 -06:00
Drew T 58a2339f54 feat(phase-30 S48-0b): jtbl family func_80154C24 — 3/3 blocked-binary siblings banked 2026-08-11 16:04:25 -06:00
Drew T 6eea1ac6a4 fix(phase-30 S48-0b): _carry_typedefs' already-carried test was line-oriented
The test was `^\s*typedef\b[^\n]*\bNAME\b` — the name must sit on the SAME LINE
as the keyword. True of `typedef unsigned char u8;`, never true of the
multi-line form the preamble backscan actually carries:

    typedef struct Foo {   …   } Foo;

so every multi-line typedef already in the unit was carried a SECOND time and
the unit reached the gate with two definitions of one tag. canon_sig_reconcile
uniquifies draft tags, so the duplicate is exact: `redefinition of struct
Foo_8013C0F8`.

- Extract the block capture as `_typedef_blocks(lines)` and derive the
  already-carried set from it (R33: one parser, two callers), so the
  multi-line form is recognised exactly as the single-line form always was.

Measured on the 0b population: func_8013C0F8 (3 slots) carried Foo+Bar twice;
func_8013B83C dropped a redundant file-scope copy of a typedef its body
declares at block scope. 6 other families byte-identical output.
2026-08-11 16:00:02 -06:00
Drew T dba6defb10 fix(phase-30 S48-0b): a def item can OPEN inside a block comment
`_proto_from_lines` starts `_strip` with in_block=False, but item boundaries
are `;`-terminated — so a declaration whose TRAILING comment wraps hands the
comment's continuation to the NEXT item, and the implied prototype came out as

  extern * a prototyped (s32) decl is `conflicting types` … */ void func_80151664(void);

It compiled only because the hoist emits the opening `/*` line immediately
above it, so the garbage lands back inside a comment — but `_file_scope_decls`
then meets a col-0 `extern …;` whose base type is `extern` and REFUSES (R32).
That is the isolate-fail class: 23 of the 111 open 0b member-slots.

- overlay_src_split._proto_from_lines: apply family_remap's D1 backstop — a
  `*/` with no `/*` before it means the chunk opened inside a comment; drop
  that residue before parsing the header.
- Repaired the 16 already-emitted region files (the garbage line's live
  payload was a redundant `extern void func_80151664(void);`).

Byte-gate after the repair: ov_MAIN_012 / ov_SC02_037 / ov_SC03_107 all
BYTE-IDENTICAL.
2026-08-11 15:58:25 -06:00
Drew T 5a42473c6e feat(phase-30 S48-0b): jtbl family func_80182BCC — 1/1 blocked-binary siblings banked 2026-08-11 15:54:24 -06:00
Drew T e4dd317572 feat(phase-30 S48-0b): jtbl family func_80179B74 — 1/1 blocked-binary siblings banked 2026-08-11 15:54:17 -06:00
Drew T a8bca8cf21 feat(phase-30 S48-0b): jtbl family func_80181CE4 — 1/1 blocked-binary siblings banked 2026-08-11 15:54:09 -06:00
Drew T 4ae63e7f6e feat(phase-30 S48-0b): jtbl family func_80178D40 — 1/1 blocked-binary siblings banked 2026-08-11 15:54:02 -06:00
Drew T dda26a3ea9 feat(phase-30 S48-0b): jtbl family func_8017AE2C — 2/2 blocked-binary siblings banked 2026-08-11 15:53:52 -06:00
Drew T 98d834ebf7 feat(phase-30 S48-0b): jtbl family func_8012ACE0 — 3/3 blocked-binary siblings banked 2026-08-11 15:53:39 -06:00
Drew T d4c6e3b2fc feat(phase-30 S48-0b): jtbl family func_801549F8 — 3/3 blocked-binary siblings banked 2026-08-11 15:53:22 -06:00
Drew T a1221881a0 feat(phase-30 S48-0b): jtbl family func_80135D20 — 3/3 blocked-binary siblings banked 2026-08-11 15:50:47 -06:00
Drew T aa2088c183 feat(phase-30 S48-0b): jtbl family func_80135888 — 3/3 blocked-binary siblings banked 2026-08-11 15:49:53 -06:00
Drew T 7259ad3d17 feat(phase-30 S48-0b): jtbl family func_80140608 — 3/3 blocked-binary siblings banked 2026-08-11 15:48:28 -06:00
Drew T b80ccb2012 feat(phase-30 S48-0b): jtbl family func_8012AAAC — 3/3 blocked-binary siblings banked 2026-08-11 15:48:09 -06:00
Drew T bda1adcd6e feat(phase-30 S48-0b): jtbl family func_801555F4 — 3/3 blocked-binary siblings banked 2026-08-11 15:47:52 -06:00
Drew T 60a3b3c6e9 feat(phase-30 S48-0b): jtbl family func_80135260 — 3/3 blocked-binary siblings banked 2026-08-11 15:47:05 -06:00
Drew T 2edb23a535 feat(phase-30 S48-0b): jtbl family func_801299C8 — 3/3 blocked-binary siblings banked 2026-08-11 15:45:47 -06:00
Drew T e14e0053c9 feat(phase-30 S48-0b): jtbl family func_80135A4C — 3/3 blocked-binary siblings banked 2026-08-11 15:44:44 -06:00
Drew T 45d08f208f feat(phase-30 S48-0b): jtbl family func_8014032C — 3/3 blocked-binary siblings banked 2026-08-11 15:43:58 -06:00
Drew T 7db73d89a0 feat(phase-30 S48-0b): jtbl family func_8015C32C — 1/3 blocked-binary siblings banked 2026-08-11 15:42:44 -06:00
Drew T b3e379faf4 feat(phase-30 S48-0b): jtbl family func_8015B950 — 1/3 blocked-binary siblings banked 2026-08-11 15:42:15 -06:00
Drew T 332ea1133c feat(phase-30 S48-0b): jtbl family func_8013FFD8 — 3/3 blocked-binary siblings banked 2026-08-11 15:41:12 -06:00
Drew T 44afe27544 feat(phase-30 S48-0b): jtbl family func_80135EB0 — 3/3 blocked-binary siblings banked 2026-08-11 15:40:54 -06:00
Drew T 7e9c6d53a4 feat(phase-30 S48-0b): jtbl family func_80159C84 — 3/3 blocked-binary siblings banked 2026-08-11 15:39:11 -06:00
Drew T 782186e598 feat(phase-30 S48-0b): jtbl family func_80131340 — 3/3 blocked-binary siblings banked 2026-08-11 15:37:38 -06:00
Drew T 9bf7c632e2 feat(phase-30 S48-0b): jtbl family func_801380E0 — 3/3 blocked-binary siblings banked 2026-08-11 15:36:47 -06:00
Drew T bb385208da feat(phase-30 S48-0b): jtbl family func_8013F350 — 3/3 blocked-binary siblings banked 2026-08-11 15:35:52 -06:00
Drew T 30f80d8a18 feat(phase-30 S48-0b): jtbl family func_8015A3C8 — 3/3 blocked-binary siblings banked 2026-08-11 15:35:04 -06:00
Drew T 374791d4be feat(phase-30 S48-0b): jtbl family func_8017A4AC — 2/3 blocked-binary siblings banked 2026-08-11 15:34:14 -06:00
Drew T f6c9867fbc feat(phase-30 S48-0b): jtbl family func_8015AE2C — 1/3 blocked-binary siblings banked 2026-08-11 15:33:32 -06:00
Drew T ec749fa584 fix(phase-30 S48-0b): JTBL_PADS follows its span through jr isolation
The 0b blocker was not "the pads line is left behind" alone — it fails two
different ways, and the second one is silent:

* bare isolate + `make build`: the stale line arms the pads filter on the
  RESIDUAL object, which emits no jump table ->
  `jtbl_rodata_pads: consumed 0 rodata .align(s) but 4 pad spec(s) given` (S47).
* isolate -> jtbl_carve (the jtbl_family_bank path): `set_pads_vars`
  regenerates the block keyed by the CURRENT subseg names, finds no prior spec
  under the new `_jr_<addr>` name, and DROPS the line. cc1's natural `.align 3`
  then pads the span's non-8-aligned interior tables and the image shifts —
  reported only as `built, bytes differ`.

- jr_isolate_all.repoint_overlays_mk: repoint the `build/src/<ov>/<sub>.o:
  JTBL_PADS` target with the `--order` leaf whenever a carve moves; refuse
  loud if the old object still hosts a .rodata piece (R32).
- jtbl_carve.set_pads_vars: second, disagreeing oracle (R34) — refuse when a
  spec would vanish for a subseg no longer in the carve set (rename/merge
  drift), instead of silently emitting a padless object.

R37 probe: func_801789AC -> ov_SC02_037 went `built, bytes differ` -> BANKED
on the whole-binary byte gate. ov_SC02_037's spec is 0,0,0,0 over tables
+0x0,+0x14,+0x34,+0x4c — load-bearing (span start is 4 mod 8).
2026-08-11 15:31:57 -06:00
Drew T 20a7cc59ee chore(phase-30 S47): FINAL session checkpoint — 2,197 banked, the residue crosses over to DIFF
2,197 instances banked, derived from the STUB ORACLE (15,542 -> 13,345), not from summing
per-batch reports (my running total said ~2,307 — summing drifts, the oracle does not).
35 commits, R22 213/213 after every batch, fleet 94.4% instr / 88.3% distinct / 96.33% fn-count.

THE STRATEGIC FINDING: the sweep residue started the session ~5:1 PLUMBING:DIFF and ends at DIFF
170 of 575 (30%), larger than the next four classes combined. The declaration-axis vein is spent;
from here the mover is volume with multipliers, not more plumbing. The Fable frontier analysis
predicted this and the residue confirmed it rather than my framing.

Landed: ~1,900 functions from plumbing at ~0 agent tokens (8 declaration axes, the symbol-KIND fix
at 205, cdFileLocTable, memcpy, the cpp-derived type map, the alias-drop fix) plus 163 from the
reach-15 agent wave at a 15x effective multiplier (reach-ordering, not the 3.55 mean, produced
that). Seven instruments repaired, cookbook to 469 sections.

Error ledger: 8, all caught. The pattern in most of them is that I proposed a mechanism before
reading evidence that was already written down — four were in files I had open.

Resume at Stage 0b (JTBL_PADS, 122 slots at ~100% measured conversion), then Stage 1's
reach-ordered sibling campaign. Stage 0a is done enough; what remains of it is bounded, not
compounding. tools-health was launched at close — confirm it before banking.
2026-08-11 14:46:29 -06:00
Drew T ce85242084 fix(phase-30 S47-0a.2): conform func_80175414 — 1,845 decls / 1,061 files; R22 213/213
The new head plumbing class after the symbol-kind fix: `conflicting types for func_80175414` (27
member-rows). Byte-true DEF is `void func_80175414(s32 _arg0)` (its DEFINE_ macro). The fleet
declared it 1,845 times in four spellings, of which three are the SAME TYPE (parameter names do not
participate) — the outlier was 28 sites declaring `(void)`.

conform_decls REFUSED the naive conform and was right to: 29 ZERO-ARG CALL SITES exist across 28
files, so conforming the declaration alone turns each into `too few arguments` — a fleet-wide
COMPILE break the per-binary gate cannot see (the tool cites 138/140 binaries, measured). It named
the count, the consequence, why the cheap check misses it, and the flag that repairs it, then
forced the two-step: --cast-zero-arg-calls (29 sites cast to the 0-arg fn-ptr shape, §17a-1 — gcc
folds the cast of a known symbol to a direct jal, so it is codegen-neutral), then the conform.

Result: 1,845 declaration sites rewritten across 1,061 files, 0 non-canonical remaining (axis
complete, R32). R22 clean-fleet: check-all 213 passed / 0 failed of 213.

WORTH RECORDING AS A TOOLCHAIN STANDARD: this is the instrument that has not wasted a cycle today.
Every other one reported SUCCESS over a defect — a classifier that discarded every gcc-2.7.2 hard
error (no `error:` prefix), a diff that miscounted 116 data-bundled .s files, a --verified-out
truncated to zero bytes over 62 real banks, a --band default that reported "0 families" on a real
135-member family, and a scope stamp describing the filesystem instead of the run. conform_decls
reports FAILURE with a repair path. A guard must state its COVERAGE, not just its verdict; the
in-repo exemplars are this tool and the §53 jr interlock.
2026-08-11 14:15:01 -06:00
Drew T fd80bd7007 feat(phase-30 S47-0a.1): the symbol-KIND fix banks 205 members; the residue crosses over to DIFF
Stage 0a's first defect, and the largest single zero-token bank of the session.

family_remap's kind test asked ONE question — is this address a function in the SIBLING'S OWN sig?
— and defaulted to `D_` on "no". But a body calls outside its image constantly: an overlay calls
resident helpers, an md_* module calls the overlay-range engine. Those addresses are absent from
the sibling's sig, so the test fell through and emitted a DATA NAME FOR A FUNCTION —
`D_800183E0`, `D_800D1EBC`, `D_80171A1C`. None exist anywhere in src/ or config/symbols.us.txt,
while `func_80171A1C` alone has 1,061 references. Measured: 611 member-rows across 45 symbols,
the largest named residue class. "Not in MY sig" means "not mine", not "is data".

Fix — three oracles, strongest first, never a blanket fallback:
 1. the sibling's own sig (authoritative for its image; this is what preserves the Phase-29 T82
    case where a slot is a function in the exemplar and DATA in the member — unioning every sig
    would have re-broken the 251 members T82 fixed),
 2. the always-linked images via extern_fn_addrs() — resident + main, 2,146 addresses whose ranges
    cannot collide with an overlay's,
 3. the exemplar reached it by `jal` — a call target is a function BY DEFINITION, which covers an
    external address neither sig claims (0x80171A1C from an md_* module, 112 rows).
Only a non-call reloc no oracle claims still falls to `D_`.

Result: BANKED 205 member-matches, failures 670 -> 575, derived net = report = 205.
R22 clean-fleet 213 passed / 0 failed of 213.
Fleet 94.4% instr / 88.3% distinct / 96.27 -> 96.33% fn-count; stubs 13,563 -> 13,345.

THE RESIDUE HAS CROSSED OVER: DIFF is now the LARGEST class at 143 of 575 — real byte divergence
outranks plumbing for the first time this session (undefined-ref 611 -> ~8, PLUMBING-other
231 -> 81). The ~5:1 plumbing:DIFF ratio that justified "tooling beats volume" has inverted in this
queue, exactly as the frontier analysis predicted: the declaration-axis vein was one-time.
The new head class is `conflicting types for func_80175414` (27) — the same addresses this fix
started naming correctly, now surfacing the NEXT layer (the symbol resolves; its declared signature
disagrees). That is the conform axis, not the remap axis.

Note for anyone auditing this class: rtu_match MASKS HI16/LO16, so a wrong %hi/%lo symbol still
reports MATCH (the T82 comment records `MATCH (10 ins)` on a member the fleet gate refused). This
defect is invisible to the per-function tool by construction — only the whole-binary gate sees it.
2026-08-11 14:02:38 -06:00
Drew T d5fbd2630f fix(phase-30 S47): family_hseq derives its own SCOPE, not just its own count; + a zero-crack glossary
The targeting oracle stamped its scope as "the N OVERLAYS only (no main, no resident)" while
load() has scanned the md_* modules and the resident since S44. Measured at this HEAD: 141 location
overlays + 70 md_* modules + the resident = 212 binaries. That is the §159 coverage law broken by
the file that documents coverage, on the repo's most load-bearing targeting instrument — and it is
how "main is structurally barren" survived two phases unexamined.

The COUNT beside it was already derived, with a comment saying "report the scope we ACTUALLY
scanned, never a hardcoded count". The PROSE describing what the count meant was hardcoded and
rotted. Both are derived now.

Caught while fixing it: my first cut read glob(".run/sig.main.jsonl") and stamped "main INCLUDED"
the moment that file existed — while load() still did not glob it. Same defect one layer down: a
stamp describing the filesystem instead of the run. Now derived from the loaded instances.

Also added a glossary line: "zero-crack" means n_matched == 0 (needs its FIRST crack) in this map,
and the OPPOSITE (a matched exemplar awaiting propagation) in roadmap §3 T3 — a ~30x mis-scope risk
for any session reading one against the other.

NOT DONE — main inclusion (0c) is still blocked on settling the attribution. Confirmed the
mechanism: main has 49 LINKED PsyQ subsegs, corpus.stubs('main') returns 2,002 INCLUDING them,
progress.py correctly excludes them and reports 1,034 game-code stubs. progress.linked_subsegs'
own docstring records this exact trap ("an importer then classifies ~1,300 already-byte-identical
LINKED library stubs as outstanding game-code work") — and my sig-main seeded from corpus.stubs,
so it inherited the LINKED rows, which is why G2's 207-family finding was inflated.
My partition probe is NOT trustworthy: 954 of 2,002 stubs returned no asm path from
corpus.asm_path, so 199 LINKED / 849 game / 954 unresolved does not reconcile with 1,034. Fix the
probe before trusting any main-scope number.
2026-08-11 13:42:40 -06:00
Drew T c0cbad1b2e docs(phase-30 S47): adopt the Fable frontier plan + the reach-ordered sibling loop
Independent frontier analysis re-derived every headline number from family_hseq.json (all reproduce
exactly) and corrected four claims, one of them mine from this session.

THE SEQUENCE: Stage 0 tooling (0a the DATA SIDE of the template engine — the 207 undefined-refs,
54/56 parse errors, 116 data-bundled .s and the F2 collisions are ONE mechanism, and unlike the
JTBL_PADS fix it COMPOUNDS across ~7,500 future member banks; 0b JTBL_PADS; 0c sig-main, recommended
yes, needs Drew; 0d a free-CPU permuter probe with a kill rule). Then Stage 1, the reach-ordered
sibling campaign to ~97.5%. Then Stage 2 singletons. Special projects LAST.

CORRECTIONS: (1) my G2 main finding was inflated — 968 of sig.main's 2,002 rows are SDK-region
stubs that fall to LINKED conversion, so the real main templating pool is ~123 families / ~303 fns
/ ~9k ins, not 207/748/11,537. (2) docs/family-hseq.md stamps its own scope as '212 OVERLAYS only
(no main, no resident)' while the map contains resident and 70 md_* modules — the §159 coverage law
violated by the file that documents coverage. (3) the close-1-4 backlog is 103, not 157, and its
reach column is TOTAL sharers not LIVE. (4) 'zero-crack' means opposite things in the roadmap and
the current map — a 30x mis-scope risk.

FRAMING: my cost-per-crack thesis holds for the singleton half only. True singleton pool is
~5,200-5,600 cracks / ~345k ins (45%); the other 55% rides on ~2,100 exemplar cracks where ORDER and
LEAK-RATE decide the calendar. Do not cross-price the two economies: 5:1 plumbing:DIFF is a property
of the residue queue, while W1's fresh wave converted 81%.

Also recorded: the 15-step reach-ordered sibling loop, with the three steps whose omission destroys
the multiplier called out (regen before targeting, regen after cracking, --band all).
2026-08-11 13:16:33 -06:00