Skip to content

Phase EJ — Evolve judging noise-floor shortlist #281

Description

@aberson

Blocked by: none — prerequisites met (Phase 9 /improve-bot-evolve operational; Phase EL shipped)
Build doc: documentation/plans/evolve-judging-plan.md
Track: 10 (Statistical robustness / evolve substrate) — alongside Phase R

Goal

Ship the six cheapest high-value changes from the 2026-07-05 evolve-judging investigation into /improve-bot-evolve's judging gates, all flag-gated with byte-identical defaults. The fitness gate's strict-majority bar lets a no-effect improvement pass ~61% of the time eventually (through the retry/bench ladder), and truly-neutral stacks get destroyed by coin-flip rollbacks. EJ.1/EJ.2/EJ.5 cut the null inflow before games are spent; EJ.3/EJ.4 stop the regression gate destroying whole generations on coin flips while keeping a hard drift backstop; EJ.6 reclaims stranded wall-clock. These compound: fewer nulls entering means the relaxed regression bar's lower catch rate matters less. Empirical games remain the final promotion authority throughout — nothing here adds an LLM judge to the gate path (SKILL.md safety-rail constraint).

Work (8 steps)

Sequencing: EJ.1–EJ.6 (#282#287) all edit scripts/evolve.py (argparse + loop) → run serially, no parallel worktrees (plan §4). EJ.7/EJ.8 are operator/wait gates.

Acceptance

  • Every flag defaults OFF → byte-identical to today, enforced by regression tests (is/exact-equality), not just review. The ONE deliberate default-visible change is the reworded priors prompt line (src/orchestrator/evolve.py L1484) in EJ.1 — its golden test update is intentional, not drift.
  • For every code step: uv run pytest (≥ 1799 baseline), uv run mypy src bots --strict, uv run ruff check . clean.
  • EJ.7 flags-on real-SC2 smoke completes without crash; every triggered EJ mechanism leaves its audit row; a defaults-off run shows zero behavior change.
  • EJ.8 overnight A/B soak produces a comparison table + default-flip recommendation. NOT gated on showing improvement — a negative result is valid and blocks default flips.

Effort

6 code steps (EJ.1–EJ.6) run serially (shared scripts/evolve.py), then 1 operator smoke (EJ.7) + 1 overnight wait soak (EJ.8).

Kill criterion

None hard — all changes ship flag-gated OFF, so production is byte-identical by default and nothing regresses. A negative EJ.8 result blocks the default-flip recommendation, not the merge. Flipping any default ON is a post-EJ.8 operator decision, explicitly out of this phase's scope.

Relationship to Phase R

The investigation partially supersedes Phase R: SPRT is rejected (negative LLR drift inside the indifference zone at the ~0.6 true win rates this loop produces, at ~3× the game cost of EJ.3's posterior rule). Phase R's Wilson-CI reporting idea remains valid backlog; Phase R should be re-scoped after Phase EJ ships.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions