« Phase 33 README · Warmup · Hitchhiker's · Deep Dive · Core Contributor · Staff Notes
Phase 33 — Principal Deep Dive: Eval-Driven Development
The Deep Dive treats the eval harness as a pipeline in isolation. This document treats it as a
production subsystem that gates deploys, spends real money, holds statistical power it can
run out of, and fails in ways that ship regressions with a green checkmark on them. The Lab 01
RegressionGate and Lab 03 ReleasePipeline are the toy; the architecture question is what it
takes to run that gate against your main branch for two years without it either rubber-stamping
bad releases or blocking good ones so often the team routes around it. Both failure modes end the
same way: an ungated release, which is the exact thing you built the gate to prevent.
EDD as a delivery gate, not a report
An eval report is something you read; an eval gate is something that blocks a merge. The
architectural consequence of that verb is everything. A report can be slow, flaky, and
approximate. A gate sits on the critical path of every engineer's PR, so it inherits the
constraints of a CI check: it must be fast enough that people keep it on, deterministic enough
that a re-run doesn't flip the result, and its failures must be actionable — "blocked: 3
backend cases regressed, safety clean" — not "score went down." A gate that emits a bare number
gets overridden; a gate that names the regressed cases gets fixed.
This forces the two-tier design (Warmup §11), and the tiers are a capacity decision, not a
preference. Full evals run a whole test suite per task, sometimes an LLM judge per case, times k
samples, times N tasks. That is minutes-to-hours and real dollars. You cannot pay it per commit,
so you split: a smoke tier (tag-selected subset, seconds-to-minutes) on every push, and the
full tier (the whole golden set plus the expensive end-to-end and judge cases) on release
branches and nightly. The smoke tier's job is to catch gross regressions cheaply; the full tier's
job is to be the release oracle. Getting the smoke subset wrong in either direction is a real bug:
too thin and it waves through regressions the full suite would catch (and now the release tier is
your first line of defense, hours after the offending commit); too fat and the per-commit cost
pushes people to skip it.
The scaling math you must be able to do live
The cost of one full run is roughly k × N × (model_calls_per_task) × cost_per_call + sandbox_minutes × compute_rate. For an end-to-end coding suite this is dominated by two terms:
the sandbox execution (a container spun up per task, dependencies installed, a test suite run)
and the k samples multiplier. Two levers move it:
- Parallelism over sandboxed execution. Tasks are embarrassingly parallel — each is an
isolated repo at a base commit — so the wall-clock is
total_task_seconds / concurrency, bounded by your executor pool. The architecture is a work queue of(task, sample)units fanned out to a pool of ephemeral sandboxes; the collector reassemblesCaseResults. This is why real harnesses are container-per-instance: isolation and parallelism come from the same decision. - Caching what's deterministic. The base repo state, the dependency install, and — critically —
a
(code_version, dataset_version, task_id, sample)result are cacheable. If neither the agent nor the dataset changed for a task, its result is fixed; re-running it is waste. A content-addressed dataset (Deep Dive, Stage 1) is what makes this cache safe: the cache key includes the dataset hash, so editing a case correctly invalidates exactly the affected entries.
The k multiplier is where principals earn their title. k samples buy you statistical power and
a pass@k signal, but they cost k×. The right k is not a constant; it is large on the small
capability tier (cheap) and small (often 1) on the expensive end-to-end tier, with the power you
lose there bought back by having more tasks instead of more samples.
Statistical power: how many tasks you actually need
The gate is a hypothesis test, and it can be underpowered. The standard error of a pass rate is
sqrt(p(1−p)/N); at p≈0.75, N=50 that is about 0.06, a 95% CI near ±12 points. A gate on a
50-task set literally cannot detect a real 5-point improvement — it is inside the noise. So the
architecture must (a) report a bootstrap CI, not a bare point estimate, and (b) gate on a paired
per-task comparison rather than the aggregate delta, because pairing cancels task difficulty and
recovers most of the power. Lab 01's compare_runs is the mechanism: count wins, losses, ties, and
gate on the net and the regression list. The killer scenario a bare aggregate hides is "fixed five,
broke four, net +2%" — the four regressions are what page you, and the paired view is the only thing
that surfaces them before merge. If you need to prove a small improvement, the answer is not a
fancier test on 50 tasks; it is more tasks. Power comes from N.
Dataset governance: contamination is the silent score inflator
The most dangerous failure of an eval program is not flakiness; it is a number that is high and wrong. The mechanism is contamination — overlap between what the model saw in training and what your eval measures. Public benchmarks are the cautionary tale: HumanEval and MBPP are function-level and largely saturated for frontier models partly because their problems have leaked into training corpora, and SWE-bench's own issue was under-specified and solution-leaked instances, which is exactly why SWE-bench Verified — a human-filtered subset where the tests genuinely specify the fix — exists. The governance rules that follow:
- Held-out means never-looked-at. A slice you evaluate at every release slowly leaks; each look steers you toward it. Rotate it: freeze a fresh held-out slice periodically from the growing set, retire the old one into dev. A held-out set you've read fifty times is half-compromised.
- Provenance per case. Record where each case came from (hand-authored, promoted from a production trace, imported from a benchmark) so you can quarantine a source if it turns out to be contaminated or mislabeled.
- Your golden set is the moat precisely because it isn't public. It encodes your production failures on your codebase — knowledge no benchmark and no competitor has, and nothing a model could have trained on.
Blast radius of a bad grader
Rank the failure modes by blast radius, because that ranking dictates where you spend review.
- A grader that passes wrong outputs (false-positive oracle). This is the worst failure in the system. It ships regressions with a green gate — the gate actively vouches for the bug. The sources are under-specified tests (the SWE-bench-Verified problem), an LLM judge that scores fluent-but-wrong as good, and a patch applier that "succeeds" on a no-op. Mitigation: fail-closed graders, execution over judgment wherever an execution oracle exists, and a periodic human sample to keep the judge honest (validate against labels with Cohen's κ before it gates anything).
- A grader that fails right outputs (false-negative oracle). Less dangerous — it blocks good releases — but it erodes trust until the team disables the gate, and a disabled gate has the blast radius of #1 by other means.
- A flaky grader. A gate that flips on re-run trains everyone to hit "re-run" until green, which
silently converts your strict policy into "pass@many." Decide the flake policy explicitly (Lab 01
defaults to strict: all
nmust pass), retry genuine infra flakes (a sandbox timeout) but never retry a wrong answer into a pass.
Cross-cutting concerns of an eval platform
- Cost and latency as first-class, gated dimensions. The Cohere JD names "accuracy, safety, and latency" together. An agent that resolves 80% in 40 tool calls and $12 is not obviously better than 75% in 6 calls and $0.40; the eval must surface that tradeoff, not hide it. Score tokens, dollars, wall-clock, and step count per task and let a budget fail a resolving task (Lab 02's budgeted failure). This is the same meter you run in production observability, pointed offline.
- Multi-tenancy and isolation. If the platform runs many teams' evals, each task's sandbox is untrusted code (the agent's patch, the repo's tests) and must be isolated — no shared filesystem, no network egress, resource limits, per-tenant cost accounting. The execution grader is a code-execution service, and it inherits every security concern of one.
- Observability of the eval itself. The version ledger (Lab 03) is the minimal form: every release
attempt recorded with
(code_version, dataset_version, scores, released|blocked, reason). That ledger is what answers "when did theauthslice regress and which commit did it" — the question you will be asked in the incident review.
"Looks wrong but is intentional"
Three decisions read as bugs to a junior and are the point to a principal. Flakiness counts as failure — treating a case that passes 4-of-5 as a pass would make the gate lie about reliability, so strict is correct for a gate even though it fails cases that "mostly work." Safety is a veto, not a weighted term — it looks like an un-averaged outlier distorting the score, but a mean is a lossy reduction and safety is exactly the signal you refuse to lose in the average. And the eval set grows forever — an unbounded, ever-changing test suite offends the instinct that says a spec should be fixed, but the input distribution is open, so coverage is impossible and curation-that-grows is the only honest substitute. Each is a deliberate trade of a comfortable property (stable suite, single score, mostly-passing tolerance) for the one thing a release gate must never do: vouch for a regression.