Commit Graph

958 Commits

Author SHA1 Message Date
Drew T 163c91e420 docs(phase-31): correct the S75 checkpoint's figures and record the one-line UNPLACED fix
Verified at close rather than asserted: 25 commits, src/config/tools clean, main
green at 143dbb89..., and HEAD genuinely carries the func_8002B0B4 C (0
INCLUDE_ASM for SaveLoadRoutine, 1 real definition). A 47-minute bisection left
several mid-run readings that looked like regressions and were not, so the
figures are now stated from a settled tree.

Adds START HERE item 0: the UNPLACED parse hole is one line --
config/symbols.us.txt:27 still declares SaveLoadRoutine = 0x8002B154 // func, so
splat keeps emitting a .s for a symbol that is now case 0: inside func_8002B0B4.
Delete, re-extract, rebuild. config/wave_exclude.txt lines 14-15 are stale for
the same reason. Left undone only because a gate held main's tree at close.

T10 checklist now carries the S75 line.
2026-09-03 12:26:26 -06:00
Drew T af4912e624 docs(phase-31): S75 FINAL checkpoint — 32 banked, nine instrument defects, the verbatim class mapped
Written for a fresh session. Headline: every codegen wall examined this session
was an instrument defect, and the two largest results came from deleting a
belief rather than writing better C -- SaveLoadRoutine's §434 wall was a splat
symbol boundary (it is case 0 of func_8002B0B4, one function on one frame), and
the '§332/§188 wall' was the reorder island, which banked 20 functions whose
drafts had been on disk since waves m04-m16.

Records what I got wrong so it is not inherited: five regex censuses
(116/112/108/178/199), contiguity mistaken for fragmentation, a build-config gap
called compiler-inexpressible, and two bursts drawn at fragments because the
triage came after the draw instead of before it.

R22 clean-fleet NOT run; the checkpoint says so at the top.
2026-09-03 12:13:02 -06:00
Drew T 8e3ce81a69 docs(phase-31): S75 addendum — the frontier is 154 game functions bigger than reported
tools/asm_in_c.py finds 199 functions that are assembly posing as C (154 game
code, 171 in main). They were in no progress.py bucket, so main's REAL% was
overstated: 45.88% -> 42.15% once counted. Nothing regressed; the denominator
was missing 173 functions of real remaining work.

Also records the counting cautionary tale (five hand counts, 116->112->108->178
->199, each wrong the same way) and the tool design that answers it. Cookbook
§448.
2026-09-03 00:02:02 -06:00
Drew T ac55da69d1 docs(phase-31): S75 checkpoint — 7 banked, seven instrument defects, SaveLoadRoutine is a carve
Full 🛑 block for a fresh session: state, the seven defects (§442-§447), the
measured frontier map, Drew's dedup decision, and the harness lessons.

The headline for whoever picks this up: SaveLoadRoutine (1,165 ins, the §434
wall, 9.2% of all remaining work) has a BYTE-IDENTICAL body and is blocked by a
jump-table carve -- which the verdict tool could not say because that verdict
class was unreachable by construction on main.

R22 clean-fleet is NOT yet run for S75 and the checkpoint says so.
2026-09-02 23:11:35 -06:00
Drew T cb948a6bbc feat(decomp): the ov_SC01 reloc-only cluster + its 5th latent victim — 5 fns, 1,301 ins
S74 handed this forward as "1,116 instructions behind one question": family_remap
on ov_SC01_004/005/006/008 gated DIFF 4/4 against the banked exemplar
ov_SC01_009:func_8017EB08, and the class had been carried as a codegen wall since
S70. The four bodies were byte-identical to the exemplar the entire time.

Word-level classification vs the exemplar, computed independently twice (a Fable
agent's script, then mine from scratch against the retail images), identical:

    nins=279   EQ 213 · RELOC-HI16 23 · RELOC-LO16 24 · INTERNAL-J 19 · CODEGEN 0

Zero register-allocation, instruction-selection or scheduling differences.

ROOT CAUSE — tools/jtbl_carve.py reserved ONE WORD TOO MANY per table:
  * spimdisasm runs an island's LAST `jtbl_` dlabel one word into the following
    NON-ZERO data (string bytes 0x696F760A / 0x000013FF / 0x62647020), so the
    zero-word trim cannot see it; and
  * the over-span clamp that would have caught it was guarded by
    `len(sltiu_bounds) == 1` -- but `sltiu` is ALSO how gcc emits an unsigned
    range check ((u32)(x-lo) < n, I1). These four carry five distinct sltiu
    immediates, so the guard silently disabled itself on precisely the functions
    that needed it.
  0x2C reserved for a 0x28 table => image 4 bytes short => ~850 %lo immediates
  shift => whole-binary DIFF about a function whose own bytes are perfect.
Fixed with a PER-TABLE bound: gcc-2.7.2's dispatch is a fixed idiom, so the
`sltiu` nearest ABOVE that table's own %hi(jtbl_X) is unambiguous whatever else
the function tests. Second defect stacked behind it: a carve span whose
JTBL_PADS line lacks a `tables=` comment lost its existing table's start on
merge and refused "table starts do not fit the span" -- which harvest_verify
then "repaired" with a needless jr_isolate_all that walked back into the first.

THE NEGATIVE CONTROL IS THE STORY. Run over every other open table-bearing stub
fleet-wide, the fixed bound changed exactly one more table: ov_SC06_022/
func_80185B80 (185 ins), a FIFTH victim nobody had drafted against. A guard that
disables itself on a common idiom does not fail once -- it fails quietly across
the whole corpus.

Banked, each with its own byte-gate verdict (--no-propagate, clean re-gate):
  func_8017EB30  ov_SC01_004  279
  func_8017F2D4  ov_SC01_005  279
  func_8017F2D4  ov_SC01_006  279
  func_8017EC68  ov_SC01_008  279
  func_80185B80  ov_SC06_022  185

Also here:
  * dedup_propagate: memoize find_site's mask (lru_cache) -- 54 ms of masking
    per call over the whole source, recomputed though it depends only on the
    text. 2x on that loop (58.3 -> 33.0 ms/call), NC identical on 120 addrs.
    Scoped honestly: that loop is ~2.4 min of a 30-min run; the profiler puts
    43% in family_remap._alias_decl_for, which is NOT fixed here.
  * Makefile: `clean` says out loud that BINARY= is ignored and it is fleet-wide
    (cookbook §445) -- it silently deleted asm/ for all 213 binaries this session.
  * Cookbook §446 (the carve law: when a standalone-MATCH jtbl draft gates DIFF,
    diff the carve extent against 4 x sltiu before touching the body), §445, and
    SETUP rows for both tools (R21).
  * CURRENT_PHASE: the S75 log, incl. the measured fleet dedup-hygiene census
    (~2,073 fns / ~12,116 items, all ALREADY MATCHED -- cleanup, not work) and
    Drew's decision to leave it and gate --no-propagate from here.
2026-09-02 22:15:20 -06:00
Drew T cdd535e45b fix(tools): reconcile_tu's cc1 premise, the &-cast arms, and the worktree sig gap
The S74 checkpoint's "one unfixed defect that is actively costing banks"
(reconcile_tu manufacturing declaration conflicts), run to ground — plus the
harness gap that produced a false carve-corruption verdict.

reconcile_tu.py — three defects, measured against the real gcc-2.7.2 front end
(cdecl._cc1_accepts, the oracle cdecl.compatible was validated with; R33):
  * The premise "a decl BELOW still conflicts" is TRUE at file scope and FALSE
    at block scope. cc1 ACCEPTS a block-scope extern against a TU decl below it
    (pedwarn "type mismatch with previous external decl"); conforming it is
    destructive, because the TU's decl names the TU's TYPE and a type declared
    below the splice point is not in scope AT it -- the emitted result gets
    "syntax error before 'D_x'". Byte-witnessed on resident:func_800D06E8 (344
    ins), whose block-scoped `extern Blk80078E78` became `extern
    Struct80078E78`, typedef 388 lines lower. That construct is what this
    ladder's OWN scope_demote_drafts (§8d) rung emits on purpose, and three
    already-banked functions in that TU use it: one rung undoing another.
  * The cast pass rewrote COMMENT PROSE -- 8 rewrites inside one header comment,
    including inside a quoted cc1 diagnostic. Now matches on cdecl._mask
    (length-preserving, so a mask offset is a source offset) and splices into
    the original.
  * `&sym` emitted `&` applied to a cast: legal for the scalar arm, `invalid
    lvalue in unary '&'` (measured) for the array/fnptr/fnptr_array arms. `&`
    now selects a pointer form and consumes itself -- but ONLY with no trailing
    subscript, because `&sym[i]` is the address of ELEMENT i and the old code
    had that case right. That last clause exists because the R39 negative
    control caught the fold as a regression in the first cut of this fix.

gate_stage.py — `--skip-stages` / `GATE_SKIP_STAGES` (loud when used). Stage 0
gates raw drafts first, so a broken rung can only cost a RECOVERY, which is
exactly what makes it invisible: the function it destroys was already failing,
so its DIFF reads as a fact about the function.

verify_worktree.py / jr_isolate_all.py / parallel_gate.py — provision() now
symlinks every .run/sig.*.jsonl (main clone 259, provisioned worktree 0), the
third member of the class holding extracted/ and .run/obj40. parallel_gate was
fixed for this identical bug in S69: two provisioners, no shared list, found
twice; they now cross-reference each other. jr_isolate_all no longer swallows
the resulting FileNotFoundError into `except: continue` -- that turned a missing
index into a confident carve-CORRUPTION verdict over 2,603 of 2,603 functions
(R54). Adds _assert_scan_covered: attempted == raised means the scan measured
nothing, so its zero is an artifact, not a finding (R32).

Verification:
  * 4 cc1 probes (the table above), each run on the pinned front end.
  * R39 negative control over the stored-draft corpus: 661 adjudicated, 652
    IDENTICAL, 9 CHANGED and every one an intended class. 4,173 of 4,864 drafts
    unadjudicable (filenames that are not func_<ADDR>) -- stated, not hidden.
  * jr_isolate_all ov_SC03_105 --dry-run: unchanged in the main tree.
  * make clean/extract/build BINARY=resident -> 8e17e02f... BYTE-IDENTICAL.

Docs ship with the change (R21): cookbook §442/§443, index regenerated (1,112
sections), 3 docs/SETUP.md rows, CURRENT_PHASE S75 log.
2026-09-02 20:30:22 -06:00
Drew T 7f7e1c7d90 docs(phase-31): refresh the S74 checkpoint — §440/§441 and the doc-state line
The checkpoint listed §435-§439 and was written before the documentation catch-up; a stale
checkpoint is worse than an absent one. Now records that every tool change this session carries a
SETUP row and a cookbook entry, and names the rule the gap taught.
2026-09-02 19:54:10 -06:00
Drew T b24394e732 docs(phase-31): S74 FINAL checkpoint — 50 banked, seven tool defects, R22 213/213
Every reject class this session was an instrument defect, not a codegen wall: 24 already-MATCHed
bodies were sitting behind seven tool bugs, six of which are now fixed. The checkpoint names the
seventh (reconcile_tu manufacturing declaration conflicts) as the first thing to fix next session,
and the harness gap (verify_worktree omits the sig files, and the scan that needs them swallows the
error and reports a false corruption) beside it.

Fleet verified from a clean rebuild AFTER the last bank: check-all 213 passed, 0 failed of 213.
split_indicator 213 OK and now a hard gate. INCLUDE_ASM lines in src/ 1,086 -> 1,036, measured at
both commits — the same 50 the gates reported, counted independently from the source.
2026-09-02 19:40:46 -06:00
Drew T aa302aa050 docs(phase-31): S73 FINAL checkpoint — consolidated, verified, fresh-session ready
Supersedes S73 CLOSE and its addendum. Every number re-verified against the repo:
REAL 880/1,918, MAIN 56.5%, frontier 124 (main 36), main jtbl fns 25 -> 2.
2026-09-02 17:25:57 -06:00
Drew T a0ff94626a docs(phase-31): all 40 actively-misleading audit findings worked, not deferred
Replaces the 'known-remaining' TODO list with what was actually fixed. The four that
were not doc typos: progress.py undercounting REAL by 7 (the #else half of a
NON_MATCHING block is live code and classify() swallowed it), the silently deleted §429,
the false §265 accusation in §434, and memory-map.md:309 claiming a 'verified' extent
that overlaps the new span-B carve.
2026-09-02 17:17:44 -06:00
Drew T 5ae43099e0 docs(phase-31): S73 CLOSE addendum — corrections, and the known-remaining list
Corrects three defects I introduced (deleted §429, a false accusation in §434, an
over-strong SaveLoadRoutine verdict), two wrong numbers in the block above, and records
the SETUP §6.6 gap that was the real answer to 'are the docs up to date'.

Also lists what the audit found and I did NOT fix, with file:line, so a fresh session
inherits the list instead of rediscovering it: jr_isolate/jtbl_rodata_pads/draw_waves
docstrings, several stale playbook census numbers and its step-1 command, memory-map:309,
and the pre-S72 --front/--tail descriptions in the Makefile and ld_interleave.
2026-09-02 17:06:52 -06:00
Drew T 2c1d21bb9d docs(phase-31): S73 CLOSE — R22 213/213, 23 main banked this session, main 56.5%, frontier 124
The jump-table class on main is resolved: 25 -> 2, and both survivors are the §434 frame
pair, provably unmatchable as separate C functions (resegmentation, not drafting).

Wave S73m_1 banked 9 of 9 drafts (2,413 ins). Cookbook entries written this morning
cracked functions this afternoon; two of mine were refuted by later MATCHes and rewritten.
2026-09-02 16:34:13 -06:00
Drew T ab0bbd257b docs(phase-31): S72 addendum 2 — exclude list regenerated, draw refuses a stale one
88 of 107 entries were stale one day after the list was written; 46 of them were
12,750 instructions of open drawable work including SaveLoadRoutine. Canonical list is
now config/wave_exclude.txt (19 entries), and draw_waves --exclude-file audits it as a
prerequisite.
2026-09-02 14:39:55 -06:00
Drew T 27c81ed0c2 docs(phase-31): S72 addendum — split_indicator found 4 more binaries (16 fns / 3,613 ins)
18% of the non-main frontier, all already in the exclude list as if unmatchable rather
than 'needs a subseg split'. Plus: 28 of that list's 107 entries are already banked, so
regenerate it before the next draw.
2026-09-02 14:10:20 -06:00
Drew T 09886be66b docs(phase-31): S72 FINAL — R22 213/213, 14 main banked, main 52.6%, frontier 133
The carve + the src/800.c split at the original TU boundaries. 7 of the 14 banks were
span B/C — impossible before the split. Next session starts with 11 functions /
4,479 instructions that are now merely undrafted rather than unbankable.
2026-09-02 13:54:16 -06:00
Drew T f0148e6822 docs(phase-31): S72 CLOSE — R22 green 213/213, 7 main banked, main past 51.8%, frontier 140
The 11 'PROVEN gate-rejects' were one missing rodata carve, not bad bodies. Next
session starts at the span B/C carve: 18 jtbl functions left in main's frontier holding
most of its remaining instruction mass, blocked on splitting src/800.c at 0x8002B0B4
and 0x80035270 — the original TU boundaries the jtbl spans reveal.
2026-09-02 12:58:44 -06:00
Drew T 8edd0f61e0 docs(phase-31): S72 progress — main's jtbl carve debugged, fixed, 3 banked; span B/C is the next lever 2026-09-02 12:09:06 -06:00
Drew T 6c904ebd0c docs: close the S71 documentation gaps - SETUP tools table, playbook steps, decision log, gate ledger
Audit found real gaps rather than assumed coverage:
* SETUP.md (R21) had NONE of the five tools written this session. Added a table for
  journal_notes / launch_check / gate_triage / restage_matching / weave_sweep, each with
  when you need it, plus the two gating rules now enforced in code (parallel_gate refuses
  main; gate_main refuses a no-op draft and counts banks from the source).
* wave-playbook: launch_check as step 4c (payloads go stale while gates run - 3 of 27
  wave-2 targets were already banked) and gate_triage as step 6b with the measured
  blocker census.
* decision-log (R31) held only the §406 pivot. Added the two strategic entries this
  session actually turned on: gating main with a tool documented as unable to gate it
  (false PASS, caught only by R22), and the drafting pool running dry while the lever
  was an exclude list nobody re-probed after a tool fix.
* CURRENT_PHASE: the per-gate ledger for all 14 cycles plus the carve/rebase/main gates.
* Two memories: gate-main-only-with-gate-main, reprobe-exclude-lists-after-tool-fixes.
2026-09-02 11:19:49 -06:00
Drew T 9631949339 docs(phase-31): S71 CLOSE — R22 green 213/213, frontier 147, 63 banked, main past 50% 2026-09-02 11:15:21 -06:00
Drew T 225f7d4ee9 docs(phase-31): frontier 150, 60 banked; main lane reopened; two gate_main defects fixed 2026-09-02 10:15:20 -06:00
Drew T 11862e3c22 docs(phase-31): gate 10 (+3), frontier 162, 48 banked; §420-§423 harvested 2026-09-02 05:51:08 -06:00
Drew T 1c932c61b8 docs(phase-31): +4 via multi-cluster symbol rebase; frontier 165, 45 banked 2026-09-02 05:38:45 -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 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 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 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 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 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 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 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 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 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 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 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 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 1632c6adec docs(phase-31): S70 FINAL-4 — 145 banked (355->210), 115/118 wave MATCH, 5 card defects (3 fixed), cookbook 1074 2026-09-01 23:40:28 -06:00
Drew T c6a0dc8f43 docs(phase-31): S70-T14 — blocker 3 fixed, carve route OPEN (+3, frontier 308); all three blockers were routing errors, not walls 2026-09-01 22:00:26 -06:00
Drew T ba24730d39 docs(phase-31): S70-T13 — carve ownership was a MODEL bug (dry run 7/17->15/17); a third blocker (jtbl_carve mixed-data island) is the real wall 2026-09-01 21:28:14 -06:00
Drew T 57031f01e4 docs(phase-31): S70-T3 carve route — 0 banked, blocker localised to stale committed carve ownership (7 binaries) 2026-09-01 21:09:18 -06:00
Drew T b5370955cc docs(phase-31): S70 FINAL-3 — 44 banked (355->311), R22 green, tools-health 333s, §332b island shipped 2026-09-01 20:46:03 -06:00
Drew T 576d69a529 docs(phase-31): S70-T4 §332b shipped (+3, frontier 311); §404 corrected; tools-health 333s green 2026-09-01 20:37:18 -06:00
Drew T 425cec253c docs(phase-31): the pre-wave tool audit — blast radius REFUTED, work_evidence shipped, cleared for waves 2026-09-01 18:59:32 -06:00
Drew T d23bc7ad56 docs(phase-31): audit the pgate blast radius — REFUTED; 606/668 plan rows absolute, defect never fired before S70 2026-09-01 18:44:31 -06:00
Drew T 16fae589d0 docs(phase-31): S70 FINAL-2 — 41 banked (355->314), R22 green 213/213, 4 tool defects (3 fixed) 2026-09-01 17:47:55 -06:00
Drew T 6b51f0383c docs(phase-31): correct S70 — main banked 0, not 1; harvest_verify alone does not persist a splice 2026-09-01 17:42:18 -06:00
Drew T 1d5f951a6d docs(phase-31): S70 FINAL checkpoint — 22 banked (355->333 real), R22 green 213/213, next-session queue led by the family_remap decl fix 2026-09-01 17:29:57 -06:00