An external-model bake-off, not a banking session. Nothing was banked; that is
the next session's first task.
FINDINGS
- CARD FUEL is the biggest lever, bigger than model choice: the same 10 cards
went 4/10 -> 9/10 when seed_ref/tu_ref/decl_prior were injected. The
"60-instruction ceiling" was an artifact of withholding fuel.
- Sub-50 is near-free: 19/19 verified MATCH at $0.007/function, blind.
7,724 sub-50 open functions = 73.5% of the remaining set.
- A free model (stealth/ox-alpha) cracked a 611-ins function and a jtbl
exemplar, and distilled §206 — whose two negative results were
independently byte-confirmed before banking.
- §206 transfers WITHIN a family (40 turns -> 11) but NOT across (56 turns,
0 compiles). jtbl costs ~40 turns of learning per family, not per class.
TOOL FIXES (all negative-controlled)
- family_remap.gather_externs: took the first ALPHABETICAL extern across the
overlay's TUs, carrying two types swapped (sh/lh vs lbu/sb). Now prefers
the extracted unit's own file. Blocked a 4-member/2,444-ins family.
- atlas.member_lever: aprop_card was loaded and never read while a bare
ledger DIFF forced needs-autopsy. PURE now outranks it — rescues 32
members / 11 families / 3,810 ins.
- decl_prior._ASM_SYM: the %hi/%lo arm had never fired (0 of 1,210 over four
waves). jal 306->306 zero regressions, data 0->299.
- api_agent.py (new): --cards, --brief, --max-cost, nudge loop, 429
attribution + backoff, transport retry, non-fatal tool faults, and a
repeated-call guard.
RULES PROPOSED: R40 (exonerate the instrument before attributing a failure to
its subject — seven instances this session) and R41 (a cost/rate/yield number
ships with its denominator — I quoted $0.30 against a $6.31 bill).
Wave AA: 69 cards / 6,539 ins / 8 gate groups, 33 siblings, snapshotted 69/69.
All 69 passed the S46 validity gate pre-draft — the first wave drawn through it
since it was wired into build_wave_atlas, and the honest population negative
control for that gate (zero false refusals; a poisoned card is refused
OUT-OF-RANGE).
decl_prior now contributes 165 DATA rows to the cards (0 on every prior wave,
the §204-E fix). The 49 uncopyable pointer-to-function spellings are marked
`fleet_note` rather than dropped: the consensus is real information, the
rendering is not valid C. NOT fixed at the source — gate_main.typesig is the
banking driver's conflict oracle, so the safe fix is a display-only
pretty-printer in decl_prior, and no index rebuild is needed since the tuple is
what the index stores.
Audit after "did you update tooling for those findings" found three gaps
beyond the four committed fixes:
- R21: docs/SETUP.md had no record of any of it. Adds the "four flow traps"
table — each trap, its measured cost, and where it is now caught.
- family_sweep --only had no coverage assertion, so the 3-vs-50 mis-scope
could recur silently. It now resolves member addrs to their family, always
prints the coverage line, and refuses when it resolves to zero families.
- pregate_check modelled the banking driver's typedef strip but never checked
the consequence. Adds [DROP-RISK] §203 USE-BEFORE-TYPEDEF. R39 NC: flags
the known-bad splice, 0 false positives on the post-hoist file and all 7
other wave-Z TUs (first draft read a typedef named in its own comment).
Also corrects §203 and the phase log: the text that banked was the RENAMED
variant, because gate_stage's backlog.save_draft() overwrote the original on
the failed attempt. Bytes are correct (R22 213/213); the claim "draft
byte-unchanged" was not.
Wave Z: 74/75 MATCH, 72 banked first gate, 2 recovered for zero agent tokens
(§203 address-order typedef hoist; §202 alias on a DEFINITION for the §183.3
DEF-side return wall). Sibling sweep re-scoped after --only was keyed on the
atlas gid rather than family_hseq's exemplar: 3 -> 50 banked.
Harvest: 82 gap reports -> 5 laws, 16 rejected, 30 already-covered; the
adversarial verifier killed 7 of 12 claims. §204 written (510 lines).
Tooling, all negative-controlled:
- the S46 validity gate was off the path for waves T-Z; wired into
build_wave_atlas where cards are born, with the PRE-DRAFT-ONLY constraint
documented (it condemns banked work if run later)
- wave_snapshot honors the card's `sub` (9/9 legacy byte-identical, 66/66
split-TU recovered)
- §204-E: decl_prior's %hi/%lo arm had never fired (jal 306->306 zero
regressions, data 0->299)
Refreshed rather than appended: the previous checkpoint (commit:2542) was outrun by the §201-A fix,
wave Z's redraw and wave Y's harvest, and a checkpoint the tree has moved past is worse than none
because it is believed. Written for a session that has none of this context: what banked, the seven
results that outlive the count, every tool shipped, the eight-step wave-closing sequence, the exact
invocation that fires the staged wave Z, the four known-open near-misses with their attributions,
and the transient-failure recovery that worked five times tonight.
Wave-metrics gains a single six-wave table: 405 drafted, 405 banked or recovered.
Wave Y's harvest found a defect in the card field shipped EARLIER THE SAME SESSION (§196). Overlay
functions are named by VRAM address and 134 overlays load at the same window, so build()'s bare
defs[name] counter mixed N unrelated functions -- and §196 ranked that row ABOVE the destination TU.
Measured over the tree: 3,911 of 9,861 symbols with a definition are defined in >1 binary; 1,219
disagree on ARITY, 1,204 of them in the overlay window; 818 of the disagreements were a top-two TIE
that Counter.most_common broke by sorted-file order, so the lowest-numbered defining overlay
silently won. On wave Y's five binaries, 26 of 65 overlay-window DEF rows (40%) named another
overlay's function. Byte-proven cost: applying one row's arity to func_8017E83C took it from
MATCH (114 ins) to 113 ins / 83 mismatched.
Fix: defs are keyed by BINARY; a DEF row is emitted only from the target's own binary for
overlay-window symbols, and otherwise withheld with a stated reason ('N other binaries define this
address; none is yours') rather than silently omitted. Resident/shared/main symbols are fleet-unique
and were always correct (0 of 43 wrong). build_wave_atlas passes the target binary through.
Wave Z was ALREADY STAGED with 24 poisoned rows across its 292; redrawn with the fixed tool -> 0
poisoned, 24 withheld with a reason. This is the fourth same-session self-correction (§194-E ->
§193-A, §199-A -> §189-A, §197-A -> §136-9, §201-A -> §196), and the first one caught before the
bad data reached agents.
Caught by Drew: the tool was committed and nothing called it — not the harvest prompt, not the
memory, not SETUP.md. A tool nobody invokes is the same defect this session keeps finding in the
CARDS (§193-A, §194-E, §196: the answer was already computed and nothing carried it), wearing
tooling clothes.
Now: step 0 of the harvest reader prompt runs it; docs/SETUP.md carries a row with the measured
threshold rationale (R21); the wave-closing memory names it in step 6. All three restate the same
caveat because it is the part that gets forgotten — a candidate is a STARTING POINT, and an empty
candidate list is NOT evidence of novelty, since dumb term overlap misses paraphrase entirely.
Measured the top-candidate score distribution on wave Y's 67 gaps: min 0.009 / p50 0.08 / p90 0.26 /
max 0.53. Hand-checking the low half showed generic co-occurrence -- 'delay slot' matching every
section that mentions a delay slot -- not real answers. Emitting those is worse than emitting
nothing: an empty list costs a reader nothing, a plausible-but-wrong section costs them a read. The
tool now reports 14 confident candidates instead of 51 mostly-noise ones.
Every harvest so far spent most of its agents rediscovering that a gap was already answered: 61/71
(T), 44/64 (U), 76/67 (V), 41/68 (W), 56/63 (X). That majority verdict is the flywheel working, but
paying an adversarial verifier to reach it is waste -- the check is a text search, and a text search
does not need a model. gap_triage scores each gap against all 441 cookbook sections by IDF-weighted
distinctive-term overlap (file:line cites, section refs, register names, MIPS mnemonics, pass names)
and hands the reader its top candidates to open FIRST.
Deliberately dumb and deliberately non-authoritative: no embeddings, no model, and a candidate is a
starting point rather than a verdict -- its failure mode is a suggestion the reader ignores, not a
refusal that discards work (R39). R32: every gap appears in the output exactly once, asserted.
On wave Y's 67 gaps: 51 get a candidate section, 16 get none. Built during a four-round API outage
that blocked the harvest itself -- the retrieval half of the harvest needed no agents all along.
547 banked this session, fleet 96.0% instr-weighted / 91.7% distinct / 97.07% fn-count, R22 213/213
twice for wave Y. Wave Z drawn and staged at .run/wave_p31z_workflow.js + .run/wave_z_args.json
(75 cards / 6,517 ins / 8 gate groups) per Drew's instruction not to launch it. Wave Y's harvest is
the one outstanding step of the seven-step closing sequence -- three launches lost every agent to
529 Overloaded at zero tokens; gap reports and target snapshots are on disk and the checkpoint
carries the exact resume invocation.
Wave Y's recovery lane ran during a total API outage (two rounds of 529 Overloaded, 12 agents, 0
tokens), so the five gate drops were fixed by hand -- and the fix turned out to be ONE repeatable
move rather than five negotiations. §183's playbook negotiates with the TU's spelling; §200 declines
to share the C identifier at all, binding a private name to the same link symbol with gcc's asm
label (§37/§124). Five different refusal classes -- array-vs-scalar where reconcile_slate's own fix
had broken the match, a slate-mate's private struct, void* vs s32, and two DEF-side return conflicts
including a function whose only in-TU use takes its ADDRESS -- all five aliased, all five still
MATCH, 4 re-gated and banked.
Ordering recorded so it stays the escape hatch and not the first move: adopt the TU's spelling ->
cast at the use site -> alias. An alias is a readability debt; every one in the tree carries a
comment naming the spelling it could not use.
Second instance of the §192 defect class, found by wave Y's ov_SC02_017 slate. The project's own
§37/§124 idiom spells a renamed symbol as `extern s32 gVecX __asm__("D_80126B5C");`, and sym_of's
generic branch matched `__asm__` -- an identifier followed by '(' -- before reaching the real one.
Every aliased declaration therefore collided with every other one under the name `__asm__`.
Measured cost on one slate: 1 byte-verified draft DROPPED and 2 phantom CONFLICTING-EXTERN
failures, on an idiom this same session used to RECOVER work.
NC over src/ plus wave Y's drafts: 1,210 changed verdicts, every one `__asm__` -> the real alias
identifier (899 of them one symbol, aD800B9A02 -- the idiom is fleet-wide), 0 regressions.
13 agents, 63 gap reports: 7 CONFIRMED, 2 REJECTED, 56 already-covered. TWO of the seven correct
laws banked EARLIER THE SAME SESSION, from two independent readers -- the adversarial-verifier
design earning its cost.
§189-A (banked this morning) claimed an interloper between a split constant's lui/ori PROVES the
target wrote two source steps, because the halves are LUID-adjacent and "no statement order and no
pin can put a third constant between them". Byte-refuted four ways: the banked one-statement slice
`prim.col[1] = 0x101010;` compiles with SEVEN insns between its lui and ori; the two-step spelling
§189-A prescribes is BYTE-IDENTICAL (the fix is inert); moving an unrelated statement moves a third
constant in and out of the gap; and one separated pair is 0x88888889 -- gcc's synthesized reciprocal
magic for a `/ 0x3C`, a constant with NO source spelling, making "the target wrote two steps"
unsatisfiable. rank_for_schedule tests INSN_PRIORITY FIRST (sched.c:2395) and reaches the LUID
tie-break only at :2428, so the derivation dropped its equal-priority scope; the real separator is
the BIRTHING BOOST (birthing_insn_p, gated reg_n_sets == 1), which the split pair can never have
because try_split gives its pseudo two sets. Verified off cc1's own -dS dump, which also corrects
the submitting reader: sched1 is a BACKWARD list scheduler, so it is the LUI that sinks, not the ORI.
8 separated pairs across 5 functions in 3 binaries. §189-A's split-TIMING half survives and now
carries a correction banner.
Recovery note: this run was killed by the session usage limit with 3 verifiers outstanding;
resumeFromRunId replayed 10 cached agents and re-ran 3 for 398k tokens vs the original 1.31M.