Measured against corpus.stubs at gate time on this session's own waves:
w2 80 drawn / 12 still open -> 85% of its agents re-derived already-banked functions
w3 80 drawn / 39 still open -> 51%
x1 80 drawn / 71 still open -> 11%
~109 of 240 agents in w2+w3 spent full budgets on work that was already banked, by the concurrent
parallel_gate commit or by sibling propagation from a twin remap. The agents DID notice ('stale
pack', 'target .s no longer exists') but only after reading the pack, and several reconstructed the
banked body just to have something to submit.
draw_waves filters against the DRAWN ledger, which stops drawing a target twice but says nothing
about whether it is still OPEN. In a campaign where gates land continuously, a wave drawn at T and
launched at T+2h is stale by construction. Openness is the same class of assertion wave_args already
makes about the .s and the pack, so it belongs here, where it costs nothing.
Negative control (both extremes): x1 drops exactly its 9 closed targets and keeps 71; w2 drops 68
and keeps 12 — matching the independent corpus.stubs measurement.
- match_one.py: a CPP/CC1/MASPSX/AS failure printed bare text and exited 1 even under --json, so
every programmatic caller got json.loads of a non-JSON line. claude_wave_packs swallowed 4 of 19
prior drafts as 'residual not measured: Expecting value' — the most actionable datum a pack can
carry (the draft does not COMPILE, here is the error) was the one it dropped. Negative control:
a near draft still measures identically (closeness 2, same residual rows); human mode unchanged.
- claude_wave_packs.py: renders that verdict, pointing the agent at the card's decl_prior block.
Coverage on wave r1 went 15/19 -> 19/19 packs carrying a measured verdict.
- wave_args.py (new): emits the claude_wave_draft.js args from <wave>/targets.json, asserting the
.s exists, that sub is exactly its parent dir, and that the pack exists. Written because I
hand-typed sub as 'ov_SC03_112/jr_80181D08' when the truth is
'asm/ov_SC03_112/nonmatchings/ov_SC03_112_jr_801817E0' (a stub's asm dir is named for its jr-carve
block, not itself) — all 19 agent oracles would have failed identically and read as a model
failure. Negative control: that exact string is REFUSED.
- draw_waves.py (new): draws waves off corpus.stubs cheapest-first, ledger-filtered, with
name-collision deferral (packs are name-keyed and refuse a duplicate). Re-measured the frontier:
the S65 tier map's '~557 cheap singletons (3-17 ins)' conflated one-member FAMILIES with small
functions — only 28 undrawn non-main stubs are <=17 ins; the bulk is 51-120 (258) and >120 (245).