Commit Graph

3629 Commits

Author SHA1 Message Date
Drew T 2cedd19aaa fix(symfix): key the slate by (binary, fn); §420 multi-cluster rebase banks 4 in 57s
aprop_symfix deduped its slate by BARE FUNCTION NAME, so a four-row slate for
func_8016AB6C across ov_SC03_107/ov_SC07_007/010/011 reported "1 drafts audited" - and
the three dropped rows each needed a DIFFERENT rebase, because each overlay has its own
target symbols. Same root as reloc_filter's binof and gate_lane's homonym staging: three
tools, one R48/§238 defect.

With all four visible, the structure is two uniform delta clusters of two, identical in
shape across all four overlays - one seed body's two data clusters each moving as a
block. STALE-DELTA only admits ONE cluster, so it refused all four as AMBIGUOUS. §420
records the safe generalisation (runs of constant delta, every run >= 2 members, D_
symbols only) and the verification step.

Rebased by hand under that rule, all four still MATCH at closeness 0, and the gate
banked 4/4 in 57 seconds with no drafting (commit:3629). Frontier 165, 45 banked.
2026-09-02 05:38:28 -06:00
Drew T 24d5017039 feat(decomp): parallel gate — 4 fns across 4 binaries (4 workers)
ov_SC03_107    func_8016AB6C
  ov_SC07_011    func_8016AB6C
  ov_SC07_010    func_8016AB6C
  ov_SC07_007    func_8016AB6C
2026-09-02 05:37:23 -06:00
Drew T f31f56ef17 docs(phase-31): the drafting pool emptied; the carve lane replaced it (+5, frontier 169)
Wave 3 drew 1 target - 0 left in pool. Of 174 open: 64 main, and of 110 non-main, 41
drafted this session, 68 excluded, 2 walls, ZERO undrawn. Re-probing the 68 with
jtbl_carve --probe found 17 now reporting `tail`, because tonight's jr_isolate_all
fixes changed their overlays. All 17 already had drafts; 10 scored closeness 0 with no
drafting. The gate banked 5, and they are exactly the five overlays jr-isolated tonight.

An exclude list is a snapshot of what the TOOLING could not do and goes stale the moment
the tooling improves - re-probe it after every tool fix.
2026-09-02 05:34:38 -06:00
Drew T c0e8731947 feat(decomp): parallel gate — 5 fns across 5 binaries (10 workers)
ov_SC03_010    func_8017F6C0
  ov_SC03_029    func_80186A34
  ov_SC03_013    func_801806F8
  ov_SC03_092    func_8017FE88
  ov_SC07_000    func_8017F8B8
2026-09-02 05:33:39 -06:00
Drew T 9bb43dd426 docs(phase-31): S71 gate 9 (+2, frontier 174, 36 banked); §419 density lever recorded 2026-09-02 05:19:10 -06:00
Drew T ca813cb5ab feat(decomp): parallel gate — 2 fns across 2 binaries (10 workers)
ov_SC01_000    func_8017DD04
  ov_SC03_028    func_80180B44
2026-09-02 05:18:24 -06:00
Drew T 5a39af246e docs(cookbook): §419 - when a pin is impossible, win the local-alloc density contest
Byte-proven on ov_SC01_000/func_8017DD04 (297 ins). Pinning the 0x80 constant to $7
loses its sched1 birthing boost, because $a3 and $a2 are ALSO set by the function's own
call-argument copies (reg_n_sets == 2) - a hard-register pin on an argument register is
unavailable to any function that passes arguments in it.

So win the ranking instead. local-alloc ranks by refs/live_length: 0x80 scored
13/319 = 4890 and took $6 (a pure $a2<->$a3 swap, 24 wrong). One six-input zero-byte
asm on mlo at the blk3/blk4 boundary buys 6 references, 5217 > 4890, mlo takes $6 and
0x80 falls to $7 with its boost intact. The boundary must be the one cut no hoisted
constant crosses, or you move the live lengths you are exploiting.

Measured inert: pinning mlo to $6 (cse never substitutes a hard reg for a bitfield
constant), and a dead hard-reg copy as a register suggestion (flow deletes it).
2026-09-02 05:12:40 -06:00
Drew T 49d1e06632 docs(phase-31): S71 gate 8 (+2, frontier 176, 34 banked); two proven walls recorded
Two functions recorded as walls with their refutation lists rather than redrafted:
ov_SC03_105/func_801834A4 (loop.c movable ordering, closeness 6) and
ov_SC06_022/func_8017DF28 (expand_block_move's copy_addr_to_reg pseudo reused by cse,
closeness 2, seven levers measured inert). One MATCH blocked purely on carve state with
its exact prescription queued in .run/S71_carve_todo.txt.
2026-09-02 05:02:09 -06:00
Drew T e1f6c5cdd9 feat(decomp): parallel gate — 2 fns across 2 binaries (10 workers)
ov_SC04_016    func_8017DF8C
  ov_SC07_006    func_80183374
2026-09-02 05:01:22 -06:00
Drew T 16c4fc75e1 docs(cookbook): §418 - second index as a GIV, and keeping a table address unfolded
Byte-proven on ov_SC04_016/func_8017DF8C (184 ins, 32 -> 0 in seven compiles).

1. Writing the stride as `off = j * 0x50` (a giv of biv j) rather than a second biv
   fixes 14 preheader rows and 8 latch rows at once: loop.c chains givs LIFO
   (loop.c:4421), so with `j = 0` spelled first the `move $s0,$zero` emits last and the
   arg-3 giv lands in its natural record slot. When the PREHEADER ORDER is wrong, check
   which variables are bivs and which are givs before touching anything else.

2. To emit la + addu + lh 0(reg) instead of a folded %hi/%lo(sym+K), hoist the table
   pointer to a function-scope local set ONCE outside both loops. No LOG_LINK crosses
   basic blocks so combine cannot fold it, and with every $s taken reload rematerialises
   it from reg_equiv_constant at the use and deletes the init - so the hoist is free.
   Spell the sum `idx + (s32)tbl`; the reverse costs one operand swap.

Measured inert here: §328's volatile cast on a reg+sym address.
2026-09-02 04:53:00 -06:00
Drew T 8709798738 docs(phase-31): S71 gate 7 (+3, frontier 178, 32 banked) + the measured blocker census
Blocker census read off the 37 gate verdicts on disk: DIFF 18, CARVE 7, PARSE 3,
NO-DIAG 3, CONFLICT 2, ARITY 2, UNDEF 2. I had called carve the dominant remaining
class mid-session on the strength of the last two agents I'd read; it is not. What
remains is mostly genuine codegen, the opposite of the integration-dominated picture
this session opened with.

Also recorded rather than redrafted: ov_SC03_105/func_801834A4 as a proven loop.c
movable-ordering wall (closeness 6, two measured-inert levers), and
ov_SC01_004/func_8017EB30 as MATCH-279/279 blocked purely on §8e carve state.
2026-09-02 04:46:02 -06:00
Drew T 7b256d1c35 feat(decomp): parallel gate — 3 fns across 3 binaries (10 workers)
ov_SC01_009    func_8017FFD0
  ov_SC03_013    func_8017E6F4
  ov_SC07_007    func_80182184
2026-09-02 04:45:11 -06:00
Drew T 46cfd92e0b docs(cookbook): §417 - a pin blocks jump.c's select collapse; unpinning exposes cse skip-blocks
Byte-proven on ov_SC03_013/func_8017E6F4 (182 ins). A pinned select arm expands as
ior+copy (two insns), so jump.c:728's `x=b; if(c) x=a;` collapse cannot fire. Unpinning
lets it fire - and then cse_end_of_basic_block's skip_blocks path walks between the two
D_80184D2C[idx] reads and CSEs the symbol_ref into $s3. The earlier agent read that as
"unpinning costs +2" and restored the pin, which re-blocked jump.c and hid the cse
behaviour: the function plateaued for three attempts on that misattribution.

The law: when removing a lever MOVES the residual instead of shrinking it, the new
residual is a different pass. Attribute it with a pass dump before re-adding the lever.
2026-09-02 04:38:41 -06:00
Drew T 072607df7b docs(phase-31): S71 gate 6 (+4, frontier 181) and cookbook §416
Four new byte-proven levers from the overnight lane, none previously in the cookbook:
re-read the store instead of passing the value (CSE store-forwarding), (&SYM)[3] vs a
pointer local as an ADDRESSING choice, one biv with +0/+2/+4 for combine_givs, and a
local's width choosing lh vs lhu+sll/sra.

Also recorded: the same-address twin hint was false three times tonight (ov_SC06_000,
ov_SC01_080, ov_SC03_030) while the same-TU neighbour was the real fuel in every case.

Three of the night's five post-limit MATCHes recovered a body off disk rather than
re-deriving it - func_80181A60 in 2 minutes instead of 16.
2026-09-02 04:32:08 -06:00
Drew T 6d21bed9db feat(decomp): parallel gate — 4 fns across 4 binaries (10 workers)
ov_SC01_084    func_80181310
  ov_SC01_080    func_80180D54
  ov_SC03_030    func_80181A60
  ov_SC06_000    func_80183398
2026-09-02 04:31:28 -06:00
Drew T ab46791e06 docs(phase-31): S71 resumed at 04:11 after the session-limit reset
All five in-flight agents died on the 5-hour limit and returned NO-DRAFT; that is a
harness kill, not a verdict about the targets (R40), so they relaunch unchanged.
Gate 5 banked 2 (commit:3614). launch_check.py added after a stale card burned an agent.
2026-09-02 04:12:25 -06:00
Drew T 0fb99b763b feat(decomp): parallel gate — 2 fns across 2 binaries (10 workers)
ov_SC02_011    func_80182714
  ov_SC04_011    func_80180B24
2026-09-02 02:10:07 -06:00
Drew T 2f46e3e0fc docs(cookbook): §415 - a file-scope decl merges the TU's later block-scope externs into it
gcc-2.7.2 pushdecl/different_binding_level: adding a file-scope extern for a callee that
the TU also declares at BLOCK scope merges those later externs into the global, which
then conflicts with the TU's own definition - and the error names the definition, not the
decl you added. Match the TU's binding LEVEL, not just its type. Byte-proven on
ov_SC04_011/func_80180B24 (215 ins), which also needed the house __asm__ alias for a
file-scope vs block-scope D_ spelling collision.
2026-09-02 02:01:50 -06:00
Drew T 6fac2e0f35 feat(waves): refuse to launch an agent at an ALREADY-BANKED target (R43/R45)
wave_args asserts a target is open AT DRAW TIME, then the payload sits on disk while
gates run. S71 launched ov_SC01_006/func_8017F9F8 from a payload built before the gate
that banked it; the agent spent a full run to report "STALE CARD - already banked
today", with no .s left to score against. Filtering the wave-2 payload found 3 such
targets of 27.

launch_check.py re-asks the same oracle everything else uses (a bank REMOVES the
INCLUDE_ASM stub, so corpus.stubs not containing the symbol IS the bank), either for one
target or by filtering a {wave,targets} payload in place. An unreadable binary is treated
as OPEN - a tool fault is not a verdict about the subject (R40).
2026-09-02 01:59:46 -06:00
Drew T 6716100e57 docs: regenerated progress + backlog from the R22-green fleet (853/1919 = 44.45%, frontier 187) 2026-09-02 01:51:14 -06:00
Drew T 4d7c297b12 docs(phase-31): S71 CHECKPOINT — fleet R22 GREEN 213/213, honest frontier 187 (23 banked), main incident recorded 2026-09-02 01:50:33 -06:00
Drew T dff33f66d9 docs(setup): WSL memory cap lowered 48GB -> 32GB (Drew, 2026-09-02); applies on next wsl --shutdown 2026-09-02 01:49:46 -06:00
Drew T 2f72f8b20d fix(pgate): REFUSE main — an incremental main gate is a FALSE PASS, not just a false diff
S71 ran main through parallel_gate, got "11 banked", committed it, and the R22
clean-fleet verify came back 212/213. main did not compile from clean; once the two
declaration conflicts were reconciled it built and was STILL not byte-identical. All 11
were then re-gated one at a time against a clean build — 11 of 11 REJECT.

The rule was already written down in ox_campaign.gate_main_batch: "main is gated by ONE
CLEAN REBUILD of the whole EXE, never incrementally … main's extract rewrites the linker
script, so an incremental main gate returns a FALSE DIFF." parallel_gate's worker IS
gate_stage, so it inherits that — and S58 recorded the false-DIFF direction while this is
the false-PASS one, which is worse: a false diff wastes drafts, a false pass commits wrong
bytes and reads green until the next clean fleet check (R53's signature — a failed build
leaves the previous object on disk and the SHA check downstream reads it).

Now a refusal naming tools/gate_main.py, not a docstring in the callee (R43).
Cookbook §414, including the two instrument errors made while recovering.
2026-09-02 01:45:21 -06:00
Drew T 6fbdfdb361 revert(main): commit:3586's 11 banks — main did not build from clean, and was not byte-identical
The R22 clean-fleet verify came back 212/213. The failure is main, and `git log -L` puts
all four conflicting declaration lines in commit:3586 — this session's own main re-gate:

  src/800.c:24519  extern int  func_8004355C(s32, void *);   vs :24396 (s32, u8 *)
  src/800.c:26395  extern void func_80038FFC();              vs the s32 definition below

Reconciling both declarations (byte-neutral, §376) made main COMPILE, and it was then
still not byte-identical — so the commit was wrong on both counts, not merely unbuildable.
The gate reported "11 banked" against a tree that cannot compile from clean.

src/800.c restored to commit:3586^; `make extract BINARY=main && make build BINARY=main`
now gives sha1 143dbb89f34491258bbc27810d0a12ec8b43a8dd BYTE-IDENTICAL. The 11 bodies are
kept at .run/S71_main_suspect/800.c.banked11 for a per-function re-gate — this revert is
about restoring a green fleet, not a verdict on every one of them.
2026-09-02 01:41:34 -06:00
Drew T 2814d385ac feat(waves): journal_notes also reads a project-local note file
A stopped agent produces no journal row, so the next agent on that function learns
nothing — including that a scratch directory full of compiled candidates and their
match_one scores is sitting on disk. .run/journal_notes_local.jsonl is the same row
shape read through the same code path, so hand-recorded evidence reaches the pack
exactly as an agent's own note does.

Used immediately: six S71 agents that ran past 36 minutes were stopped to free their
slots; each now has a local note naming its scratch dir and stating that a stop is NOT
evidence of difficulty. All six are back in the draw pool and will draw at the Fable
tier per §413.
2026-09-02 01:33:21 -06:00
Drew T 0e4c98dc97 docs(phase-31): S71 gate cycle 4 — frontier 210 -> 176, 34 banked; residual-class routing + the R48 name-key exposure 2026-09-02 01:31:57 -06:00
Drew T 27cc083de9 feat(decomp): parallel gate — 5 fns across 5 binaries (12 workers)
md_MAIN_028    func_800CB8A0
  md_MAIN_003    func_800D24D0
  ov_SC01_006    func_8017F9F8
  ov_SC07_000    func_8017F69C
  ov_SC07_002    func_8017FCA8
2026-09-02 01:31:10 -06:00
Drew T bfea4affd8 feat(draw): route the model tier off the prior RESIDUAL CLASS, not nins
Measured on S71's own wave: wall-clock tracks iteration count, and iteration count
tracks the residual class, not size. A 26-instruction function took 18 min / 31 tool
calls (regalloc, finished NEAR); a 122-instruction one took 80 s / 10. The 20-33 min
runs were all compiler-internal residuals — scheduling ties, birthing boost, register
colouring, LUID order — where every hypothesis costs a compile-and-measure cycle.

arm_for keys on nins alone, so a 47-instruction regalloc wall could not be drawn at
the higher tier and nothing escalates mid-run. arm_from_history() now reads the
function's own journal notes at draw time and returns fable when they name one of
those classes; it never downgrades the size ladder's choice.
R39 control over 3,147 functions with history x 3 bands = 9,441 decisions:
4,020 upgrades (43%), 0 downgrades.

The control's FIRST form passed over an empty set — it keyed on journal rows carrying
a binary, and there are none: the agent verdict schema never had that field, so every
historical note is name-keyed and the same name is a different function in another
overlay (§238). claude_wave_draft.js's VERDICT now requires `binary`, so new rows are
exact. Cookbook §413.
2026-09-02 01:29:59 -06:00
Drew T fecbfac5f8 docs(phase-31): §412 — §323 carve blocker 2 was a regex blind to __attribute__; 5 of 6 carve overlays cleared 2026-09-02 01:25:56 -06:00
Drew T 7bcb3e51ec feat(carve): §323 blocker 2 cleared — jr-isolate ov_SC03_029 for func_80186A34, byte-identical
The type-name scan matched `}\s*(\w+)\s*;`, which reads `__attribute__` as the name
and fails on the following `((` — so a packed file-local typedef never entered the
carried set, every decl naming it read as an unknown type, and the isolate refused the
whole overlay. Stripping attributes before the scan is the entire fix.
2026-09-02 01:25:06 -06:00
Drew T 93bfa45561 feat(carve): §323 blocker 2 cleared — jr-isolate ov_SC07_000 for func_8017F8B8, byte-identical
The type-name scan matched `}\s*(\w+)\s*;`, which reads `__attribute__` as the name
and fails on the following `((` — so a packed file-local typedef never entered the
carried set, every decl naming it read as an unknown type, and the isolate refused the
whole overlay. Stripping attributes before the scan is the entire fix.
2026-09-02 01:24:53 -06:00
Drew T ad0d883810 feat(carve): jr-isolate ov_SC03_092 for func_8017FE88 — byte-identical, carve refusal cleared 2026-09-02 01:21:49 -06:00
Drew T f0512ff9ee feat(carve): jr-isolate ov_SC03_013 for func_801806F8 — byte-identical, carve refusal cleared 2026-09-02 01:21:36 -06:00
Drew T 49c41094a6 feat(carve): jr_isolate_all places file-local statics — ov_SC03_010's carve refusal cleared
The CARVE-REFUSED class (10 of the frontier's gate failures) has one dominant cause:
"subseg <ov>_jr_<addr> would host NON-CONTIGUOUS .rodata carves", whose named remedy
is jr_isolate_all. The isolate itself then refused 4 of the 6 affected overlays over a
file-local `static inline` helper (bandsetup, setup_80188D90) that has no address BY
CONSTRUCTION — §82.1 helpers exist to shape their caller's code and emit no symbol.

* jr_isolate_all now places such a definition with the ONE region that uses it, and
  refuses loudly if two regions do (two copies of a used static is a byte change, R43).
* overlay_src_split._proto_from_lines no longer prefixes `extern` to a declaration that
  already has a storage class — `extern static inline void f(...)` is "multiple storage
  classes" to cc1. The two changes are inseparable: placing statics is what first made
  the tool emit a prototype for one.

Byte-gated on ov_SC03_010: extract + build rc=0,
sha1 cacaf7c2c08037e6934f9d02c0ae5d7c78cf2463 BYTE-IDENTICAL. jtbl_carve --probe then
moves from `plan-refused` to `tail — standard §8a carve at gate time`.
2026-09-02 01:20:44 -06:00
Drew T 6c4391abb9 docs(phase-31): S71 gate cycle 3 — 29 banked; journal-notes made permanent; jr_isolate_all unblocked 2026-09-02 01:17:47 -06:00
Drew T 8f87334399 docs(setup): WSL2 memory reclaim — autoMemoryReclaim=gradual + the interim cache dropper
Task Manager showed WSL holding 30 GB while Linux was using 4 GB and ~22 GB was
reclaimable page cache (a gate wave reads the 450 MB asm/ tree plus every build
object). .wslconfig had a memory cap but no reclaim policy, so WSL2 never handed
freed pages back to Windows. Added autoMemoryReclaim=gradual (needs wsl --shutdown),
recorded the no-restart manual reclaim, and .run/memkeeper.sh as the interim
automatic form. R21.
2026-09-02 01:17:25 -06:00
Drew T 2064b5beee feat(decomp): parallel gate — 6 fns across 5 binaries (12 workers)
ov_SC04_015    func_8017EB78
  ov_SC05_008    func_8017E464
  ov_SC06_032    func_80185F4C
  ov_SC06_029    func_8017EF34 func_80185D44
  ov_SC07_010    func_80180E68
2026-09-02 01:17:20 -06:00
Drew T 02e1b3a7e6 feat(waves): every pack now carries that function's own PAST-ATTEMPT history
tools/journal_notes.py mines the agent journals per (binary, fn) and appends a
PAST ATTEMPTS section to the pack; claude_wave_packs.py calls it automatically, so
it is the default rather than a step to remember. Idempotent, and R48-safe (a note
stamped with a different binary is never served — §238 homonyms).

Measured before adopting (S71 wave 1, 50 one-agent workflows over the 210-function
real frontier where every target had already refused an earlier wave):
  * 38/39 MATCH at closeness 0 (97.4%) vs S70's 124/131 (94.7%) on an EASIER pool
  * 29/39 agents cite a prior attempt as what they used
  * 4/39 banked by RECOVERING a body that already matched, from a path a note named
  * 11/39 matched on the first compile

The two costs it removes are re-testing a measured-inert lever (§406 lists twelve,
§407 fifteen, §410 four — each paid for by an agent and never seen again) and
re-deriving a body that already exists on disk.

Also: jr_isolate_all places file-local `static` definitions with the region that uses
them instead of refusing the whole file. A `static inline` helper (§82.1) has no
address by construction, which is not a defect; the R32 guard was refusing these and
blocking the isolate on 4 of the 6 overlays whose CARVE-REFUSED functions it is the
named remedy for. Two regions using one static is still a hard refusal (duplicating a
used static is a byte change, R43).

docs: cookbook §411, wave-playbook step 3b, accelerators entry.
2026-09-02 01:11:52 -06:00
Drew T 89c3cf831b docs(phase-31): S71 wave 1 — journal-fuelled packs, 100% first-pass MATCH; cookbook 1078
* Every pack carried PAST ATTEMPTS ON THIS EXACT FUNCTION, mined per-function from the
  historical agent journals (52 of 60 targets, 131 notes). Every landed agent returned
  MATCH at closeness 0 on the hardest frontier we have.
* §409 — the wave and the nine laws it produced. Law 1: a relocation-stream
  TRANSPOSITION is invisible to match_one, the permuter scorer and every similarity
  tier (HI16/LO16 masking; the §195-D blind spot for a different reloc class), and it
  retroactively explains "MATCH but the gate rejected it" verdicts.
* §410 — COPY THEN ACCUMULATE ON THE COPY: satisfies the $s2 in-place destination and
  the sched1 birthing boost at once, with the agent's measured refutation list.
2026-09-02 01:04:27 -06:00
Drew T c97ccee98d feat(decomp): parallel gate — 9 fns across 7 binaries (12 workers)
ov_SC02_005    func_80180610
  md_MAIN_003    func_800D0B1C
  ov_SC01_005    func_8017F9F8
  ov_SC03_105    func_801829CC func_80182BD8 func_80182DCC
  ov_SC04_011    func_8018FE20
  ov_SC05_010    func_80183098
  ov_SC06_010    func_8017FAAC
2026-09-02 01:04:04 -06:00
Drew T e76f82e31f feat(decomp): parallel gate — 2 fns across 2 binaries (11 workers)
ov_SC03_007    func_8018611C
  ov_SC01_009    func_80182438
2026-09-02 00:55:11 -06:00
Drew T 137c418bc7 docs(phase-31): S71 — the 64 standalone matches priced honestly; 12 banked, 52 in four named lanes
* gate 1 (all 64 across 33 binaries): 12 banked — main 11 + ov_SC07_006 1.
* gate 2 tested "a bad draft kills its binary's good ones" by re-staging only the 25
  that recover_integration --probe-only called MATCH in their real TU: 0 banked.
  An honest null — that probe compiles and diffs bytes but never LINKS or CARVES,
  so it is a third oracle with its own blind spot.
* triage (25/25 accounted): CARVE-REFUSED 10, undefined-reference 4, DIFF 3,
  CC1-FAIL-no-diagnostic 2, PARSE 1; gate 1 adds 7 func-decl / 4 data-decl /
  6 type-decl conflicts.
* R37 probe of the carve class: 6 of 8 are one refusal — a subseg would host
  NON-CONTIGUOUS .rodata carves — whose named remedy is jr_isolate_all (§8b).

tools/restage_matching.py — rebuild a gate plan from probe verdicts.
tools/gate_triage.py — route a gate's verdicts to the lane each one names (R47).
2026-09-02 00:39:18 -06:00
Drew T 8cf0104386 fix(cards): defect 5 — an expired BASELINE-RED claim, without discarding any measurement
The S70 patch was refused by its own adversarial review for sorting rows by recency:
a pair's ledger rows are several PROBES about one draft, alternating between
`closeness 4` and `won't compile standalone`, so max(ts) serves whichever probe ran
last — often the least informative. This form keeps both.

* the ts-newest verdict is still selected (file order made the per-binary bulk ledger
  always win regardless of age: 25 pairs mis-selected),
* AND the best measurement ever taken on the pair rides alongside it, so a later
  uninformative probe can no longer erase an earlier residual: 981 of 2,605 pairs
  gain a line they were previously denied.
* BASELINE-RED is a fact about a binary at a moment (R51), frozen into an append-only
  ledger and replayed forever — 2,676 rows all stamped 2026-08-26. gate_feedback now
  reads the same live red union gate_stage consults, so a pack and the next gate run
  cannot disagree: 173 expired claims retired, 0 binaries currently red.

R39 control 3/3 (expired-when-green, harness-line-when-red, measurement-survives).
2026-09-02 00:32:20 -06:00
Drew T 13a16a15c6 fix(pgate): the merge scope missed main entirely — 11 byte-proven banks were dropped silently
* `git status --porcelain -- src/<binary>/` finds nothing for main, whose TUs are
  src/800.c, src/boot.c, ... — so a main worker returned `files: {}` while the bank
  oracle (the stub disappeared) still counted the banks. parallel_gate printed
  "12 banked across 2 binaries" and committed one of them.
* src_scope() takes the scope from the binary's own stub rows (each names its TU),
  captured BEFORE the gate because a bank deletes the stub that names it, and keeps
  the directory prefix for overlays that have one.
  Negative control: main 0 -> 54 TUs, ov_SC07_006 1 -> 3 (superset, no regression).
* A reused worktree kept the previous job's .run/harvest_failed*.classified.txt, so
  verdicts surfaced under the wrong binary; the worker clears them first.
* tools/gate_triage.py — routes a gate's verdicts to the repair lane each names (R47),
  with the staged-draft denominator asserted (R32/R41).

Re-gated main: 11 banked (commit:3586), main real frontier 64 -> 53.
2026-09-02 00:27:52 -06:00
Drew T 588208d50f feat(decomp): parallel gate — 11 fns across 1 binaries (1 workers)
main           func_8001A114 func_8001AAD0 func_8001AF34 func_8002EED8 func_8002F248 func_800316F8 func_80031988 func_8003602C func_80036260 func_80038FFC func_80039C70
2026-09-02 00:27:07 -06:00
Drew T 23ffa6082f feat(decomp): parallel gate — 12 fns across 2 binaries (12 workers)
main           func_8001A114 func_8001AAD0 func_8001AF34 func_8002EED8 func_8002F248 func_800316F8 func_80031988 func_8003602C func_80036260 func_80038FFC func_80039C70
  ov_SC07_006    func_8016AB6C
2026-09-02 00:23:34 -06:00
Drew T 698f2959ae fix(campaign): R48 — reloc_filter resolves a draft's binary per-draft, not by bare name
* `binof = {c["fn"]: c["binary"]}` was last-writer-wins, and `status`, `det` and `subof`
  had the same shape — a draft of a name carried by two binaries was stamped with
  whichever card came last and then reloc-checked against the OTHER binary's symbols.
* Resolve per draft instead: the shard's own target list first
  (`.run/wave_<tag>_targets.<i>.json` = `targets[i::workers]`, each row carrying its
  binary), a unique-name card second, a counted refusal when neither can answer (R43).
* R39 negative control over every historical wave: 42,655 drafts, 0 regressions,
  2,317 (5.4%) previously mis-stamped; 2,107 homonym card names fleet-wide.
  Intra-shard ambiguity: 0 of 50,684 (shard, name) pairs over 302,370 shard files.

docs: §408 — §406 refuted as a sweep (0 MATCH / 14 applied, 0 / 210). The 134-member
census counted main's 960 LINKED library stubs and matched a symmetric SHAPE; derived
from the mine-vs-target residual the addressable set is 15 / 210. Decision-log entry
records the pivot: 64 of 210 (30.5%) already match standalone, so the frontier's
largest lane is §376 integration, not codegen.

tools/weave_sweep.py — the derived-selector sweep (R32 coverage, R41 denominators,
--lever-all ablation control).
2026-09-02 00:19:59 -06:00
Drew T da3bb36c56 docs(phase-31): S70 FINAL-5 — fresh-session checkpoint, §406 sweep first; 145 banked (355->210), R22 green, cookbook 1074 2026-09-01 23:56:13 -06:00
Drew T a1e8c59640 docs(phase-31): card defect 4 shipped, defect 5 refused by adversarial review (would have suppressed 159 real verdicts) 2026-09-01 23:44:56 -06:00
Drew T e532033c5e fix(cards): the SYMBOL MISMATCHES block gated on shape, not aligned — served void advice
gate_feedback selected the newest reloc_rejects row with shape=='MATCH' and printed
its mismatches under "your instruction stream already matched; ONLY these names were
wrong". But reloc_identity's binding condition is `aligned` (shape=='MATCH' AND equal
relocation-stream lengths); when that fails it downgrades status to "MISMATCH?" and
stamps the row ADVISORY. Gating on `shape` alone therefore republished ADVISORY rows
as binding per-index instructions — and when the streams are not index-aligned, draft
index i is compared to target index i of a DIFFERENT stream, so every "the target
references 0x..." line is arithmetic on the wrong word.

MEASURED (agent-run, not predicted):
  * 15 of 130 S70 targets were served this block; 15 of 15 were aligned=False, i.e.
    100% carried reloc_identity's own "verdicts are ADVISORY" caveat while the pack
    text told the agent the opposite.
  * 55 of the 66 printed lines (83%) name a value that is not an address at all
    (0x82020084, 0x880801C0, ...).
  * Of the 4 whose .s is on disk, 4 of 4 named symbols the target never relocates.
  * Whole index: 182 servable (binary, fn) rows, 149 aligned=False; 140 of those 149
    print >=1 non-address vs 1 of the 33 aligned=True.
This reproduces both S70 agent reports verbatim (ov_SC02_035:func_8017D3F4 "cross-
overlay contamination"; ov_SC06_020:func_8017D918 "those symbols are absent from
this .s").

Root cause has a second half, still OPEN upstream: ox_campaign.reloc_filter stamps the
row's binary from `binof = {c["fn"]: c["binary"]}` — a BARE-NAME dict (R48). Wave `el`
carried 44 names in >=2 binaries, so func_8017D918's row was stamped ov_SC06_020 while
the draft it checked belonged to ov_SC01_074. A correct read key cannot repair a wrong
write-side stamp, which is why the fix validates against the TARGET'S OWN bytes.

Adversarially reviewed (sound=True) and controlled here: the known-true aligned=True
case ov_SC07_011:func_8016AB6C is STILL SERVED; ov_SC02_035:func_8017D3F4 is withheld
with a loud reason. The reviewer's own first attempt validated draft_symbol against the
.s and rejected that good block — a false positive caught only by a known-true case.
2026-09-01 23:44:37 -06:00