mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-27 22:45:39 -04:00
85fb289db582d842fc41dc059fa187bb992e76ea
146 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
b0c1e14fda |
feat(phase-30 S46-final): 400+ cascade banked (11) + waste-prevention gate; B re-scoped, C blocked
- BANKED: 11 functions at 400-952 ins from the cascade (func_8017D898 952, func_8017CE58 733,
func_801902EC 673, func_8018C2D8 673, func_8018A8D4, func_8017C6F4, func_800CBB38,
func_800CF3A4, +3). check-all 213/213 from a clean tree. 6 near = jr/switch (§53 separate
banking step), 1 failed. The cascade agents wrote 6 new cookbook sections incl. §158.
⚠️ tools-health UNVERIFIED at commit (stale cookbook index fixed, confirming re-run
interrupted) — run it first next session. check-all is the byte oracle and it is green.
- WASTE PREVENTION (Drew: "prevent this from ever happening again, however you need to"):
* tools/validate_targets.py (NEW) — names 5 defect classes (NO-ASM / MID-BODY /
OUT-OF-RANGE / ALREADY-DONE / NO-BOUNDARY), exits non-zero.
* WIRED INTO wave_snapshot so it fails closed — every wave passes through there for its .s
files, so no path from target list to spawned agents bypasses validation. Negative-control:
a 3-target bad list is refused with the exact mid-body offset (+72 bytes of 100).
* The cascade `done()` predicate now short-circuits on SKIPPED as well as MATCH. It tested
only MATCH, so a non-existent target fell Sonnet -> Opus -> Fable and three agents each
proved the same phantom absent: ~29 invalid targets x 3 tiers = 87 of 119 agents, ~9.7M
tokens. A tier that cannot act must END the pipeline, not escalate emptiness.
* docs/accelerators.md A9, including that wave_snapshot's own R32 assertion REFUSED that list
(24 of 57 found) and was routed around — the one instrument warning that was right and ignored.
- B RE-SCOPED (S46-10) and deliberately NOT done: the extend blocker is INTRA-HEADER, not
target-side. engine_core.h declares memcpy FOUR incompatible ways across its DEFINE_ macros;
two in one TU collide. NOT a safe cleanup — the in-tree note at ov_MAIN_012.c:14333 records
that `extern memcpy` disables gcc's builtin and turns an inlined block-move into a CALL, so the
declaration CHANGES CODEGEN. Probe one macro in one binary and byte-gate before any sweep.
- C (dedup_extend over the 129) stays blocked on B. Full context for both in the checkpoint.
|
||
|
|
5c61e00199 |
chore(phase-30 S45p9): track the two irreplaceable live load-maps
.run/attract_loadmap.jsonl (304s full attract cycle) and .run/sc03_hunt_loadmap.jsonl (the SC03 hunt + boot chains) are LIVE CAPTURES — not regenerable without another emulator session — so they fall under the R20/P27 curated-.run policy (irreplaceable recon tracked, regenerable bulk ignored). They are the evidence base for: - MAIN/7 + MAIN/9 absent across a complete attract cycle (the dead-code case) - the 7 routing-table addresses confirmed live (the R34 second oracle for S44) - the 0x801EF468 script-slot observation that cracked the SC03 trio docs/memory-map.md cites attract_loadmap.jsonl by name, so leaving it untracked would have left a doc pointing at a file a fresh clone does not have. Caught by Drew asking 'and you checkpointed everything?' -- my earlier git add had 2>/dev/null on it, which silenced the gitignore rejection. A silenced add is a silent skip (R32). |
||
|
|
788f33d523 |
feat(phase-30 S45 L3-p3): SC02/9 = the Steam Knight boss module — decoded, captured, retro-verified, onboarded; parked = 5
- the gate DECODED from matched C (func_8012832C case 0x300E -> func_80128998 -> streaming API with &cdFileLocTable[144]) -> scene arithmetic named the 1ST-BOSS arena -> ONE targeted load captured it at 0x801E4C60 - RETRO-VERIFIED: Phase-3's dumps/ram_castle.bin (2026-06-14) holds it at the SAME address, same 6,764-B exact prefix — R10 two independent datapoints two months apart; bossHp_SteamKnight (0x801E4398) lives inside this module's image - onboarded md_SC02_009 (id 0x3E, TLO 0x4): BYTE-IDENTICAL first build; fleet 213; R22 213/213; tools-health OK; audit-disc UNCLAIMED 6 -> 5, residue 0 - the last 5 (MAIN/7, MAIN/9, SC03/53/54/56) reclassified emulator->STATIC-RE targets with decoded leads (memory-map §S45 p3); loc-id map appended to docs/debug-menu-list.txt - negatives banked: pause menu, memory-box prompt, new-game intro, high/low game, Minku spawn (slot-A actor 0x15 = md_MAIN_015 candidate naming) |
||
|
|
fa7b9d4c71 |
feat(phase-30 S45 L3): the emulator tour — all 28 script modules + MAIN/3 onboarded; fleet 212, R22 212/212
- THE TOUR (Drew driving the retail debug menu; mode-7 hammer over the Redux web API): all 28 script modules captured live at four byte-verified per-chapter slots (SC03/73-79 @0x801EF468 ch2-period, SC03/132-138 @0x801E25E8 ch3, SC04/24-30 @0x801E7B28, SC05/23-29 @0x801ED988); the routing law: debug-menu AREA selects the chapter, each CITY interior streams its own module (member k <-> interior k). md_MAIN_011/DISELECT byte-proven 24,236/24,240 in RAM; slots A/B/boot R34-verified live. - MAIN/3 DISCOVERED: the main-menu module (id 0x39, 121,884 B), mis-bucketed as data by BOTH audit oracles; live byte-proven @0x800CEDF8 (42,632-B exact prefix); onboarded. - 29 onboardings BYTE-IDENTICAL on first build -> fleet 212; R22 212/212 after three md_MAIN_003 catches: the A4 DsMix leak; an extract-order-sensitive splat boundary (bytes: a 1-word data sentinel in .text + fn at +4 -> pinned in symbols file); corpus.stubs now treats D_*/jtbl_* INCLUDE_ASM as blob includes (mirrors progress.py) - module-id census (offline, disc-wide): 77 id-law code payloads, 0 further misses; SC03/55 = confirmed DATA. audit-disc: UNCLAIMED 34 -> 6, residue 0 — the 6 carry byte-checked negative evidence; next tier = the CD-read tracer - docs: memory-map §S45 (slots + routing + debug-menu ops), disc-completeness S45 addendum, decision-log R31 entry, docs/debug-menu-list.txt (Drew's transcription) - .run/s45 evidence allowlisted (tour logs/scripts/rosters); 104 ram dumps LOCAL-ONLY - new baseline: 93.8% instr / 95.68% fn / 87.2% distinct over 212 |
||
|
|
41a3de342d |
fix(phase-30 S43): family_remap now carries TYPEDEFS (transitive, brace-aware) — the §146/§152 gap closed
- ROOT CAUSE PINNED, and my first hypothesis was WRONG (R14, corrected in the log): I wrote that a gate transform ate a `/*` opener and turned comment prose into code. REFUTED — cast_call_sites, sig_unify and reconcile_tu each run with the gate's real --src-file all preserve it. The real cause is family_remap's preamble backscan, whose accept-set (blank/extern/comment/typedef) HALTS AT THE FIRST `#define` and never reaches typedefs above the macro block. `_carry_macros` then re-attaches the macros, which HIDES the truncation — the unit looks complete and is not. "parse error before 'unsigned'" was that failure surfacing at the next token (the following `extern unsigned char` line): a misleading label, not a second defect. - FIX: _carry_typedefs() — additive, TRANSITIVE (a carried typedef may name another; measured: carrying Vec8_80182FD4 alone then failed on SVECTOR_8016E7C8), and BRACE-AWARE (a `;`-terminated scan stops INSIDE the struct at its first member line, emitting a truncated unclosed typedef). Emits dependency-first for C89. Only types the unit actually names and does not already carry. - VERIFIED: the 0x80182FD4 unit now carries its Prim_8016E7C8 block complete; the 0xECC family's remaps now carry the four typedefs I had prepended BY HAND before gating them — i.e. the fix automates the exact workaround that banked those three siblings. Residual isolated-compile failure on SVECTOR_8016E7C8 is a match_one artifact: that type lives in src/shared/engine_types.h, which the real TU includes — the typedef gap is fatal ONLY when the target TU lacks the type, which is why this class failed loudly for some families and silently succeeded for others. |
||
|
|
5c84ad5ada |
feat(phase-30 S43): the 263x5 cluster BANKED 5/5 (+1,315 ins) — the SWEEP was corrupting correct drafts
- R22 CLEAN-FLEET: 140 passed, 0 failed of 140. Fleet 12,502,519/13,160,961 = 94.997% instr (+18,146 instructions this session, 23 functions). 393 instructions from the 95.000% bar. - REDO of the S43-9 retraction, done correctly through harvest_verify (splice/build/keep-iff- byte-identical/revert) instead of hand-building. 5/5 banked, each re-verified three ways: image SHA == locked SHA, stub gone, real definition present. ov_SC03_101/func_801814F8 · ov_SC03_104/func_80184934 · ov_SC04_003/func_8017E4F4 · ov_SC04_005/func_80181054 · ov_SC04_007/func_8017FF08 - THE DEFECT THIS PROVES: family_sweep --hseq reported this family 0/5 with "PLUMBING: parse error before 'unsigned'" — but the remapped drafts are byte-CORRECT. The only `unsigned` in the draft is INSIDE A COMMENT, so a gate-pipeline transform is eating a `/*` opener and turning comment text into code. Per-transform runs on the draft alone all preserve it, so it needs the gate's real invocation (--src-file) to reproduce. NOT YET PINNED — and it is silently costing banks in every sweep it touches. Next: run the three transforms with --src-file and diff. - Workaround that banked them: carry the exemplar's typedefs by hand (the family_remap _carry_macros gap, §146/§152) and gate directly, bypassing the sweep's recovery ladder. - Also killed a self-inflicted infinite poll: an `until ! pgrep -f "permuter_ils.py <fn>"` loop whose pattern matched its OWN bash command line, so the condition could never go false (spun 2h30m). Same family as the day's other defects: a check that cannot return the answer that ends it. |
||
|
|
37c60a5ff3 |
feat(phase-30 S43): R22 CONFIRMS ALL 18 BANKS 140/140 — fleet 94.99% instr; §147 refuted by the bytes
- ✅ R22 CLEAN-FLEET: make clean && extract-all && check-all -> 140 passed, 0 failed of 140.
Discharges the [R22 PENDING] caveats on commit:1486 (the 0xECC family x12) and commit:1487
(func_8018D98C). All 18 of today's banks are confirmed, not incremental artifacts (§130).
- FLEET: 96.63% fn-count / 94.99% instr-weighted (12,501,204/13,160,961) / 89.4% distinct-code.
Session +16,831 instructions, 18 functions. P30's 95% instr bar is 1,708 instructions away
(18,539 at session open). NOTE the report line rounds to "95.0%" — the bar is NOT yet met.
- THE 5th WAVE AGENT: func_8017CE58 is TWO bodies at one address (246 in SC02_000/003, 734 in
SC03_092). The 246 body is byte-identical to func_8017C294 — THE FUNCTION §147 WAS WRITTEN FROM —
so one draft covers 4 instances, and it went 12 (with a recorded "stop searching" verdict) -> 2.
- §147 CORRECTED IN PLACE (H5: original text preserved, correction appended):
* A "stratum 3, unreachable from C" is REFUTED — there is NO stratum 3. The frame is declared
locals then reload spill slots in pseudo-regno order; the mystery 0x108 slot is an ordinary
spill on a loop.c-created pseudo, reachable by writing the loop as an INDEX loop (a pointer
walk puts it at the bottom). Prior drafts faked it with volatile pEnd + dead[7]. (121 -> 54)
* B the unreferenced slots are combine-orphaned sign-extension intermediates (combine.c:10839),
not "?: on memory" frame cost.
* E the qty_compare tie IS breakable — §148-C's zero-emission ref slider. (30 -> 25)
* D applied properly (drop volatile out + the $24 pin, let a1 spill) remains: 54 -> 30.
- CONSEQUENCE: func_8017C294's 15 siblings were parked "until stratum 3 is explained" — that hold
is VOID. Both near-misses logged to the ledger with their measured closeness, not forced (P9).
- PROCESS LESSON in §147: a confident NEGATIVE verdict is a claim like any other — date it, name
its evidence, and re-measure it before letting it park work (same shape as §146).
|
||
|
|
f5498c3c66 |
feat(phase-30 S43): the 0xECC family — ONE crack banks 12 overlays / 11,364 ins [R22 PENDING]
⚠️ R22 CLEAN-FLEET OWED (two agents still reading asm/, so `make clean` is unsafe). Each of the 12
was gated whole-binary AND independently re-checked against its own config/check.<bin>.sha (12/12),
stubs confirmed replaced — but incremental (§130). Treat as UNCONFIRMED until the clean run.
- THREE isolated cheap-Opus agents, briefed with §150/§151 + the mandatory all-drafts scan,
CONVERGED INDEPENDENTLY: func_8017C6F4's 947-ins body exists in 12 OVERLAYS under 5 DIFFERENT
NAMES at 6 DIFFERENT ADDRESSES, each differing by exactly TWO per-overlay symbols (screen-rect
helper + 64x64 cell table). Gated 12/12, 0 failed. 11,364 ins from this morning's single crack.
- WHY IT HID ~30 PHASES (cookbook §152): name-keyed grouping scattered it across 5 names,
address-keyed across 6 addresses (and the address collides with an unrelated 15-ins body in 3
other overlays), and h_seq-keyed scattered it too — which is why the Phase-26 sweeps missed it.
THE KEY IS BYTE SIZE: `grep -rl 'nonmatching .*, 0xECC' asm/*/nonmatchings/*/` returns exactly
the 12, reads the asm (cannot go stale like family_hseq.json), no false positives. Refines the
Phase-26 "h_seq is spent" finding: h_seq is worth exactly ONE size-keyed sweep behind each FRESH
core crack — here it paid 11:1.
- TWO CAUTIONS THAT TRAVEL WITH IT: (1) a MASKED tool cannot validate a remap — match_one and
rtu_match both mask jal/%hi/%lo, exactly the fields a remap edits, so a wrong symbol map still
reports MATCH; gate remaps by the whole-binary SHA only. (2) a stale residual is NOT evidence two
functions differ — I briefed "func_8017C59C scores 340, different body"; refuted in one command
(that 340 came from a pre-§150-fix draft, which scores nonzero against its own target too).
- OPEN TOOL DEFECT (R32): family_remap's unit backscan halts at the first #define, so it carried
16/16 gte macros and 0/10 typedefs, silently — the §146 gap from the other side.
- MY ERROR, RETRACTED IN THE LOG (S43-9): I reported the 263x5 cluster as "5 byte-identical, 1,315
ins". FALSE — the drafts had been reverted, so I measured the INCLUDE_ASM STUB BASELINE, which is
byte-identical by construction. R34's trap, self-inflicted by hand-building instead of using
harvest_verify. Nothing was banked there; the cluster is UNRESOLVED. ("41 behemoth drafts" was
likewise a file count — 79 files, 20 distinct functions.)
|
||
|
|
01d7d3276c |
feat(phase-30 S43): FABLE5 CRACKS func_8017EF68 (the 2-of-969 wedge); R22 CONFIRMS ALL FIVE BANKS 140/140
- func_8017EF68 MATCH 969/969, re-verified by me, gated: ov_SC06_000 byte-identical at da4a26ff.
- MECHANISM (from cc1's own -dR trace, not inferred): the r3000 machine description gives the
memory unit load-ready-cost 2 / store 1, so blockage(load,store)=2 — a LOAD CAN NEVER BE PICKED
IN THE TICK IMMEDIATELY AFTER A STORE PICK. sched2 therefore always wedges one ready ALU insn
between the lw and the sh, and the target's zero-wedge order is UNREACHABLE BY ANY STATEMENT
ORDER. That is why ~20 documented hand variants AND the repaired permuter both floored at 2.
The draft's own §49 sched1-LUID story was incomplete — real but secondary.
- THE LEVER (cookbook §151, "the ghost wedge"): a zero-emission tied in/out asm
`__asm__("" : "=r"(v) : "0"(v), "r"(rival));` — 0 bytes, but a schedulable insn that absorbs the
blocked tick, and it sets reg_n_sets(v)=2 which also kills sched1's birthing boost (one
instrument, both passes). Two measured fallouts: rival-read in the same asm (22->12), then a
second re-tie on a HIGH-REF host to restore allocno live-length parity (each in-loop insn is +1
live length for every loop-spanning allocno; a trio of invariant addresses sat exactly on
allocno_compare's integer-floor boundary). Host choice empirical: pkt=MATCH, ot=705, double=10.
- ✅ R22 CLEAN-FLEET: make clean && extract-all && check-all -> 140 passed, 0 failed of 140.
This DISCHARGES the [R22 PENDING] caveat on commit:1484 — all five banks are confirmed, not
incremental-build artifacts (§130).
- FLEET: 96.63% fn-count / 94.9% instr-weighted (12,489,130/13,160,961) / 89.2% distinct-code;
0 NON_MATCHING (G4); dedup 1919 groups. Session +4,757 ins from 2 cracks x 5 binaries.
Distance to P30's 95% instr bar: 13,782 ins (was 18,539 at session start).
|
||
|
|
25402b2eb4 |
feat(phase-30 S43): FABLE5 CRACKS func_8017C6F4 pin-free — banked ×4 (~3,788 ins) [R22 PENDING]
⚠️ R22 CLEAN-FLEET VERIFY IS OWED, NOT DONE. All four gates below were INCREMENTAL builds
(§130: an incremental build can report BYTE-IDENTICAL for a change a clean build cannot link).
Committed now only to protect the work — a second Fable5 agent is reading asm/, so `make clean`
would destroy its inputs mid-run. The clean-fleet run follows the moment that agent finishes;
treat these four banks as UNCONFIRMED until then.
- THE CRACK (Drew approved the Fable5 escalation, R27): byte-exact, PIN-FREE, 947 ins. My §147-E
"qty_compare tie, unreachable from source" diagnosis was WRONG. The residual was VARIABLE
IDENTITY: (1) the X-pass and Y-pass min/max intermediates are DIFFERENT variables (8, not 4
reused); (2) mnc/mxc do not exist — the cell clamps reuse the prim-loop mn/mx (X) and mny/my (Y).
Ablations: split-only 63, reuse-only 624, conjunction MATCH. That is also why S42's "separate
X vs Y variables" probe was filed as a failure (it was half the fix), and why every allocator
lever was inert — pins, §148-C sliders, declaration order and 14 permuter restarts cannot reach
a draft with the wrong NUMBER OF PSEUDOS.
- VERIFIED INDEPENDENTLY BEFORE BELIEVING IT (R14): I re-ran match_one -> MATCH (947 ins), then
the whole-binary gate per binary.
- BANKED ×4 (every 948-ins sibling of this body), each byte-identical:
ov_SC03_126 c48a8bb8 · ov_SC03_003 898bf52a · ov_SC04_021 33614234 · ov_SC05_019 3f5b4f13.
family_remap produced all three siblings cleanly.
- §146 SEEN AGAIN: all three siblings first failed with `PLUMBING: parse error before 'MTX_C6F4'`
— _carry_macros carries #defines but NOT typedefs; prepending the 9 typedef lines fixed all
three. That label is legible ONLY because of this session's classifier fix; before it, it read
"CC1-FAIL: make: *** Error N" and cost a manual splice-and-rebuild each.
- cookbook §150 (decode register ownership from the MATCHING diff regions before touching the
allocator; per-instance register asymmetry ⇒ per-instance variables; the deleted-self-move tell
and the global.c:719-vs-:729 death-before-store exemption behind it). §147-E corrected: it named
the wrong allocator — these are global.c allocnos, not local qty_compare quantities.
|
||
|
|
f5ea22b4f5 |
feat(phase-30 S43): serial queue — func_8017EF68 is at 2 of 969, and was scanned against the WRONG BODY
- THE ALL-DRAFTS SCAN PAID (S4's law): .run/drafts-p30beh/func_8017EF68.c is a 969-ins draft that
scores "969 mismatched" against ov_SC03_007's 12-ins body — which is what every name+home scan
keyed on. Against its OWN body (ov_SC06_000, 970 ins): DIFF 969/969, **2 mismatched**,
SCHEDULE-REORDER/2, everything else — registers, frame, spill map — already byte-exact.
- THIRD instance of today's address collision: 0x8017EF68 = 12 ins (SC03_007) AND 970 (SC06_000);
0x8017CE58 = 246 (SC02_000/003) AND 734 (SC03_092). The serial queue's own size annotations
("func_8017EF68 (969)", "func_8017CE58 (733x3)") are therefore unreliable — re-derive from bytes.
- THE VINDICATION: the draft's header ends "NEXT STEP: this is the permuter's exact profile", and
drafts-p30beh is one of the 63 GTE dirs S43-1 unblocked — this function sat ONE working permuter
run from a bank, with the note naming the permuter, for as long as the silent fallback existed.
- The residual is a 2-ins adjacent transposition (lw $v0,0($s3) <-> srl $a2,$a1,16), root-caused in
the draft to a sched2 INSN_LUID tie (§49) with ~20 hand variants recorded DO-NOT-RE-BUY.
Repaired-permuter ILS (schedule profile, 6x240s) reaches 2 and holds flat; a free 12x600s run is
queued. Logged to the backlog at closeness 2 with the correct binary.
- Queue triage: func_8017C974's 22 stored drafts are all far (best 812/947); func_8017CE58 has only
a CC1-FAILing Ghidra-C draft. Neither is a near-miss.
|
||
|
|
e75ed7adcc |
docs(phase-30 S43): checkpoint — the permuter takes 63->41 and plateaus; evidence preserved
- func_8017C6F4 FINAL for this session: hand 63 -> ILS 42 (pin-free seed, masked 44, flat over 8 warm restarts) -> ILS 41 (pin-t5 seed, masked 43, flat over 5). Best draft .run/s43/func_8017C6F4.ils43-pin.c (closeness 41), logged + allowlisted. Both basins are now MEASURED FLAT — do not re-run the ILS on these seeds; next levers are §148-C by hand, then Fable5. - .gitignore: allowlist .run/s43/*.py + *.json so the refutation evidence (probe_leftovers.py, leftover_probe.json) is preserved, not one `git clean` from gone (R20, the S42 lesson). - S43 checkpoint block refreshed at the top of the file: the four instrument defects as one table, the one number that moved, the resume list (with "26 unpropagated members" struck as refuted), the harvest_verify import hazard, and my four process errors. |
||
|
|
fa122cf62f |
fix(phase-30 S43): permuter takes func_8017C6F4 63->42; the "rumour row" was an ADDRESS COLLISION
- THE FLOOR MOVED: permuter_ils on the S42 draft -> masked 65->44 (cycle 1, flat over 5 warm restarts); re-measured in match_one terms 63 -> 42 mismatched, 947/947 ins. First movement after ~40 hand probes, and it came from repairing an instrument (S43-1), not from new C. Draft preserved + allowlisted: .run/s43/func_8017C6F4.ils44.c; logged at closeness 42. - THE S42 "rumour" CLAIM WAS WRONG (R14): the 2026-07-01 row HAS an artifact, it IS on disk, and it reproduces exactly (14 mismatched of 15 target ins, SIZE-MISMATCH/redraft). It is a near-worthless draft on a DIFFERENT BODY: 0x8017C6F4 is 15 ins in ov_SC03_010/011/013 and 948 ins in ov_SC03_126/003 + ov_SC04_021 + ov_SC05_019 (§148-E, ledger side). - THREE ledger defects fixed: (1) load_best keyed on ADDRESS ALONE -> the two bodies merged and the lower ABSOLUTE closeness won, so 14-of-15-wrong (7% correct) masked 63-of-947 (93%); now sub-keyed by known nins, legacy rows unchanged. (2) binary=null defaulted to ov_SC01_077, where the fn does not exist AT ALL, and "not an open stub" was read as "banked" -> today's result was invisible to render/grinder/target-selection (absent != done, R32/R34); now derive binary from the draft path + only drop when closed everywhere it exists. (3) `log` had NO --binary flag -- the root cause of every null; added + derived in append_record. - IMPACT DERIVED, NOT ASSERTED (R37): replaying the pre-fix selection = 836 -> 837, 1 appeared (func_8017C6F4 nins=947), 0 vanished. One row today; the mechanism would eat every future one. - PROBED AND NOT BUILT: relative-closeness ranking (only 24/836 rows carry closeness+nins, and the two orderings agree 14/15 on those). Documented in the log instead. |
||
|
|
35d00fe3ec |
chore(phase-30 S42): PRESERVE the two serial NEAR drafts + log them; flag a draft-less ledger row
Answering "did you bank the results": the two serial functions did NOT match, so there was nothing
to bank (G3 -- NEAR is not a match). Everything that DID match this session is already banked and
committed (7 from the S4 redo, 24 wave exemplars + propagations, both giants x138).
But the drafts were about to be LOST, which is worse than not banking them:
.run/s42/ov_SC01_077/func_8017C294.c NEAR(12) of 246 ~245k subagent tokens
.run/s42/ov_SC03_126/func_8017C6F4.c NEAR(63) of 947 ~434k subagent tokens
.run/s42/ov_SC03_126/func_8017C6F4.pin-t5.c NEAR(47), pinned variant
All three were gitignored -- one `git clean` from gone (R20: commit irreplaceable work). Added a
curated /.run/s42/ allowlist and committed them. They are the best base any future attempt has:
func_8017C6F4 has frame 0x120 + vars=232 EXACT with only a register rotation left, and its permuter
has never been aimed at it (make_base_c fails on the gte_ macro block -- demacroize first).
Both logged to the backlog with today's MEASURED values, class, reach and draft path.
⚠️ LEDGER INTEGRITY, flagged not silently fixed: the backlog already held
`func_8017C6F4 closeness=14` (2026-07-01, ov_SC03_010, source=bulk-harvest) -- BETTER than today's
63, but with **draft: None, klass: None, nins: None, reach: None**. There is no artifact behind it
and no draft of it survives on disk (today's agent scanned every stored draft and found two, both
junk). `load_best` takes the LOWEST closeness per address, so this unverifiable row will out-rank
today's real, reproducible 63 in every future target selection.
This is the Phase-28 defect class (`func_80178004` recorded close=0 when it was 91). It is left in
place rather than deleted because deciding between "a lost good draft" and "a bad number" needs
evidence I do not have. **Whoever picks this up: treat the 14 as UNVERIFIED, start from the
committed 63/47 drafts, and if the 14 cannot be reproduced, purge the row.**
The general rule this argues for: a backlog row with no draft artifact is a rumour, not a result --
`backlog.py log` should require a draft path (or mark the row unverifiable) so an artifact-less
number cannot outrank a reproducible one.
|
||
|
|
e879ec6da2 |
feat(phase-30 S4-redo): SCAN don't SAMPLE — 14 matches found on disk, 7 banked (+1,338 ins)
Answering "did we do S4?" honestly: NO, not properly. The earlier pass re-gated only the NEWEST stored draft per draft-exemplar head (8 banked of 35). S6 then proved that is sampling, not scanning -- its giant's match was the 9th of 31 drafts, and my first pass had reported "closeness 40". Redone with EVERY stored draft run through match_one, over the 39 draft-exemplar heads + Drew's named large-function list (38 targets, 33 with drafts on disk): 14 of 33 targets MATCH from a stored draft (some had 51-57 drafts each) -> 6 banked first pass, +1 after recover_giant = 7 banked -> including func_8018057C (897 ins), which was on the "needs an agent" list The 14 came overwhelmingly from ov_SC01_077 -- exactly the heads where only the newest draft had been tried. The winning drafts sit in .run/_a10_sample-cn-cast-rc/, .run/drafts-wave-cn-cast/, .run/drafts-wave-cn/, .run/ab-exp/opus-cn/, .run/backlog_drafts/ -- i.e. spread across many historical pipelines, which is precisely why "newest" is the wrong selector. 7 still open after recovery (5 near, 2 failed) -- integration classes, drafts kept in .run/s41/rec/. VERIFIED: make clean && make extract-all && make check-all -> 140 passed, 0 failed of 140. Fleet 12483035 -> 12484373 instr; distinct +1,338 / +7 uniq; fn-count +7. instr-weighted 94.9%. audit-digest OK. 0 NON_MATCHING (G4). STILL OPEN from S4: the 263x5 cluster (0x80182fd4 exemplar) sweeps 0/5 with `parse error before 'unsigned'` in the spliced draft -- NOT the missing-type class, undiagnosed, do not assume codegen. And the 2 resident stubs with gate-rejected match_one-MATCH drafts remain untouched. THE RULE (cookbook §146, now paid for twice): SCAN every stored draft, never sample. A head with 57 drafts has 57 chances, and the pipelines that produced them differ in ways that matter. |
||
|
|
9f61cd33c5 |
feat(phase-30 S6): BOTH GIANT WALLS CRACKED ×138 (+50,094 ins) — the verdicts were stale, not wrong
The two functions the roadmap has carried as PERMANENT WALLS since Phase 24 are matched in all 138
overlays. Neither needed a siege. Both matched from drafts ALREADY ON DISK.
func_80178004 165 ins x 138 = 22,770 Phase 26: Fable5, ~477k tokens, "intrinsic 3-integer
regalloc wall". THREE stored drafts report match_one
MATCH today; one banked first try, no new work.
func_801412A8 198 ins x 138 = 27,324 close=29/110 since Phase 24. Matched from 1 of 31 stored
drafts + the §37/§124 alias.
WHY func_801412A8 LOOKED INTRINSIC (worth understanding — match_one is structurally blind to it):
the TU declares `extern int func_801412A8(int,int,int,int,int,int)` and its callers USE the return
(`param_1 = func_801412A8(...)`), while the byte-true definition is
`Prim_1412A8 *(Prim_1412A8 *, int, int, int, u16, u16)`. Narrow params cannot agree with an `int`
prototype and the no-prototype escape is illegal once a param promotes, so NEITHER side can move --
and the resulting byte difference is in the CALLERS, which match_one never compiles. The §37/§124
def-side asm-label alias decouples them: the TU decl keeps governing the call sites (codegen
untouched), the definition keeps its byte-true signature.
THEN PROPAGATION RETURNED 0/137 TWICE, both times a missing TYPE, not codegen:
family_remap's `_carry_macros` carries file-scope #defines but (a) NOT typedefs, and (b) is NOT
TRANSITIVE -- it brought addPrim_1412A8 and stopped, though that macro calls setaddr/getaddr and
getaddr casts to PTag_1412A8. Lifted Env_1412A8 / PTag_1412A8 / Prim_1412A8 + OT/getaddr/setaddr
into src/shared/engine_types.h (inside the include guard) -> 137/137, 0 failed.
MY ERROR, CAUGHT BY THE GATE: I lifted the typedefs but did not STRIP them from ov_SC01_077.c, so
they were declared twice and gcc-2.7.2 rejects a repeated typedef even when identical -- the lesson
already recorded at the foot of engine_types.h. R22 came back 139/140 with [FAIL] ov_SC01_077 (the
exemplar's own overlay). Stripped, re-verified, 140/140. A proper lift strips the source;
build_engine_types --strip does both and I did it by hand.
Also a measurement error worth recording: I checked whether the draft defined Prim_1412A8 with a
plain `grep -c` -- which matches inside `addPrim_1412A8` -- and briefly concluded the carry worked.
Substring false positive; the same shape as reading a `return` as a declaration.
VERIFIED: make clean && make extract-all && make check-all -> 140 passed, 0 failed of 140.
Fleet 12432941 -> 12483035 instr (+50,094 -- EXACTLY the two giants x138); fn-count +276;
instr-weighted 94.5% -> 94.8%. audit-digest OK. 0 NON_MATCHING (G4).
THE RULE THIS BUYS: re-measure a wall before respecting it, and SCAN every stored draft rather than
sampling (my first pass checked 8 of 31 and reported "closeness 40" for a function whose MATCH was
in the 9th). Four minutes of re-measurement was worth 50,094 instructions.
|
||
|
|
669367dab0 |
feat(phase-30 S40): propagate the 19 wave exemplars — 61/87 members banked (+7,087 ins), R22 140/140
Propagation behind every crack, same session (the multiplier the waves exist for). 19 newly-banked exemplars from waves 1+2, all in the family_sweep lane (0 has_mid_jr): 87 candidate members / 10,212 ins -> 61 BANKED / 26 failed across 39 overlays The 26 that did not bank are the known plumbing shapes, not codegen: 20 CC1-FAIL + 5 callee `conflicting types` (func_8017EFA0 x3, func_8012B23C x2) -- the same classes the S40 recovery ladder already has levers for (§17a-1 no-proto + call-site cast; recover_giant block-scoping). Left open deliberately rather than force-banked (P9); they are the cheapest fuel on the board next session. TOOLING GAP RECORDED: the sweep's classifier writes "CC1-FAIL: make: *** Error 33" WITHOUT the actual cc1 message, so 20 of 26 failures carry no actionable reason. Diagnosing one currently requires manually splicing the draft into its TU and rebuilding (done twice this session). The classifier should capture cc1 stderr the way harvest_verify already does -- worth fixing before the next big sweep, or every CC1-FAIL costs a manual reproduction. VERIFIED: make clean && make extract-all && make check-all -> 140 passed, 0 failed of 140. Fleet 12425854 -> 12432941 instr (+7,087); distinct +6,145 / +51 uniq; fn-count +61. instr-weighted back to 94.5% ON THE HONEST (post-main-regen) denominator of 13,160,961. audit-digest OK. 0 NON_MATCHING (G4). |
||
|
|
443a3e3afe |
feat(phase-30 S40): waves 1+2 bank 24/24 after recovery — ZERO codegen walls; +5,479 ins
Two ultracode waves over the open-only h_norm clusters (the pool nobody had ever aimed a wave at),
pool VERIFIED from the sigs first (R14).
wave 1 8 targets 8/8 match_one 5/8 gate first pass -> 8/8 after recovery
wave 2 16 targets 16/16 match_one 14/16 gate first pass -> 16/16 after recovery
THE HEADLINE IS NOT 24/24 -- IT IS THAT NOT ONE FAILURE WAS CODEGEN. All six first-pass gate
failures were TU-integration plumbing, each with an already-documented lever:
func_801802EC redefinition of morph_lerp strip the §77 PROBE LAYER (the draft carries types +
a static inline so match_one can compile standalone;
the real TU already defines them -- scaffolding is
not part of the bank)
func_8018B238 conflicting types D_80115158 recover_giant: draft declared it file-scope as a
struct array, TU declares u8[] BLOCK-scope inside
other functions -> block-scope the draft's externs
func_8017EF54 conflicting types (SELF) §37/§124 def-side asm-label alias (TU declares
void f(void) for no-arg callers; byte-true def takes
s32 in $a0; no-proto escape illegal once a param
promotes)
func_80183D78 conflicting types (callee) recover_giant
func_8017F278 conflicting types func_80146C3C §17a-1: the fleet canonical is the NO-PROTOTYPE
form + the intended signature applied AT THE CALL
SITE; a concrete prototype collides with it
(wave-2's 14 first-pass banks needed nothing -- the wave-1 lessons were folded into the prompt)
=> the gate number measures INTEGRATION, not matching. Run the recovery ladder before recording a
wave's yield or the metrics under-report the drafters and send the next wave hunting walls that are
not there. docs/wave-metrics.md S40-1.
POOL VERIFICATION (R14, and it cut both ways): the frontier report's cluster pool MEASURED
1,677 clusters / 5,795 fns / 319,755 ins at a 3.68x multiplier vs its claimed 1,689 / 5,956 /
326,261 at 2.7x -- within 2-4%, and the multiplier is BETTER than claimed. The SAME document's whale
claim was 3/4 wrong. Verify each claim separately; do not accept or reject a source wholesale.
ALSO: 24/24 members propagated from wave 1's 5 banked exemplars (0 failed) -- the same machinery
that returned 0/39 before this session's cast_call_sites fix.
NEW IDIOMS, distilled in-session (R16/R30):
§144 the LITERAL'S SPELLING picks the immediate encoding (`cnt + 0xff` vs `cnt - 1`: mod-256
identical, both one addiu, but gcc emits 0x00FF vs 0xFFFF from the source text)
§145a combine_givs ANCHOR RULE -- the address-giv group anchors on the LAST address-giv in SOURCE
order (record_giv prepends, combine_givs takes the head); store order decides the base and a
wrong choice spawns a third induction register
§145b a bare `p = r;` is a COMBINE BARRIER (can_combine_p/use_crosses_set_p) -- it preserves a
pointer-bump addiu that combine would otherwise fold into every MEM offset
§145c chained assignment `a=b=c=0` emits stores RIGHT-TO-LEFT
VERIFIED: make clean && make extract-all && make check-all -> 140 passed, 0 failed of 140.
Fleet 12420375 -> 12425854 instr (+5,479); distinct +5,479 / +43 uniq; fn-count +43.
audit-digest OK. 0 NON_MATCHING (G4). Cost: 3.73M subagent tokens across 24 agents, 0 errors.
|
||
|
|
6e0b1605c6 |
fix(phase-30 S40): cast_call_sites read a RETURN as a prototype and deleted it — 0/39 sweep becomes 18/39
THE BUG. tools/cast_call_sites.py classifies a declaration line with
^([ \t]*)(extern\s+)?([A-Za-z_][\w \t\*]*?)\b([A-Za-z_]\w*)\s*\(([^;{]*)\)\s*;
Feed it a return statement and `return` is a perfectly good identifier where a type is expected:
return func_8012CB64((s32)out, -0xC0, 0x40, -0x60, 0);
^^^^^^ captured as the return TYPE, func_8012CB64 as the DECLARED NAME
so the "rewrite this decl to canonical" path REPLACED the statement with
`extern s32 func_8012CB64(s32,s32,s32,s32,s32);`, DELETING the return. In C89 a declaration after a
statement is a parse error, so the damage surfaced as a bare syntax error in the DRAFT -- reading as
the draft's fault, not the tool's. 9 of 9 staged members of family 0x801848dc lost their return.
fix: a keyword guard (a declaration's type-specifier can never begin with a statement keyword)
family_sweep --hseq --band all over 5 families: 0/39 -> 18/39 banked (only the guard changed)
⚠️ AND THE TRAP INSIDE THE FIX: the obvious R33 move is "route it through cdecl". CHECKED, and it is
WRONG -- cdecl.parse() is a DECLARATOR-GRAMMAR parser that assumes it was handed a declaration; it
reports `return func_X(...);` as declaring func_X and `if (f(a));` as declaring `if`.
Statement-vs-declaration is a question cdecl does not answer. Routing there would have been a silent
non-fix that looked principled. §134's law still holds for line-SHAPE masking; this is a different
question.
BLAST RADIUS (measured, not assumed -- R14): cast_call_sites is in gate_stage's DEFAULT pipeline
(canon_resident_calls -> cast_call_sites -> sig_unify -> harvest_verify) and has been since Phase 20.
Of 44,833 stored drafts, 318 (0.7%) carry a `return f(...);` line this mis-reads, across 67 callees
(func_8014F468 x41, func_8014F6F4 x37, func_8014F74C x32, ratan2 x25). Every one, every time it
passed the gate pipeline, lost its return and failed as PLUMBING. Part of the historical plumbing
tail is this bug.
ALSO IN THIS COMMIT
- S5 CALIBRATION WAVE (8 agents, ultracode, 1.31M tokens). Pool VERIFIED FIRST (R14 -- Fable's whale
claim was 3/4 wrong): measured 1,677 clusters / 5,795 fns / 319,755 ins at a 3.68x multiplier vs
its claimed 1,689 / 5,956 / 326,261 at 2.7x -- its numbers hold, and the multiplier is BETTER.
Result: 8/8 match_one MATCH (close=0), and 5/8 banked whole-binary -- the §52b/§61 gap is
integration, not codegen. Banked: func_801822E0 func_8017EC98 func_801851A8 func_80189A34
func_80188E10 (693 ins x1 before propagation). Not banked: func_8018B238 (FAILED),
func_8017EF54 + func_801802EC (NEAR) -- drafts kept in .run/wave-s40/ for recovery.
- 18 member-banks from the re-run sweep (the cross-address free-h_exact pool: h_exact-identical at
DIFFERENT addresses, which dedup_propagate correctly refuses since it assumes position-locking --
family_sweep is the right lane).
- cookbook §143 (this bug + the cdecl trap + the blast radius); index regenerated.
VERIFIED: make clean && make extract-all && make check-all -> 140 passed, 0 failed of 140.
Fleet 12419169 -> 12420375 instr; distinct +1,526 / +5 uniq; fn-count +23. audit-digest OK.
0 NON_MATCHING (G4).
NEW IDIOM FROM THE WAVE, not yet folded into §31 (agent was told to write only its draft): a byte
counter must be spelled `cnt + 0xff`, NOT `cnt - 1`. Both are mod-256 identical and both compile to
one addiu, but gcc-2.7.2 picks the immediate encoding from the SOURCE SPELLING (0xFFFF vs 0x00FF).
Also flagged: .run/ghidra_c/func_8017EF54.c is a stale decompile of the WRONG function.
|
||
|
|
638f97dbbb | feat(phase-30 S39): propagate free h_exact class 0x80176144 (53 ins x 1) - R22 140/140 | ||
|
|
c3bf1c988d |
feat(phase-30 S39): func_801758FC propagated x137 (+7,535 ins) — the largest free h_exact class
Measured the h_exact free pool from the bytes rather than trusting the frontier report's numbers (R14 — its whale claim was 3/4 wrong: it said the whale was open in all four SC07 overlays; three were already banked and I closed the fourth earlier this session). MEASURED: 215 open function-instances / 8,763 instructions are byte-identical (h_exact, including reloc payloads) to an already-matched function. ONE class is 86% of that pool: func_801758FC — 55 ins, same address in all 138 overlays, matched in ov_SC01_000 only, OPEN in the other 137 => 7,535 instructions. h_exact means identical INCLUDING jal/lui/%lo reloc immediates, so the matched body compiles byte-identically at every member with NO remap (dedup_extend's correctness argument, §14). dedup_propagate --addr authored it once as DEFINE_func_801758FC() in engine_core.h and instantiated it at all 137 open sites in address order. [ OK ] 138 overlays byte-identical after propagation; 1 new group in config/dedup.us.yaml VERIFIED: make clean && make extract-all && make check-all -> 140 passed, 0 failed of 140. Fleet instr 12411467 -> 12419002 = +7,535 EXACTLY; fn-count +137; instr-weighted crosses to 94.5%. distinct-code unchanged BY DESIGN -- the class was already matched in ov_SC01_000, so the 137 add fleet instructions but no new DISTINCT function. audit-digest OK. 0 NON_MATCHING. Note this function had been sitting in the stored-draft backlog for ov_SC06_030 and ov_SC07_010 and re-gated "no" earlier tonight -- because gating a DRAFT is the wrong move for an h_exact class. The right move is propagating the already-MATCHED body. Same function, two routes, and only one of them is free. Remaining free pool after this: 78 instances / 1,228 ins across 32 classes. |
||
|
|
0414171237 |
feat(phase-30 S39/S4): 8/35 draft-exemplar heads re-gate and bank (+474 ins, 4 gate cycles, 0 agent tokens)
The 39 draft-exemplar families all have their exemplar still OPEN in ov_SC01_077 -- a
draft-exemplar family cannot propagate until its head banks. Re-gated the newest stored
ov077 draft per head, in 4 small batches (§61: a wide harvest broke a TU in S38).
Set aside the top 4 heads (65% of the pool's weight, all known-hard): func_801412A8 +
func_80178004 ARE S6's two giant walls (198x138 + 165x138 = 50,094 ins riding on 2 cracks),
func_8017C974 is today's byte-proven close=47, func_8017C294 its 246-ins neighbour.
batch 0 1/9 batch 1 3/9 batch 2 4/9 batch 3 0/8 = 8/35 (23%)
BANKED: func_8017EC7C func_8018281C func_801820DC func_80182988 func_80183BAC
func_80183AF0 func_80183CF4 func_80182E7C
(+474 ins x1 now; ~1,441 ins of templatable weight behind them once their families propagate.)
CALIBRATION REFINEMENT (docs/calibration.md, S39): this population re-gates at 23%, vs 8%
for the general stored pool and 4/6 for fresh post-repair drafts. Three different populations,
three different rates -- which is exactly why the rule is "re-gate what a repair plausibly
touched", not "re-gate the ledger". ov_SC01_077 is the split-heaviest overlay, so the S38
alias-deletion repair plausibly touched all of these.
VERIFIED: make clean && make extract-all && make check-all -> 140 passed, 0 failed of 140.
Fleet 12410275 -> 12410749 instr (+474), distinct +474 / +8 uniq, fn-count +8. audit-digest OK.
0 NON_MATCHING (G4).
|
||
|
|
7b5eda0424 |
feat(phase-30 S39/S4): re-gate probe — A10 broadly stands; 4 banked from the reverted overlays (+146 ins)
Tested whether decision-log A10 ("stored drafts re-gate at 0/958", measured in T1) survives
S38's tool repairs. Three populations, plain re-gate, no draft edits:
fresh wave-6 drafts (diagnosed "blocked on a class") 4/6
stored pool, unbiased sample (every 96th of 1,155) 1/12 <- hit was in a REVERTED overlay
the two REVERTED overlays, targeted 3/17
A10 BROADLY STANDS. ~8% on the general stored pool is not a harvest, and a 1,155-wide sweep
(= 1,155 whole-binary builds) is not justified by it. Do NOT generalise the fresh-draft rate
(4/6) onto the stored pool -- different populations. The honest rule is narrower and cheaper:
after a tool repair, re-gate the drafts THAT DEFECT plausibly touched, targeted by its
blast radius -- not the whole ledger. (R35 applied to the backlog, not just to metrics.)
BANKED (+146 ins): ov_SC06_030 func_80161208 + func_80162CCC; ov_SC07_010 func_801506A4 +
func_8016F0AC. R22 clean-fleet 140 passed, 0 failed of 140 -- which also proves byte-neutral a
fleet-shared engine_core.h edit the bank required (extern s32 func_801506A4(s32,s32) -> the
no-prototype form), reaching all 138 overlays (T2 blast radius).
Fleet 12410129 -> 12410275 instr; distinct +95 / +1 uniq; fn-count +4. audit-digest OK.
Also documents the LEDGER MECHANICS in calibration.md (Drew asked): .run/backlog.jsonl is
append-only and nothing is deleted on bank -- open-ness is DERIVED from corpus.stubs at every
read (load_best drops now-banked rows per-binary, P9) and `make report` runs `backlog.py prune`.
Membership is therefore self-maintaining and currently clean: 863 rows, 0 already-banked, 14
duplicate-addr (was 6,867 rows / 98% banked before Phase-29 compaction). What pruning does NOT
re-validate is the VERDICT on surviving rows -- closeness + residual class are as old as the
tooling that wrote them (Phase 28 found a corrupt one: func_80178004 close=0 -> 91). That is
the staleness that matters, and it is exactly what this probe measured.
|
||
|
|
d8016c49c8 |
docs(phase-30 S38): checkpoint v4 — POST-S1d, fresh-session safe
Refreshes a checkpoint that had gone stale (v3 predated S1d) — stale is worse than absent. FLEET 96.46 / 94.4 / 89.2, +37,166 instructions this session, ~0 agent tokens after the opening wave. R22 run thirteen times: 140/140 on eleven, TWO REAL FAILURES (ov_SC07_010, ov_SC06_030), both caught by the clean-tree rebuild after passing their per-binary gate, both reverted and recorded. Records the session's biggest find: the §37/§124 DEFINITION-SIDE ASM-LABEL ALIAS is a CLASS lever, not a one-off. It cracked the 208-conflict narrow-parameter class 138/138 after cast_call_sites, --normalize-self-decls and --fix-def-sig were each eliminated BY MEASUREMENT. S33 proved it once and it was never generalised. Carries the unresolved accounting anomaly prominently (new task #11 / S1e): distinct-code FELL 89.3 -> 89.2 across the alias harvest while fn-count ROSE, which no pure naming artifact explains. The bytes are proven; the yield number is not. Next session starts there, before scaling the lever. Also records eleven tool defects fixed (nine of ten "walls" were our own instruments, two of them mine), that §134 has now appeared in SIX tools and wants cdecl._mask rather than a seventh patch, and seven process errors of my own including piping away a gate summary I then could not report. |
||
|
|
a5e97739fb |
feat(phase-30 S38/S1d): the def-side asm-label alias cracks the 208-conflict class — 138/138 banked
Family 0x80146ab4 (18 ins, x138, PURE) had been failing 0/138 with `conflicting types for
func_80146A6C` — 208 of the ~398 conflicts in the sweep residue, its single dominant blocker.
DIAGNOSED BY READING THE DRAFT, after three levers were eliminated by measurement:
draft def : void func_80146A6C(s16 a0, s32 a1, s16 a2, s16 a3, u16 a4, s32 a5, s32 a6)
TU decl : extern s32 func_80146A6C(s32 a0, void *a1, s32 a2, s32 a3, s32 a4, s32 a5, s32 a6);
The NARROW PARAMS are the wall: C's default argument promotion means s16/u16 cannot agree with an
s32 prototype, and the `()` no-prototype escape is ILLEGAL precisely when a param promotes. Neither
declaration side can move.
- cast_call_sites: already on by default; wrong axis (fixes CALLEE decls, not the def's own).
- --normalize-self-decls: 0 banks + non-neutral reverts; wrong axis (the target's decl in callers).
- --fix-def-sig: measured 0/138, error UNCHANGED — it cannot reconcile a promoting param at all.
THE ESCAPE (§37/§124, S33-proven on func_80147364 — definition (u16,u16) vs 4,046 fleet decls,
banked x137 first try; 1,725 in-tree precedents): give the DEFINITION a private C identifier and
bind the emitted symbol with a GNU asm label, so the TU's declaration never meets the definition and
its type becomes irrelevant. Zero blast radius on every caller; byte-neutral by construction.
void aF80146A6C(<byte-true params>) __asm__("func_80146A6C");
void aF80146A6C(<byte-true params>) { ... }
RESULT: 138/138 banked, ~2,484 instructions, ZERO agent tokens. R22 clean-fleet 140/140.
.run/alias_defs.py applies the transform to a staged draft set.
NEXT: this is a CLASS lever, not a one-family fix — generalise it across the remaining sweep residue.
|
||
|
|
10f9546272 |
chore: regenerate the fleet digest + backlog after S1/S2/S3
docs/progress.fleet.md is the authoritative metric source the checkpoint's staleness self-check compares against — committing it keeps that check meaningful for the next session. |
||
|
|
15f936e2ea |
feat(phase-30 S38/S3): the whale banks in 3 of the 4 SC07 overlays — 137/138, not 138/138
func_80144B9C (770 ins) was matched in 134/138 overlays and open in the four SC07s — 3,080
instructions of code BYTE-IDENTICAL (h_exact, reloc payloads included) to what was already banked,
blocked by a missing file boundary. Now banked in ov_SC07_006 / _007 / _011 for ~0 agent tokens.
R22 clean-fleet 140/140.
THE PLAN'S FRAMING WAS WRONG. This was recorded as "the SC07 carve defect (T2 Arm-A %lo +0x20)".
The carve was never broken: o0_subsplit reported `split byte-neutral` on the FIRST attempt in all
four. The real blocker is that carving the whale out of a jr file makes jr_isolate_all hoist the
parent's file-scope decls into the new region as its `ambient` set — so for the first time the
fleet's loose-typed spellings share a TU with the shared header's (`extern void *D_801274CC` vs
`extern s32 D_801274CC`). In the 134 working overlays the whale sits in a CLEAN -O0 file (common.h +
the header, nothing else) and the two never meet. Fix: drop, in that one file only, the ambient
decls the header already declares — the header being the byte-proven side.
Three iterations, each exposing the next layer of the ambient set, every one a DECLARATION:
1. data symbols (D_80126B58, D_801274CC, D_801274D0)
2. function symbols (func_801336E8, func_8005C324)
3. the alias form terminated by a trailing COMMENT, which an endswith(';') test skipped —
the §134 comment-blindness shape for the THIRD time today.
ov_SC07_010 REVERTED and left open (hence 137/138). Its split landed in an EXISTING _o0c file
rather than a fresh _o0d, producing region _jr_801457A4 whose asm dir splat never generated. It
passed its per-binary build and FAILED the clean-tree R22 — the first R22 failure of the session,
and precisely why a per-binary pass is not a fleet byte claim (§61). Committing on that per-binary
"BANKED" would have shipped a broken overlay.
|
||
|
|
df99a71732 |
fix(tools): jtbl_family_bank reported "gate-fail" with no reason — the third missing-payload defect today
`last_err` was only ever set when a STAGE failed to produce a candidate. A candidate that built to the wrong bytes — i.e. the actual gate rejection — recorded nothing, so every caller saw a bare "gate-fail" and the failure was unroutable (measured: wave 6's 13 sibling failures could not be classified at all). Now captures the build's hard diagnostics, keeping BOTH ends of the line so the symbol survives (never left-truncate — same fix as harvest_verify.classify_fail earlier today), and says "built, bytes differ (genuine DIFF)" when there is no diagnostic. Third instance of one defect class this session: a tool reporting an OUTCOME without the EVIDENCE that routes it (harvest_verify.classify_fail truncating the symbol away; .run/s6f_gate.py booking a crashed child as silence; this). All three were quietly converting recoverable plumbing into apparent walls. Also adds .run/jr_family_sweep.py — the S2 front end for the has_mid_jr matched-exemplar families that family_sweep --hseq refuses BY DESIGN (§53). Families are DERIVED from the map and looked up by EXEMPLAR (a just-banked head leaves the `members` array — that cost a round earlier today), members re-checked against corpus.stubs, --raw passed when a seed exists, and it commits per family because jtbl_family_bank requires a clean tree between families. |
||
|
|
97a6864677 |
docs(phase-30): adopt the Fable-5 frontier plan as T7 + persist the report
The Fable-5 agent's harness blocked it from writing to disk, so its full analysis existed ONLY in the completion notification — one session away from being lost. Transcribed verbatim to .run/fable_frontier/ANALYSIS.md and force-added (with its computed pools, pool_ovres.json), and CURRENT_PHASE.md's new T7 points at it so future sessions know where the detail lives. T7 supersedes T6's wave ordering on one number: across every sweep run this project has done, blockers are ~24k PLUMBING vs 4,917 DIFF (5:1). Fixing plumbing moves work from the ~490 tok/ins wave column to ~0, and S1 restores the propagation multiplier that makes every later wave ~3x cheaper. DO S1 BEFORE ANY WAVE. S1-S7 recorded with reachable-ins and tok/ins estimates. Provenance is explicit: the two headline refutations were independently re-verified (23,211 classified files exist; 0x801833f0 went 0/6 -> 6/6 after the type lift, R22 140/140); the POOL NUMBERS are the agent's own computation and are NOT re-verified — flagged in the file to verify before scaling a wave onto them (R14). Standing pre-probe rule added: check h_norm identity across members BEFORE probing (an h_norm- identical family returning 0% is a compile-error certainty), and read the classified files before theorising about a sweep failure. |
||
|
|
2483fc902a |
fix(tools): jr_isolate_all was SILENTLY DELETING asm-label-alias definitions during a repartition
ROOT CAUSE (byte-witnessed, P30 S38 — the fifth tool with this same blindness).
A function banked under the §37/§73 DEFINITION-SIDE ASM-LABEL ALIAS form is spelled with a private
C identifier and bound to its real symbol by a GNU asm label:
void aF8018A860(s32, s16 *, u8 *, u8 *) __asm__("func_80183AF8"); <- decl, stays in preamble
void aF8018A860(s32, s16 *, u8 *, u8 *) { ... } <- THIS emits func_80183AF8
overlay_src_split.addr_of() resolves `func_<hex>` arithmetically and everything else through `syms`.
`aF8018A860` matches NEITHER, so it returned None — and partition() keeps only items with a
resolved address, so the definition was dropped from EVERY region. The file was then rewritten
without it and nothing said so. One carve of ov_SC02_028 deleted the definitions emitting BOTH
func_80183AF8 and func_80184268; the overlay stopped linking with `undefined reference`, and six
wave-6 drafts were written off against that as a plumbing/compiler wall.
TWO FIXES:
- CAUSE: overlay_src_split now builds an asm-label alias map from the source and resolves a
definition through its EMITTED SYMBOL rather than its C name (verified: aF8018A860 -> 0x80183AF8,
aF8018AFD0 -> 0x80184268 — exactly the two symbols the link was missing).
- SILENCE: partition() and jr_isolate_all._partition() now REFUSE to rewrite a file when any
construct's address does not resolve (R32), instead of discarding it. That guard alone would
have surfaced this the first time it happened.
RESULT: 3 of the 6 alias-class wave-6 drafts bank immediately, for ZERO agent tokens —
func_801884D8 (137 ins) · func_80180B04 (251) · func_801380E0 (438). R22 clean-fleet 140/140.
The other 3 (the three LARGEST: 557/513/710 ins) have a second, size-correlated cause — open.
NOTE FOR THE FLYWHEEL: family_remap._alias_decl_for ALREADY handled this exact form, and its
docstring records the identical lesson ("that blindness was the WHOLE of the h_seq sweep's 137 'no
matched unit' skips. The tool, not the compiler (R35)"). The fix was never propagated. The alias
form needs ONE shared oracle, the way §134 comment-masking ended up on cdecl._mask — five tools
have now independently rediscovered it.
|
||
|
|
8057709407 |
fix(.run/w6_pool.py): "attempted" must mean a wave that RAN, not a manifest that exists
Two fixes to the pool derivation: - the previously-attempted glob was `s*_wave.json`, which misses `w6_wave.json` — so wave 6's own failed targets would have been silently re-offered to wave 7; - but widening it to `*_wave.json` introduced the opposite defect: a STAGED manifest counted as attempted, so deriving a 16-target wave and then a 64-target wave made the second exclude the first's 16 best entries (pool 2,928 -> 2,913 -> 2,893 across three derivations, each poisoned by the last). Now a manifest counts only if its drafts directory exists: `<tag>_wave.json` ran iff `.run/<tag>/*/*.c` is non-empty. A manifest with no drafts is a PLAN, not a result. Wave 7 staged in two sizes off one clean pool (2,913 fresh families / 432,020 open templ ins): .run/w7_wave.json 16 targets / 19,088 templ ins .run/w7_wave64.json 64 targets / 52,483 templ ins <- the ~50k shape NOTE the 50k now costs 64 targets, not 16: wave 6 harvested the head of the distribution (its top single target was 15,152 ins), so the frontier is now a long tail of ~1,000-1,500-ins families. |
||
|
|
bc04f65562 |
docs(phase-30 S38): checkpoint — wave 6 banked (+10,616 ins), the gate defect fixed, 9 drafts diagnosed
FLEET 96.29% fn / 94.2% instr / 88.9% distinct, R22 140/140 twice. Session banked 7 wave-6 heads + 25 propagated siblings = +10,616 instructions (12,368,236 -> 12,378,852; the digest delta matches the hand-derivation exactly). wave-metrics.md gains Findings 5 and 6: - RANK WAVES BY INSTRUCTIONS, NOT HEADS. Wave 6 banked ~45% more instructions than wave 5 while banking less than half as many heads, because a bigger head carries more instructions AND its family propagates at the same cost per sibling (func_8017FEE0: ONE 299-ins head -> 4,485 ins across 15 siblings, ~0 agent tokens). The metric to beat is POOL REALISATION (21%), not bank rate — and wave 6's bank rate is NOT comparable to waves 3-5 because the difficulty knob moved deliberately (median target 438 ins vs 143, mostly has_mid_jr). - A WAVE TALLY IS A COVERAGE CLAIM and needs its own assertion. The 9 unbanked drafts are diagnosed and preserved, and 6 of them are ONE class worth cracking first: `undefined reference` to a sibling that IS defined in the overlay but only via a definition-side __asm__ alias (§37/§124) — the carve repartitions the object and separates the call site from the alias definition. One fix frees 6 already-paid-for drafts and will recur in every carve-heavy wave. The other two are genuine near-misses (close=47 REGALLOC-PERM, close=370). Tooling committed for reuse: w6_pool.py (the pool derivation, now a script), w6_diag.py (runs the REAL gate path — s36_capture.py splices without the carve and is wrong for jr targets), w6_jtbl_prop.py (carve-path propagation with the per-family commit jtbl_family_bank requires). |
||
|
|
73321fe2c2 |
fix(phase-30 S38): the gate was booking CRASHES as silence — 10 of wave 6's 16 drafts vanished
THE DEFECT CHAIN (byte-witnessed, both ends fixed):
1. harvest_verify._reload_corpus re-applied the `--src` filter AFTER a jtbl carve. Following a
carved stub to its NEW TU is that function's entire documented purpose, and it was deleting the
very stub it had just followed. Then:
_stubs loses fn -> render() raises KeyError -> UNCAUGHT -> _jtbl_restore(snap) never runs
-> the carve is STRANDED in config/ + src/ -> every LATER group in the same gate run then
built against a tree the earlier crashes had mutated.
line 136 already calls --src "an optional filter, not a location oracle"; this was the one place
treating it as one. Fix: the filter never drops a draft under verification, wherever it now
lives, + an R32 loud report if a working stub vanishes across a reload (which also repairs
_touched/baseline — a carved fn missing from _stubs left its new TU unbaselined, so the revert
path could not have restored it either).
2. .run/s6f_gate.py never checked the child's returncode — it grepped stdout for VERIFIED:/FAILED:
and booked "neither" as NOTHING, printing a clean-looking tally over 10 missing verdicts. This
is the §136a defect I logged against my own capture tool last session, in the gate itself.
Fix: 1:1 accounting assertion (banked+failed+no-verdict == drafts), the child's rc + output tail
on anything unaccounted, and exit 1 — a crashed child may have stranded a carve, so it must
never look like success.
PROOF THE FIX IS NOT COSMETIC: func_8017EA84 (579 ins) now carves and banks BYTE-IDENTICAL. The old
tool reported it as nothing at all.
BANKED 7 (R22 clean-fleet 140/140 from `make clean` + extract-all + check-all):
func_8017EA84 ov_SC02_000 (579) · func_8017FEE0 ov_SC02_026 (299) · func_80181CE4 ov_SC03_111 (491)
func_80183AE0 ov_SC03_112 (240) · func_80184C74 ov_SC06_018 (288) · func_80180F98 ov_SC03_097 (263)
func_801841C8 ov_SC02_035 (44)
MY OWN ERROR, RECORDED (R37/R14): after reverting the stranded carves I re-extracted ONE overlay,
not all 16 — the Phase-20 R22 corollary (a reverted CONFIG needs a `make extract`, not just a
revert) which I know and skipped. Run 2 therefore read WORSE than run 1: three genuinely-banked
functions failed against stale asm. Re-extracting the 16 touched binaries produced the honest run.
A gate result measured against stale asm is not a measurement (R35).
.run/w6_diag.py: run the REAL gate path for one (ov,fn) with the child's full output. s36_capture.py
splices without the carve, which is the wrong path for a table-bearing fn (§61b: the carve must
follow the splice) and produces a failure that is an artifact of the diagnosis.
|
||
|
|
fd1bdd4b2f |
chore(phase-30 S38): preserve wave-6 drafts before gating (5.2M agent tokens)
16 drafts, 14 claiming MATCH. .run/ is gitignored, so these are force-added: the wave-5 restart proved the Workflow resumeFromRunId cache is SAME-SESSION-ONLY, and a draft that has to be re-earned costs ~300k tokens. Gate follows; the byte-gate is the sole arbiter (G3/P9) and these are claims. |
||
|
|
139e21118b |
docs(phase-30 S38): wave 6 launched — pool derivation is a script now, + 2 derive-don't-assert fixes
- .run/w6_pool.py: THE pool derivation, finally a script instead of inline python (R33).
Ranks by OPEN templatable weight (corpus.stubs over the family map's member list, §138 rule 4 —
never off the map's `exemplar` field), carries the walls/ledgered-residual exclusion set, drops
any family whose address was attempted-and-still-open in a prior wave (83 addrs), and enforces
one target per (overlay, TU) so a wave cannot manufacture its own §138-rule-2 type-tag conflict.
Pool: 2,928 fresh families / 476,611 open templatable ins.
- wave 6 = 16 targets / 50,596 open templatable ins (3x wave 5), large-function heavy
(median ~270 ins, max 947); prompt carries the S37/W6 block (stage the big ones; cross-address
families need STEP 0 because searching by address cannot find their twin; the PAIR rule).
- TWO R37 FIXES TO THE MANIFEST ITSELF, both "asserted, never derived":
* `seed` was an arbitrary i%2 alternation carried over from the previous wave's shape — it
controls whether the prompt claims a cached Ghidra seed EXISTS. Now derived from
.run/ghidra_c/ on disk: 9 of 16, not 8 by alternation.
* `model` routed by MEASURED band, not the stale §136i ladder: Sonnet is measured 81-100%
first-pass over 125-793 ins, so func_8017C974 (947) is outside it and goes to Opus directly.
- CURRENT_PHASE.md: in-flight checkpoint (the wave-5 restart lost 2.7M tokens of ungated drafts;
this block says force-add the drafts and resume by GATING, never by re-running).
|
||
|
|
3f51101ca9 |
docs(phase-30): SESSION-33..37 checkpoint — PAUSED; 16 ungated wave-5 drafts preserved in git
Paused at Drew's request for a Windows restart. Nothing running, tree lock free, tree clean (R23 db churn aside). R22 run 19x this session, 140/140 every time. THE ONE THING OWED: `.run/s37/*/func_*.c` — 16 wave-5 drafts, all claiming MATCH, NONE gated. Force-added to git (.run/ is gitignored) because they cost ~2.7M agent tokens and Workflow's resumeFromRunId cache is SAME-SESSION-ONLY, so it does not survive the restart. Resume by GATING them, not by re-running the wave. Also preserved: the wave scripts (.run/s36w.js, .run/s37w.js), manifests, the hardened gate driver, and the four capture drivers. MEASURED THIS SESSION (both answer questions Drew asked): - The wave PROMPT is the lever. Bank rate 76% -> 77% -> 100% -> 100% on the same models and the same gate, prompt the only variable. The jump was STEP 0 (a magic-literal grep of src/, ahead of engine_core.h) — and that step came from a wave-2 agent's index_gap report, i.e. the agents write the next prompt. - The pipeline() fix, before/after: wave 4 parallel() 14 targets / 136 min / 2.5x parallelism; wave 5 pipeline() 16 targets / 82 min / 3.8x. 40% faster on 14% more targets. The two-batch design was a hard barrier with 46-min dead gaps at each boundary; the harness already caps at 16 so the batching bought nothing. Housekeeping: removed 3 stray cc1 intermediates (t.i, t.i.greg, t.s) that an agent left at the repo ROOT — scratch belongs under .run/ (R12), same class as the gccdump.lreg noted at the Phase-24 close. |
||
|
|
1859266d60 |
feat(phase-30 S10): Sonnet wave — 13 heads + 57 members; the §136i ~120 boundary is too LOW
- DREW'S CALL (2026-08-03): route the 30-target x2-9 wave to SONNET instead of Opus. The §136i >=120-ins Opus threshold was MY EXTRAPOLATION, never measured; this wave (125-793 ins) probes exactly the region where there was no data. - RESULT: 13 banked of 16 that ran = **81%**, vs Opus's 10/13 = 77% on the comparable S8-3 slice. At least 8 banked SONNET-DIRECT (65 agents spawned: 60 sonnet, 5 opus escalations). Propagated 57 member-matches / 4 failed across 42 overlays. 70 instances. R22 clean-fleet 140/140. FLEET 96.01% fn / 93.6% instr / 88.0% distinct (77,550 uniq). => **Sonnet is at least as capable as Opus on 125-793 ins. The ~120 boundary is too low.** NOT rewriting it to a specific number yet: 16 samples under a throttle confound cannot name a cliff. The controlled A/B (task #12) is how that number gets fixed properly. - THE REAL LIMITER IS CAPACITY, NOT CAPABILITY: 14 of 30 agents were killed by SERVER-side throttling ("Server is temporarily limiting requests (not your usage limit)") that 30 concurrent Opus agents did not trigger. Practical rule: run Sonnet waves at ~12-16 concurrency, not 30. The 14 unrun targets are listed in the checkpoint for a smaller-batch retry. - Sonnet's work quality was not shallow — three examples: func_8018797C read local-alloc.c and forced loads into an AGGREGATE to stop find_free_reg greedily taking 3 callee-saved regs; func_8018D870 used §136c sibling-first for ~70% of the body then blocked a coalesce with a pin; func_8017E3AC diagnosed an RC-3 callee-saved-order swap and noted the pin must be s32 or a stray `andi 0xffff` appears. - MY ERROR, RECORDED: `until [ -s <output> ]` fires at the FIRST LINE of output, not at completion. It fired mid-propagation and I ran `make clean` on top of a live family_sweep, deleting asm/ and aborting both the regen and the sweep (corpus's R32 assertion refused to answer rather than return a wrong stub set — working as designed). No bad bytes: R22 verified 140/140 immediately after, and the propagation simply re-ran clean. Correct waiter is `pgrep -x make` (exact process name), which also cannot self-match the way `pgrep -f <pattern>` did when it leaked 4 waiter shells earlier. Third instance today of ONE root cause: trusting a proxy instead of the thing itself (a weight column vs a probe §136h; an exit status vs build output §136a; file-existence vs process exit). |
||
|
|
cf10d28459 |
feat(phase-30 S9): x2-9 calibration wave — 22/25 banked + 67 members; the grind rate is MEASURED
- CALIBRATION (25 stratified targets: 12 head-by-weight + 13 sampled across the band, so the
measurement captures the DECAY, not just the head): 28 agents -> 22 claimed -> gate BANKED 22/25
(88%) -> propagated 67 member-matches / 13 failed across 38 overlays. 89 instances.
**22,937 templatable instructions banked in one wave.**
HEAD 9/12 -> 19,492 of 28,584 templ ins
BODY 13/13 -> 3,445 of 3,445 templ ins (the small ones are EASY; all 3 misses were 611-793 ins)
- FIRST SONNET DATA (§136i ladder's new middle rung): **Sonnet 6/6 · Haiku 6/6 · Opus 10/13.**
The two cheap tiers went 12/12 and Opus absorbed every hard failure — consistent with correct
size-routing rather than luck. Small n; the controlled A/B stays parked (task #12).
- THE PROJECTION for the >=95% instr bar (Drew's decision input): 411 of 1,872 families cover the
212,594-instruction gap = ~19 waves optimistic, 20-30 realistic. Mean templ ins/family decays
1,844 (top-25) -> 1,046 (top-100) -> 525 (top-400) -> 193 (band-wide), so early waves look like
this one and later ones bank MORE functions for FEWER instructions.
- DECISION (Drew): NO phase close — keep grinding. Campaign tracked as task #15.
- Carried failures -> next lanes: func_8017D174 (793 ins, closeness 5 after ~90 variants; diagnosed
a backward-scheduler priority race -> permuter, correctly NOT ledgered a wall), func_80186E24
(611 ins, 133 of 139 diffs pure register numbers -> a natural §137 test), func_8017E2EC.
- §136c sibling-first paid again: func_8017DF84 (766 ins) MATCHED because a banked byte-matched twin
existed in the same TU; its 697 index-diffs traced to ONE root cause (a bare 0xFFFFFF literal that
loop.c hoisted to the OUTER preheader, stealing $s3) — closed by binding it to a local declared as
the FIRST statement of the inner loop body. Verified via rtu_match (real-TU), not just match_one.
|
||
|
|
a4bc49a23d |
feat(phase-30 S8): the x10-99 band closes 23/23; §137 makes REGALLOC-PERM arithmetic, not a permuter job
- S8-3 (23 fresh x10-99 families, 121-328 ins — the hardest band this session): draft 16/23 ->
capture (1 PLUMBING / 6 DIFF) -> reconcile 1/1 -> redraft 6/6 => **23/23 (100%)**.
Propagated 206 + 81 = 287 member-matches across 80+54 overlays. R22 clean-fleet 140/140.
FLEET 95.97% fn / 93.4% instr / 87.5% distinct (77,404 uniq); dedup 1905/0; 0 NON_MATCHING.
- §136b CLOSES AT 15/15 — no function ledgered "genuine byte-DIFF" survived a redraft, all session.
- §137 (NEW, the session's most reusable result): REGALLOC-PERM — a clean 2-register swap — is a
TWO-COMPILE ARITHMETIC PROBLEM. global.c:allocno_compare ranks by floor_log2(R)*R/L*1e4*size;
read R and L out of `cc1 -dl -dg` for BOTH contenders AND their ranked neighbours to get the
admissible priority WINDOW, then place a zero-byte `__asm__ __volatile__("" ::"r"(v))` so L lands
inside it. func_801833F0: contenders ONE unit apart (1297 vs 1296), window (1228,1296), five
placements probed, only L=219 -> pri 1232 worked. R and L are FORCED BY THE EMITTED CODE (L is
recomputed post-sched1), which is exactly why source-reordering is a dead end for this class.
Converts a class the permuter banked 0 from all session into a deterministic calculation.
Companion: floor_log2 makes ref-count a STEP function (5/6/7 refs are worthless, you must reach 8)
— func_8017EFA8 closed 30 register-name mismatches by taking a pseudo 4 refs -> 8 with a dead read.
- §136j — the failure MIX FLIPS WITH SIZE: <=120 ins fails ~70% on declarations; 121-328 ins fails
86% on genuine codegen. Budget reconcile for the small band, redraft for the big one — and do NOT
read 70% on a big-function wave as a broken pipeline; that is the expected shape.
- §137a — a gate verdict has a TIMESTAMP. Two "DIFF" ledger entries were STALE (draft rewritten 28
min after the gate ran, never re-gated); both were already byte-perfect. Compare verdict time to
draft mtime before redrafting. Plus two offline oracles an agent built: a FULL RELOCATION RESOLVE
(catches wrong jal/%hi/%lo targets that match_one's mask hides) and a COLLATERAL CHECK (whole-TU
objdump with/without splice). Together they discriminate all three causes of "match_one says MATCH
but the overlay SHA differs" without running make.
- §136f addendum — the collider is often an already-banked SIBLING BELOW the splice; locate it by
arithmetic (draft grows the file N lines, so TU line L reports at L+N).
- cookbook-index 380 -> 382 sections.
|
||
|
|
18fc50d0f8 |
docs(phase-30): §136i — insert SONNET between Haiku and Opus in the drafter ladder (Drew 2026-08-03)
- MEASURED BASIS (P30 S7, 144-target campaign): the two-tier rule from the 2026-06-29 A/B left the ~50-120-ins band unassigned, and every wave since defaulted it to Haiku-with-Opus-escalation. Haiku-direct banked 3/8 on that band while Opus-escalation-after-a-Haiku-miss banked 10/11 — i.e. Haiku was acting as EXPENSIVE TRIAGE (a wasted draft + a full Opus redraft), not a cheap drafter. The original A/B only proved parity <=52 ins; everything above that was extrapolation. - LADDER: haiku <=~50 ins · SONNET ~50-120 · opus >=~120 or escalation · fable5 for a genuinely NEW wall class only. Never haiku->opus directly; never default a whole wave to opus because the band "looks hard" (the same extrapolation in the other direction). - WIRED, not just documented: s7_manifest.py routes by the new thresholds; s7_wave4b.js escalates haiku->sonnet->opus instead of haiku->opus, and its meta/prose say so. - Boundaries (~50/~120) are current best estimates — re-measure per-tier from the journal + the gate, never from the workflow's by_tier (it counts claims, not banks — §136). - Byte-gate remains the sole arbiter, so a weaker drafter is a throughput risk, never a correctness risk (G3/P9). cookbook-index 378 -> 379. |
||
|
|
6fe9b66f2d |
feat(phase-30 S6h): wave 3 — 34/38 banked, +639 members, reconcile lane now 12/12 (R22 140/140)
- 38 targets / 44,297 templ ins, model-routed (Haiku <=89 + Opus escalation, Opus direct >=90):
52 agents, ~4.1M tokens -> gate 27/38 (71%). All 11 failures captured + classified: 8 declaration/
link plumbing, 3 genuine byte-DIFF. An 8-agent Opus reconcile wave fixed 8/8 (7 banked) ->
wave-3 total 34/38 = 89%. Propagation +639 members / 1 failed / 83 overlays.
R22 clean-fleet 140/140. Fleet 95.42% fn / 92.4% instr / 85.5% distinct.
- DESIGN (S27 law applied BEFORE it bit): six of eight reconcile targets share ONE TU, so this wave
FORBADE agents any build — six concurrent splice-builds would have clobbered a tracked file.
- THE AGENTS OUT-DIAGNOSED MY BLOCKERS:
* func_801848B0 — an agent REJECTED MY PREMISE: I said byte-correct + decl-blocked; it ran
match_one first, found a real 1-ins DIFF, fixed both. R14 aimed back at me, correctly.
* func_8017C5F0 — the "invented symbol" D_801DA0F0 is an INTERIOR ADDRESS: offset 0x6C into
D_801DA084 (0x801DA084..0x801DA103). The lui/addiu pair builds an interior pointer.
* func_8018A860 — the TU declares memcpy THREE times with incompatible signatures, with a latent
byte bug behind it. One symbol declared three ways is a defect awaiting the next draft.
- Carried (4): func_80184A94 (match_one MATCH, gate-refused) + 3 genuine byte-DIFFs
(func_801845B0, func_8017BEBC@ov_SC02_026, func_8018480C).
|
||
|
|
372dc62d35 |
feat(phase-30 S6g): wave 2 — 93% bank rate (was 83%), all 4 reconciles closed, +342 members (R22 140/140)
- 15 targets (11 fresh Haiku + 4 gate-failed reconciles on Opus), 15 agents, ~0.74M tokens.
Gate banked 14/15 (93%) vs wave 1's 20/24 (83%); ALL 4 RECONCILES BANKED.
Propagation +328 members / 0 failed / 76 overlays. R22 clean-fleet 140/140.
Fleet 95.23% fn-count / 92.1% instr / 85.0% distinct (phase opened 92.00 / 87.5 / 78.0).
- THE 83->93% CAME FROM THREE FIXES, ONE PER WAVE-1 FAILURE (the S27 finding reproducing):
(1) args pasted from the DERIVED manifest, never typed — all 30 paths verified on disk first;
(2) blocker-capture BEFORE the reconcile fan-out (S29 law: agents cannot run the gate, so a
match_one-MATCH draft dying on `conflicting types` reads to them as a codegen wall) —
each got the exact symbol+line plus the two byte-neutral levers;
(3) wave-1's Opus DISCOVERIES became wave-2's Haiku INSTRUCTIONS (ori-vs-addiu unsigned
destination; store-sinking scheduler order).
- THE RECONCILES OUT-DIAGNOSED MY CAPTURE: func_80189B78's error named ONE symbol; the agent found
SIX invented prototypes, two AFTER the splice point where cc1 had not yet reached — all fixed by
copying the TU's decls verbatim + casting at the call site, zero bytes changed. func_8018584C had
lever (A) blocked in BOTH directions (the draft must also compile standalone for match_one) and
closed with the DATA form of the asm-label alias. func_80180A4C was one character class (s32[] vs
the TU's u8[], declared 11 lines after the splice point).
- Carried: func_80189C4C (the one agent that returned no structured result; gate refused).
|
||
|
|
6e181db771 |
feat(phase-30 S6f): B-shaped wave — Haiku drafts, Opus closes, +544 members (R22 140/140)
- POOL (derived from the regenerated map): 36 families / 28,829 templatable ins, kind=modal (no member matched ANYWHERE so no sweep could reach them), >=20 members, <=60 ins, non-jr, and NOT ONE exemplar in ov_SC01_077. Hand-calibrated 3/3 one-shot before scaling (Phase-15/18 discipline). - WAVE (ultracode; Haiku drafters + Opus escalation, 24 targets): 31 agents, 0 errors, ~2.0M tokens, 12.5 min. Agents claimed 24/24 MATCH; the whole-binary gate banked 20/24 (83%); propagation +524 members / 0 failed / 91 overlays. 17 of 20 banks were HAIKU, 3 Opus — the cheap-tier-ab-validated call (Haiku == Opus at <=~50 ins, ~4.8x cheaper) held on real work. - WHAT OPUS BOUGHT: (1) a `sh` of a constant with the stored width's top bit set needs a u16 destination — via s16 gcc folds it sign-extended and li emits addiu, via u16 force_fit_type keeps it positive and li emits ori; (2) a schedule-reorder closed by STATEMENT ORDER not the permuter (gcc's list scheduler preserves relative order of disambiguable stores); (3) three loose-typing fn-ptr casts a cheap drafter had misread as delay-slot/permuter residuals. - MY ERROR (R37/R14): I generated the manifest to .run/s6f_wave_targets.json then HAND-TRANSCRIBED the args into the Workflow call, pattern-filling _jr_8017BEBC across overlays where no such split exists (corpus.stubs says _jr_8017AE2C). Three agents lost time rediscovering real paths. The gate driver written after (.run/s6f_gate.py) DERIVES every TU/split from corpus.stubs and asserts nothing. Assert nothing you can derive. - The 24->20 gap is the known match_one->gate gap (standalone compile cannot see a TU decl conflict; Phase 19 measured 88-92% -> 60-71%). 4 carried: func_8018584C, func_80180A4C, func_8017CC80, func_80189B78. - R22 clean-fleet 140/140. Fleet 95.13% fn-count / 92.0% instr / 84.9% distinct (phase opened 92.00 / 87.5 / 78.0). |
||
|
|
e6cec30736 |
feat(phase-30 S6f): calibrate the B-shaped vein — 3/3 one-shot by hand, +65 members (R22 140/140)
- func_8017E934 (ov_SC05_001, 29 ins x65): hand-drafted off the .s, match_one MATCH first try, whole-binary gate byte-identical, propagated 64 members / 0 failed across 63 overlays. - That makes the B-shaped lane 3-for-3 one-shot (func_8017CDD8 17ins, func_8017CE7C 16ins, func_8017E934 29ins) for ~0 agent tokens = 330 member-matches from 62 instructions of C. - THE POOL (derived from the regenerated map): 36 families / 28,829 templatable ins that are kind=modal (NO member matched anywhere, so no sweep could ever reach them) with >=20 members and <=60 ins, non-jr. NOT ONE exemplar is in ov_SC01_077 — they are invisible to exactly the two habits this phase already corrected (the ov077-source default and --band substantial). - The calibrated recipe, now the wave prompt: read the .s as ground truth (a cached Ghidra-C seed was measured this session decompiling a DIFFERENT body) -> conform every callee decl to what the TU already says (the PLUMBING class: standalone-MATCH C is gate-REJECTED as `conflicting types` when it redeclares a callee the TU defines as (void)) -> match_one -> whole-binary gate. - R22 clean-fleet 140/140; fleet 94.96% fn-count / 91.9% instr / 84.7% distinct. |
||
|
|
381cd56d40 |
feat(phase-30 B): the x138 era was NOT over — 2 tiny cracks -> 268 members (R22 140/140)
- A: frontier regen at HEAD (sigs + family_hseq) before pricing anything (R35). Also the reason
it was needed: .run/hseq_verified.*.txt has accumulated 22,841 files across every sweep ever
run, so any per-family analysis globbing them over-counts; the regenerated map derives state
from sigs + corpus.stubs (R33), which is the authority.
- B / THE FINDING (third §133-class miss in a row): the S29 checkpoint's structural signal
"after S2 the x138 era ENDS — those are the last two crackable fleet-wide families" — the stated
TRIGGER for the phase close — is wrong. Two fresh-crack families with >=126 members were open:
0x8017cdd8 ov_SC02_039 17 ins x 142 members PURE
0x8017ce7c ov_SC03_114 16 ins x 126 members IMM
Both kind=modal (NO member matched anywhere, so no sweep could reach them) and neither exemplar
in ov_SC01_077 — invisible to exactly the two habits this phase already corrected.
- Both hand-drafted off the .s, match_one MATCH on the FIRST try, ~0 agent tokens. First gate
attempt failed PLUMBING (not DIFF): the draft declared `extern void func_8017CFCC(s32 a0)` while
the TU DEFINES `void func_8017CFCC(void)` — the target passes $a0 only because the caller's
incoming argument still sits in the register (loose typing). Byte-true C calls it with no
argument; re-verified MATCH, gated byte-identical, propagated 266 members / 0 failed / 118 overlays.
- R14 on the seed: the cached Ghidra-C for func_8017CE7C decompiled an entirely DIFFERENT body
(three calls absent from the asm). Reading the .s is what made it one-shot.
- R22 clean-fleet 140/140. Fleet 94.88->94.96% fn-count, 91.9% instr, 84.6->84.7% distinct.
|
||
|
|
aa600c56ef |
fix(phase-30 S6e): family_sweep snapshotted TUs it never edited — the self-decl lever measures 0, honestly
- D6: hseq_sweep took the tu_snapshots snapshot UNCONDITIONALLY, one line before the `if nfix:` that decides whether to edit. A TU that normalize_self_decls merely INSPECTED was therefore registered, and the phase-2 MISMATCH backstop attributed ANY group failure to a "self-decl edit" that was never made -> revert + `0/N banked`. Measured: 909 of 909 groups took that branch while NSD actually fires on ~25% of members (3 of 12 probed). The §103 tu-scope path below has always snapshotted inside `if _rep["moved"]:`; NSD now matches it. - After the fix: NON-NEUTRAL 909 -> 303 (consistent with the fire rate) and STILL 0 banked — the 606 groups that now take the normal path bank nothing, so the lever's verdict is REAL, not an artifact: this residue is not self-decl-conflict-bound. Lever measured, closed, zero. - R14 on my own conclusion: I byte-measured a firing case instead of trusting the backstop — func_80162CCC/ov_SC01_000 builds to 9052dc0e... WITH and WITHOUT the NSD edit (byte-NEUTRAL), so the surviving 303 verdicts are wrong too (likely accumulated multi-member edits in one TU). Logged as a named open item, not chased: the lever yields 0 either way. - The tell, twice in one session (§134): a 100% rate is a property of the mechanism, not of 1,622 different functions. Three earlier sweeps over the same population reported 0 NON-NEUTRAL. |
||
|
|
21ccb171ac |
feat(phase-30 UC): wave-2 propagation — 2,192 members, fleet 91.4% instr (R22 140/140)
19/19 wave-2 heads banked and propagated: 2,192 member-matches / 411 stage-but-DIFF residue (each individually gate-rejected and reverted). FLEET 94.43% fn / 91.4% instr / 84.0% distinct; dedup 1905/0; 0 NON_MATCHING (G4). Session arc: 93.25->94.43 fn / 89.2->91.4 instr / 80.5->84.0 distinct. Phase arc: 92.00->94.43 fn / 87.5->91.4 instr / 78.0->84.0 distinct. |
||
|
|
1a1463b1c6 |
feat(phase-30 UC): wave-1 propagation — 1,370 member instances, fleet 90.9% instr (R22 140/140)
- 9 banked heads propagated: 1,096 non-jr member-matches (family_sweep --hseq --band all, 0 failed) + 137 (func_80159A20, jr) + 137 (func_801549F8, jr) - func_80176734 (371 ins, the largest single item in the frontier) banked + propagated - FLEET 93.81% fn / 90.9% instr / 83.9% distinct; dedup 1905/0; 0 NON_MATCHING (G4) - cookbook §132b (--span-rel: the already-matched owner that is ITSELF multi-switch) and §133 (the DEFAULT-FILTER class — three times in one session a tool silently answered a narrower question than the one asked: my own >=80-ins cut, worklist's h_exact pricing, --band substantial) |
||
|
|
4a23c82a33 | feat(phase-30 S2): func_8016EC0C x138 complete — 137/137 siblings, fleet 90.1% instr (R22 140/140) | ||
|
|
56210fdadd |
feat(phase-30 S1): zero-crack tier — 186 members banked; fleet crosses 90% instr
- head func_8014032C 137/137 (25,071 ins, --span-rel §132b) + jr tier 46 members incl.
func_8017BEBC 13/13 (12,376), func_8015A3C8 6/6, func_8015AE2C 4/4, func_8017A4AC 4/4,
func_8013FFD8 9/10 + non-jr pass 3.
- MY ROUTING ERROR (recorded): pass 1 ran all 28 families through jtbl_family_bank; 13 are NOT
jr functions, so they carve-failed by construction — §123's own law ('propagate a family with
the tool its TIER needs'), which I had quoted in the task description. Re-routed via
family_sweep --hseq: 3 banked / 38 failed => that residue is the genuine stage-but-DIFF class.
- MEASURED: 13 of 29 zero-crack families have remaining members ONLY in the 4 P27-onboarded SC07
overlays (18,856 ins) — not a stub-count gap; they simply missed every sweep that predates them.
- R22 clean-fleet 140/140. Fleet 93.38% fn / 90.0% instr / 82.4% distinct; dedup 1905/0.
Phase arc: +1.38pp fn / +2.5pp instr / +4.4pp distinct.
|