Skip to content
Console
Browse documentation
Reference

Evaluation release gates

Declare release objectives, evaluate admissible evidence, and interpret permanent decisions.

On this page

Start with your first evaluation for a runnable workflow. See API and permissions for endpoint and credential requirements.

Release gates — deciding whether a release may ship

A release gate binds a candidate release to evaluation evidence and produces a pass or a refusal with the reason, kept for ever. It is the thing that turns a comparison into a decision.

A gate is fixed when you create it — its evidence, its objectives, its confidence level. A changed objective is a new gate, because a gate whose bar can move under it is not a gate.

The two kinds of evidence, which are different designs

evidence_kind What it compares Paired?
GATE_EVIDENCE_KIND_EXPERIMENT One arm of a declared experiment against that experiment's own declared baseline, on the same frozen cases. Yes — the same case is scored under both configurations.
GATE_EVIDENCE_KIND_CANARY Two windows of live traffic that you declare: one before the candidate shipped, one after. No. The runs in the two windows are different runs, so the interval carries the full case-to-case variance.

You do not name the comparison arm for experiment evidence — the experiment's own declared baseline is used. Choosing the arm afterwards is how a flattering pair gets picked.

For a canary, the window boundary is your declaration of when the candidate shipped. Everything else that changed at that boundary is confounded with the release, and every stored canary comparison says so in words alongside its numbers, because a narrow interval and a causal claim look identical on a chart.

Each canary window includes its start and excludes its end: [start, end). Selection uses the subject's occurrence time, including windows within one second. Saved window bounds retain microsecond precision; result occurrence times retain nanosecond precision.

Objectives

Each objective names an evaluator at an exact version, the metric it must produce, what to compare, and the line to clear:

basis The number compared against the threshold
GATE_BASIS_CANDIDATE_MEAN The candidate's own average. An absolute floor or ceiling; needs no baseline.
GATE_BASIS_DIFFERENCE_MEAN The point estimate of candidate minus baseline.
GATE_BASIS_DIFFERENCE_INTERVAL The conservative bound of the interval around that difference — the low bound for a floor, the high bound for a ceiling. The strong form: the whole interval must clear the line, so a candidate that passes on noise does not.

comparator is the direction the threshold is checked in:

comparator Passes when the basis value is
GATE_COMPARATOR_GREATER_OR_EQUAL >= threshold
GATE_COMPARATOR_GREATER > threshold
GATE_COMPARATOR_LESS_OR_EQUAL <= threshold
GATE_COMPARATOR_LESS < threshold

threshold is the line itself — the number the basis value is compared to using comparator.

min_samples is required and zero is refused. A gate that will pass on a single observation is something you have to ask for out loud.

min_judge_agreement is optional and puts a floor on how far the objective's evaluator must agree with human judgments — see Calibration. It is not a way to opt out: an objective bound to a decision-score evaluator with no calibration at all is inadmissible whatever this field says, and a gate whose only evidence comes from that evaluator answers GATE_VERDICT_INADMISSIBLE rather than passing. Leaving it at zero asks only that a calibration exist.

The rule applies to decision-score evaluators alone, the one kind a model answers. A deterministic or reference-trajectory evaluator is reproducible from its own definition and is calibrated against nobody, so nothing is asked of it.

Calibration is resolved when the gate is evaluated, not when it is created. A gate written before its evaluator was calibrated passes once the evaluator is; an evaluator whose calibration was superseded by an edited judgment set stops passing until it is recomputed.

An objective is checked against your evaluator registry when the gate is created, including that the evaluator you named actually produces the metric you named — so a gate that could only ever measure nothing is refused before it exists rather than after a release waited on it.

Verdicts: only GATE_VERDICT_PASS passes

Verdict What it means Where to look
GATE_VERDICT_PASS Every objective was measured on admissible evidence and met. —
GATE_VERDICT_FAIL At least one objective was measured and missed. The objective's numbers.
GATE_VERDICT_PENDING Created, never evaluated. Not a pass. Evaluate it.
GATE_VERDICT_NO_EVIDENCE An objective had nothing admissible to measure, or less than it declared it needs. Your sampling — nothing ran.
GATE_VERDICT_INADMISSIBLE Results exist for an objective and none of them may be used — incomplete provenance, an execution record that cannot say how the score was produced, a job that did not complete, or a decision-score evaluator that has not been calibrated. Your evaluator reference — things ran, and cannot be used.
GATE_VERDICT_RELEASE_MISMATCH Every objective met, but the candidate runs did not all observably declare the release the gate names. Not a pass. The decision's release_binding: it distinguishes another release, no declared release, partial instrumentation, and an unmeasured subject shape.

The last two are kept apart deliberately: "nothing ran" and "what ran cannot be used" are different problems with different fixes, and one empty answer cannot tell them apart.

Per objective you also get observed_present, which is the only way to tell "the value was 0" from "there was no value". A score of 0.0 is a legitimate measurement, so the number can never be that discriminator — never infer absence from observed_value. inadmissible_samples counts results that exist and may not be used; they are reported rather than filtered away, for the same reason.

Evaluating one

The first request computes a complete preview of the verdict, objective outcomes, sample counts and release binding, without storing a decision. A stable idempotency_key is required through REST, MCP or anectico evals gates evaluate --idempotency-key <key>. Review the complete current and proposed state, then repeat identical arguments with the returned confirm_token (CLI --confirm-token). If the evidence changed, obtain and review a new preview.

Confirmation appends one permanent decision. Reusing its key returns that original decision, even if new results arrive later. Its decided_at, counts and outcomes describe the original evidence snapshot. Use a new explicit key for a fresh decision; it is stored beside the first. Gate reads return one page of decision history; follow pagination.next_cursor with unchanged filters.

A gate never runs an evaluator and never spends your evaluation budget. That is deliberate — a gate that produced its own evidence on demand could never report GATE_VERDICT_NO_EVIDENCE, which is the one answer it exists to make reachable. Score first, then gate.

If the evidence store cannot be read, you get an error and nothing is stored. "We could not look" is never recorded as "we looked and found nothing".

A release label is a claim that the evidence must prove

release is the label you declare when creating the gate. Evaluation reconciles it against the release actually carried by every admissible candidate run, deduplicated across objectives; baseline runs are expected to belong to the earlier comparison arm and do not participate in this check.

Every decision stores release_binding with the observed release names, released, unreleased, and unmeasured subject counts, a reason, and one of GATE_RELEASE_BINDING_STATE_MATCHED, GATE_RELEASE_BINDING_STATE_MISMATCH, GATE_RELEASE_BINDING_STATE_UNDECLARED, GATE_RELEASE_BINDING_STATE_PARTIAL, GATE_RELEASE_BINDING_STATE_UNMEASURED, or GATE_RELEASE_BINDING_STATE_NO_EVIDENCE. Only GATE_RELEASE_BINDING_STATE_MATCHED may accompany GATE_VERDICT_PASS. If the objective numbers meet but the label does not, the verdict is GATE_VERDICT_RELEASE_MISMATCH rather than a green decision carrying a warning. If an objective already missed, the verdict remains the more direct GATE_VERDICT_FAIL, but the same binding discrepancy is still recorded.

“No release declared” is a first-class answer. A gate evaluated over those runs returns binding GATE_RELEASE_BINDING_STATE_UNDECLARED and cannot pass; it does not error, silently discard those runs, or pretend they belong to the gate's label.