Commit Graph

2909 Commits

Author SHA1 Message Date
Drew T eebe792a0b feat(decomp): ox wave eh overlays — 129 banked
Committed before the main batch: gate_main reverts on failure and would take these with it.
2026-08-25 17:10:42 -06:00
Drew T f0450910dd feat(decomp): ox wave ee overlays — 4 banked
Committed before the main batch: gate_main reverts on failure and would take these with it.
2026-08-25 16:37:01 -06:00
Drew T fe97918979 feat(decomp): free A-prop sibling lane (maintenance pass) — zero model tokens 2026-08-25 16:26:03 -06:00
Drew T 84706c9860 feat(draw): draft EVERY instance, siblings included (ONE_PER_GID=0) + K attempts per card
Two ways to spend a free drafting window on a tail that is 92% walls.

ONE_PER_GID=0 — the sibling collapse exists because a same-gid sibling banks by mechanical
remap once its exemplar cracks, so drafting it pays for what the remap does free. That prices
AGENT TOKENS as the scarce resource. On the free ox window they are not, and the collapse is
what makes 3,271 open crackable functions look like 334 drawable skeletons — of which 308 are
gen6+ walls whose exemplars have already refused six waves each. A sibling drafted directly
can crack on its OWN terms instead of waiting on an exemplar that never will.

Measured on a live draw rather than argued:
    uncollapsed  627 cards / 44,403 ins / 160 binaries / 215 gate groups = 2.9 drafts per rebuild
    collapsed    334 cards / 30,926 ins / 104 binaries / 127 gate groups = 2.6 drafts per rebuild
The gate cost is per (binary, TU) group and chunked, so siblings landing in binaries the wave
already touches are close to free at the gate — the card count nearly doubles and the gate gets
MORE efficient per build, not less.

ATTEMPTS=K — K independent shots at each card. The gate cost does not multiply: reloc_filter
keys by fn and staging writes <binary>/<fn>.c, so a function still gets exactly one whole-binary
build per wave; the attempts compete to BE that build, ranked by match_one, which is local and
needs no build. Alternates stay on disk for a later recovery pass. Default 1 (no-op).

A BUG I CAUGHT IN MY OWN SELECTOR before it shipped: it passed binof[fn] (a BINARY NAME) where
match_one wants --asm-subdir (an asm DIRECTORY). Every attempt would have scored identically at
infinity and the picker would have silently degraded to first-seen while appearing to rank —
the same "true number about the wrong thing" class as the day's other defects. Fixed with a
subof map, and a missing subdir now returns neutral instead of a fake score.
2026-08-25 16:18:43 -06:00
Drew T 78047a0fc8 chore(decomp): commit in-tree banked work before the next gate
Uncommitted src/ changes found at gate entry. These are banked functions from a lane that gates with commit=False, not residue — preserved, not reverted. Top-level src/*.c (main TUs) are excluded by construction (S59).
2026-08-25 16:18:37 -06:00
Drew T 2b3a2674cf feat(decomp): ox wave ec overlays — 10 banked
Committed before the main batch: gate_main reverts on failure and would take these with it.
2026-08-25 16:18:25 -06:00
Drew T 274932d209 chore(decomp): commit in-tree banked work before the serial lane 2026-08-25 16:06:04 -06:00
Drew T 2c3201b2fd feat(decomp): ox wave eb overlays — 5 banked
Committed before the main batch: gate_main reverts on failure and would take these with it.
2026-08-25 16:00:57 -06:00
Drew T b604fc1e4e feat(decomp): ox wave dy overlays — 12 banked
Committed before the main batch: gate_main reverts on failure and would take these with it.
2026-08-25 15:50:19 -06:00
Drew T bd50b9191c chore(decomp): commit in-tree banked work before the serial lane 2026-08-25 15:42:21 -06:00
Drew T 201015c0d1 feat(decomp): ox wave dx overlays — 21 banked
Committed before the main batch: gate_main reverts on failure and would take these with it.
2026-08-25 15:38:29 -06:00
Drew T 9e45486282 docs(phase-31): S60 checkpoint — five harness defects, the registry rescue, and the endgame reframed
1,947 banked today. Throughput went 65 -> 341 req/min peak and gates 63 -> 39 min, all by
removing harness defects rather than changing models. The registry incident (config/overlays.mk
committed EMPTY, taking main and every overlay gate down) is written up with its blast radius
and the config_sane guard that now prevents it.

The strategic finding is the part that matters for planning: 3,652 open crackable functions
collapse to 334 DRAWABLE skeletons, of which 308 are gen6+ walls — the ~2,900 untouched
functions sit behind those skeletons and bank by mechanical remap, not by drafting. Wide
drafting now converts at 5%. main is 327 crackable, not 1,288.

Four rule candidates for PhaseEnd (R51-R54), each earned by a defect that fired today.
2026-08-25 15:34:50 -06:00
Drew T 7d4c717cae feat(decomp): serial idiom lane — func_8017D1C0 (118 ins, extend-tell, group worth 681) 2026-08-25 15:29:06 -06:00
Drew T 9d6a748387 feat(decomp): ox wave du overlays — 3 banked
Committed before the main batch: gate_main reverts on failure and would take these with it.
2026-08-25 15:23:00 -06:00
Drew T 3b90d2db39 feat(decomp): main lane m40bba — 1 banked
One clean whole-EXE rebuild verified the batch (gate_main), and main re-checked
BYTE-IDENTICAL against config/check.us.sha before anything was credited.

  SYS_OBJ_21A4
2026-08-25 15:22:34 -06:00
Drew T 389c0c1065 feat(decomp): main lane m40a — 3 banked
One clean whole-EXE rebuild verified the batch (gate_main), and main re-checked
BYTE-IDENTICAL against config/check.us.sha before anything was credited.

  func_80028EF0
  func_80031CC8
  func_8005D118
2026-08-25 15:20:38 -06:00
Drew T 317d31d18a feat(decomp): ox wave dw overlays — 33 banked
Committed before the main batch: gate_main reverts on failure and would take these with it.
2026-08-25 15:04:19 -06:00
Drew T 849020a536 chore(decomp): commit in-tree banked work before the next gate
Uncommitted src/ changes found at gate entry. These are banked functions from a lane that gates with commit=False, not residue — preserved, not reverted. Top-level src/*.c (main TUs) are excluded by construction (S59).
2026-08-25 15:02:44 -06:00
Drew T 09b7f71a19 fix(serial lane): it was dead at turn 0 — a family-card file fed to a per-function consumer
idiom_serial passed `--cards .run/aprop_cards.json` to api_agent. That file is a FAMILY-card
file — rows are {family, members, seed, cls, reach}, with no per-function key — while
api_agent's --cards wants per-function wave cards and built its map with `c['fn']`. Result:
KeyError at line 647, the agent died before its first turn, and every target logged
"no-draft". The lane read as a model failure; its ledger holds 8 rows total and the tells
lane had, literally, "never yet run".

TWO FIXES, one on each side of the contract:

  * api_agent REFUSES, never crashes (R43). It accepts 'fn' or 'name', skips rows with
    neither, and says how many it skipped. The R32 warning two lines below — "ZERO matched —
    wrong card file?" — existed to catch exactly this and was unreachable behind the crash. A
    guard downstream of the failure is not a guard.
  * idiom_serial passes no --cards at all. Its fuel is the --brief: the target plus every
    idiom distilled so far in the run, which IS the compounding channel the 2,000-way fan-out
    lacks. It never needed a wave card.

Verified: the lane now reaches `api_agent: stealth/ox-alpha -> 1 target(s), max 60 turns` and
drafts, instead of exiting in 0.1 s.
2026-08-25 15:00:31 -06:00
Drew T 0a2bc5c7f7 feat(decomp): ox wave dm overlays — 3 banked
Committed before the main batch: gate_main reverts on failure and would take these with it.
2026-08-25 15:00:06 -06:00
Drew T ade4bd0bbe chore(decomp): commit in-tree banked work before the serial lane 2026-08-25 14:59:09 -06:00
Drew T ebb83dd9ab chore(decomp): commit in-tree banked work before the serial lane 2026-08-25 14:57:13 -06:00
Drew T b0587c573e fix(idiom_serial): main is never a target, and a contended index is not a dirty tree
The serial lane's first-ever run on tells died 0 seconds in, on both counts:

  [1/6] func_8017D1C0 @ ov_SC06_027 · 118 ins  -> drafting
  [2/6] func_8001382C @ main · 103 ins         -> could not commit — refusing on a dirty tree

MAIN IS NOT A SERIAL-LANE TARGET. main gates through gate_main on the main lane's own cadence
(a clean whole-EXE rebuild with bisection), so this lane cannot bank it however good the draft
is — a main target burns a slot to learn that. md_* was already excluded for jtbl; main never
was, because the lane predates main being in the atlas at all.

A CONTENDED INDEX IS NOT A DIRTY TREE. Six campaign lanes plus the re-gate runner commit
continuously, so `git commit` here loses the index.lock race routinely — twice today it was a
STALE lock blocking every lane for 8 and 21 minutes. The lane refused over a tree that was
fine. It now retries the commit six times at 5 s before concluding, and the refusal is
reserved for FOREIGN DIRT it must not adopt — which is the property that rule was protecting.

Verified: pick_targets('extend-tell', 8, 80) now returns 8 overlay targets, no main.

Also in this commit: MAX_BINS 160 -> 50 in the drafter shell. Wave size was the right lever at
50% conversion (dd: 217 banked of 422 gated in 39 min); at 5% it is dead weight — dq banked 8
of 167 gated and took 98 MINUTES, while four drafted waves queued and the free-ox fleet sat at
14 agents / 10 req/min. At this conversion a 150-card wave banks what a 430-card wave banks,
in a third of the gate.
2026-08-25 14:57:13 -06:00
Drew T a372b648ef chore(decomp): commit in-tree banked work before the next gate
Uncommitted src/ changes found at gate entry. These are banked functions from a lane that gates with commit=False, not residue — preserved, not reverted. Top-level src/*.c (main TUs) are excluded by construction (S59).
2026-08-25 14:51:13 -06:00
Drew T 04bb99d370 feat(decomp): ox wave dq overlays — 8 banked
Committed before the main batch: gate_main reverts on failure and would take these with it.
2026-08-25 14:50:48 -06:00
Drew T 98085269b1 docs(cookbook): §278-§282 — wave cf distilled, 4 new laws from the post-429-fix wave
34 candidates: 13 COVERED · 8 ADDENDUM · 4 NEW · 9 REJECT.

  §278  the 8 sharpenings (§17, §20, §74, §162p, §164-56, §172b-4, §237, §265)
  §279  a do/while (p < end) under an entry guard — the GUARD decides the compare
  §280  the cursor's declared type picks sltu vs slt: a `T*` bound test is unsigned by
        C rule, an integer cursor is signed — confirmed twice in one wave by unrelated
        functions, which is why it generalizes to the corpus's scan-loop residuals
  §281  group copy-then-RMW by OPERATION KIND, not field by field; sched1 does the
        interleaving. §213 explicitly disclaimed this shared-pseudo case — a named gap now filled
  §282  gcc's own loop reversal places the reversed counter's init AFTER the hoisted
        movables, a position no hand-written down-count loop can reach — resolves a class of
        "prologue order" residuals that looked unfixable from the C side

VERIFICATION, both directions (R14/G3). Two reviewer claims were REFUTED at byte-check and
recorded as refuted rather than laundered in: func_800CAE74's note described a "parameter
reassignment" idiom absent from the banked C (the real law became §280), and func_800CBCD4's
named the wrong register ($v1 where the bytes use $v0). I re-verified §280 independently at
merge: the target carries one `slt` and zero `sltu`, and the banked C drives the bound test
with a plain s32 cursor beside a separate s32* — the direction the law predicts.

Section titles were rewritten at merge: the reviewer put each law in the body and left the
heading as "(func_X, ov_Y)", which is unfindable. A section is written to be GREPPED, so the
title states the law.

Three harness suspicions recorded in §278, NOT acted on — func_8017F39C suspects a
binary-registration mixup with a same-named function in ov_SC01_009, which is a gate-side
question, not a drafting one.

Index: 824 sections. Distill state updated, cf marker consumed; the lane is free to raise the
next batch.
2026-08-25 14:42:01 -06:00
Drew T 9b407f5441 feat(decomp): main lane m37a — 1 banked
One clean whole-EXE rebuild verified the batch (gate_main), and main re-checked
BYTE-IDENTICAL against config/check.us.sha before anything was credited.

  func_80028F78
2026-08-25 14:37:29 -06:00
Drew T f96ad0bd6d chore(decomp): commit in-tree banked work before the serial lane 2026-08-25 14:35:50 -06:00
Drew T 9b74262697 chore(decomp): commit in-tree banked work before the serial lane 2026-08-25 14:35:50 -06:00
Drew T e7353d63de feat(tells 6.3): put the TELL COUNTS on the card and in the prompt
A tell-lever card named a lever and then made the agent go find its sites: it said
"extend-tell" and nothing about where or how many. atlas_features already counts the
detectors per function into .run/feat.<bin>.jsonl at atlas time, so this is a JOIN, not a
computation — one dict load per binary in the wave.

build_wave_atlas attaches 'tells' {extpair, dupselect, magic_div, sign_lh, sign_lb} to every
card that has a nonzero one — not just tell-lever cards, because a sll/sra pair site or a
repeated select is worth knowing whatever lever drew the card. Measured on a live draw: 85 of
185 cards carry counts.

api_agent._fuel renders them as a CHECKLIST rather than a hint, which is the point: the
counts come from the TARGET's own bytes, so a draft emitting fewer has provably missed sites
and should go looking before spending a turn elsewhere.

Verified: a card with {extpair 3, dupselect 2, sign_lh 1} renders all three with the zero
fields omitted; NEGATIVE CONTROL — a card with no tells renders no TELLS line at all.

Takes effect on the next draw + the next shard (api_agent is spawned per draft).
2026-08-25 14:35:36 -06:00
Drew T 98f7205a3a feat(decomp): ox wave dl overlays — 12 banked
Committed before the main batch: gate_main reverts on failure and would take these with it.
2026-08-25 14:34:35 -06:00
Drew T d0da3f24f7 feat(decomp): main lane m36 — 4 banked
One clean whole-EXE rebuild verified the batch (gate_main), and main re-checked
BYTE-IDENTICAL against config/check.us.sha before anything was credited.

  SYS_OBJ_1F64
  SsGetMute
  func_80028F34
  func_80031DEC
2026-08-25 14:23:25 -06:00
Drew T 073cf446ce feat(draw): generational TOP-OFF — every wave fills from the lowest generation up
Neither extreme was right. Ignoring generations lets a card that has failed five waves
compete with one nobody has ever drafted; filtering to a single generation starved the fleet
to 46 cards. So generation becomes the PRIMARY ORDERING and the existing mass/count criterion
breaks ties, at both levels of the assembly:

  * gate groups holding never-drafted cards rank ahead of all-retry groups (before the
    --max-bins truncation, so an untouched group is never cut for a fat retry group);
  * within a group, untouched cards are taken before retries.

Wave SIZE is untouched — only the order changes — so the fleet stays full while the scarce
never-drafted work always goes out first.

Verified on a live draw: gen0 2 · gen1 2 · gen2 14 · gen3 2 · gen4 3 · gen5+ 340. It took
EVERY card below generation 5 (all 23 available) and filled the remaining 340 slots from the
5+ pile, which is the whole point.

The gen0 count is 2 because wave dw drew the last 51 untouched skeletons an hour ago. That is
the campaign's real state: essentially everything drawable has now been drafted at least
once, and ~635 distinct skeletons have refused. The remaining work is levers, not draws.
2026-08-25 14:22:59 -06:00
Drew T 70c9fc13f5 chore(decomp): commit in-tree banked work before the next gate
Uncommitted src/ changes found at gate entry. These are banked functions from a lane that gates with commit=False, not residue — preserved, not reverted. Top-level src/*.c (main TUs) are excluded by construction (S59).
2026-08-25 14:22:54 -06:00
Drew T f9e5b1d865 feat(decomp): ox wave dt overlays — 9 banked
Committed before the main batch: gate_main reverts on failure and would take these with it.
2026-08-25 14:22:29 -06:00
Drew T 7cc969ceeb feat(decomp): main lane m35bbb — 2 banked
One clean whole-EXE rebuild verified the batch (gate_main), and main re-checked
BYTE-IDENTICAL against config/check.us.sha before anything was credited.

  func_8002823C
  func_80031F14
2026-08-25 14:19:12 -06:00
Drew T 78044772d6 feat(decomp): main lane m35ba — 1 banked
One clean whole-EXE rebuild verified the batch (gate_main), and main re-checked
BYTE-IDENTICAL against config/check.us.sha before anything was credited.

  GetDispEnv
2026-08-25 14:17:39 -06:00
Drew T 607fe0b9b4 feat(decomp): main lane m35a — 2 banked
One clean whole-EXE rebuild verified the batch (gate_main), and main re-checked
BYTE-IDENTICAL against config/check.us.sha before anything was credited.

  func_80014128
  func_8001E378
2026-08-25 14:15:50 -06:00
Drew T da8794e5d6 chore(decomp): commit in-tree banked work before the next gate
Uncommitted src/ changes found at gate entry. These are banked functions from a lane that gates with commit=False, not residue — preserved, not reverted. Top-level src/*.c (main TUs) are excluded by construction (S59).
2026-08-25 14:09:45 -06:00
Drew T 0dca62485a feat(decomp): ox wave dk overlays — 15 banked
Committed before the main batch: gate_main reverts on failure and would take these with it.
2026-08-25 14:09:24 -06:00
Drew T 9687dcd8c0 feat(draw): generational pass (opt-in) — and the measurement that stopped it being default
--generational (or BFM_GENERATIONAL=1) draws ONLY the lowest generation present: no function
gets a 2nd draft while any drawable function still lacks a 1st. draw_count is derived from
the prior wave card files already being read for the already-waved filter.

MEASURED BEFORE SHIPPING, and it changed the plan. With every cap opened — no band, no
--max-bins, all levers, whole fleet minus main — generation 0 is:

    232 candidates -> 46 distinct skeletons (186 are same-gid siblings the remap banks free)

against ~681 drawable skeletons in total. So "3,926 never-drafted stubs" was three illusions
stacked: ~961 are main's LINKED PsyQ stubs and data blobs (not decomp targets at all), most of
the rest are same-gid siblings that one exemplar banks mechanically, and 2,119 were already
drawn in earlier waves. Making generational the DEFAULT starved the fleet from ~640 cards to
46 — so it is opt-in, for a priority pass over the untouched population, not standing policy.

The real shape of the endgame, stated plainly: of ~681 distinct drawable skeletons, only 46
have never been drafted. The other ~635 refused at least one draft each. That is a LEVER
problem — distillation, A-prop, the o0/jtbl carves, the permuter — not a resampling problem,
and no amount of drafting throughput addresses it.

Fired as wave dw (51 cards / 1,990 ins across 36 binaries) so the untouched population is
drafted today rather than left as a policy.
2026-08-25 14:06:36 -06:00
Drew T 2fea549c53 feat(decomp): ox wave dr overlays — 28 banked
Committed before the main batch: gate_main reverts on failure and would take these with it.
2026-08-25 13:55:25 -06:00
Drew T a5eecbbec7 chore(decomp): commit in-tree banked work before the next gate
Uncommitted src/ changes found at gate entry. These are banked functions from a lane that gates with commit=False, not residue — preserved, not reverted. Top-level src/*.c (main TUs) are excluded by construction (S59).
2026-08-25 13:24:01 -06:00
Drew T 9f4aecd7c8 feat(decomp): ox wave dp overlays — 54 banked
Committed before the main batch: gate_main reverts on failure and would take these with it.
2026-08-25 13:21:14 -06:00
Drew T 45e6963b8b chore(decomp): commit in-tree banked work before the next gate
Uncommitted src/ changes found at gate entry. These are banked functions from a lane that gates with commit=False, not residue — preserved, not reverted. Top-level src/*.c (main TUs) are excluded by construction (S59).
2026-08-25 13:07:12 -06:00
Drew T 1d3081bca4 fix(gate): refuse to commit a COLLAPSED config file, restore it from HEAD instead
The gate's dirty-tree committer swept an empty config/overlays.mk into commit:2863 and took
the whole fleet down with it. R42 says commit a dirty tree rather than revert — true for
src/, where a per-binary gate leaves PROVEN banks uncommitted and reverting destroys them.
A config file is the opposite case: it holds no proven state that exists only in the
worktree, and a collapsed one is never intended.

config_sane() runs at all three commit sites: if config/overlays.mk or config/dedup.us.yaml
has fewer than 80% of HEAD's lines, it is restored from HEAD, NOT committed, and the refusal
is logged loudly. Controls both ways — positive (min_ratio=1.5 makes the healthy registry
trip the same branch: detected, restore path runs, file intact) and negative (normal
threshold: silent, returns True). P28's registry died this way too (H5); now it is enforced
rather than remembered.
2026-08-25 13:02:36 -06:00
Drew T bca5eff072 fix(config): RESTORE config/overlays.mk — the entire 5,077-line overlay registry was empty
commit:2863 ("ox wave dk overlays — 2 banked") committed config/overlays.mk as a ZERO-LINE
file, deleting the registry that defines all 141 overlay binaries: EXE paths, VRAM bases,
ASM_DIR/SRC_DIR roots, symbol files, and every JTBL_PADS spec.

BLAST RADIUS while it was empty:
  * main could not build AT ALL. Its object glob prunes sibling binaries via
    $($(b)_ASM_DIR); with no binaries registered, every overlay's asm/<ov>/nonmatchings/*.s
    fell into MAIN's OBJS and was assembled standalone, where glabel/endlabel/nonmatching
    are undefined ("unrecognized opcode `glabel func_801831C8'").
  * the main lane found its committed baseline RED and REFUSED to draft or gate (correctly,
    R43) — 1,288 open main stubs idle behind it.
  * overlay gates collapsed: GATE do banked 0 of 236 gated, GATE dk 2 of 445 drafts.
  * every overlay left BINARIES, so check-all's fleet scope collapsed with it.

HOW IT HAPPENED — two failures, neither sufficient alone:
  1. A NON-ATOMIC WRITE. The version at commit:2863^ was ALREADY damaged: it ends with a stray
     partial line ("uto.txt") after the proper final line — one writer's tail landing after
     another's. This file is rewritten in place with no tmp+rename while lanes edit it
     concurrently (jtbl carves, o0 subsplits, pad specs).
  2. A BLANKET COMMITTER. "tree dirty at gate entry — committing it rather than reverting"
     swept the truncated file into a commit. R42 says commit rather than revert and that
     stands for src/ — but a tool cannot tell a truncated config from an intended one, and
     this is the second time that reasoning has destroyed a registry (P28's yaml.safe_dump,
     H5: never silently drop content on a rewrite).

Restored from commit:2863^ with the stray fragment removed; make parses it again. Atomic
writes and a sanity guard on the committer come next.
2026-08-25 12:59:54 -06:00
Drew T 7891069c4b feat(decomp): ox wave dk overlays — 2 banked
Committed before the main batch: gate_main reverts on failure and would take these with it.
2026-08-25 12:37:47 -06:00
Drew T c95dde87a8 feat(decomp): ox wave dl overlays — 1 banked
Committed before the main batch: gate_main reverts on failure and would take these with it.
2026-08-25 12:30:13 -06:00
Drew T 7713700d72 feat(decomp): ox wave dj overlays — 43 banked
Committed before the main batch: gate_main reverts on failure and would take these with it.
2026-08-25 12:21:43 -06:00