Skip to content

optimizer: fix structurally-uneconomical screening, promote control-relative as primary gate signal - #689

Merged
OsherElhadad merged 1 commit into
mainfrom
worktree-agent-abac93057aaa4d9f3
Oct 8, 2026
Merged

OsherElhadad merged 1 commit into
mainfrom
worktree-agent-abac93057aaa4d9f3

Conversation

@OsherElhadad

Copy link
Copy Markdown
Collaborator

Summary

Fixes issue #684 items 5 and 6 only (screening redesign, control-relative-as-primary
gating). Does not touch the Pareto/archive gate (items 1-2), merge_search.py (item 4),
plan_round.py's branch-count/ownership logic (item 3), the dashboard, hill-climb, or
cost-reduction guidance — those are owned by other in-flight PRs against #684.

Item 5 — screening redesign (screen.py / subsample.py)

Confirmed bug: tier-1 screen subsets (5-11 tasks) measured SEs of 0.11-0.17 while the
round deltas that actually mattered were 0.02-0.09, so the old significance-based kill
rule (mean(Δ) + k_se·SE < 0) could never clear its own confidence bar. Result: 0
screen-kills across 7 candidates
in that run (0/8 in an earlier one), with screening
costing more rollouts than it saved.

Per GEPA's own validated design (a cheap minibatch gate that just checks "did it beat
the parent, yes/no" — no significance test, because the full/expensive eval is the real
decision point), screen_decision now kills on a gross negative signal —
mean(Δ) <= GROSS_KILL_DELTA (default -0.15), regardless of SE — and otherwise
promotes.

Threshold reasoning: -0.15 sits strictly between the ~0.10 drift measured between
byte-identical control replicates (so ordinary re-measurement noise never trips it) and
the ~0.2 of the one confirmed gross failure in a real run (cand_7, an infra-broken
edit), so it still catches genuinely broken candidates without being trigger-happy on
real noise or a genuine close call. Configurable via --gross-kill-threshold.

This is a deliberate, documented behavior change, not a silent one — called out
prominently in subsample.py's module docstring, screen.py's own docstring, and
references/algorithm.md / references/measured-lessons.md.

Added a screening_economics audit (test_subsample.py): a fixture reproducing
cand_7's real screen delta confirms the new rule kills it (and that the old
significance rule would have missed it, at the SEs that run actually measured), while
genuinely close-call effect sizes (0.02-0.09) still promote.

Item 6 — control-relative as primary (gate.py / round.py)

Confirmed bug: measurement drift between rounds (~0.10) is comparable in magnitude to
the real effects being chased (~0.02-0.09). round.py treated the delta against the
parent's STORED reward (which can carry that drift) as primary, with the delta against
a freshly-measured byte-identical control kept as a secondary cross-check — backwards,
and it required a manual grow.py escalation to resolve real disagreements twice in
one run.

Inverted: round.py now gates PRIMARILY against the pooled null-control replicates
whenever one was measured this round (--control-replicates 2 is the default — the
standard case), with the raw comparison against the stored parent kept as a secondary
diagnostic field (raw_vs_parent) for detecting drift itself. The pre-existing
control_relative field keeps its old shape for backward compatibility with
commit.py's --reject-basis drift_control and the dashboard's control-relative
panels — it is simply redundant with the primary verdict under the new default, since
there's no longer a disagreement for it to resolve. Falls back to the unchanged
parent-primary behavior whenever no control exists this round (--no-control).

Added test_round_control_relative_primary.py: reproduces the real run's exact
ambiguous scenario end to end through a real round.py invocation (reward tie against
the stored parent, a real significant win against fresh control replicates) and asserts
the primary verdict now resolves ACCEPT directly, with no grow.py growth round needed.

Test plan

Closes part of #684 (items 5, 6).

@skillberry-bot skillberry-bot added bug Something isn't working algorithm Optimization algorithms: GEPA / SkillOpt / hill-climb priority-p1 High impact documentation Improvements or additions to documentation labels Oct 8, 2026
@skillberry-bot

Copy link
Copy Markdown
Contributor

🏷️ Automatic Labeling

I've analyzed this pull request and added the following labels:

  • bug - algorithm - priority-p1 - bug - algorithm - priority-p1 - documentation

These labels were selected based on the PR title, description, and changed files. If you believe any labels are incorrect or missing, feel free to adjust them manually.


import json
import shutil
import sys
import json
import shutil
import sys
from pathlib import Path
import sys
from pathlib import Path

from test_round_requires_screen_ladder import CORE, SCRIPTS, _project, _run
…elative as primary gate signal

Issue #684 items 5-6, from forensic diagnosis of two real runs.

Item 5 (screen.py / subsample.py): tier-1 screen subsets (5-11 tasks) measured SEs
of 0.11-0.17 while the round deltas that mattered were 0.02-0.09, so the old
significance-based kill rule (mean(delta) + k_se*SE < 0) could never clear its own
confidence bar. Result: 0 screen-kills across 7 candidates in that run (0/8 in an
earlier one), with screening costing more rollouts than it saved. Per GEPA's own
validated design (a cheap minibatch gate with no significance test; the full/expensive
eval is the real decision point), screen_decision now kills on a GROSS negative signal
(mean(delta) <= GROSS_KILL_DELTA, default -0.15) regardless of SE, and otherwise
promotes. -0.15 sits above the ~0.10 drift measured between byte-identical controls and
below the ~0.2 of the one confirmed gross failure (cand_7), so it catches genuinely
broken candidates without tripping on noise or a genuine close call. Documented
prominently in subsample.py's module docstring, screen.py's own docstring, and
references/algorithm.md and references/measured-lessons.md so this is not a silent
behavior change. Added a screening_economics audit (test_subsample.py) that reproduces
cand_7's real screen delta as a fixture, confirms the new rule would have killed it
while the old significance rule would have missed it, and confirms genuinely close
calls (0.02-0.09) still promote.

Item 6 (gate.py / round.py): measurement drift between rounds (~0.10) is comparable
in magnitude to the real effects being chased (~0.02-0.09). round.py used to gate each
candidate's top-level verdict against the parent's STORED reward (which can carry that
drift) as primary, with the delta against a freshly-measured byte-identical control
kept as a secondary cross-check. Inverted: round.py now gates primarily against the
pooled null-control replicates whenever one was measured this round (the standard
case), with the raw comparison against the stored parent kept as a secondary
diagnostic field (raw_vs_parent) for detecting drift itself. The pre-existing
control_relative field keeps its old shape for backward compatibility with
commit.py's --reject-basis drift_control and the dashboard's control-relative panels.
Falls back to the unchanged parent-primary behavior when no control exists this round
(--no-control). Added test_round_control_relative_primary.py, which reproduces the
real run's exact ambiguous scenario end to end through round.py (reward tie against
the stored parent, a real win against fresh control replicates) and asserts the
primary verdict now resolves ACCEPT directly, with no grow.py escalation needed.

core/tests -q passes except the 2 known pre-existing test_tau2_airline_eval_cost.py
failures (unrelated to this change).

Signed-off-by: Osher Elhadad <Osher.Elhadad@ibm.com>
@OsherElhadad
OsherElhadad force-pushed the worktree-agent-abac93057aaa4d9f3 branch from 335d211 to 0e3fc4b Compare October 8, 2026 11:36
@OsherElhadad
OsherElhadad merged commit 20badf3 into main Oct 8, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

algorithm Optimization algorithms: GEPA / SkillOpt / hill-climb bug Something isn't working documentation Improvements or additions to documentation priority-p1 High impact

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants