Winners-curse revs 3–4: the growth lookahead as a virtual injection + the yield rule#196
Open
gfrmin wants to merge 4 commits into
Open
Winners-curse revs 3–4: the growth lookahead as a virtual injection + the yield rule#196gfrmin wants to merge 4 commits into
gfrmin wants to merge 4 commits into
Conversation
…he score (rev 4) Gibbs kills the flow: any own-posterior forward flow equals KL(P_union ‖ P_inc) ≥ 0 per context, so rev-3 §1b's zero-or-negative chance-window story is unsatisfiable by theorem, and ×H amplifies the residue (measured: +0.55-nat fire at P_newcomers ≈ 0.11, violating the design's own mechanism claim (i)). The resolution is a further deletion: the ratified yield observable IS the union-over-incumbent window Bayes factor under the complexity prior, so score = net_value(yield, op_compute_cost). The wait-option (Gittins-style) argument earns the ×H deletion — the far-term value is common to adopt-now and wait-and-re-decide, so only the evidence-vs-price timing survives. Plateau retires at the growth seam (realised yield already prices reality-of-gain). Two named assumptions pinned: the cost slot is the #189-inherited declared price (no-tuning discipline), and the wait-arm regeneration assumption is the named bridge to the non-stationarity work. §8.5 records the boundary framing from ratification. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ion coherent injection + the yield rule
Engine half of winners-curse revs 3-4:
- add_programs_to_state! gains a Vector{Grammar} method: the UNION
injection — one joint newcomers-only replay over the deduped union
(global expr dedup: against all incumbents and across candidates),
one two-ledger scale restoration, one construction. Joint-not-
sequential is load-bearing (sequential injections would misalign
later groups' ledgers by earlier groups' normalisation shifts);
commutation is inherited from the single-injection theorem
(test_virtual_injection.jl §5 asserts it for this method). The
single-grammar method keeps its per-gid dedup untouched (bit-
stability of re-enumeration); the injection arithmetic is extracted
verbatim into _inject_coherently!, shared by both.
- GrowthProposal (scratch, n_added, yield_nats, p_newcomers): one
virtual injection, projected by score, op log, and transition
(Invariant 3). threshold_growth_proposal / feature_growth_proposal
inject ALL candidates (ratified Q3); the Occam charge rides inside
the mixture (Q4 — no prior term at any seam).
- The score is the yield rule (§8.2): injection_yield_nats(scratch) =
the union-over-incumbent window Bayes factor, netted against the
declared price by the caller. No flow (Gibbs-degenerate, §8.1), no
×H, no plateau. T-3.53 exact in FORM: escape ops net_value(E[next
yield], cost) learned; growth ops net_value(computed yield, cost)
exact.
- copy_agent_state + adopt!: FIRE = adopt the scratch — score ≡
transition as an identity (T-3.55), not a shared candidate function.
- Retired: _grammar_marginal_log_loss, _candidate_residual_mass,
_best_threshold_refinement, _best_feature_addition, explore_grammar,
explore_features, exploration_voi/fit, feature_discovery_voi/fit —
the per-candidate argmax was an order statistic over chance fits
(selection unpriced), its window rate extrapolated by H
(stationarity unlicensed), and installing the winner an
argmax_m P(m|D) collapse (average-not-collapse, applied to the
transition).
- test_virtual_injection.jl (new, 6 sections + host-seam §1): the
seed-6 chance window WAITS at -0.56 nats while the retired score's
counter-oracle fires at +5.12; the informed fire lands from n = 8;
multiplicity-by-mixture; commutation inheritance; #193 self-healing;
score ≡ transition as ===.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…coring; test re-baselines Host half of winners-curse revs 3-4: - score seam: gw_growth_proposal is the ONE candidate function score and transition share, memoised in growth_cache keyed by (op, cache_epoch, gid, n_buf, depth). Scores are net_value(prop.yield_nats, op_compute_cost). GW_FEATURE_PRIOR_TERM retired (Q4). The attribution gate re-expresses as refinement-fires- first (-Inf on add_feature iff the threshold proposal's own score clears the floor). - execute: growth branches adopt the memoised scratch (ratified Q1; score-blind callers recompute — the same function). Per-fire log carries (yield, P_newcomers, n_added) — the gate mechanism-claim read. - cache_epoch now bumps on EVERY space change alongside space_epoch (the proposal depends on the live belief, unlike the retired pure- fit cache — a stale scratch must never be priced or adopted). - h_events / n_cond_events horizon bookkeeping deleted (nothing consumes a horizon at this seam any more — §8.3's residual discharged by deletion); plateau no longer multiplies scores (regime maintenance unchanged). - Re-baselines: test_threshold_explore §3 (discovery via the union; structural completeness replaces the residual-order guard), test_feature_discovery §3/§4 (yield strictly below fit-axis Δℓ — the mixture prices the prior axis), test_growth_returns §6 (one score form, both fidelities), test_grid_world_meta §1/§3/§4 (yield-rule pins; empty buffer scores exactly -price, not a veto). Full 56-file suite green; credence-lint 178 files 0 violations. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…echanism claims verified, must-not-degrade fails on a benchmark-utility finding HALT THE LINE: 8 assertions still fail; not merged on this run alone. What the run shows, honestly: - Winner's curse: DEAD. Every eu_max growth fire is informed (verbose seeds 0/5/6: min yield 0.748 nats, min P_newcomers 0.613, most ≥ 0.9 — mechanism claim (i) verified; the step-4-8 chance fires of rounds 3-4 no longer exist). Meta churn stays dead (13.1 metas/run). Headline vs never_explore holds (+0.106 [0.004, 0.21]; final-regime 17-3, p = 0.0026). Tails vs random_p005 marginally improved (worst -0.45 from -0.50, q10 -0.45 from -0.48). - Must-not-degrade FAILS vs the tuned fixed schedule — which switched to fixed_k5 and jumped 48.5 → 52.9 AUC: the shared adopt-the-union transition made blind frequent firing much stronger for every policy. eu_max - fixed_k5 primary CI (-0.254, -0.017), significantly negative. - Diagnosis (epsilon-price counterfactual, 20 seeds, reported not asserted): at op_compute_cost ≈ 0 eu_max recovers only +0.04 (0.42 vs fixed_k5's 0.517), the escape tier churns (630 metas — a learned E[yield] never reaches exactly 0; only the price stops it), and the refinement-first gate starves add_feature. The price is not the fix. - The finding is one level up (measure-matches-declared-utility): the gate's utility charges ZERO compute, so 'move the boundary every 5 steps for free' dominates ANY priced selectivity by construction — while eu_max pays 13 metas + per-step proposal replays (16.2s wall-clock vs fixed_k5's 1.9s) that the gate cannot see. Under the gate's own declared utility, always-fire is genuinely EU-optimal; the gate as constructed cannot reward the thing the mechanism optimises. Clairvoyant is now degenerate for the same reason (its forced at-change fires all no-op on the yield floor — trajectories identical to eu_max, +6 no-op metas). Next move (needs ratification): a dominance-design amendment charging compute in the gate's utility (the one-currency exchange rate declared as task data), then re-run. Wall-clock note: the union replay is ~3x faster than the retired K-replay lookahead (46.2s → 16.2s per 20 seeds). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Code PR for the ratified winners-curse design (#195) plus its ratified-in-conversation §8 amendment (rev 4). Gate status: HALT THE LINE — opened for review, not for merge on this run (see the results commit and the findings below).
What this builds
add_programs_to_state!(state, ::Vector{Grammar}, …)): one joint newcomers-only replay over the globally-deduped union of all candidates' programs — one ledger, one construction. Joint-not-sequential is load-bearing for exactness; commutation is inherited from Coherent injection: hypothesis addition commutes with conditioning (dominance halt-the-line fix) #187's theorem and asserted for the vector method (test_virtual_injection.jl§5). The single-grammar method's per-gid dedup is untouched (bit-stability of re-enumeration); the injection arithmetic is extracted verbatim into_inject_coherently!.GrowthProposal(scratch, n_added, yield_nats, p_newcomers)— one virtual injection, projected by the score, the op log, and the transition (Invariant 3). All candidates injected (Q3); the Occam charge rides inside the mixture (Q4 —GW_FEATURE_PRIOR_TERMdeleted, no prior term at any seam).score = net_value(injection_yield_nats(scratch), op_compute_cost)— the union-over-incumbent window Bayes factor under the complexity prior, net of the declared price. The rev-3 flow is never written: any own-posterior forward flow equalsKL(P_union‖P_inc) ≥ 0(Gibbs), so the §1b story was unsatisfiable by theorem — TDD caught it (§8.1). No×H(the wait-option/Gittins argument — the far-term value is common to adopt-now and wait-and-re-decide), no plateau (realised yield already prices reality-of-gain).adopt!, ratified Q1 memo viagrowth_cache): score ≡ transition as an===identity (T-3.55), pinned through the host seam. The cache epoch now bumps on every space change (the proposal depends on the live belief; a stale scratch must never be priced or adopted).net_value(E[next yield], cost)(learned); growth opsnet_value(computed yield, cost)(exact). One observable, one currency, one score form, two fidelities._grammar_marginal_log_loss, the residual-mass screen, both per-candidate argmax cores,explore_grammar/explore_features/exploration_voi/exploration_fit/feature_discovery_voi/feature_discovery_fit,GW_FEATURE_PRIOR_TERM, the host'sh_events/n_cond_eventshorizon bookkeeping (nothing consumed it — the §1 stationarity residual discharged by deletion at this seam).Verification
test_virtual_injection.jl(new, 27 checks): the seed-6 chance window waits at −0.56 nats while the retired score's counter-oracle fires at +5.12 on the same fixture; the informed fire lands from n = 8; multiplicity-by-mixture; commutation inheritance; Removal consumption: replacement semantics for applied removals (ratified #192) #193 self-healing end-to-end; score ≡ transition as===.test_threshold_explore§3,test_feature_discovery§3–§4 (stronger pin: realised yield strictly below the fit-axis Δℓ — the mixture pricing the prior axis),test_growth_returns§6,test_grid_world_meta§1/§3/§4. Full 56-file suite green; credence-lint 178 files, 0 violations.Gate findings (the honest part)
The winner's curse itself is dead: every eu_max fire is informed (min yield 0.748, min P_newcomers 0.613 across verbose seeds — mechanism claim (i) verified), churn stays dead (13.1 metas/run), the headline vs never_explore holds (+0.106 CI > 0; final-regime 17–3, p = 0.0026), and the union replay is ~3× faster than the retired lookahead.
But 8 assertions still fail, and the must-not-degrade clause binds: the shared adopt-the-union transition made blind frequent firing much stronger for every policy (fixed_k5: 48.5 → 52.9 AUC, now significantly above eu_max on the primary). The ε-price counterfactual (20 seeds, reported-not-asserted) shows the cost slot is not the fix: eu_max recovers only +0.04, the escape tier churns (a learned E[yield] never reaches exactly 0 — only the price stops it), and the refinement-first gate starves features. The real finding is one level up: the gate's utility charges zero compute, so "move the boundary every 5 steps for free" dominates any priced selectivity by construction — the gate cannot reward the thing the mechanism optimises (eu_max: 13 metas/16.2s; fixed_k5: 42 metas/1.9s — invisible to the gate). Clairvoyant is now degenerate for the same reason (its forced at-change fires all no-op on the yield floor; trajectories identical to eu_max).
Proposed next move (needs ratification): a dominance-design amendment charging compute in the gate's utility — the one-currency exchange rate (evidence-nats price ↔ energy ↔ replay compute) declared as task data in advance — then re-run. This is measure-matches-declared-utility one level up: the measure set was fixed in advance, but the utility itself under-specifies compute.
🤖 Generated with Claude Code