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_242C
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).
The audit's headline, measured: THE WALL IS AN INTEGRATION WALL, NOT A CODEGEN WALL. Of the 292
functions the gate has refused 6+ times, 178 (61%) have ALREADY produced a closeness-0 draft —
match_one byte-equality, whole-binary gate rejection. The blocker is symbols/decls/TU plumbing,
and the fleet keeps re-drafting them: 10,049 reject rows over 574 distinct functions. Highest-EV
build is a zero-token integration-resolver lane, not more drafting.
CORRECTIONS TO MY OWN NUMBERS, verified against the tree before accepting:
* siblings are 1,334 behind 480 multi-member groups, NOT ~3,900. 1,292 groups are SINGLETONS
carrying 57% of open instruction mass. I conflated the never-drafted stub count with the sibling
count and overstated remap leverage ~3x, in this checkpoint and repeatedly in conversation.
* 'everything drawable is gen6+' holds only for the collapsed wave-eligible view; whole-pool
generation is 53% gen0/1, 25% gen6+, and only 292 fns are 6+ GATE-refused.
* '30-67 min gates at 8% CPU' conflated wall_min (includes drafting/queue) with gate wall (12-31
min healthy). Gate cost is proportional to FAILURES, not drafts: ~3 whole-binary builds per
failing draft, so banks/gate-min fell 17.5 -> 0.10 as conversion fell.
* the 5,388 closeness<=2 rows de-dupe to ~543 open functions; my own 19:40 re-measure found 290
still open, down from its 470 — the re-gate and grinder are draining that pool now.
* campaign_status's 'banked today' undercounts: the stub invariant says ~2,644 net, because the
A-prop lane's 357 rode in a chore commit its regex cannot see.
One documented counterexample to 'model quality is not a bottleneck': func_80181714, where
ox-alpha plateaued at closeness 4 while Opus/GLM/DeepSeek each reached reloc-verified MATCH —
argues for a small escalation tier AFTER the resolver drains the fake walls.
Taken on trust and flagged as such: the A-prop residual split (169 STRUCT / 121 no-seed-decl /
73 IMM / 12 void) — the refusal mechanisms exist in aprop_autodraft.py but no file carries those
counts; re-derive before building the decl-inference tool.
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_8001C5B8
func_80028E24
func_8005D0D8
~2,200 banked today. Throughput went 65 -> 554 req/min peak by removing harness defects, not by
changing models. The registry was wiped THREE times by four non-atomic truncating writes, now
routed through tools/mk_write.py; each wipe made every gate reject every draft.
The strategic picture for next session: 3,062 open crackable collapse to ~334 drawable skeletons,
~308 of them generation 6+, with ~3,900 siblings behind them that bank by remap. Wide waves
convert at 1-5% and the GATE is the bottleneck (30-67 min at 8% CPU). Optimise banks per gate
minute. The reasoning budget is NOT the cause of the decline — truncation is inversely correlated
with bank rate.
A Fable analyst is writing docs/tool-designs/frontier-analysis-s60.md, briefed that we are not
married to the ox-wave model; that document is the first thing to read next session.
Five rule candidates (R51-R55), each earned by a defect that fired today.
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).
THE GATE WAS A BLACK BOX. sweep_parallel's stdout was captured and dropped, so a gate logged
"reloc_identity -> gating 216" and then THIRTY MINUTES OF SILENCE before its bank line — no
worker count, no per-binary progress, no phase-A/phase-B split. Gate times went 31 -> 37 ->
50 -> 67 min across ej/ek/en/eo with nothing to diagnose from, and I twice asserted things
about phase B that the log could not support (its absence measured LOG CAPTURE, not
behaviour). A lane that must run unattended has to leave evidence.
MEASURED WHILE DIAGNOSING, and it rules out the obvious suspects: load average 2.6 on 32
cores with 1-3 concurrent builds during a gate — the gate is NOT CPU-bound and is not
saturating its own -j 24. Raising to 32 is cheap given ~8% utilisation, but the real answer
will come from the log this change adds.
TAIL_DONE_FRAC 0.85 -> 0.80. 0.85 overcorrected: the fleet fell to 15 agents / 11 req/min
because the drafter parks between waves while the gater drains a deep queue. 0.75 was too
deep (26% 429s, draft completion sliding 94->91->73->47% across eq/er/es/et). Neither number
is really the lever: the drafter cannot start a wave the gater has no room for, so the gate
throughput is what bounds the campaign now.
Generational tiering confirmed already correct: the top-off orders by generation at both
assembly levels (group ranking and within-group) without FILTERING any tier out, so every
generation stays eligible and the scarce never-drafted work simply goes first.
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_800189A8
func_80028E68
func_8005D0F8
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).
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).
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).
Five reviewers on disjoint wave groups (D1 dd/de/df · D2 dg-dm · D3 cg-cm · D4 cn-cw ·
D5 cx-dt): 859 COVERED · 46 ADDENDUM · 9 NEW · 289 REJECT. Index now 888 sections.
§283 the 46 sharpenings, one block per target section
§284 combine can reassociate two sequential bitwise-AND masks against the PRE-mask value;
an asm fence at the mask's definition point stops it
§285 pre-initializing a variable with a shared constant BEFORE a branch makes both arms of
the following if/else destructively reuse one register
§286 fold a statement's side effect into a comma-expression in an argument position to
place its RTL relative to a call's own delay slot
§287 a stack-frame hole below two address-taken aggregate locals is a LEADING PAD MEMBER of
one combined struct, not separate locals
§288 a register pin declared UNINITIALIZED and assigned only at its late sole use still
forces the fixed register's save/restore
§289 an array local's decayed base keeps EVERY element's store alive under DSE, though only
one pointer value escapes
§290 one strength-reduced giv can drive stores to several distinct relocatable symbols,
each keeping its own %hi/%lo anchor
§291 the delay-slot false-value: a conditional branch's zero arm must be a fall-through
adjacent block ending in an explicit goto
§292 declaring a symbol upstream of an already-banked sibling that relies on its implicit
(K&R) declaration silently reprototypes the sibling's call site
VERIFICATION CAUGHT SIX BAD CLAIMS, recorded in §283 as refuted rather than laundered in:
three independent "the harvester leaked an unbanked NEAR into a banked-only harvest" reports
(all three functions are genuinely banked per corpus.stubs — the notes predate their gate and
read as harvester bugs hours later); a "match_one resolves targets by bare symbol name" claim
(it resolves an explicit path, and api_draft always passes it — the real hazard is its
resident-defaulting --asm-subdir, hardened separately in commit:2917); and two idiom claims
whose mechanism is absent from the banked code. §284's fence was described as NON-volatile
and the banked code uses `__asm__ volatile` — corrected in the text, since that is a detail
readers copy verbatim.
THE STRONGEST SIGNAL IS NOT A SECTION: eight cards across four waves independently
re-derived that the whole-object gate needs every sibling matched. It is implicit in the
corpus and has never been stated as its own law. Recorded in §283 as the batch's clearest
missing-section signal.
PROCESS, for the next batch: forked sub-reviewers exceeded their brief in three of five
groups — one re-derived five waves it was not assigned and self-merged over the shared output
path, one silently dropped 11 rows including a whole function, one produced nothing. Each
parent caught its own fork. Tell forks not to spawn forks (they infer it from the parent's
inherited context) and give each a private output path.
A distill reviewer reported "match_one resolves targets by bare symbol name, not
(binary, address)" from 6+ observed target-confusion instances. VERIFIED AND THE CLAIM DOES
NOT HOLD as stated: match_one resolves '%s/%s.s' % (asm_subdir, fn) — an explicit path — and
the drafting path is safe because api_draft.match_one() always passes
dirname(card['asm']). The 675 "match_one MATCH but the whole-binary gate rejected" rows today
keep their real explanation: they landed in the window when config/overlays.mk was empty and
NOTHING could build.
The narrower hazard behind the report is real. --asm-subdir defaults to
asm/resident/nonmatchings/resident, function names are ADDRESS-DERIVED, and overlays share
the address space — so the same name is routinely a DIFFERENT function in another binary
(§238 homonym trap). Any caller that omits the flag gets a confident verdict about the wrong
target, and the failure is silent because the file exists.
It now warns loudly on stderr when the default is used, naming the fn and the directory, and
stays silent when the flag is passed (controlled both ways). A warning rather than a refusal:
resident-era callers legitimately rely on the default, and R43's "refuse what you cannot
handle" does not apply to a tool that CAN handle the input — it applies to one that cannot
tell whether the input is what the caller meant.
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).
ROOT CAUSE of both wipes today. config/overlays.mk was rewritten in four places with
open(mk, "w").write(txt)
(jr_isolate_all.py:593, jtbl_carve.py:1077/1118/1165) — which TRUNCATES to zero first and only
then writes. Three ways that loses the registry: the process dies between truncate and write
(empty file); another process reads inside that window (sees an empty registry); two writers
interleave (a partial line lands after the last good one — this morning's file ended in a stray
`uto.txt` fragment, exactly that fingerprint). The jtbl carve automation runs AT THE GATE, which
is when all three wipes happened, and ONE_PER_GID=0 made it far likelier by putting many more
carve members in every wave.
BLAST RADIUS, measured twice: with no binaries registered, main's object glob sweeps every
overlay's nonmatchings/*.s into MAIN's OBJS and assembles them standalone, so main cannot build,
the main lane correctly refuses against a RED baseline, and every overlay gate rejects every
draft. Waves dn/do banked 0/224 and 0/236; waves ei..em banked 2 of ~1,100 with 675 backlog rows
reading "match_one MATCH but the whole-binary gate rejected" — the local oracle proving the
drafts were byte-correct while the tree could not build them.
tools/mk_write.py is now the only writer: atomic (tmp + fsync + os.replace, so no reader ever
sees a partial file and a crash leaves the original intact), collapse-refusing (a rewrite below
80% of the current line count raises), and flock-serialized.
TWO HONEST LIMITS, recorded rather than papered over:
* Callers still READ outside the lock, so two concurrent carves can each read-edit-write and
the second drops the first's line. That is a LOST UPDATE — a missing line, not a wiped file —
caught downstream by the fleet check and jtbl_pads_fix. Closing it means holding the lock
across read-modify-write in every caller.
* The guard now also refuses when the CURRENT file is under 100 lines. That case cost me
directly: my own verification control overwrote a registry a carve had truncated seconds
earlier, because the collapse check was skipped when the old file was empty. A control must
assert its precondition; mine did not, and now the tool enforces it instead.
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_80028EAC
Second registry wipe today. commit:2911 ('ox wave ei overlays — 1 banked') committed
config/overlays.mk as a zero-line file, exactly as commit:2863 did this morning, and the
consequence was identical: no overlay can build, so every gate rejects every draft. Waves
ei/ej/ek/el/em gated ~1,100 drafts and banked 2 between them, with 675 backlog rows reading
'match_one MATCH but the whole-binary gate rejected' — the local oracle proving the drafts
were byte-correct while the tree could not build them.
WHY config_sane() DID NOT FIRE. I added it at 13:0x. The gater process has been running since
midnight and executes the code it loaded at startup — Python does not reload, and a
long-running lane never re-invokes its own module. The runbook already states this ('tool code
next invocation, lane args/env only on a fresh shell') and I applied it to the drafter and the
maintenance lane today while leaving the gater untouched. A guard that is not running is not a
guard.
Restored from commit:2911^ (5,083 lines, 141 binaries). The gater is restarted in the same
change so the protection is actually live.
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.
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).
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.
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
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