Commit Graph

821 Commits

Author SHA1 Message Date
Drew T 85671bc1f7 feat(phase-31): S54 — wave T selector (--one-per-gid, --rank total) + the pre-gate ladder learns to see overlays (§192)
build_wave_atlas: --one-per-gid collapses same-skeleton siblings to one card and defers
them to <out>.siblings.json for the post-bank family_sweep remap (R32 accounting asserted);
--rank total ranks gate groups by DELIVERED mass (card + deferred siblings). Measured on the
wave-T draw: 6,557 drafted ins carrying 12,709 sibling ins behind 69 of 71 gids = 19,266
instructions of potential for 71 agents, vs 9,985 behind 57 under --rank mass. R39 NC: the
flag is byte-inert on a pool whose gids are unique.

gate_main/pregate_check (§192): three defects that made the pre-gate ladder main-only while
reporting "clean" on overlay slates — (1) resolve_conflicts/substitute hardcoded
corpus.stubs('main') -> per-binary _stubs_for(); (2) sym_of returned the keyword `void` for
every `extern void (*D_x[])(...)`, manufacturing 192 phantom CONFLICTING-EXTERNs (NC over
5,526,100 declarations: 189,301 changed verdicts, 0 regressions); (3) `void f()` and
`void f(void)` were normalized together, costing 40 more phantoms — C89's unspecified-
parameter rule is now gate_main.sig_conflict. §192b: the tool refuses when it substituted 0
files, and prints the per-draft [DROP] reasons it used to compute and discard.

Same overlay slate now reports 2 failures, both real (duplicate typedef; memcpy declared two
ways). Cookbook §192/§192b + index regenerated (585 sections).
2026-08-17 11:00:14 -06:00
Drew T 034c46bc28 chore(phase-31): S53 checkpoint rewritten as a clean fresh-session handoff (161 banked, main 20.4%, §188 correction, 5-step next-session plan) 2026-08-17 10:14:41 -06:00
Drew T c973d0e803 chore(phase-31): S53 checkpoint — record the journal harvest (10 confirmed / 4 weak / 4 rejected) and the §177 correction 2026-08-17 09:56:25 -06:00
Drew T 23985e6b51 chore(phase-31): S53 FINAL checkpoint — 161 banked, fleet 213/213, libgs link refuted (§187), 15 cookbook sections 2026-08-17 01:15:28 -06:00
Drew T 35803ece9a chore(phase-31): S53 log — recovery backlog banked 15, four tool defects fixed, three TU retypes proven 2026-08-16 22:55:19 -06:00
Drew T af7ae913d3 chore(phase-31): S53 checkpoint — 75 banked / 7,400 ins, fleet 213/213, wave S prepared (not started) 2026-08-16 21:07:53 -06:00
Drew T bc669d5407 chore(phase-31): S53 preflight — atlas regen, leftover-draft harvest (34 free MATCHes found), wave R launched 2026-08-16 18:08:46 -06:00
Drew T 9202c5f54e chore(phase-31): S52 final checkpoint — 131 banked, main 293 matched, 5 new tools, cookbook 543->564 2026-08-16 17:46:01 -06:00
Drew T c70f6d4e34 chore(phase-31): S52 closed — 91 banked, wave Q drafted-but-unbanked with a $0 resume path 2026-08-16 10:08:25 -06:00
Drew T 8534c95321 chore(phase-31): S52 final checkpoint — 91 banked, R22 213/213, the UNKNOWN unlock + the 6k doctrine + reconcile-before-gating 2026-08-15 22:12:32 -06:00
Drew T ad2aa6173f feat(phase-31): wave P — 32 main functions banked, main byte-identical (S52)
Wave P was the first full run of the 6k-ins doctrine: 60 cards / 6,589 ins in 2 gate groups,
59/60 claimed and 58/60 independently re-verified MATCH (6,372 ins), reloc_identity 58/58 AGREE
with ZERO symbol errors -- the second consecutive clean wave on symbol identity.

Banking cost a dozen rebuilds and exposed four more gate_main defects plus three regressions of
my own. The tool fixes, all NC'd:
- resolve_conflicts never read a draft's OWN DEFINITION, so the DEF-side wall (a draft defining
  s32 func_X against a TU prototyping void func_X) reached the compiler. Now definition-aware:
  it caught 13 conflicts up front where the build had been finding them one rebuild at a time.
- DECL and both typedef patterns anchored on end-of-line, so a TRAILING COMMENT hid a declaration
  or typedef entirely -- and agents comment nearly everything they declare. Seventh instance of
  one root cause: a scanner that looks green while reading less than it claims (R32).
- typedef handling is now BODY-AWARE and POSITION-AWARE, in a single pass:
    * identical definition visible ABOVE the insertion point -> strip and reuse;
    * same name, different shape -> rename (private to the draft);
    * definition below the insertion point -> never reuse (it is not in scope there).
  Three wrong strategies preceded this, each costing a rebuild: blanket strip (the file's copy can
  sit BELOW the draft -> implicit-int, then a collision), blanket rename (breaks drafts that share
  an IDENTICAL typedef, because their externs stop agreeing -- my regression, three drafts at
  once), and a rescan loop that found the definition it had just renamed and stripped it as a
  self-duplicate -> 'parse error before *'.

KNOWN LIMIT, recorded not fixed: the conflict check compares spelled type NAMES, so three drafts
each defining their own Slot54 with different layouts all declared func_80032A74(Slot54*) and
looked compatible. Comparing struct LAYOUTS for locally-defined types is the real fix.

13 + 4 verified-correct drafts are parked in two named buckets (competing local type models;
immovable TU declarations that gate_main reverts before every build).
2026-08-15 21:55:38 -06:00
Drew T 0753641d4b feat(phase-31): adopt the 6k-instruction wave doctrine + --target-ins (Drew, 2026-08-15)
A wave is now sized by INSTRUCTION MASS, not card count. The metric is instruction-weighted, so a
wave is worth what its instructions are worth: the 12-42-ins card lanes carried ~1,400 ins/wave
(~0.011pp, ~440 waves to finish) while wave O carried 6,266 ins at the same gate cost and the same
draft rate.

build_wave_atlas --target-ins draws cards until the instruction budget is met (still capped by n)
and refuses to under-fill silently. Standard recipe: --target-ins 6500 --min-ins 60 --max-ins 200
--max-bins 4, levers now including UNKNOWN.

THE MEASUREMENT BEHIND IT: draft rate barely decays with size -- wave M 98% at avg 51 ins, wave N
92% at avg 65, wave O 96% at avg 128. Mass is nearly free.

THE UNKNOWN UNLOCK: UNKNOWN is not a difficulty label, it means the atlas could not name a lever,
and it had been routed as needing its own bespoke lane. Wave O's 22-card R37 probe drafted it like
any other lane -- reclassifying ~138k ins (a quarter of everything open) as ordinary wave fuel.
With UNKNOWN in, 9,224 fns / 417,325 ins = 70% of all open instructions are agent-draftable; the
60-200-ins mass band alone is 164,357 ins ~= 27 waves, and is the band to work first.

Also banks the five-step PRE-GATE PROTOCOL (independent re-verify -> reloc_identity -> dry-run to
0-dropped -> reconcile declarations toward the form the match needs -> gate), cookbook §176g.
2026-08-15 14:05:15 -06:00
Drew T 965ae3902e measure(phase-31): the AGREE re-gate lane is a 5% null — symbol verification does not rescue stored drafts (S52-12)
R37 probe: 20 shape-verified AND symbol-verified stored drafts, 5 gate groups -> 1 banked (5%),
statistically the same as the project's A10 stored-verdict law (~0-8%; T1 measured 0/23 on the same
kind of pile earlier this phase). The null is the finding: a stored draft's rejection is almost
never symbol identity, it is TU plumbing (§176d) or staleness. reloc_identity's real home is a
PRE-GATE check on FRESH drafts, not a backlog resurrection tool. The remaining 30 groups are not
worth 30 rebuilds -- lane closed rather than pursued because the tooling was new and interesting.

Also names the SYMBOL-COLLAPSE class in the fixer's refusal (one draft extern standing in for N
distinct globals; a textual rename moves every occurrence together, so it needs one extern per
site) and records the R38 self-note: the 0/23 prior was already in the phase log.
2026-08-15 09:50:48 -06:00
Drew T 0487c0c627 docs(phase-31): cookbook §176e — symbol identity is COMPUTABLE offline, plus reloc_identity --fix (S52)
§174 law 1c recorded match_one's relocation blindness as a caution to the reader ('check every
symbol by hand after MATCH'). It is a computation, not a human's job. Banks the arithmetic, the two
failure shapes it separates (uniform-delta stale seed symbols vs wrong field offset), the four
traps that bit me building it (splat-derived names absent from the symbol files; MIPS o32 REL keeps
the addend in the instruction; index alignment is a precondition; a nearest-symbol label needs a
tight window), and the honest limit measured the same session: symbol-verified + shape-verified is
still NOT sufficient for a bank -- the first re-gate group of five such drafts banked 0/5, because
what remains is TU plumbing (§176d), not identity.

--fix rewrites only unambiguously-wrong symbols (every mismatch naming a symbol must imply the SAME
corrected base) and refuses otherwise: 10 of 12 repaired, 2 correctly refused.
2026-08-15 09:46:10 -06:00
Drew T fb4c1f03a1 fix(phase-31): wave-selector coverage + gate_lane crash-vs-empty (S52-1, S52-8)
build_wave_atlas.py:
- taken-set was a hardcoded 'abcdefghijkl' wave-letter literal -> glob('.run/wave_*_cards.json')
  (R33 derive, don't re-derive). NC: 634 -> 726 taken, strict superset, +92 cards from waves m/n
  that the literal would have silently re-issued.
- --exclude-bins defaulted to 'main' on the REFUTED link-defect rationale; default now empty and
  the help states the real reason (main cannot be gated incrementally; use tools/gate_main.py).
- new --only-bins allow-list: main waves need it, since gate_main rebuilds once per SLATE.

gate_lane.py: an unhandled gate_stage exception produced no JSON line -> v={} -> '0 banked',
indistinguishable from an honest empty gate (cost 2 cycles in P31). Now a non-zero rc or a missing
JSON line is labelled CRASH with the stderr tail, recorded in the results JSON, listed in the
summary as NEVER GATED, and exits non-zero. R39 NC both directions.
2026-08-15 09:31:10 -06:00
Drew T 1a36531eff chore(phase-31): checkpoint records the banked idioms (§174-176) — nothing left only in commit text 2026-08-15 09:09:32 -06:00
Drew T 6c12790719 chore(phase-31): SESSION CHECKPOINT — overnight campaign closed; cron cancelled; full handoff
- waves C-N: ~448 banked, stubs 12,059 -> 11,549, fleet 95.4% instr, 213/213 after every
  batch, main 0 -> 175 matched.
- records the three campaign-changing findings (main is open and was never hard; gate-group
  packing is the throughput lever; match_one verifies SHAPE not SYMBOL IDENTITY), the tools
  built/fixed, the prioritized open work, and the methodological lesson.
- cron be8fb48c cancelled; nothing in flight at handoff.
2026-08-15 07:30:48 -06:00
Drew T db8deb3558 chore(phase-31): velocity ledger — waves L and M rows (band test + law 1c) 2026-08-15 07:09:04 -06:00
Drew T 00e018ee41 chore(phase-31): checkpoint — overnight result (~408 banked, main 0->175) + the main-lane runbook
- records the night's totals and, more importantly, HOW to run the main lane: gate_main.py
  batch clean-rebuild, never gate_lane/gate_stage (incremental + .ld rewrite = false diff).
- notes the one mechanical improvement left (strip duplicate typedefs on substitution) and
  that the ~10 conflict-dropped main drafts are verified-correct and recoverable.
2026-08-15 06:10:09 -06:00
Drew T e05f3e3e83 fix(phase-31): gate_main typesig kept only the prefix — u8 D_x and u8 D_x[] compared EQUAL
- gate_main reported wave K BYTE-IDENTICAL; the clean fleet R22 then failed [FAIL] main.
  Three drafts declared D_80078D98 inconsistently (1 scalar, 2 array) and my conflict checker
  could not see the difference: typesig() split on the symbol and kept only the prefix.
- fixed to retain the declarator suffix ('' vs '[]'); NC'd both directions — the wave-K
  conflict is now caught, wave J's known answer (34/5) is unchanged.
- BOTH failure modes now documented in the tool: v1 too STRICT (compared parameter names,
  discarded 2 good drafts), v2 too COARSE (ignored [], passed a real conflict). R22 caught
  what the tool missed, which is exactly why the clean-rebuild rule exists.
- phase log: recorded the night's methodological lesson — every serious stall was an
  instrument trusted without a control, never the compiler.
2026-08-15 04:32:23 -06:00
Drew T b8dbf6f6a7 feat(phase-31): wave J — 34 MAIN functions banked (main 4 -> 38), R22 213/213
- first full wave against the main EXE: 40 atlas mass cards -> 39/40 standalone (98%), ALL haiku.
  main drafts exactly like an overlay; the only special handling is the gate path.
- gated via the clean-rebuild batch path: substitute -> make extract BINARY=main -> make build
  BINARY=main -> 143dbb89 BYTE-IDENTICAL; then full-fleet R22 213/213. main stubs 1030 -> 996.
- NEW CLASS: in-TU cross-draft declaration conflicts. Batching N drafts into ONE .c means their
  externs must agree with EACH OTHER (D_800A4ED4 s16-vs-u16; func_8001C9D0 void/void*/s32).
  Resolved greedily (keep-in-order, drop incompatible) at a cost of 5 recoverable drafts.
- the recovery lever, proven on func_80037368: adopt the shared header's decl VERBATIM
  (extern u8 D_80076251;) and adapt at the USE site ((&D_80076251)[i]) instead of redeclaring.
- NOTE on my own tooling: my first conflict detector compared parameter NAMES and wrongly
  dropped 2 good drafts ((s32 *_) vs (s32 *)); comparing type signatures only recovered them.
  Second time tonight a refusal check of mine discarded good work (R39).
2026-08-15 03:57:50 -06:00
Drew T 61806c8a31 chore(phase-31): checkpoint — main open (4 banked), wave I 44/44, tooling debt logged; wave J (main) in flight 2026-08-15 03:33:16 -06:00
Drew T b5101909f4 CORRECTION(phase-31): main is NOT link-blocked — it was a stale-.ld gate path (R22 corollary)
- I reported 'main is blocked on a link-resolution defect' with confidence. REFUTED by the
  control I should have run first: with src/ fully reverted and NO draft, make build BINARY=main
  still produced the same c4546248 and the identical 2-byte jal diff. A defect that reproduces
  with zero drafts is not caused by drafts.
- byte-proven both ways: 'make extract BINARY=main && make build BINARY=main' -> 143dbb89
  BYTE-IDENTICAL (twice); 'make build' alone -> c4546248 + the 2-byte diff, deterministically.
- cause: main's extract runs the EXE-only psyq_integrate + ld_interleave steps that REWRITE the
  linker script; gate_stage/harvest_verify build without re-extracting, so main gates against a
  stale .ld. Overlays have no such step and are unaffected (all overlay banks are R22-clean).
- implication: main's 79,510 ins @ 0.5% are behind a TOOLING gap, not a wall. Fix the main gate
  path to re-extract, then re-gate the 4 preserved drafts in .run/wave_p31e/main/.
- the earlier 'archive-member selection' evidence is a downstream symptom of the stale .ld.
2026-08-15 02:59:13 -06:00
Drew T 6d09d35b6d feat(phase-31): wave H — 34 banked (1 gate group); cookbook §175 caller-saved pin hazard
- wave H: 40 atlas mass cards on ov_SC02_005 -> 38/40 standalone (95%), 34 banked, ONE gate
  group. R22 213/213. stubs 11,788 -> 11,751. fleet 95.4%.
- §175 (NEW): a register pin to a CALLER-SAVED reg is not a scheduling hint, it changes program
  meaning. func_80182EB0: value written before a jal and read after it; the $2 pin let gcc treat
  the pre-call store as dead across the call and SILENTLY DELETE addiu v0,zero,-1 (49 vs 50 ins),
  post-call read = garbage. Fix was to DROP the pin and kill the cross-call live range in C.
  Rule: never pin a caller-saved reg to a value whose live range crosses a jal — use a
  callee-saved $s0-$s7 (safe by ABI, the §17 lever) or restructure. A one-instruction count
  mismatch on a caller-saved-pinned draft is this bug until proven otherwise.
- 2 NEARs enqueued with full diagnoses (prologue $ra-save scheduling; S3 chain-priority).
2026-08-15 02:50:57 -06:00
Drew T b398a9d908 docs(phase-31): narrow main's link defect — retarget delta == sizeof(.text 800c2.o) == 0x2A0
- call site is libmcrd1/func_80060D9C.s +0xD8, referencing the callee BY NAME (jal func_80061FA8)
- our build resolves that name 0x2A0 later, which is EXACTLY the .text size of build/src/800c2.o,
  the object starting at 0x80061FA8 -> the name binds to the END of the object (the next
  section's first symbol, firstfile in psyq/apicard/A66.o) instead of its start
- 3 ordered hypotheses recorded (duplicate func_80061FA8/.NON_MATCHING pair; object dropped or
  reordered when src/800.o gains an undefined ref; an absolute symbol shadowing the object's)
- everything to test it is in the map + the 4 preserved main drafts
2026-08-15 02:33:02 -06:00
Drew T cb30f26799 fix(phase-31): recover 3 falsely-withheld wave-G drafts (3/3 banked); symfix flags are ADVISORY
- I withheld 3 drafts on symfix STALE/AMBIGUOUS flags; all 3 already used the CORRECT PsyQ
  names (RotMatrixY, RotTransSV). What symfix called 'draft-only symbols' were LOCAL
  identifiers: a typedef, two inline-asm macro names, two local struct typedefs.
- gated unchanged -> 3/3 banked. wave G closes 35/36.
- two symfix defects behind it: (a) local typedef/macro names counted as symbol references;
  (b) draft-symbol extraction misses some extern forms, so a name the draft DOES declare
  still reports as asm-only.
- OPERATING RULE: symfix is advisory, the whole-binary gate is the arbiter. Never withhold a
  standalone-MATCH draft on a symfix flag alone (R39 applied to my own judgement).
2026-08-15 02:10:46 -06:00
Drew T efd0dd4ee1 feat(phase-31): wave G — 36/36 drafted, 32 banked, fleet 95.4%; §174 law 1b (PsyQ symbol names)
- wave G: 36 atlas mass cards on ov_SC03_006 -> 36/36 standalone (100%, independently
  re-verified), 32 banked of 33 gated, ONE gate group. R22 213/213. stubs -> 11,788.
- two TU-packed waves now confirm the shape: ~1 rebuild per wave instead of 23.
- law 1b added to the wave prompt: agents reconstruct CODE at 91-100% but INVENT PsyQ symbol
  names (S80131E00->Square0, Blk20_...->RotMatrixY, SRM_...->RotTransSV). Dangerous because
  match_one MASKS relocations -> a wrong callee name still reports MATCH; only the
  whole-binary gate + symbol audit catch it, after a wasted rebuild.
- 3 wave-G drafts held by that audit (would previously have crashed it pre-commit:2330).
2026-08-15 01:54:31 -06:00
Drew T ab649794ca feat(phase-31): wave F — 50 banked from ONE gate group; the TU-packed mass lane is the campaign shape
- wave F: 60 atlas 'mass' cards (fresh crack, NO seed body) -> 55/60 standalone pre-repair
  (59/60 post-repair), 50 BANKED of 53 gated, in a SINGLE gate group. R22 213/213.
- the throughput thesis is confirmed: wave D banked 45 across 23 whole-binary rebuilds;
  wave F banked 50 across 1. gate cost scales with (binary,TU) groups, not drafts.
- the fresh-crack lane converts like the seeded lanes (~91%) => the atlas's ~7k draftable
  candidates are all reachable, not just those resembling a prior match.
- grinder: 0 banked across 8 seeds / 11 ILS cycles (band exhausted); re-exposed the Phase-22
  split-file blindness (no .s under md_MAIN_027).
- KNOWN DEFECT logged: aprop_symfix crashes on non-hex symbols (int('Square0',16)) — one
  PsyQ-named callee aborts the whole audit; needs 1:1-rename handling + per-pair isolation.
- stubs 11,876 -> 11,826
2026-08-15 01:23:33 -06:00
Drew T 1a23d90b31 chore(phase-31): R22 213/213 after wave D; wave F launched (first TU-packed wave, 60 drafts/1 gate group) 2026-08-15 00:35:03 -06:00
Drew T dde7a35ca3 feat(phase-31): wave D banked 45/48 + main link-blocker diagnosed; selector packs by gate group
- wave D (48 adapt cards): 47/48 standalone, 45 BANKED across two gates (40 + 5 late-repair).
  Operational lesson: build the gate slate AFTER the repair stage lands — the first slate was
  built early and 5 rescued drafts needed a second gate.
- wave C (35: 11 tell + 24 weak): 32 banked, 91% gate. Weak lane proven 24/24 on haiku.
- MAIN BLOCKER DIAGNOSED (the night's most valuable finding): main drafts are byte-correct yet
  gate 0/4. Byte-diff of the built EXE = exactly 2 bytes in 413,696, NOT in the drafted fn: a
  jal at 0x80060E74 retargets func_80061FA8 (game code, 800c2.o) -> firstfile (PsyQ libapi
  A66.o). Adding one C fn perturbs symbol resolution between game code and the LINKED PsyQ
  archives. main is an INTEGRATION wall, not a matching wall -> its own lane; excluded from
  build_wave_atlas by default.
- build_wave_atlas.py now packs by (binary, TU) — the REAL gate-group key, since each group is
  one whole-binary rebuild (wave D: 42 drafts / 23 groups = the throughput ceiling).
- 3 NEARs enqueued as grinder fuel incl. func_80183578 at close=1 DELAY-SLOT (§60a precedent).
2026-08-15 00:32:03 -06:00
Drew T 540d2cefaa feat(phase-31): wave C banked 32 (R22 213/213) + tools/build_wave.py; 3 instrument defects fixed
- wave C: 35 cards (11 tell + 24 weak) -> 35/35 standalone (re-verified independently, R14)
  -> 32 banked / 3 near, 91% gate, 0 symbol failures (Law 4 prevention worked)
- weak lane proven for the first time: 24/24 on haiku; 890 candidates remain
- reach measured: 32 exemplars, 8 with sharers, x2 each => ~1.25x effective (the x134
  era ended in P25/29/30) -> throughput, not leverage, is now the lever
- tools/build_wave.py (pool=adapt|weak, corpus-derived open-stub filter, R35 gate guard)
- 3 self-inflicted instrument defects found+fixed+NC'd (P9, recorded not buried):
  pgrep self-match via shell=True; corpus.stubs() is addr->Stub not names (nearly
  declared both card pools spent); a wave fired on hand-typed placeholder cards (stopped)
- STRATEGIC: card lanes are ~0.23% of open ins/wave; the Atlas's head-crack bucket is
  1,276 groups / 186k ins with high-reach groups up to 265 instances -> retarget waves
  at atlas groups next
2026-08-14 23:44:03 -06:00
Drew T 9d1e8e8c38 chore(phase-31): resume — owed R22 banked (213/213) + atlas regen at HEAD (11,994 open); wave-C fuel verified 2026-08-14 22:26:33 -06:00
Drew T e9e3db88de chore(phase-31): SESSION CHECKPOINT — campaign mid-flight; 65 banked this session; wave-B 35/37 (95%); resume steps + fuel inventory 2026-08-14 22:03:10 -06:00
Drew T 2655585c45 feat(phase-31 T10 wave-A): adapt lane opens — 12 banked +1 prop (75% draft / 67% gate, ~117k tok/bank); ledger + lessons 2026-08-14 21:12:28 -06:00
Drew T 173d184514 chore(phase-31): refresh session checkpoint (build arc complete) 2026-08-14 19:59:48 -06:00
Drew T 6cd81173cd feat(phase-31 T9): warmstart feeder + weak-cards — the campaign lanes are armed
- tools/warmstart.py: --from-banked walks a banked exemplar's family's open
  members, builds remapped proven-body drafts (symbol_map + build_draft), and
  STREAM-classifies member-vs-seed with zero compiles; enqueues ONLY permuter-
  shaped work (bucket==permuter or LENGTH-DRIFT |delta|<=2) as backlog records;
  --lenmiss ingests T8's 49-route. Armed live: 59 enqueued, 120 refused by the
  stream filter (the anti-92%-wasted-CPU discipline)
- grinder patch NOT needed: candidates() deliberately keeps unclassified
  records ('unknown is not a reason to skip'), so pre-filtered enqueues flow
  as-is — documented in the feeder docstring (YAGNI honored)
- family_cousins --weak-cards: 954 seeded-crack cards from the never-consumed
  0.70-0.85 band, ins-ranked, §168 laws embedded, model-routed haiku 804 /
  v3 43 / sonnet 86 / opus 21 (cheap tiers dominate), 0 unresolved .s
2026-08-14 19:59:21 -06:00
Drew T 0840eda5bb feat(phase-31 T8): LEN+N lane — 587 near-misses routed; 345 wrong-drafts reclassified; detectors live
- match_one --emit-streams (additive; stdout-identity NC'd): word streams for the
  len lane
- family_align.addr_true_rel: reloc-vs-constant range discriminator — FULL
  conservative set kept for pair semantics (NC-1 157/157 regression), address-
  true subset for indel eligibility only (a constant li-cluster must not read as
  reloc-in-indel); synthetic probes green both directions
- tools/len_tells.py: aligned classification + §172b tell tagging (EXTPAIR/
  SELECT/NOP) on target-side indels; detectors imported from atlas_features
  (R33); cookbook text embedded in cards
- tools/lenmiss_route.py: pool-parallel (A8) — 587 audit LEN rows re-verified
  live + routed in 24s: redraft 345 (frac>0.35, APPEND-ONLY backlog
  reclassification — near-miss metrics stop lying) / permuter-length 49 (grinder
  fuel) / cards 192 incl 14 tell-tagged (the audit's own detectors had emitted
  ZERO) / mechanical 0 — an HONEST NULL: stored drafts rarely get constants
  wrong; LEN drift is shape, family_align's value here is classifier/detector
- R32 accounting 587/587
2026-08-14 19:54:57 -06:00
Drew T 682d0fa1fd feat(phase-31 T7): family_align — aligned classifier + imm engine, NC'd; mechanical-cousin lane refuted by probe
- tools/family_align.py (NEW module — classify_member's return contract untouched,
  the remap_hseq silent-pass trap avoided by design): SequenceMatcher alignment
  over FC.tok streams; li-cluster reconstructor (lui/lui+addiu/lui+ori/li-from-$0
  chains, split-cluster absorb for the rs-changed addiu partner); verdicts
  LEN-LI/LEN-NOP/LEN-JTBL/LEN-STRUCT/STRUCT-ALIGNED/PURE/IMM; aligned imm engine
  mirroring imm_map_tier1 (ordinal deliberately out in v1)
- NC-1 verdict-equivalence 157/157 banked pairs — the NC caught two real gaps:
  R-type non-shift sa diffs are STRUCT; registers tested BEFORE the reloc skip
  (a reloc-slot word with a different register is STRUCT). NC-2 parity 21/21
- R37 PROBE REFUTED the planned mechanical driver before it was built: 0/26
  LI-ONLY cards classify mechanically (regfields x19) — cousins are 0.85-similar
  DIFFERENT functions; §168 law 1 re-derived by measurement; no driver written
- family_align re-scoped: its consumer is T8's LEN+N near-miss pile (draft vs
  its OWN target = same function); reloc-vs-constant range discriminator parked
  for T8. decision-log entry (R31)
2026-08-14 19:49:22 -06:00
Drew T 1a8cda6c54 feat(phase-31 T6): PLUMBING campaign — +9 banked (64% probe); recipe + 3 laws (§173)
- tools/plumbing_groups.py: derives the honest still-open pool from the classified
  ledgers (R38) — '1,217 PLUMBING' collapsed to 237 (SELF 109 / CALLEE 48 / OTHER
  48 / DATA 32)
- recover_integration: PER-GROUP ISOLATION (git-checkout binary TUs between groups
  — one TU-stage edit was poisoning every other group's whole-binary gate with a
  phantom shared error; per-group banked_from_source capture) + new stages
  'macro-externs' (§121 draft-tier, via family_sweep.macro_def_sig_map, R33) and
  'tu-scope' (§103 STU binary-tier, the sweep-only lever)
- the probe (ov_SC03_107): raw 0/14 -> root-caused (poisoning + stale seed
  symbols; rtu_match MATCHes them — blind to reloc names, R34) -> symfix-first
  -> 9/14 BANKED (64%)
- sweep finding (Law 3): the no-draft majority (ov_SC02_037 44/44, most of
  ov_MAIN_012) had verdicts from transient sweep remaps never persisted — family-
  lane fuel, not recovery fuel; the stored-draft class is consumed
- cookbook §173 (symfix-first / per-group isolation / verdicts-without-drafts);
  index 518 green; R22 clean fleet 213/213; phase total 17 banked @ 0 agent tokens
2026-08-14 19:42:55 -06:00
Drew T e18738c48e feat(phase-31 T5): THE FRONTIER ATLAS — 5,139 lever-labeled crack groups over all 12,058 open fns
- tools/atlas.py: cousin units baseline + T1.5 h_seqn merges + CALIBRATED warm
  tier (measured: li-norm metric holds ~99% recall to 0.55; rule = smallest t
  with neg-accept<=0.2% AND recall>=95% -> THRESH_WARM=0.70 @ 99.1%/0.18% —
  false merges waste exemplar cracks, misses only route cheaper) + seed sweep
  (65% of open skeletons carry a >=0.55 matched seed) + kNN graph + tiny-direct
  + evidence joins (audit/backlog/ledgers/cards; unparsable=fatal) + lever
  labels with confidence measured>ledger>tell>default>UNKNOWN
- partition ASSERTED: 12,058 = progress stubs 12,051 + NM 7 EXACTLY (chased the
  +1: data blobs now excluded, reconciled against classify() buckets; T1 banks
  confirmed absent); every instance in exactly one group; main joins at the
  atlas layer only (family maps stay non-main — 4 silent-skip hazards)
- warm tier merged 1,019; top group unifies 268 drifted per-location skeletons
- lever table: head-crack 186.9k ins / UNKNOWN 138.6k (honest) / extend-tell
  76.7k / redraft 46.8k / jtbl-carve 45.7k / integration 23.4k / seeded 23.4k /
  len-vein 16.8k / swaprepeat 9.2k / plumbing 8.1k / o0 6.6k / cc1 6.4k
- atlas_features: li_norm_toks exported (shared with atlas, R33; hash-stable);
  mid_jr verifier fixed (compared ZERO rows — R32 silent no-op; now 6,444/6,444)
- make atlas = full regen chain (~10-15 min, zero tokens); --targets emits
  crack slates (12/12 .s resolved); survey 92 s
- SETUP rows (R21); docs/frontier-atlas.md committed
2026-08-14 18:06:46 -06:00
Drew T 636809714d feat(phase-31 T4): atlas_features.py — per-fn feature layer for the Frontier Atlas
- one deterministic feature record per function across all 213 registry binaries:
  memoized per distinct h_exact (.run/feat_memo.json, 92,855 bodies), fanned out
  1:1 with sigs to .run/feat.<bin>.jsonl (363,525 rows) in 21s
- features: nins/band, o0 prologue tell, frame/saves/fp, CFG skeleton (branch-scan;
  jal=call never edge — position-independent, argued in docstring), mid_jr/jalr,
  stable-call-seq hash (fixed main+resident ranges), reloc-kind-seq hash, 16-bucket
  ophist, §172b tells as SHARED importable detectors (extpair/dupselect/sign_mix/
  magic_div — len_tells will import, R33), li-normalized skeleton h_seqn
- verifies: R32 (addr,h_exact) join per binary; determinism 0/200; mid_jr vs
  family_hseq independent oracle 6,444/6,444 exemplars agree (verifier's first
  draft compared ZERO rows — string/int addr mismatch, R32 silent-no-op class,
  fixed + fails loud on compared==0)
- o0 cross-check finding: 94 open fns carry the -O0 prologue inside -O2 TUs —
  §116-class carve candidates (campaign fuel)
2026-08-14 17:54:18 -06:00
Drew T 22eed7d78a feat(phase-31 T3): main enablement — sig-main at splat-true lengths + main streams
- sig_image: --seeds accepts '0xADDR NINS' (and jsonl nins); a seeded nins is
  authoritative ([addr, addr+4*nins), bypasses func_end whose heuristic mis-sliced
  3/40 main samples); R32 guard on seeded end > hi
- corpus: s_ins_count() factored from audit() (R33, one counter) + '--seed-ends'
  CLI emitting per-stub splat-true lengths
- make sig-main: 2,002 main stubs signed -> .run/sig.main.jsonl; FULL word
  cross-check 2,002/2,002 EXE slices == .s words (0 SLICE-SUSPECT; .s word field
  is byte-order hex, not LE — first checker draft misread 1,999 false suspects).
  Deliberately splat-SEEDED; main's independent second oracle stays deferred
  (second-oracle.md; sig_is_independent(main) stays False)
- family_remap: vram_of/img_path special-case 'main' derived from splat.us.exe.yaml
  (file0-vram = code-seg vram - start = 0x8000F800; target_path); stream_words
  ('main') verified 25/25 vs .s
- regression: sig-resident re-run byte-identical after the shared read_seeds change
- SETUP §6.3 rows (R21)
2026-08-14 17:48:51 -06:00
Drew T fa425f89a5 feat(phase-31 T2): reference expansion — PsyQ SDK sample source extracted + gcc-2.7.2 completed
- PsyQ 4.0 dev-CD Track-1 walked with the frozen iso9660.py (R33): 2,374 files /
  231.6 MB -> tools/reference/psyq-sdk/ (gitignored); 400 C sources incl. the full
  PSX/SAMPLE tree (373) — drafting-agent style priors, esp. for main
- provenance find: GNU/SNGNUVER.TXT = SN's gcc build history (2.7.2.SN32.3.7.0002)
  naming SN's exact patches vs vanilla; only UNROLL.C codegen-relevant
- gcc-2.7.2 reference +6 files (calls.c + caller-save.c — §172-cited, previously
  missing — + integrate/optabs/varasm/recog), tarball sha256 recorded
- docs/psyq-sample-idioms.md seeded; SETUP §5.6 rows (R21)
2026-08-14 17:44:32 -06:00
Drew T 2a0ac5ab8d feat(phase-31 T1): integration quick-bank sweep — 8 banked, 0 agent tokens; symfix STALE-DELTA
- aprop_symfix: STALE-DELTA class — the S50 1:1 stale-seed-symbol rule generalized
  to n:n (sorted-by-address zip, ONE uniform target-draft delta required; refuses
  count mismatch / non-addressed names / disagreeing deltas). R39 negative controls
  (synthetic + S50-snapshot equality over still-stub rows, zero false positives);
  first live batch 4 rebased -> 4/4 BANKED (func_8016BCC0, func_8017F1C8,
  func_80186BD8, func_80186BF8). The delta test refused func_80186C1C whose deltas
  differ by 4 — a hand-check had wrongly accepted it. cookbook §171-D
- recover_integration demacroize (SELF-decl class): 4/7 banked (func_80139BE0,
  func_8014ED28, func_80161D88, func_801659DC)
- R38-first partition of the MATCH-108 pile: 75 still-stub = 13 never-gated +
  62 verdictted (31 PLUMBING = 7 SELF + 15 CALLEE->T6 + 3 UNDEF-DATA + 6 OTHER;
  14 CC1->T6; 8 md CARVE-REFUSED->ledger; 1 DIFF); immfix pile fully consumed
- stored-draft re-gates 0/23 (the ~8% A10 law held); 9 STALE->clean world-motion
  drafts identified (siblings' banks defined their missing symbols)
- gate_lane: propagate-commit tag derives from GATE_PHASE (was hardcoded)
- R22 clean fleet: extract-all 212/212 + main; check-all 213/213 BYTE-IDENTICAL
2026-08-14 17:40:38 -06:00
Drew T d6ade08f3a feat(phase-31 T0): pivot log + instrument freshness + hygiene
- decision-log: the P31 re-charter entry (organize-before-grind; R37/R38/R39
  ratified at gate-1) per R31
- harvest_verify.py: import guard — a bare import now RAISES loud instead of
  running a full gate (CLI unchanged, verified both directions)
- sig-resident: bootstrap boundary artifacts fixed (fused +0 data word with
  func_800CEDFC; func_800D33E0 dropped past a glued tail) -> ELF-seeded per the
  S45 pattern, exactly 145 fns; true denominator confirmed 145 (progress was
  right); audit-corpus 0 PHANTOM + 0 TRUNCATED; all three oracles agree
- family maps regenerated at HEAD commit:2161: 11,025 open non-main members
  reconciles EXACTLY with 12,059 - main 1,034 (102 stale phantoms cleared);
  adapt cards 704, aprop cards 204 (full emission)
- main fuel-gap finding: 2,001/2,002 main stubs already have cached Ghidra-C
  (only func_80049600 missing) — the roadmap '0/2,096' note was stale
- tools-health OK (dedup 2,063/0; C1 254,521/254,521; audit-digest green)
2026-08-14 16:40:43 -06:00
Drew T d6b38245e5 chore(phase-30): CLOSE — overlays at their measured ceiling (95.3% instr / 90.0% distinct / 96.68% fn, 213/213)
- PhaseEnd_Phase30.md written; CURRENT_PHASE.md archived to phase-ends/logs/Phase30.md (R19)
- 25 sessions (S26-S50), 947 commits, stubs 28,296 -> 12,059, dedup 2,061/0
- milestone met on both clauses: >=95% instr AND every remaining stub on a named ledger
- v1.28.0 -> v1.29.0
2026-08-14 15:18:00 -06:00
Drew T 1c631ff39f feat(phase-30 S50-Max): the gcc-read audit — +52 banked, R22 213/213 (S50 FINAL v2 checkpoint)
The §172a/§172b tells + repaired instruments swept over all 892 open near-misses:
- 33/95 stored drafts re-verified MATCH and banked through the whole-binary gate
  (aprop_symfix caught 40/108 carrying stale seed symbols before gating — §171 at scale)
- 19/20 hand/mech fixes banked: four pure lhu<->lh s16 flips; the lhu+sltiu->lh+slti
  shared-global quadruplet (D_80126B5E/B66/CB0, D_80126CB0 are s16 FLEET-WIDE); one xor-eq
  rewrite; 11 per-location literal swaps (mask/threshold constants from sibling binaries)
- 1 refusal (func_8017EE78) stays as redraft fuel
Stubs 12,111 -> 12,059. Fleet 95.3% instr / 90.0% distinct / 96.68% fn-count.
Veins mapped for next waves: ~400 LEN+N drafts, 13 ambiguous-symbol, 7 multi-literal.
Audit ledger: .run/c294/audit_results.json (classifier derives from match_one's own sig).
2026-08-14 14:32:48 -06:00
Drew T e903713b71 feat(phase-30 S50): the mechanical A-prop draft — 256 members banked with no agent in the loop
Final S50 state: 307 instances banked, stubs 12,468 -> 12,161, fleet 95.3% instr / 90.0%
distinct / 96.65% fn-count. R22 clean rebuild 4x, check-all 213/213 every time.

- tools/aprop_autodraft.py + tools/draft_prechecks.py: seed body + symbol_map + a MINIMAL
  synthesized preamble. The seed's decl layer never travels — that layer is family_sweep's
  dominant failure (331 of 458 S49 verdicts). 256 banked at zero agent tokens, against the
  ~20M the same work would have cost as a wave.
- Macro seeds (567 of 1196 members, all 3737 de-macroize) take the DEFINITION only; the block
  stays the decl source. Pasting it whole measured 28% vs inline's 68% — func_8016AB6C's macro
  is 1,891 lines of which 108 are the function.
- IMM is a second engine, not a wall: T2a's imm_map_tier1 resolves a per-location LITERAL like
  symbol_map resolves a per-location SYMBOL. 131 of 275 IMM members resolve.
- draft_prechecks negative-controlled against ALL 205 banked drafts: zero false positives,
  catches 39 of 67 known failures. That control found two bugs in the checks themselves —
  C89 `f()` declares UNSPECIFIED parameters (not zero), and a member's own definition read as
  a call to itself. Conservative by design: a pre-check that discards good drafts is worse
  than one that lets a few builds fail.
- The A-prop pool is now priced exactly: PURE 437/37,376 ins, IMM 275/8,849, STRUCT 238/4,259.
- Cookbook §171a; SETUP rows; CURRENT_PHASE S50 FINAL checkpoint.
2026-08-14 07:42:19 -06:00
Drew T 895bb6a239 feat(phase-30 S50): clear the func_801EDC18 carry blocker — 4/4 banked, and re-priced
- The blocker was carried as "one missing file-scope extern gates 83 PURE members". Both
  halves were wrong (R14): corpus.stubs says 4 open members, and D_801ED98C is a DEFINED
  const Blk8 whose rodata lives inside the member's own nonmatchings .s — replacing the stub
  deletes the data with it. gather_externs can carry an extern DECL, never a DEFINITION,
  which is why it reported "no file-scope decl" for a symbol md_SC05_023 defines on line 114.
- Fix: paste typedef + const definition + body per sibling (data bytes verified identical
  across md_SC05_024/025/028/029). 4/4 banked.
- aprop_symfix: new `local-only` class — draft-DEFINED identifiers that merely carry a
  vram-looking suffix (Blk8_…, S8_…, L_call_…) are not stale symbols. Measured: that is every
  non-clean case in the whole wave-7a/7b stored-draft residue, which holds ZERO stale-symbol
  recoveries (a clean negative result — the defect was A-prop-specific).
- cookbook index regenerated (tools-health fails closed on a stale index — it caught §171).
- R22 clean rebuild: check-all 213 passed, 0 failed of 213. Stubs 12,445 -> 12,441.
2026-08-14 00:23:32 -06:00
Drew T 2f7e06564b feat(phase-30 S50): the stale seed symbol — A-prop's 57% was ours, not the lane's (§171)
- REFUTES §170's open hypothesis (batched cards concentrate members into one TU ⇒ §169
  collision): 5-draft groups banked 5/5; 11 of 35 unbanked drafts were already one-per-TU;
  and the two "concentrated" groups banked 12/12 and 10/10 once the real defect was fixed.
- The cause: a per-location data symbol carried out of the seed body unrebased. match_one
  compares instruction ENCODINGS and is blind to a relocation's target NAME, so it scores
  MATCH standalone and dies at link in the host TU. 24 of 24 concentrated failures, all 1:1
  rewritable at one constant vram delta (0x4128).
- tools/aprop_symfix.py: audit + --fix, emits a gate_lane-shaped slate; deterministic and
  build-free, so it runs BEFORE the gate. The R34 second oracle for the class match_one
  cannot see.
- family_cousins.py --aprop-cards: members now carry sym_map, the explicit {seed -> member}
  renames, read from the seed's C BODY (a matched seed has no .s of its own) vs the member's
  .s. Two case-mismatch defects fixed while wiring it (sig lowercase vs splat uppercase).
- 23/24 banked. Stubs 12,468 -> 12,445. Fleet 95.2% instr / 89.9% distinct / 96.57% fn.
  R22 clean rebuild: check-all 213 passed, 0 failed of 213. dedup 2,043/0.
- A-prop's true conversion is 87% (79/91); the 320 batched members are unblocked.
- Cookbook §171 + §170 struck in place; SETUP row; decision-log (R31).
2026-08-13 23:41:36 -06:00