Commit Graph

830 Commits

Author SHA1 Message Date
Drew T 8887cf87bc feat(phase-29): func_801299C8 sweep chunk 2 — 45/45 banked 2026-07-22 14:36:09 -06:00
Drew T 048edcc6c2 feat(phase-29): func_801299C8 sweep chunk 1 — 45/45 banked 2026-07-22 14:30:07 -06:00
Drew T 540f096502 feat(phase-29): func_801299C8 family probe — 3/3 banked 2026-07-22 14:22:58 -06:00
Drew T 9c9ee6ea94 chore(phase-29): burn-down snapshot + regenerated digests 2026-07-22 14:20:28 -06:00
Drew T 6ff05498c8 docs(phase-29): decision-log — the shared gate compared against another binary's hash (R31) 2026-07-22 14:12:59 -06:00
Drew T 64bfe59bc0 fix(phase-29): gate_stage gated EVERY non-077 binary against ov_SC01_077's SHA — one-line default, one month
THE BUG (tools/gate_stage.py main(), introduced commit:0181, 2026-06-21, Phase 21 T3):

    good_sha=a.good_sha or DEF_SHA,      # DEF_SHA = ov_SC01_077's locked hash

DEF_SHA is TRUTHY, so it beat run_gate's per-binary lookup
(`good_sha or _check_sha(binary) or DEF_SHA`) and made that lookup DEAD CODE on
every CLI invocation. gate_stage therefore BUILT one binary and compared it to a
DIFFERENT binary's hash: it can never match, every draft reports as "near", and
NOTHING COULD EVER BANK outside ov_SC01_077 from the CLI. A "near" is
indistinguishable from a genuine codegen residual, so the failure looked like a
compiler wall for a month.

WHY IT HID: the programmatic callers take a different path and were all correct —
grinder/idiom_hunt pass good_sha=None (per-binary lookup), lora_grind/bulk_harvest
pass an explicit per-binary sha, orchestrator is 077-only where DEF_SHA is right.
That is exactly why the grinder banked func_80181F78 in ov_SC03_014 (Task 13B)
while my CLI ladder banked 0/10 on the same tree. Two paths disagreed for a month
and nothing compared them (R34's lesson, from the inside).

BLAST RADIUS, MEASURED (not assumed): 0 of 6,708 backlog records come from the
affected path — by source: worker 2724 / bulk-harvest 2275 / lora-grind 766 /
grinder 522, all correct. THE BACKLOG NEEDS NO RE-RUN. The void verdicts are the
manual CLI gates on non-077 binaries, i.e. exactly the Task-5 wave's "the gate
banked ZERO" on 12 preserved cracks — never a codegen finding at all.

FIXED: pass a.good_sha through; run_gate reads config/check.<bin>.sha (R33).
VALIDATED end-to-end: the raw draft that produced {banked:0, near:1} now gives
{banked:1}.

RE-RUN RESULT — 7 of the 12 preserved t5wave cracks are now banked:
  func_8018F694 (478) · func_8019059C (673) · func_80135A4C (181) ·
  func_80135888 (113) · func_80135D20 (100) · func_801749C8 (105) ·
  func_801299C8 (158, was filed "PLUMBING: prototype declaration")
STILL BLOCKED (5, believed genuine): func_8012AAAC, func_80135260, func_801365B8,
func_80165CA0, func_80191C50.

⚠️ SUPERSEDES the earlier retraction: the "0/10 ladder" was not vague interference
— it was the gate comparing against the wrong binary's hash. Task 14 stages 2-3
were priced against a number that could only ever have been zero.

- R22 clean-fleet 140/140 BYTE-IDENTICAL; all 6 verified stub-free
2026-07-22 14:12:32 -06:00
Drew T 8016c172f9 docs(phase-29): SESSION-9 CHECKPOINT — sweep 274 siblings, the PURE≠templatable finding, the tooling answer 2026-07-22 13:47:14 -06:00
Drew T 05f9b20f1d feat(phase-29): func_80135D20 family COMPLETE 137/137 (~13.7k ins) 2026-07-22 13:31:24 -06:00
Drew T 595b6476f9 feat(phase-29): func_80135D20 sweep chunk 2 — 46/46 banked 2026-07-22 13:16:35 -06:00
Drew T c56de627e0 feat(phase-29): func_80135D20 sweep chunk 1 — 46/46 banked 2026-07-22 12:57:09 -06:00
Drew T adf379fb88 feat(phase-29): func_80135888 family COMPLETE 137/137 (~15.5k ins) 2026-07-22 12:34:57 -06:00
Drew T fbed540ef2 feat(phase-29): func_80135888 sweep chunk 2 — 46/46 banked 2026-07-22 12:14:04 -06:00
Drew T c1c910ffdc feat(phase-29): func_80135888 sweep chunk 1 — 46/46 banked 2026-07-22 11:53:35 -06:00
Drew T e4f8bdca3c chore(phase-29): refresh backlog ledger 2026-07-22 11:24:57 -06:00
Drew T 84fd6c785a docs(phase-29): the isolation-must-follow-the-splice finding, 5/11 cracks banked, and the retraction 2026-07-22 11:24:36 -06:00
Drew T 52e772628b feat(phase-29): isolate-with-body FIX + 3 more preserved cracks banked (incl. a 673-ins giant)
THE FIX (harvest_verify._jtbl_prep_one): isolate WITH THE BODY STILL SPLICED.
jr_isolate_all accumulates each object's file-scope decls as the new region's
`ambient` set, so partitioning around an INCLUDE_ASM stub hands the region a
DIFFERENT decl context than the draft's body needs — and the gate then produced a
byte-DIFF rather than a compile error, which is why a batch of these read as
"9 compile / 0 bank" and looked like a codegen wall. §61b's law extends one step:
THE CARVE MUST FOLLOW THE SPLICE — AND SO MUST THE ISOLATION.

The un-splice existed only because the tool is stub-centric (a spliced fn is no
longer in corpus.stubs). New _unsplice_body() handles that properly: it finds the
file that NOW holds the body (isolation may have MOVED it into a fresh region file)
and writes back the stub line for THAT subseg, so the gate re-splices identical text.

BANKED via the corrected path (each whole-binary byte-gated, one per invocation):
  func_80135D20  (100 ins, reach 138)
  func_801749C8  (105 ins, reach 136)
  func_8019059C  (673 ins, reach 3 — a giant)
Together with func_80135888 and func_8018F694 earlier: 5 of the 11 preserved
t5wave cracks are now banked.

THE REMAINING 6, honestly classed: 2 genuine DIFF (func_80135260, func_80191C50),
2 CC1-FAIL (func_801365B8, func_80165CA0), 2 §57 self-decl plumbing
(func_801299C8 `prototype declaration`, func_8012AAAC own-name conflict).

⚠️ RETRACTION: the earlier "the ladder converts 0/10, which prices Task 14 stages
2-3" is WRONG and is withdrawn. Three of those ten bank through harvest_verify
alone with the SAME transformed drafts that gate_stage rejected — so that 0/10 was
measuring gate_stage's own interference, not the residuals. Prime suspect is the
arity pre-pass (fix_arity_callers --apply --any-proto edits engine_core.h before
the gate; the §19 regression mode). GATE_NO_ARITY=1 is the ready A/B. Task 14
stages 2-3 remain UNPRICED until that runs.

- R22 clean-fleet 140/140 BYTE-IDENTICAL; tree clean before and after
2026-07-22 11:18:43 -06:00
Drew T 1ded372164 feat(phase-29): func_80135888 (113 ins, reach-138) BANKED — the isolation must keep the BODY spliced
THE DIAGNOSIS (the recommended next task) did not find an image-level difference:
performed manually, there is no difference. The recipe

    splice draft -> jtbl_carve (NON-CONTIGUOUS) -> jr_isolate_all --only <fn>
    WITH THE BODY STILL SPLICED -> make extract -> jtbl_carve -> make extract -> build

yields BYTE-IDENTICAL (R22 clean-fleet 140/140). The draft was never wrong.

THE DIFFERENCE from the ladder path is one line: harvest_verify._jtbl_prep_one
UN-SPLICES before isolating, so jr_isolate_all partitions a TU in which the
function is still INCLUDE_ASM. jr_isolate_all accumulates each object's file-scope
decls as the new region's `ambient` set, so partitioning around a stub gives the
region a DIFFERENT decl context than the one the draft's body needs — and the gate
then builds a byte-DIFF rather than a compile error, which is why it read as
"9/10 compile, 0 bank" and looked like a codegen wall.

So §61b's law — THE CARVE MUST FOLLOW THE SPLICE — extends one step further:
THE ISOLATION MUST FOLLOW THE SPLICE TOO. The un-splice exists because after
isolating with the body in, the function is a real C def and corpus.stubs no longer
lists it (the tool is stub-centric). That is a fixable plumbing problem, not a
reason to isolate around a stub.

- func_80135888: 113 ins x reach 138 = 15,594 instruction-instances (~0.12pp) once
  swept; banked x1 here, sweep is its own batch (§55b)
- R22 clean-fleet 140/140 BYTE-IDENTICAL; tree verified clean before and after
- the other 9 residuals are now expected to be the same class — to be re-run through
  the corrected sequence, one per invocation (§61c fault 2 stands)
2026-07-22 10:58:08 -06:00
Drew T 7529ee3d86 docs(phase-29): SESSION-8 CHECKPOINT — §61c refuted, the tree-eating undo fixed, family ×138 + a giant banked 2026-07-22 01:57:04 -06:00
Drew T 02b16fa7a7 refactor(phase-29): DELETE gate_stage's jtbl pre-pass (R33) + the honest ladder measurement
gate_stage._jtbl_prepare carried the SAME config-only undo as harvest_verify's did,
and ate the tree again on the first ladder run: 5 orphan region files, truncated
TUs, `undefined reference to func_80192F64`. That INVALIDATED the run's 0/10, so it
was re-measured rather than reported (R35 — a probe from a broken tool is not
evidence). Tree restored from HEAD and re-verified byte-identical first.

DELETED, not patched (R33 — the best outcome is a deleted stage). It was wrong on
two independent axes:
  1. §61b already byte-proved THE CARVE MUST FOLLOW THE SPLICE. A batch pre-pass
     carving unspliced functions reports "prepared" and yields a spec that fails
     once the body lands — which is why it banked nothing.
  2. Its undo snapshotted only config/, while jr_isolate_all rewrites region 0 back
     over the ORIGINAL src/<ov>/<nm>.c truncated.
harvest_verify's per-draft prep is the correct mechanism, snapshots the full source
set, and undoes per function. Two implementations of one capability, the outer one
ineffective AND destructive.

THE HONEST RE-MEASUREMENT (clean tree; tree verified clean after):
- 0/10 bank, but 9/10 now COMPILE and land as whole-binary byte-DIFF; 1/10 plumbing.
- match_one close=0 on several (the function's own bytes exact) and rtu_match says
  MATCH-in-real-TU for func_80135888 — while func_801299C8's transformed draft does
  not compile in its real TU at all. The residual is MIXED, not uniform; at least one
  is an IMAGE-level effect rather than the draft or its TU decl context (prime
  suspect: jtbl/rodata carve placement). NOT generalized from one data point.
- This PRICES Task 14 stages 2-3 by measurement: the existing ladder converts 0 of
  10, so they are not "wire in normalize_self_decls + the type-lift and collect ten
  banks" — the projection error §57a already caught once this phase.

- R22 clean-fleet 140/140 BYTE-IDENTICAL with the giant func_8018F694 banked and the
  func_80135A4C family swept 138/138
- cookbook §61d (the tree-eating undo in two tools; the constant-label defect; the
  re-probe + ladder measurements; the general rule: an undo whose scope is narrower
  than its write scope destroys work no byte-gate can see)
- decision-log + CURRENT_PHASE updated (R30/R31)
2026-07-22 01:55:47 -06:00
Drew T fcd83f705e fix(phase-29): the undo was EATING the tree — snapshot src too; kill the §58 label; giant func_8018F694 banked
THE DEFECT (byte-witnessed, and it is the §61c mechanism). `jr_isolate_all`
repartitions a code object by writing region 0 back over the ORIGINAL
src/<ov>/<nm>.c — TRUNCATED to just that region — and emitting the rest as new
_jr_<lo>.c files. `_jtbl_restore` undid only config/ + the new region files, so
every gate-REJECTED draft left the original TU permanently truncated and its
stubs gone. Nothing regenerates them (splat does not rewrite a committed overlay
.c). Measured across an 11-draft re-probe: live stubs 419 -> 414 -> 406 -> 395,
ending in `undefined reference to func_80191C50`.

It is INVISIBLE to the gate that causes it: the incremental build keeps linking
stale objects (§42b) so `make build` stays green while a CLEAN rebuild fails.
That is exactly the "139/140, twice" signature that became the §61c blocker —
the tree was being eaten by the undo meant to protect it. The §61c attribution
(batch _jtbl_prep residue) is now a demonstrated defect, not an inference.

FIXES (both negative-control-validated on a draft that fails):
- _jtbl_snapshot captures every src/<binary>/*.c; _jtbl_restore restores them and
  removes exactly the files the attempt created (derived from the snapshot's file
  set, not re-guessed from the _jr_* name shape, R33). Undo by SNAPSHOT-RESTORE,
  never an inverse transform — §61's law one level deeper. Same failing draft that
  previously broke the tree now leaves it byte-identical, git status clean.
- classify_fail ignores `warning:` lines. The benign `conflicting types for
  built-in function 'memcpy'` warning was winning the match on 8 of 8 failures
  across four different real causes — a label identical for every input, which the
  cookbook had to work around by hand ("the gate label is useless here, splice
  individually and read real cc1 stderr"). Now reports the real error, and falls
  through to CC1-FAIL:<last error line> rather than guessing.

THE RE-PROBE THIS ENABLED (11 preserved t5wave cracks, one invocation each):
- BANKED: func_8018F694 (478 ins) — one of the wave's three giants, previously
  recorded as part of "the gate banked ZERO".
- The other 10 now carry TEN DISTINCT diagnoses: 4 data-decl conflicts (D_80193B64
  x2, D_8011D030, D_80126B5C), 3 callee-decl (func_80135480 x2, func_8012F14C),
  3 self-decl/own-sig (§57). ZERO jtbl-drift, ZERO local-type redefinition, ZERO
  codegen DIFF.
- So §61a's "§8e-2 jtbl table-count drift blocks 10 of 12" does NOT survive the
  carve-follows-splice prep: the carve now succeeds and what is left is ordinary
  decl plumbing the existing ladder already handles (cast_call_sites / reconcile_tu
  / normalize_self_decls / fix_arity_callers) = Task 14 stages 2-3, no new tooling.

- ov_SC06_018 BYTE-IDENTICAL cbbc4f44 with the giant banked; nothing committed broken
  at any point (tree was restored from HEAD and re-verified before these fixes)
- cookbook: the `git add -u` complementary hole (an isolation's NEW region file is
  untracked, so a carve/isolation bank needs `git add -A src/ config/`)
2026-07-22 01:30:30 -06:00
Drew T 01882c58d7 feat(phase-29): func_80135A4C family sweep chunk 3 — 46/46 siblings banked (family COMPLETE 138/138) 2026-07-22 01:21:19 -06:00
Drew T 18e989ca07 feat(phase-29): func_80135A4C family sweep chunk 2 — 45/45 siblings banked 2026-07-22 01:08:55 -06:00
Drew T 115a6c536f feat(phase-29): func_80135A4C family sweep chunk 1 — 45/45 siblings banked 2026-07-22 00:56:45 -06:00
Drew T b70fb3a728 feat(phase-29): func_80135A4C family sweep probe — ov_SC01_000 banked (mechanism validated) 2026-07-22 00:42:36 -06:00
Drew T 12a14410f9 fix(phase-29): §61c REFUTED — the jtbl bank IS clean-reproducible; func_80135A4C banked ×1
The session-7 checkpoint gated the entire jtbl track behind one finding: the
carve+isolation path yields a bank that is incrementally valid and clean-invalid
(139/140, [FAIL] ov_SC06_018, "twice, identically"). The prescribed diagnosis
(diff the incremental vs clean object set) never ran, because the failure does
not reproduce.

MEASURED, with the bank applied through the single-function automated path
(harvest_verify --chunk 1 -> [jtbl] carved -> + chunk(1) -> BYTE-IDENTICAL):
  per-binary clean (rm asm+build; extract; build)  -> BYTE-IDENTICAL cbbc4f44
  make clean && extract-all && check-all  (run 1)  -> 140 passed, 0 failed of 140
  make clean && extract-all && check-all  (run 2)  -> 140 passed, 0 failed of 140

ATTRIBUTION (best-supported; the failing tree is gone): the 139/140 runs were
taken on the tree left by the BATCH _jtbl_prep (6 table-bearing -> 1 carved,
4 isolate-FAILED, 1 stale-asm carve fail) — five failed preps' residue of
stranded carves + half-applied isolations. The per-function snapshot-restore
that removes exactly that residue landed AFTER those runs, in commit:0803, the
same commit that named the blocker.

THE LESSON (R35 on ourselves, -> decision-log): "twice, identically" was not a
replication — two reads of the SAME contaminated state is one observation. A
replication must RE-CREATE the state, not re-run the check. Standing guard:
re-apply a fault from a known-clean tree before writing it down as a property
of the mechanism. Sixth "structural wall" to resolve to our own tree/tooling.

- BANKED: func_80135A4C (181 ins) x1 in ov_SC06_018 — isolated into its own
  code subseg + .rodata carve (single-table, no JTBL_PADS; tail3..tail18 renumber)
- §61c faults 1-2 STAND: a stranded carve poisons the overlay; per-function undo
  is unsound in a batch -> ONE jtbl draft per harvest_verify invocation.
  jr_inventory's 1:1 ownership assertion was right and is unchanged.
- UNFROZEN: this family = 138 members / PURE / 24,978 ins ~ +0.19pp (jtbl_family_bank,
  §53 carve law); the 9 preserved t5wave cracks (Task 14 stages 2-3, §57 plumbing)
- R22 clean-fleet 140/140 x2; tools-health OK (dedup 1848/0, C1 234481/234481,
  cdecl 53189/53189, audit-binaries 140); 0 NON_MATCHING (G4)
- fleet 78.0% instr / 66.5% distinct / 87.95% fn-count
- also: preserve the 4 untracked wave-4 .o0 drafts (R20); killed an orphaned cc1
  from the Jul-21 session burning a full core for 13h23m
2026-07-22 00:40:26 -06:00
Drew T e1e77c7482 docs(phase-29): SESSION-7 CHECKPOINT — full fresh-session block (§61c is the single next task) 2026-07-22 00:12:04 -06:00
Drew T 0cf6356ffd docs(phase-29): jr_inventory was right; the clean-rebuild blocker stops jtbl banking 2026-07-21 23:51:38 -06:00
Drew T 41d65af73f fix(phase-29): per-function jtbl prep + stranded-carve undo; the clean-rebuild blocker named
THE BLOCKING FINDING (§61c): the jtbl carve+isolation path yields a state that is
INCREMENTALLY valid and CLEAN-INVALID. func_80135A4C banks every time through the automated
path (BYTE-IDENTICAL at harvest_verify's gate) and fails `make clean && extract-all &&
check-all` twice, identically (139/140, [FAIL] ov_SC06_018). The bank is therefore NOT
reproducible from committed config + source, and the gate that authorises it cannot see the
defect because the gate IS the incremental build (§42b, most expensive form).
=> NO jtbl core can be banked until that divergence is diagnosed. Next step is to diff the
incremental vs clean build/ov_SC06_018/** object set + generated .ld/asm for the carved
subseg — NOT to bank more. All 12 wave cracks stay preserved at .run/giants/t5wave_*.

TWO REAL DESIGN FAULTS FOUND AND FIXED IN harvest_verify:
1. A stranded carve poisons the overlay. _jtbl_prep carved a draft the gate then REJECTED;
   the carve remained with NO owner (the fn is still INCLUDE_ASM), and jr_inventory's 1:1
   ownership assertion then refused every later isolation in that overlay
   ([('UNOWNED','0x801d288c')] = func_801299C8's table). THE ASSERTION WAS RIGHT AND CAUGHT IT
   — R32/R33 working as designed; the defect was mine for leaving the carve behind. Fixed:
   per-function carve + exact snapshot-restore (config text + only this attempt's region files)
   on gate rejection.
2. Per-function undo is UNSOUND IN A BATCH: isolation REPARTITIONS shared source, so restoring
   one draft's snapshot deletes region files now hosting OTHER pending drafts, and their stubs
   vanish (KeyError in render). jtbl drafts must run one per harvest_verify invocation, or the
   undo must be region-aware.

MEASURED so it is not re-derived: of 11 preserved cracks exactly ONE (func_80135A4C) reaches
byte-identical through the carve path; the other 4 table-bearing ones fail one-at-a-time too,
on PLUMBING (§57 self-decl et al), not the carve.

Tree reverted; clean-fleet 140/140; nothing banked. cookbook §61c.
2026-07-21 23:51:16 -06:00
Drew T 86e262e844 docs(phase-29): jtbl-in-harvest_verify result + the jr_inventory ownership blocker 2026-07-21 22:13:50 -06:00
Drew T aa1b8b3c1a feat(phase-29 T14 stage 4): jtbl prep moved into harvest_verify — it BANKS; new blocker named
THE LAW IMPLEMENTED: the carve must follow the splice. harvest_verify._jtbl_prep() splices each
table-bearing draft TEMPORARILY, asks jtbl_carve, isolates on the §8b walls, un-splices, re-extracts,
and RE-DERIVES the stub map + baseline (isolation MOVES a stub's TU, so both are keyed on stale
paths otherwise). gate_stage's batch pre-pass could not work: while a fn is still INCLUDE_ASM the
non-contiguity is undetectable, so jtbl_carve reports success and yields a spec that fails when the
body lands.

BYTE-PROVEN AUTOMATED: func_80135A4C (181 ins, 138 members) ->
  [jtbl] carved 1/1 table-bearing draft(s): func_80135A4C
  + chunk(1): func_80135A4C        verified 1 / failed 0   BYTE-IDENTICAL

NEW BLOCKER, PRECISELY NAMED — banking a jtbl core makes its own carve UNOWNED to jr_inventory,
which then refuses every subsequent isolation in that overlay:
  "committed .rodata carve ownership is not 1:1 (R32/R33) — a stranded/duplicated carve
   (§8b func_801734BC class): [('UNOWNED', '0x801d288c')]"
Byte-proven both ways: on the COMMITTED tree `jr_isolate_all --only func_80135260 --dry-run`
succeeds; with func_80135A4C banked it fails the assertion. The assertion is RIGHT (a banked fn's
stub .s is pruned, so the owner lookup finds nobody) but its conclusion is wrong — the carve IS
owned, by C rather than a stub. SO TODAY JTBL CORES BANK ONE PER OVERLAY. 10-draft batch: 6
table-bearing -> 1 carved, 4 isolate-FAILED on this assertion, 1 stale-asm carve failure.

NEXT INCREMENT (precise): resolve jr_inventory's carve owners from corpus.matched U stubs, not
stubs alone (R33 — the same derive-don't-reparse move that fixed the corpus oracle).

BANK NOT KEPT: R22 clean-fleet showed 139/140 (ov_SC06_018 FAILS from a clean tree) even though the
INCREMENTAL build read BYTE-IDENTICAL — the stale-incremental false pass R22 exists to catch (§42b).
Reverted; clean-fleet re-verified 140/140, tools-health OK (dedup 1848/0). All 12 wave cracks remain
preserved at .run/giants/t5wave_*. cookbook §61b updated.
2026-07-21 22:13:30 -06:00
Drew T 96d1324acd feat(phase-29 T14 stage 4): jtbl isolate+carve stage built; the CARVE-MUST-FOLLOW-SPLICE law
DIAGNOSIS CORRECTED: the wave's 10/12 blocker is NOT "§8e-2 table-count drift" (the symptom
the filter reports) but a NON-CONTIGUOUS .rodata carve — the new function's table is separated
from the TU's existing carve by an UNMATCHED function's table, and one object cannot straddle
that gap. jtbl_carve names its own remedy in the refusal message.

RECIPE BYTE-PROVEN (func_80135A4C, 181 ins / 138 members):
  jr_isolate_all --only <fn> ; make extract ; <splice> ; jtbl_carve --func <fn> ;
  make extract ; make build   ->  BYTE-IDENTICAL
(isolation verified byte-neutral on its own first; a config change needs extract, not just build.)

BUILT: gate_stage._jtbl_prepare — per-draft carve + auto-isolate on the §8b walls, logic LIFTED
from jtbl_family_bank (R33: one implementation, two callers — their divergence IS this bug),
snapshot-restore undo, GATE_NO_ARITY A/B guard. Ladder: canon -> cast -> reconcile_tu -> jtbl
-> arity -> gate -> sig_unify -> gate.

IT DOES NOT YET BANK, and that is the finding: THE CARVE MUST FOLLOW THE SPLICE. The
non-contiguity is only DETECTABLE once the body is in the object; while the fn is still
INCLUDE_ASM, jtbl_carve reports SUCCESS and produces a spec that fails when the body lands.
Byte-witnessed both ways (spliced -> NON-CONTIGUOUS 0xaa810/0xaa920; unspliced -> "prepared 1/1"
then byte-DIFF). Innocent suspects A/B'd out: the draft is IDENTICAL through canon/cast/
reconcile_tu, and GATE_NO_ARITY=1 changes nothing. FIX = per-draft prep inside harvest_verify's
splice loop (it owns the splice), not a batch pre-pass in gate_stage.

SUB-FINDINGS: (a) a wholesale `git checkout -- config/` undo is WRONG in a batch gate — it
discarded a previously-banked-but-UNCOMMITTED carve, leaving that bank's source with no subseg
(undefined reference to func_80136C90 at link). Now snapshot-restore + drop only this run's
region files (§61's constraint, which I had written and then not applied here). (b) being in a
_jr_* TU != having a table: only 4 of 8 wave drafts reference a jtbl_.

Tree restored byte-identical; nothing banked. cookbook §61a corrected + §61b.
2026-07-21 21:07:50 -06:00
Drew T a7f3fce4cf feat(phase-29 T5 wave): 11/12 MATCH, 0 banked — three integration walls named + 12 cracks preserved
Ultracode wave, 12 agents (~2M tokens), over freshly-prefetched ov_SC06_018 exemplars.
11 MATCH / 1 near, INCLUDING ALL THREE GIANTS (710/673/478 ins). Whole-binary gate: ZERO.

Splicing each failure individually (the gate's own label is §58's memcpy red-herring) gave
THREE DISTINCT blockers, none of which the ladder clears:
 (1) §8e-2 jtbl table-count drift -- 10 of 12. "more rodata .align directives than pad specs".
     STRUCTURAL FINDING: fresh crack fuel in a well-matched overlay CONCENTRATES in jtbl-carved
     TUs (the non-carved ones were harvested first), so §8e-2 GATES the next tranche of
     substantial cracking rather than being a straggler.
 (2) §57 self-decl conflict -- the 2 plain-TU drafts ("argument 'arg2' doesn't match prototype").
     normalize_self_decls exists, is wired into family_sweep, and is NOT in gate_stage -- the
     same gap the arity pre-pass had.
 (3) local-type redefinition (from the Task-14 diagnosis set) -- wants the type-lift.
So gate_stage needs THREE stages; only the arity pre-pass landed today.

All 12 drafts PRESERVED at .run/giants/t5wave_* (R20): genuine cracks with per-function lever
notes (cross-jump barrier placement, MEM_IN_STRUCT_P store/load ordering, §43 K&R s16 params,
$s-pins, CSE-break barriers). Do NOT re-draft -- they bank the moment the stages exist.

METHOD NOTE: `make build | grep -i error` missed the real failure TWICE (the jtbl_rodata_pads
line contains no "error" token; and the build failed at a later stage than the warnings I read).
Check rc, read the tail unfiltered -- a filtered build log is a selection tool, and every
selection tool here has eventually lied (R32/R35).

Tree reverted clean; nothing banked. cookbook §61a.
2026-07-21 19:47:05 -06:00
Drew T be43af8b59 feat(phase-29 Task-5): Ghidra-C prefetch — scoped by measurement, one overlay imported (+101 exemplars)
SCOPING (it corrected my own claim twice — the durable part of this task):
Remaining frontier = 2,873,658 stub ins = 22.0pp (resident+138 overlays; main excluded).
Substantial 80-1000 ins = 10,934 fns / 12.84pp across 1,398 distinct h_seq families.

I claimed "Task 5 gates 12.84pp". It does not:
  340 families / 7.72pp  exemplar ALREADY ATTEMPTED or WALLED — the top-12 by value are our
                         known set (func_801412A8 permanent wall, func_8013C414 -O0-blocked,
                         func_8014D820 close-11, func_8015B950/func_8013B83C cracked-but-
                         deferred, func_8013D53C 14/137, func_8013BD74 §8e-2). These need the
                         DEFERRED TOOLING fixes, not fresh drafting.
  1058 families / 5.40pp exemplar NEVER attempted — the true fresh fuel, of which
     48 fams / 0.62pp    already have a cached member (draftable now, no MCP)
    877 fams / 3.10pp    have none — median 1 MEMBER, i.e. overlay-UNIQUE code (every big
                         138-member family lives in ov_SC01_077 and was cached+drained by
                         waves 1-4). So the prefetch is PER-OVERLAY, never fleet-wide.

Greedy overlay cover: ONE import (ov_SC06_018) unlocks 54 fresh families = 1.59pp; imports
2-8 add only +0.59pp combined, leaving a 632-family long tail. Ranked list:
.run/autopsy/t5_ready.json.

EXECUTED (R23 lock dance): MCP stopped (save succeeded) -> ghidra_import_raw.sh
extracted/retail/SC06.CD.dir/FILE_018.dir/0.4.dec @0x80128158 -> DefineFunctions
(created=72 existed=29 failed=0) -> DecompileFunctions over the 101 uncached substantial
stubs -> 101 ok / 0 fail. Ghidra-C cache 882 -> 983; ov_SC06_018 now 149 substantial stubs
cached. MCP restarted (41 tools, serving).

Overlay Ghidra program NOT committed (Phase-13/15 precedent: script-reproducible from
ghidra_import_raw.sh + DefineFunctions, no manual RE on it; avoids ~14MB/overlay .git bloat).

CAVEAT on the ready-list: attempted-detection matches backlog entries + preserved-draft
filenames, so it carries false-fresh entries (func_8014032C is jtbl-table-count-drift blocked;
func_8017A4AC is already banked). The 48 figure is an UPPER BOUND — verify per family.
2026-07-21 18:41:04 -06:00
Drew T 1074f2f202 feat(phase-29 Task-14 stage 1): the ARITY pre-pass — and the shared-state constraint it cost
DIAGNOSED, not assumed. The 12-draft integration probe banked 1/12 and reported the SAME
label for 10 of the 11 failures: `conflicting types for built-in function 'memcpy'` — the
§58 red-herring (a WARNING, from an unrelated TU position). Splicing three top-reach
failures individually and reading real cc1 stderr gave the actual causes:
  conflicting types for `func_XXXX'     3/3   <- loose-typing ARITY conflict
  redefinition of `struct V8'                 <- a SECOND class (type-lift), stage 2

A banked shared caller macro in engine_core.h declares the function with FEWER params than
its byte-true definition takes (the original calls K&R-style with fewer args than the callee
reads); a C89 prototype makes that a hard error. tools/fix_arity_callers.py --any-proto
already fixes it and was simply NEVER WIRED into gate_stage's ladder (only family_sweep
carried §57). Now wired as a TU-side pre-pass.

MEASURED: 2 of 7 top integration candidates banked (func_8016EFC8, func_80164418, both
reach-138) vs the 1/12 old-ladder baseline. R22 140/140; tools-health OK (dedup 1848/0).

INCIDENT — this stage BROKE 138/140 AND R22 CAUGHT IT (nothing was ever committed):
pairing `--apply --any-proto` with `--revert` for the unbanked drafts corrupted declarations
fleet-wide. `--revert` rewrites ()->(void), which inverts a PLAIN apply but NOT --any-proto,
so an unbanked fn whose real decl was `extern void func_801708B0(void *a0)` came back as
`(void)` — in engine_core.h (included by all 138 overlays) and 6 sites in ov_SC01_077's own
sources. harvest_verify --binary ov_SC01_077 reported BYTE-IDENTICAL and was RIGHT about that
binary; the other 137 were structurally invisible to it. Repaired to the exact lines.

ROOT CAUSE FIXED: the ladder now snapshots every file the pre-pass touches and undoes by
RESTORE + re-apply-for-the-banked-set-only — exact by construction, cannot invent a signature.

NEW HARD CONSTRAINT (cookbook §61): any ladder stage mutating SHARED state must be undone by
snapshot restore, never an inverse transform, and validated FLEET-WIDE (R22) rather than by
the per-binary gate that authorised it. §55b's propagation law, one level down. The planned
type-lift stage edits engine_types.h and inherits it by default.

ALSO FIXED: the first wiring passed only --drafts (the narrow-param FILTER) without the
required --funcs, so the stage exited `no funcs given` as a SILENT NO-OP and the gate reported
0/6 as though diagnosed. sh() does not raise on non-zero exit -> explicit rc check added.
2026-07-21 18:19:04 -06:00
Drew T 835c45905d feat(phase-29 Task-13B close): plateau autopsy = ZERO missing-transforms; narrow the admission instead
The hindsight-study §7 taxonomy predicts plateaus decompose into missing-transform (the
"highest-value bucket and the whole point"), seed-structural, and genuine-wall. Run against
real plateaus this class produced NO missing-transforms, and the answer needed no LLM.

MEASURED: `length` probe, 20 targets, 1 win. tail 1/6; partial 0/12.
AUTOPSY (read directly from the bytes, 3 partial plateaus):
- func_8017F0C0 / func_801806C8: target has `sltiu $v0,$v0,1` = gcc's codegen for `!x`/`x==0`;
  the drafts wrote `(u32)(D_x ^ 1)` which emits `xori`. No local mutation crosses that.
- func_8017FF90: draft stores to arg0+8, target stores to a GLOBAL. Different function.
=> these are WRONG DRAFTS wearing a small closeness, i.e. seed-structural, not a mutation gap.

THE FIX IS THE OPPOSITE OF "ADD TRANSFORMS" — a tighter ADMISSION rule:
- _drift_route: permuter only when |d|<=2 AND explains=="tail" (the shape that measurably
  converts). length pool 339 -> 34; permuter bucket 389 -> 84.
- SIZE-MISMATCH: added a PROPORTIONAL test (|d| >= 0.5*nt). max(2,0.15*nt) is far too
  permissive on a tiny target — a 2-ins draft vs a 4-ins target read as a near-miss.
permuter_weights needs NO extension for this class.

Transferable (cookbook §60b): raising a search-closer's yield is at least as often about
refusing it unreachable work as widening its mutation set. Same knife as Task-13A's
targeting fix, one cut finer. Drafter idiom recorded: `sltiu rd,rs,1` => `!x`, never `x^1`.

17 unit tests green; corpus re-collected (1654 rows, closeness cross-check clean).
2026-07-21 17:45:49 -06:00
Drew T 83f20f4271 feat(decomp): grinder gate — +1 fns x0 propagated (fleet None%) 2026-07-21 15:39:27 -06:00
Drew T 5c894c1e62 feat(phase-29 Task-13B): func_80141B90 x138 + the reach repricing + the length profile
PROPAGATION (§55b, its own targeted batch): dedup_propagate --addr 0x80141B90 --recover
-> "138 overlays byte-identical after propagation"; 117 remaining stubs -> 0; 1 new
dedup group. This was the ONLY one of the 21 directed-run banks worth propagating.

THE REPRICING (R14 — measure a bucket's VALUE, not just its conversion rate):
the directed run converted 27% (21/77) but moved the fleet ~0.03pp, because h_exact
reach of the 21 is: func_80141B90=138, TEN at reach-1 (nothing to propagate), rest 2-10.
Instruction-weighted, the ENTIRE permuter bucket is worth ~0.36pp at 100% conversion.
The mechanism is validated; the fuel was small. Priced frontier (ins-weighted / 13.08M):
  LENGTH-DRIFT |d|<=2   472,178  ~3.6pp  (339 fns)   <- the real permuter-adjacent lever
  integration           419,162  ~3.2pp  (305 fns)   <- Task 14's ladder
  WIDTH                  71,593  ~0.55pp (45)
  permuter (current)     46,571  ~0.36pp (74)
  BRANCH-POLARITY         9,462  ~0.07pp (22)
So WIDTH/BRANCH-POLARITY are NOT worth prioritizing; my earlier "~200 candidates"
framing undersold LENGTH-DRIFT 10x and oversold WIDTH.

NEW: permuter_weights._LENGTH profile (perm_temp_for_expr/perm_expand_expr are the only
passes that change instruction COUNT; the reorder/decl-order levers that dominate the
regalloc+schedule profiles cannot, so they are down-weighted here) + residual_class
._drift_route (|d|<=2 -> permuter/`length`, larger stays structural — same class,
opposite tool) + classify() accepts a PROFILE NAME directly (the measured profile beats
re-parsing a free-text label). 17 unit tests green.

grinder: --profile filter (probe ONE residual class's conversion) + a PERSISTENT attempt
ledger. `tried` was in-process only, so every fresh --once run re-permuted the previous
run's losers — the permuter is deterministic given (base.c, target.o), so that CPU can
never produce a new win. Measured: a 20-target probe drew 19 already-tried targets.
Keyed by draft_sig so an improved draft legitimately re-opens the function.
2026-07-21 15:05:56 -06:00
Drew T e3e4d329a5 feat(decomp): grinder gate — +2 fns x0 propagated (fleet None%) 2026-07-21 13:40:03 -06:00
Drew T 3e2de98522 feat(decomp): grinder gate — +2 fns x0 propagated (fleet None%) 2026-07-21 13:39:30 -06:00
Drew T e6b60a38f1 feat(decomp): grinder gate — +3 fns x0 propagated (fleet None%) 2026-07-21 13:38:58 -06:00
Drew T 865633ec87 feat(decomp): grinder gate — +2 fns x0 propagated (fleet None%) 2026-07-21 13:38:25 -06:00
Drew T 0e5796aef6 feat(decomp): grinder gate — +2 fns x0 propagated (fleet None%) 2026-07-21 13:37:53 -06:00
Drew T 835657d70d feat(decomp): grinder gate — +2 fns x0 propagated (fleet None%) 2026-07-21 13:37:19 -06:00
Drew T 23a3854a1f feat(decomp): grinder gate — +1 fns x0 propagated (fleet None%) 2026-07-21 13:36:47 -06:00
Drew T 64d0188dba feat(decomp): grinder gate — +2 fns x0 propagated (fleet None%) 2026-07-21 13:36:14 -06:00
Drew T eb6a2eeac9 feat(decomp): grinder gate — +2 fns x0 propagated (fleet None%) 2026-07-21 13:35:42 -06:00
Drew T 941d04c450 feat(decomp): grinder gate — +2 fns x0 propagated (fleet None%) 2026-07-21 13:35:09 -06:00
Drew T 6c43c0243d feat(decomp): grinder gate — +2 fns x0 propagated (fleet None%) 2026-07-21 13:34:35 -06:00
Drew T 51177eb672 feat(decomp): grinder gate — +2 fns x0 propagated (fleet None%) 2026-07-21 13:34:02 -06:00
Drew T efe3680bcc feat(decomp): grinder gate — +2 fns x0 propagated (fleet None%) 2026-07-21 13:33:28 -06:00