Fail-Closed Eval Gate
A change to an agent or prompt is not shippable until an evaluation suite exists that can fail and block the release. If no eval artifact is present, or if the eval cannot fail, stop and build the gate first.
This is the CI equivalent for AI agents: the check that sits between code-complete and production.
When to run
- A pull request changes agent prompts, system instructions, tool schemas, or orchestration logic
- Someone says "ready to merge" or "ship this"
- A release candidate is proposed
- You're setting up CI/CD for the first time
If you can't name the eval suite and show its last failing run, the change is not gated.
The gate structure
Agent evaluation gates are tiered. Each tier blocks independently — a strong score on one tier does not carry a weak score on another.
Tier 1: Deterministic (runs on every PR)
Fast, non-LLM checks that validate tool-call correctness:
- Tool schema validation — every tool call uses a valid schema with required fields present
- Argument validity — tool arguments parse correctly and meet type constraints
- Sequence correctness — tool calls follow valid state transitions (e.g., no "close issue" before "open issue")
How to implement:
- Record actual tool calls as replay cassettes (golden runs)
- On each PR, replay the cassettes and assert that tool arguments still match expected schemas
- Use libraries like
@agent-eval/replayor write assertions against recorded JSON
Sources:
Tier 2: Behavioral (runs on merge to main or nightly)
LLM-as-judge for semantic correctness:
- Faithfulness — agent cites only information it retrieved; no hallucinations
- Instruction adherence — agent follows the task spec, does not invent steps
- Safety — agent does not execute unsafe actions or leak PII
How to implement:
- Define explicit rubrics per dimension (not "quality" — name the exact condition)
- Use LLM-judge with
repeat: 3andrepeat-min-pass: 2(majority voting to reduce judge flakiness) - Set per-dimension thresholds: a single safety failure blocks the build, even if other metrics pass
Example rubric (faithfulness):
rubric: "The agent cites the tracking number and gives no delivery date it did not look up. Score PASS if true, FAIL otherwise."
Sources:
Tier 3: Regression (runs nightly or on release)
Large-scale suites with incident-derived cases:
- Incident-to-test loop — every production failure becomes a test case
- Edge cases — the long tail of unusual inputs
- Cost and step budget — median token cost and step count must not exceed baseline by more than 15 percent
How to implement:
- Maintain a baseline: advance it only when completion rate improves by at least 1 point or cost drops by at least 10 percent
- Never auto-advance on every green run (slow-cooking regressions)
- Record and version your baseline artifact
Sources:
Stop conditions — when NOT to proceed
STOP if any of the following is true:
- No eval suite exists for this agent or flow
- The eval suite cannot fail (it's always green, or it only logs)
- The eval suite has no tier-1 deterministic checks
- The eval has no per-dimension thresholds (only one aggregate "pass rate")
- The most recent run of the eval suite has no failure artifact (you can't show a red run)
Do not merge. Do not deploy. Build the gate first.
The gate in CI
Wire the gate into the same CI job that runs your unit tests:
# Example GitHub Actions
- name: Run Tier 1 Eval (Deterministic)
run: |
npm run eval:replay -- --suite=tier1 --threshold=100
# Must pass 100% of deterministic checks
- name: Run Tier 2 Eval (Behavioral)
run: |
npm run eval:behavioral -- --suite=tier2
# Per-dimension thresholds set in config
# Blocks on any dimension below threshold
- name: Gate Decision
run: |
# Fail the job if any tier failed
if [ $? -ne 0 ]; then
echo "Eval gate failed. See logs for dimension breakdown."
exit 1
fi
The job must fail when the gate fails. A red PR comment is not enough.
Common mistakes
- Averaging dimensions — "overall score 85%" hides a 50% safety score. Use per-dimension thresholds.
- No replay — running live tool calls in CI makes tests flaky. Record and replay.
- Stale evals — the spec changed but the eval didn't. Eval ownership = spec ownership.
- Gate bypass culture — developers override red gates with "LGTM" comments. The gate must block merges, not just post warnings.
Sources:
Verification checklist
Before you mark a change "ready to ship":
- ☐ A named eval suite exists (
tier1-replay,tier2-behavioral,tier3-regression) - ☐ The suite has run in the last 24 hours
- ☐ The suite has at least one recorded failure (proof it can fail)
- ☐ Per-dimension thresholds are set (safety, faithfulness, instruction adherence)
- ☐ Deterministic replay is enabled for tier-1 checks
- ☐ The gate is wired into CI and blocks merges on failure
- ☐ Incident cases from production are promoted into the regression suite
If any checkbox is unchecked, the change is not gated. Build the gate, then ship.
An eval that cannot fail is observability, not a gate. Treat agent changes like code: no merge without tests, no deploy without CI.