Model Evaluation Service

Architecture Views

21 views, in reading order. Every view ships three ways: an HTML page, an SVG that re-opens in diagrams.net fully editable, and draw.io source.

The system that decides whether the next version of a consumer AI assistant reaches its 40 million users. Read it in seven acts: what sits inside the boundary, who it serves and what they get to do, how it is put together, what it stores, what happens when a candidate is evaluated, how it is operated, and why it is safe. One rule runs through every view — a score is permanently bound to the frame that produced it, and two scores from different frames are never compared.

Context and scope

What the platform is asked to decide, who asks, and what it deliberately does not own.

People and journeys

Who this is for, what each of them is trying to get done, and where the experience actually fails.
03 The people who ship models ML Engineer 25 candidates / week Goal — Find out whether my change made the assistant better, before I have to defend it in a review. Core journeys Run a smoke check ≤ 8 min, waits for it Take a candidate through the gate ≤ 90 min Argue with a block wants the examples Product Manager owns the assistant Goal — Know what this release actually changes for users, in plain terms, before it goes out. Core journeys Read the release evidence Check a cohort that matters language · task The people who own quality Quality Lead 18 suites · 34 gated slices Goal — Keep the gate trusted — sensitive enough to catch regressions, honest enough that nobody routes around it. Core journeys Author a suite and its gate Approve a frame change costs a re-baseline Review the waiver register Human Rater 40 reviewer-h / week Goal — Judge which answer is actually better, without being told which one the company hopes wins. Core journeys Label the calibration set Adjudicate a blocked regression blinded pairwise The people who carry the release Release On-Call rollout + rollback Goal — Ship when the evidence says ship, and get the old model back fast when it does not. Core journeys Watch a canary Roll back on a guardrail breach ≤ 5 min Privacy Officer governs production-derived data Goal — Be able to say exactly which user data is in which dataset, and get it out when asked. Core journeys Trace an example to its consent Action a deletion request Who this is not for End User 40 M monthly Goal — Never meet this platform, and never meet the release it stopped. Core journeys Gets a better assistant or does not get a worse one Model Evaluation Service — Actors and Their Core Journeys The end user is the beneficiary and never a participant — the only evidence they generate is telemetry, redacted before it becomes an example. v 1.0 · owner Data & AI Global Practice · date 2026-09 Actors and Their Core Journeys Six kinds of people, what each of them is actually trying to achieve, and the end user who must never meet the platform. HTML page SVG draw.io
04 ML Engineer ships 2-3 candidates a week Goal — Get a defensible yes or no on a prompt change before the end of the day Trigger — A rewritten system prompt that looks better on a dozen hand-picked examples Done when — A PASS with evidence, or a BLOCK naming the slice and the examples that moved 1 · Try local, hand-picked 2 · Smoke 400 examples 3 · Submit config pinned 4 · Wait ≤ 90 min ◆ moment of truth 5 · Read the verdict ◆ moment of truth 6 · Act What they do Eyeballs a dozen outputs Runs the smoke tier Pins the full config Submits the candidate Works on something else Opens the slice report Fixes, waives or ships Where Notebook CLI CLI · register Chat notification Verdict page Pull request What the platform does Nothing — not its job 400 examples · 3 gens Digest · frame resolve Cost ceiling check 6,500 × 3 gens 39k judge calls Per-slice deltas + CI Records the decision Feeling Confident Encouraged Fiddly Blocked and idle Blocked — on one slice Knows what to fix User Journey — ML Engineer Takes a Candidate Through the Gate The trough is the 90-minute wait followed by a block on a slice the engineer never looked at. The smoke tier exists to move that discovery earlier; the example-level diff exists to make the block arguable rather than final. v 1.0 · owner Data & AI Global Practice · date 2026-09 Journey — Taking a Candidate Through the Gate The engineer's day: a prompt change that looked good on a dozen examples, and what the gate does with it. HTML page SVG draw.io

Structure

The parts, the planes they belong to, and the surfaces other systems touch.

Data

What is immutable and why, who owns each store, and how a score stays meaningful for five years.
11 candidate candidate_id PK config_digest UNIQUE model_ref prompt_version tool_defs_version index_version is_incumbent submitted_at frame frame_id PK dataset_version FK scorer_version judge_version harness_version retired_at run run_id PK candidate_id FK frame_id FK suite_id FK state harness_error_rate cost_cents dataset_version dataset_version PK dataset_id class owner example_count published_at example example_id PK dataset_version FK input_ref slice_labels provenance consent_state is_canary tombstoned_at score score_id PK run_id FK example_id FK frame_id FK scorer_id FK value generation_idx trace_ref superseded_by suite suite_id PK dataset_id FK gated_slices repetitions online_correlation scorer scorer_id PK family version rubric_version kappa_vs_human gate_admissible gate gate_id PK suite_id FK slice strength threshold alpha verdict verdict_id PK candidate_id FK frame_id FK outcome baseline_run_id FK decided_at human_label label_id PK example_id FK rater_id preference blinded labelled_at waiver waiver_id PK verdict_id FK gate_id FK approver reason expires_at evaluated by scopes scored as emits labelled by cleared by excused by gated by Model Evaluation Service — Core Data Model frame_id on both run and score is deliberate redundancy: a score must be self-describing even if its run row is lost, because the frame is what makes the number mean anything. Three foreign keys are carried as columns rather than drawn — score.run_id, example.dataset_version and suite.dataset_id — to keep the relations readable. v 1.0 · owner Data & AI Global Practice · date 2026-09 Core Data Model Twelve entities, and the one foreign key that carries the whole architecture. HTML page SVG draw.io

Runtime

What actually happens when a candidate is evaluated — and what a frame change costs.

Operations

How the platform is built, released, watched, and how the loop back from production closes.

Assurance

Why running model-written tool calls at volume is safe, and who may change a gate.

Architecture One-Pager

The problem, the shape of the answer, the decisions that carry it, and why it should still be right in ten years.

A score is a fact about a comparison frame, not about a model. Two scores from different frames are never compared — the incumbent is re-scored instead.

Every week, a team ships a new version of an AI assistant to 40 million people. A new base model, a rewritten system prompt, a changed tool definition, a different retrieval configuration — each one a bet that the assistant got better, and each one capable of making it quietly worse for a cohort nobody checked. The question the organisation needs answered is narrow and hard: is this candidate better than what users have today, and where is it worse? Answering it requires measuring open-ended quality at a volume no human team can reach, which forces a model into the role of judge; and it requires those measurements to stay comparable for years, across corrections to the corpus, clarifications to the rubric, and upgrades to the judge itself. The second requirement is the one that is usually lost. A platform that loses it does not fail loudly — it keeps producing confident numbers that mean nothing, indefinitely, without ever erroring.

A candidate is a fully pinned configuration, identified by its digest. A run is planned against a comparison frame — dataset version, scorer version, judge version, harness version — resolved before any inference is bought. A harness fans out across GKE, generating outputs with tools executed in a kernel-isolated sandbox that has no route to production, and stores a full trace for every generation. A separate scoring stage reads those traces: deterministic checks, a pinned and calibrated model judge evaluating both orderings of every pair, and a sampled human audit. Scores are appended to BigQuery as immutable facts, each stamped with its frame. The gate engine compares candidate against incumbent within a single frame, per declared slice, with an interval on every delta, and returns PASS, BLOCK or INSUFFICIENT_EVIDENCE to a deployment pipeline that will not release without an affirmative pass. Exposure is staged — shadow, canary, progressive rollout — with online guardrails armed to roll back automatically, and production failures flow back into targeted regression sets so that every incident becomes a permanent test.

What it is, and what it is not

A measurement bound to the conditions that produced ita score attached to a model version, compared across years of silently changing corpora and rubrics.
A comparison against the incumbenta benchmark leaderboard position, or a score against an absolute threshold that ages out.
A judge under calibration control, with published agreement and a revocable licence to blockwhichever strong model was available, trusted because its rationales read well.
A three-valued verdict where absence of evidence stops a releasea pass/fail gate that quietly lets an incomplete run through.
A small, declared set of gate-bearing slices with a stated error preferencegating on every measurable cohort and discovering the false-block rate later.
Safety, latency and cost as independent vetoesa composite quality score in which a large enough helpfulness gain can outvote a safety regression.
An untrusted workload executing model-generated tool calls in isolationan internal batch job that happens to call some APIs.
Offline as a proxy that must earn its place by predicting online outcomesa growing collection of suites nobody can justify or retire.

The decisions that are the architecture

01A score is bound to its frame

The tuple (dataset × scorer × judge × harness) version is part of a score's identity. Cross-frame comparison is a rejected operation, not a discouraged one.

ADR-01

02Frame changes re-score the baseline

The incumbent is re-scored in the new frame; its old number is never reinterpreted. Gating is suspended until that completes, and the cost is a budgeted line.

ADR-02

03Immutable corpus, append-only scores

A dataset correction publishes a new version; a score correction supersedes rather than updates. This is what makes a three-year-old number interpretable.

ADR-03

04The subject is the whole configuration

Model, prompt, tools, retrieval index, decoding and safety filter together. Scoring the model alone confounds a prompt edit with a model upgrade.

ADR-05

05Generation is separate from scoring

Traces are stored, so a rubric clarification costs a scoring pass rather than a full generation sweep — and a blocked engineer can read what actually happened.

ADR-06

06The judge is an instrument under calibration control

Pinned version, continuous drift detection against a fixed calibration set, and a published agreement threshold below which it may observe but not block.

ADR-08

07Absence of evidence is not a pass

INSUFFICIENT_EVIDENCE is a distinct verdict. An incomplete run, an unavailable judge or an unevaluated gated slice stops the release.

ADR-11

08Guardrails veto rather than trade

Safety, latency and cost block regardless of quality gain, and safety guardrails have no waiver path in code.

ADR-13

09Fail closed, in the consumer's contract

A pipeline that cannot reach the gate does not release. The property lives where an outage of the platform cannot reach it.

ADR-14

10The harness is untrusted

It executes text a model wrote, against tools, at volume. Kernel isolation, denied egress and a hard in-harness cost ceiling follow from that classification.

ADR-18

Why this should still be right in ten years

An evaluation platform outlives the models it was built to judge, because its output is the historical record an organisation uses to know whether it is getting better. These are the properties that should survive a change of model, of cloud, and of the people who built it.

The frame rule names no technology

ADR-01 depends on nothing about BigQuery, Google Cloud, or any judge. It is a statement about what a measurement means, and it survives replacing every component underneath it. It is also the property a future team would most easily discard without noticing, which is why it is enforced by a rejected query rather than a convention.

Re-baselining gets cheaper, not more painful

The main cost of the design is re-scoring the incumbent on every frame change. Inference costs fall and caching improves; the discipline therefore becomes easier to sustain over time rather than harder, which is the right direction for a rule that must not be broken.

Judge authority is data the gate reads

Admissibility lives on the scorer row, not in a policy document. A future team swapping in a judge nobody has calibrated finds it cannot block, without anyone having to remember why.

The three-valued verdict outlasts its metrics

Suites, slices and thresholds will all churn. The distinction between 'worse' and 'unknown' will not, and any future gate built on this platform inherits it for free.

Untrusted-by-classification ages well

As agents gain more tools and more autonomy, treating model output as untrusted input moves from prudent to obvious. This decision will read as unremarkable long before it stops mattering.

The named compromise is recoverable

The erasure-versus-immutability gap in ADR-17 is written down rather than hidden. A future team facing tighter obligations can make a different trade knowingly, which is not possible when a compromise was made silently.

Non-functional targets

Every number here is a stated assumption from the requirement, chosen to be argued with rather than believed. The right-hand column names the view where the mechanism that meets it is drawn.

QualityTargetHow it is metView
Gate decision availability ≥ 99.9% monthly, in release windows Control plane across two zones; the verdict API is the only synchronous obligation, and fail-closed lives in the pipeline's contract rather than here. 16
Smoke tier latency ≤ 8 min p95, 400 examples A small subset of the gating suite on the same execution pool at interactive priority — the only tier a human waits on. 04
Gate suite latency ≤ 90 min p95, ≤ 150 min p99 6,500 examples × 3 generations fanned across 0-600 harness pods, each example independently retryable. 12
Full regression sweep ≤ 6 h p95, 42,000 examples Same pool at lower priority, on Spot capacity with checkpointed resume. 16
Re-baseline window ≤ 12 h across all gating suites Queued ahead of candidate runs on a frame change, so a rubric edit lands inside one working day. 15
Throughput 1,200 generations/min steady, 4× burst for 30 min Pub/Sub work items against an autoscaling node pool, rate-limited against shared serving quota. 13
Slice query latency ≤ 3 s p95 over 12 months of scores BigQuery partitioned by run and clustered by slice; ~55 M rows/year. 18
Judge agreement ≥ 0.75 κ to gate; < 0.65 κ inadmissible Calibration against ≥ 1,200 human labels per rubric, stored on the scorer row and read by the gate engine. 14
Detection power 2 pp regression at ≥ 90% power, α = 0.05 The requirement that sets the 6,500-example suite size, evaluated as a paired comparison against the incumbent. 12
False-block rate ≤ 5% of candidates 34 declared gate-bearing slices rather than every measurable cohort, with human adjudication on every block. 14
Reproducibility ± 0.5 pp on ≥ 99% of re-runs Stored (candidate, frame) re-runs against immutable artefacts; bounded by the tombstone case in ADR-17. 11
Rollback latency ≤ 5 min p99 from guardrail breach Continuous guardrail evaluation against serving telemetry, emitting a rollback trigger without waiting for analysis. 19
Cost per gate run ≤ $340 fully loaded; judge ≤ 55% In-harness ceiling that halts the run, plus per-team monthly budgets enforced at admission. 18
Evaluation spend ≤ 2.5% of production inference spend Suite cost reported against measured offline-online correlation, so an unproductive suite is a visible retirement candidate. 18
Verdict retention 7 years, immutable Append-only verdict records in BigQuery with no update or delete path; traces for blocking runs held 3 years. 10
Recovery Scores RPO 0 / RTO ≤ 4 h; run state RPO ≤ 5 min Managed multi-region stores; in-flight runs resume from checkpoint rather than restarting. 16

Scope

In scope

  • Candidate registration with full-configuration identity, and maintenance of the incumbent pointer.
  • Versioned, immutable datasets in three classes — frozen golden, rolling production sample, targeted regression — with provenance and slice labels.
  • Harness execution with tool sandboxing, trace capture, checkpointed resume and harness-error classification.
  • Deterministic scorers, a calibrated and drift-monitored model judge, and the human audit and adjudication paths.
  • Frame-bound append-only scoring, and a gate engine that refuses cross-frame comparison.
  • Per-slice and guardrail gates, the three-valued verdict, and the waiver register.
  • Staged online exposure, guardrail-triggered rollback, and the loop from production failure back into targeted regression sets.

Explicitly out of scope

  • Training, fine-tuning and serving. The platform measures a candidate; it does not produce or run one.
  • Choosing which candidate to build — a research decision this platform informs rather than makes.
  • General observability of the assistant in production. Serving telemetry is an input, not a product.
  • Experiment design and analysis beyond the declared guardrail and rollout metrics.
  • Human rater recruitment, payment and workforce management, which the rater console vendor owns.
  • Model safety policy itself. The platform enforces safety gates; it does not decide what is safe.

What a four-week prototype should prove

Four of this architecture's claims are cheap to test and expensive to be wrong about. A prototype that proves these can be built on; one that skips them is a demonstration of running a benchmark, which is the easy half.

  1. Frame enforcement end to end: register a frame, score a candidate, change the rubric, and confirm the platform refuses the comparison and enqueues a re-baseline rather than quietly reusing the old number.
  2. Judge calibration and drift: measure κ against 1,200 human labels, then re-score the calibration set daily for four weeks and confirm the monitor would detect a deliberately substituted judge version.
  3. Cost and latency at scale: 6,500 examples × 3 generations × 2 judge orderings on the target node pool, with wall-clock p95 and fully-loaded cost measured against the $340 and 90-minute assumptions.
  4. Caching honesty: run the same deterministic candidate twice and confirm reproducibility within ±0.5 pp; run a stochastic one twice and confirm the cache correctly misses.
  • Kill the judge endpoint mid-run and confirm the run pauses and resumes rather than substituting a different judge or scoring the gap as failure.
  • Submit a candidate with a deliberately injected 3-point regression in one language slice and confirm the gate blocks on that slice, names the examples, and routes to adjudication.
  • Make the evaluation platform unreachable and confirm the deployment pipeline stops rather than proceeding, timing out to pass, or finding a break-glass path.
  • Raise a deletion request for a user whose conversation became an example, and confirm the tombstone path executes and the affected verdict is correctly marked as no longer fully reproducible.

Open risks, carried rather than hidden

RiskIf it landsResponse
Re-baselining proves unaffordable If a frame change costs more than modelled, teams will avoid changing rubrics and datasets — and a corpus nobody improves is the slow version of the problem the frame rule exists to solve. Measure re-baseline cost in the prototype. The mitigation is score caching for scorer-only changes (ADR-16), which requires the temperature-zero question to be settled.
Gating at temperature zero mis-measures production The cache, and much of the cost model, assumes gating suites can run deterministically. If deterministic runs do not represent live behaviour, the largest cost lever disappears. Compare deterministic and stochastic runs of the same candidate across all gate-bearing slices before committing to the cache.
Judge agreement is lower than assumed If no available judge reaches 0.75 κ on the rubrics that matter, the gate has no automated blocking authority and human capacity becomes the binding constraint immediately. Measure κ first, on the real rubrics. The fallback is narrower rubrics with higher agreement, plus deterministic scorers carrying more of the gating load.
False blocks erode trust in the gate A gate people route around is worse than no gate, because it carries authority it no longer earns. The 34-slice set and the 5% target are modelled, not measured. Track false-block rate from the first week and treat a breach as a policy defect. Reducing the gate-bearing slice set is the available lever.
The erasure gap widens ADR-17 accepts that a tombstoned example makes a verdict not fully reproducible. Tightening obligations could make tombstoning insufficient and force retroactive corpus changes. Track what fraction of gating examples are production-derived. If it is small, migrating gating suites to synthesised or licensed material removes the conflict rather than managing it.

Architecture Decision Record

Why every component and every technology on these 21 views is what it is, and what each choice costs.

Eighteen decisions make up this architecture. Everything else across the twenty-one views is convention, sizing or consequence. Each record states the forcing question, the context that makes it hard, what was decided, how it is realised on Google Cloud, the options weighed, what the choice buys and costs, the conditions that would flip it, why it should still be right in ten years, and the lesson that transfers beyond this platform.

Status of this document. This is a design, not a report on a running system. The rates, latencies, volumes, retentions and thresholds are the requirement's stated assumptions for a consumer AI assistant — 40 million monthly active users, 25 release candidates per week, 18 suites over 42,000 examples — invented to be defensible and arguable rather than absent. They are to be replaced by measured telemetry before build, and four of them in particular are the first numbers real data should overturn: the 0.75 κ judge-admissibility threshold, the 2 percentage-point detectable regression that sets the 6,500-example suite size, the 5% false-block rate, and the assumption that judge inference is no more than 55% of run cost.

How to read a record

QuestionThe forcing question: why a decision was needed at all.
ContextThe requirement, the scale and the constraint that make it hard.
DecisionWhat this architecture does, stated so it can be checked.
How it is realised on Google CloudThe concrete mechanism: which service or package, configured how, in which project.
Options weighedChosen, rejected, deferred, or right elsewhere, with the reason for each.
ConsequencesWhat the choice buys and what it costs, both kept visible.
Choose differently whenThe conditions that would flip the decision for your system.
Why it holds up over timeWhat keeps the decision right as scale, staff and technology change.
LessonThe principle that transfers beyond this platform.

Decision map

Comparability and the frame 4

What a score is a fact about, and why two numbers may not be placed side by side.

ADR-01A score is bound to a comparison frame, and cross-frame comparison is a rejected operation ADR-02A frame change re-scores the incumbent rather than reinterpreting its stored number ADR-03Datasets are immutable, versioned artefacts; a correction publishes a new version ADR-04Scores are append-only facts; a correction supersedes rather than updates

What is measured 3

The subject of an evaluation, and the corpus it is evaluated against.

ADR-05The evaluation subject is the full pinned configuration, not the model ADR-06Generation and scoring are separate stages joined by a stored trace ADR-07Three dataset classes: a frozen golden set, a rolling set, and targeted regression sets

The judge as an instrument 3

Using a model to score a model, without pretending the ruler is fixed.

ADR-08The judge is pinned to an explicit version and monitored for silent drift ADR-09A judge may block a release only above a published agreement threshold ADR-10Known judge pathologies are countered structurally, not by prompt wording

The decision 4

How evidence becomes a verdict, and what happens when there is not enough of it.

ADR-11The verdict is three-valued: PASS, BLOCK and INSUFFICIENT_EVIDENCE ADR-12Gates are evaluated per slice against a declared gate-bearing set ADR-13Guardrail gates block regardless of quality gain, and safety guardrails are never waivable ADR-14Fail closed is a property of the pipeline's contract, not of the platform's availability

Offline and online 2

The proxy, the truth, and how each earns its authority.

ADR-15Offline gates entry to exposure; online guardrails gate rollout and trigger rollback ADR-16Suites justify themselves by predicting online outcomes, and cached scores must not assert false determinism

Data, cost and safety 2

User data under an immutable corpus, and running generated code at volume without an unbounded bill.

ADR-17Production examples are redacted at admission, and erasure is a tombstone with bounded reproducibility ADR-18The harness is an untrusted workload, and every run carries a hard cost ceiling

Technology by capability

Every capability and what it is realised with, the origin of that choice, the alternative that was weighed, and the record that argues it. The requirement stays vendor-neutral throughout; this table is where the architecture commits to Google Cloud.

Open source This design
CapabilityChoiceOriginCredible alternativeWhy this oneRecord
Score store BigQuery, EU multi-region, partitioned by run and clustered by slice Google Cloud ClickHouse on GKE with object storage The dominant query is a per-slice comparison across tens of millions of frame-bound rows with a 3-second p95 target; a columnar warehouse with no cluster to operate wins on both the query shape and the operational burden. ADR-01
Dataset, trace and artefact store Cloud Storage, dual-region, object versioning on, in a separate project Google Cloud A content-addressed store built on a filesystem Immutability and retention are enforced by the platform rather than by application code, and project separation puts the corpus outside every execution-plane identity's reach. ADR-03
Run, candidate and frame state Cloud SQL for PostgreSQL, HA, point-in-time recovery Google Cloud Spanner Single-region transactional state at modest volume with an RPO of 5 minutes; Spanner's global consistency buys nothing here and costs materially more. ADR-02
Execution fan-out GKE node pool on Spot capacity with an on-demand floor Google Cloud Cloud Run jobs, or Batch 0-600 pods with checkpointed resume makes re-baselining a natural fit for interruptible capacity, while the on-demand floor protects gate runs inside a release window. ADR-06
Work distribution and events Pub/Sub, six topics Google Cloud Cloud Tasks, or a queue on Redis Independently retryable per-example work items with at-least-once delivery, and the same spine carries verdict and drift events to consumers. ADR-06
Candidate inference Vertex AI endpoints, pinned model versions Google Cloud Direct provider APIs for everything The primary in-house model is served here already; pinning is first-class and quota is manageable against production serving. ADR-05
Judge inference External provider API, pinned version, behind an egress allowlist Third party A self-hosted open-weight judge Judge quality currently justifies the dependency; ADR-08 exists precisely because that dependency cannot be trusted to stay fixed, and ADR-18 keeps the egress path narrow. ADR-08
Tool sandbox gVisor-isolated pods, egress denied, side-effect-free tool stubs Open source on Google Cloud Plain containers with network policy The workload executes model-generated tool calls at volume; kernel-level isolation is proportionate to running untrusted generated code. ADR-18
Score cache Memorystore, keyed by candidate, example and frame Google Cloud No cache The single largest cost lever, admitted only for deterministic candidates — a cached score for a stochastic candidate asserts a determinism it does not have. ADR-16
Redaction at admission Sensitive Data Protection, versioned inspection templates Google Cloud A bespoke redaction service Production-derived examples must be de-identified before anything is durable, and the redaction version is recorded so the treatment applied to an example is itself auditable. ADR-17
Data perimeter VPC Service Controls around the corpus, label and trace projects Google Cloud IAM alone IAM governs who may call; a service perimeter governs where data may go, which is the control that survives a leaked service-account key. ADR-18
Workload identity Workload Identity Federation, short-lived tokens only Google Cloud Service account keys There is no long-lived credential anywhere in the policy path, so a gate change cannot be made by anything holding an old secret. ADR-14
Policy source of truth Git repository with enforced two-person review Open source A policy table in Cloud SQL A gate is a production control; it must be reviewable, diffable and impossible to edit in place, which a database row is not. ADR-14
Platform CI/CD Cloud Build to Artifact Registry with signed images Google Cloud GitHub Actions with Workload Identity Federation Keeps the build identity inside the same trust domain as the perimeter, and the synthetic regressed candidate runs as a release gate on the platform itself. ADR-13
Observability OpenTelemetry into Cloud Monitoring, quality signals into BigQuery Open source on Google Cloud A self-hosted Prometheus and Grafana stack Operational signals and measurement-quality signals have different shapes: one is time series, the other is a statistic over scores, and each goes where it belongs. ADR-08

The decisions, and the alternatives that lost

Comparability and the frameWhat a score is a fact about, and why two numbers may not be placed side by side.

ADR-01

A score is bound to a comparison frame, and cross-frame comparison is a rejected operation

Accepted

Is a score a property of a candidate, or a property of a candidate measured a particular way?

Context
The natural schema stores `candidate-7 scored 0.83`. It makes the dashboard trivial and it is wrong in a way that takes about a year to surface. Datasets get corrected. Rubrics get clarified. A judge is upgraded because the old one could no longer separate two good answers. The harness changes how it truncates context. Each change is individually reasonable and individually small, and each silently redefines what the stored number means. A year later the quality chart shows a smooth upward line assembled from measurements never taken the same way, and nobody can say which improvements were real. This is not a data-hygiene issue: it is the failure mode that makes an evaluation platform actively harmful, because it produces confident numbers that mean nothing and produces them indefinitely without ever erroring.
Decision
A comparison frame is the tuple (dataset version × scorer version × judge version × harness version). Every score carries its frame_id as part of its identity, not as metadata beside it. The gate engine and the reporting layer refuse — explicitly, with an error — any request that would place two scores from different frames on the same axis.
How it is realised on Google Cloud
`frame` is a first-class table in Cloud SQL with the four axes as columns and a `retired_at`. `frame_id` is a required column on both `run` and `score` in BigQuery, and every comparison query joins through it. The frame resolver runs at plan time, before any inference is purchased, so a run that cannot be compared is never paid for.
Options weighed
  • ChosenFrame as part of score identity, cross-frame comparison refused: Comparability by construction. Costs a re-baseline on every frame change and occasionally forces the platform to tell someone their chart cannot be drawn.
  • RejectedFrame as metadata, comparison discouraged by convention: Every team intends to check the metadata. None does, at 2 a.m., in a quarterly review deck. A convention that is not enforced is a defect with a documentation page.
  • RejectedNormalise old scores into the new frame with a correction factor: Requires knowing the mapping between frames, which is exactly what has not been measured. It converts an honest 'cannot compare' into a plausible wrong number.
Consequences
What it buys
  • A number produced today can be honestly placed next to one from eighteen months ago, or the platform says why it cannot.
  • Every expensive property of this architecture — immutable datasets, append-only scores, a pinned judge — follows from one rule rather than from a list of best practices.
  • A scorer defect becomes visible, because fixing it is a frame change that forces a re-baseline rather than a silent shift in the series.
What it costs
  • Every frame change costs a full re-scoring of the incumbent, which is a standing budget line rather than an exception.
  • The platform will sometimes refuse to draw a chart someone wants, which is an unpopular property that has to be defended repeatedly.
Choose differently when
If the organisation genuinely never changes a dataset, rubric, judge or harness — which no organisation does past its first year — the frame collapses to a constant and this machinery is overhead. More realistically: if a cheap, validated mapping between frames could be established empirically, normalisation would become defensible and the refusal could soften into a warning.
Why it holds up over time
The rule names no technology. It survives replacing BigQuery, Google Cloud, the judge and the harness, because it is a statement about what a measurement means rather than about where it is stored. It is also the property a future team would most easily throw away without noticing, which is why it is enforced by a rejected query rather than by a paragraph in a README.
LessonWhen a system produces numbers that will be compared over time, the conditions of measurement are part of the measurement. A metric store that cannot say how a number was produced will eventually be a very confident liar.
Shown on views06 11 12 15
ADR-02

A frame change re-scores the incumbent rather than reinterpreting its stored number

Accepted

When the dataset, rubric, judge or harness changes, what happens to the baseline the next candidate will be compared against?

Context
ADR-01 makes cross-frame comparison illegal, which leaves an operational question: a rubric is clarified on Tuesday, and on Wednesday an engineer submits a candidate. The incumbent has no score in the new frame. The tempting answers are to carry its old number forward — which is precisely the comparison ADR-01 forbids, performed by a different route — or to compare the candidate against an absolute threshold, which answers a different question than 'is this better than what users have'.
Decision
The incumbent is re-scored in the new frame before gating resumes. Gating is suspended between frame registration and the completion of that re-score, and the suspension is announced rather than discovered. Re-baselining capacity is budgeted as a recurring cost sized to complete across all gating suites within a declared window.
How it is realised on Google Cloud
The frame resolver checks for an incumbent score in the resolved frame at plan time. If it is absent, the run planner enqueues the re-baseline ahead of the candidate's own run on the same execution pool, at higher queue priority, and reports both costs against the change that caused them. Target: all gating suites re-scored within 12 hours.
Options weighed
  • ChosenRe-score the incumbent, suspend gating until done: Honest and expensive. Makes the price of a frame change visible at the moment it is approved.
  • RejectedCarry the incumbent's old score forward: It is the forbidden cross-frame comparison wearing a different name, and it is undetectable once done.
  • RejectedGate against an absolute threshold while re-baselining: Answers 'is this good enough' rather than 'is this better', and thresholds drift out of date faster than baselines do.
  • DeferredLazy re-baseline: score the incumbent only on slices the candidate touched: Attractive for cost, and correct only if slices are independent. Worth revisiting once per-slice variance is measured.
Consequences
What it buys
  • A frame change is a priced decision. The quality lead approving a rubric edit sees the compute bill and the gating pause before approving it.
  • The baseline is always real rather than inferred, so a gate never blocks on a difference that is partly an artefact of changed measurement.
What it costs
  • Gating stops for up to a working day after a frame change, which is genuinely disruptive on a week with several.
  • Re-baselining consumes capacity that would otherwise evaluate candidates, so frame changes compete with releases.
Choose differently when
If score caching proves safe at scale (ADR-16), a re-baseline for a scorer-only change becomes a re-score of stored outputs rather than a re-run of the model, which cuts the cost by roughly the generation share and could remove the gating pause entirely.
Why it holds up over time
The rule follows from ADR-01 rather than from any implementation, so it holds as long as that does. What will change is the price: cheaper inference and better caching make re-baselining less painful over time, which strengthens the decision rather than weakening it.
LessonA rule that is expensive to honour will be quietly broken unless the cost of honouring it is budgeted in advance. Naming the price is what keeps the rule real.
Shown on views12 15 17
ADR-03

Datasets are immutable, versioned artefacts; a correction publishes a new version

Accepted

When an example is found to be wrong — a bad reference answer, a mislabelled slice — is it fixed in place or superseded?

Context
Fixing in place is obviously convenient and quietly catastrophic under ADR-01: a score references a dataset version, and if that version's content can change, the frame no longer identifies anything. Every score computed before the fix silently becomes a measurement of a corpus that no longer exists, and there is no way to detect that from the data.
Decision
A dataset version is immutable once published. Corrections, additions and removals produce a new version with a new identifier. Old versions remain readable indefinitely because scores reference them. Every example carries provenance — source, date, consent state, approver — and slice labels, and a gating dataset must have a named, current owner.
How it is realised on Google Cloud
Dataset versions are content-addressed objects in Cloud Storage in a separate `mes-corpus` project, with object versioning on and no delete role granted to any execution-plane identity. The manifest is the dataset's identity; examples are addressed from it.
Options weighed
  • ChosenImmutable versions, corrections publish anew: The only option compatible with ADR-01. Costs storage, which is the cheapest thing in this architecture.
  • RejectedMutable datasets with an audit log of edits: The log tells you an edit happened; it does not make the old scores meaningful again. It is forensics, not comparability.
  • RejectedCopy-on-write at run time — snapshot whatever the dataset is when a run starts: Produces a version per run, which is correct and makes the corpus unmanageable and cross-run comparison nearly impossible.
Consequences
What it buys
  • A three-year-old score still names a corpus that can be read, which is what makes a long quality series defensible.
  • Dataset review becomes meaningful: a version is a reviewable artefact rather than a moving target.
What it costs
  • Storage grows monotonically, and dataset sprawl becomes a real curation burden as versions accumulate.
  • It collides head-on with the erasure obligation, which ADR-17 resolves imperfectly and deliberately.
Choose differently when
Nothing short of abandoning ADR-01 flips this. If the erasure obligation were to tighten such that tombstoning is insufficient, the corpus would have to move to synthesised or licensed material, which changes what is stored rather than whether it is immutable.
Why it holds up over time
Immutability is a property of the data model, not of the storage technology. Object stores have supported versioning and retention for two decades and will continue to; the decision outlives any particular one.
LessonImmutability is not tidiness. It is the mechanism by which a measurement stays interpretable after the thing that produced it has been replaced.
Shown on views09 10 11
ADR-04

Scores are append-only facts; a correction supersedes rather than updates

Accepted

When a score turns out to be wrong, is the row updated or is a new row written?

Context
An updatable score row means a past verdict can change after the fact without anyone noticing. Release decisions are audited years later, and a verdict whose supporting evidence has been silently edited is not evidence. There is also a subtler problem: an update loses the information that the platform once believed something different, which is exactly the information needed to understand how a regression escaped.
Decision
Scores are append-only. A correction writes a new score row and sets `superseded_by` on the old one. Verdicts are immutable release records retained for the life of the product. No component has update or delete permission on the score table.
How it is realised on Google Cloud
BigQuery tables partitioned by run and clustered by slice, written through an append-only service account. Corrections are a distinct write path requiring a reason and an author. Reporting views filter on `superseded_by IS NULL` by default but can reconstruct any historical view.
Options weighed
  • ChosenAppend-only with supersession: A past verdict stays reconstructible exactly as it was decided. Costs storage and query complexity.
  • RejectedMutable scores with row-level history: Equivalent in principle and worse in practice: the default read is the mutated one, so the correct behaviour requires everyone to opt in.
  • RejectedImmutable scores, no correction path at all: Purity that forces a full re-run for a single bad score, and pushes people to fix things outside the system.
Consequences
What it buys
  • Recovery of any component can never alter a past verdict, because there is no code path that writes to an existing row.
  • The history of what the platform believed is itself data, which is what makes a post-incident review of the gate possible.
What it costs
  • Every reporting query carries supersession logic, which is a small permanent tax on readability.
  • Storage grows with corrections as well as with runs.
Choose differently when
If audit obligations disappeared entirely and nobody ever asked why a release was approved, the history would be dead weight. That is not a plausible direction of travel for AI product decisions.
Why it holds up over time
Append-only is a design stance rather than a feature of BigQuery; it transfers to any store. As regulatory interest in AI release decisions grows, the reconstructibility this buys becomes more valuable, not less.
LessonIf a decision will have to be defended later, the evidence behind it must be incapable of changing — not merely unlikely to.
Shown on views10 11

What is measuredThe subject of an evaluation, and the corpus it is evaluated against.

ADR-05

The evaluation subject is the full pinned configuration, not the model

Accepted

What exactly is being scored when the platform says a candidate improved?

Context
An assistant's behaviour is produced by a model, a system prompt, a set of tool definitions, a retrieval index, decoding parameters and a safety filter. Teams routinely attribute a quality change to 'the new model' when the prompt changed in the same week. If the subject of a score is underspecified, the score is attributed to nothing, and two runs that look like a comparison are measuring different systems.
Decision
The unit of evaluation is a release candidate: model identifier and weights digest, system prompt version, tool definitions version, retrieval index version, decoding parameters and safety filter version. A candidate whose configuration is not fully pinned is refused. Candidate identity is the digest of that configuration, so resubmitting the same configuration is recognised rather than re-evaluated.
How it is realised on Google Cloud
`candidate.config_digest` is a unique column in Cloud SQL, computed over the canonicalised configuration. The incumbent is a candidate row with `is_incumbent` set, maintained by the deployment pipeline, so the platform always knows what production is actually running.
Options weighed
  • ChosenFull configuration digest as the subject: Attribution is exact and deduplication is free. Costs discipline at submission time.
  • RejectedModel version as the subject, other components as tags: Reintroduces the confound it was meant to remove, because a tag does not participate in identity.
  • RejectedSubject defined per-experiment by the submitter: Makes comparability a per-team convention, which is how two teams end up with incomparable numbers and an argument.
Consequences
What it buys
  • A quality change is attributable to a specific change, which is the difference between a measurement and an anecdote.
  • Resubmitting an unchanged configuration is a cache hit rather than a repeat bill.
What it costs
  • Engineers must pin everything before submitting, which is friction at exactly the moment they feel closest to done.
  • A configuration surface that grows — a new retrieval component, a new filter — changes the digest for everyone and invalidates deduplication.
Choose differently when
If the assistant's architecture collapsed to a single model call with no prompt, tools or retrieval, the configuration and the model would be the same thing and this would be redundant. The direction of travel is the opposite.
Why it holds up over time
The principle — score the system, not the component — transfers to any composition of models, agents and tools, and becomes more important as the number of components rises.
LessonMeasure the thing the user meets. Attributing a system's behaviour to its most interesting component is the most common way a quality programme misleads itself.
Shown on views01 02 11 12
ADR-06

Generation and scoring are separate stages joined by a stored trace

Accepted

Does a scorer run inline with the model call, or against stored outputs?

Context
Inline scoring is simpler and one fewer store. It also means that fixing a scorer bug, clarifying a rubric or adding a new metric requires re-running the model against the entire corpus — which is the expensive half. Given that scorer and rubric changes are frequent and generation is the dominant cost, this is a choice about how expensive it is to improve the measurement.
Decision
The harness generates and stores a full trace — prompt as sent, retrieval context, tool calls, raw output — as an addressable artefact. Scoring is a separate stage that reads traces. A scorer-only frame change re-scores stored outputs rather than re-running the candidate.
How it is realised on Google Cloud
Traces are written to Cloud Storage keyed by (run_id, example_id, generation_idx) and referenced from `score.trace_ref`. Scoring workers are a distinct GKE deployment that consumes a separate Pub/Sub subscription, so scoring capacity scales independently of generation capacity.
Options weighed
  • ChosenSeparate stages joined by stored traces: Makes rubric iteration cheap and diagnosis possible. Costs ~2.2 TB/year and a second pipeline stage.
  • RejectedInline scoring during generation: Cheaper to build, and makes every scorer improvement cost a full generation sweep — which means scorers stop improving.
  • RejectedStore outputs only, not full traces: Halves storage and removes the ability to tell why a candidate failed, which is what the engineer actually needs from a block.
Consequences
What it buys
  • A rubric clarification costs a scoring pass, not a generation sweep — roughly an order of magnitude less at assumed prices.
  • A blocked engineer can read the actual prompt, tool calls and output for the examples that moved, which is what makes a block arguable rather than infuriating.
What it costs
  • Trace storage at ~2.2 TB/year, and a retention decision that must balance evidence value against cost and privacy exposure.
  • Two pipeline stages to operate, monitor and keep in version agreement.
Choose differently when
If generation became nearly free relative to storage — a large drop in inference cost with no drop in storage cost — inline scoring with discarded traces would become defensible for the highest-volume suites. The diagnostic argument would still favour traces for gating suites.
Why it holds up over time
Separating expensive irreversible work from cheap repeatable work is a general pipeline principle. As models get cheaper this decision weakens economically and strengthens diagnostically, and the diagnostic case is the one that matters to users of the platform.
LessonPut the boundary where the cost is. If improving the measurement requires redoing the expensive part, the measurement stops improving.
Shown on views02 09 13
ADR-07

Three dataset classes: a frozen golden set, a rolling set, and targeted regression sets

Accepted

Should the gating corpus be a stable benchmark or a live sample of what users are actually asking?

Context
A frozen golden set is comparable across time, contamination-detectable and stable, and drifts away from real traffic within months — at which point it measures a distribution nobody has. A rolling sample always represents the live distribution and destroys cross-time comparison, because every refresh is a frame change under ADR-01. Neither alone is adequate, and the conflict is genuine rather than a failure to choose.
Decision
Three classes with declared roles. The frozen golden set is the gate-bearing corpus and the long comparability axis; changing it requires an explicit reviewed decision. The rolling set is refreshed from recent production traffic on a cadence, is advisory rather than blocking, and exists to detect when the golden set has stopped representing users. Targeted regression sets are grown from real incidents and are blocking for the class of failure they encode.
How it is realised on Google Cloud
Each class is a separate dataset lineage in `mes-corpus` with its own owner, cadence and gate strength. A rolling-set refresh publishes a new version; comparisons spanning a refresh are re-scored rather than stitched. Staleness is measured continuously as divergence between the rolling set's distribution and current production traffic.
Options weighed
  • ChosenThree classes with declared, different gate strengths: Keeps the comparability axis stable while retaining a live signal. Costs roughly double the corpus to maintain.
  • RejectedFrozen golden set only: Comparable and progressively irrelevant. The gate keeps passing candidates that are worse for real users.
  • RejectedRolling set only: Always relevant and never comparable; every week is its own frame and no trend can be read.
  • DeferredFrozen and rolling with equal blocking authority: Leaves open what happens when they disagree, which is the question that actually matters. Deferred until disagreement frequency is measured.
Consequences
What it buys
  • The golden set's drift becomes measurable rather than assumed, because the rolling set is the instrument that detects it.
  • An incident can be converted into a permanent blocking test without touching the comparability axis.
What it costs
  • Roughly twice the corpus curation effort, and three owners rather than one.
  • A candidate the golden set likes and the rolling set does not is an unresolved situation the platform reports but does not decide.
Choose differently when
If the rolling set's verdicts were shown over a year to track online outcomes substantially better than the golden set's, blocking authority should move to it and the golden set should be demoted to a long-series instrument only.
Why it holds up over time
The tension between a stable benchmark and a live distribution is permanent in any measurement programme for a system facing changing demand. The three-class answer will outlive any particular corpus.
LessonWhen two requirements genuinely conflict, name both instruments and declare which one is allowed to stop the line. Choosing one and pretending the other does not matter is how benchmarks become theatre.
Shown on views03 09 10 18

The judge as an instrumentUsing a model to score a model, without pretending the ruler is fixed.

ADR-08

The judge is pinned to an explicit version and monitored for silent drift

Accepted

Which model scores the outputs, and what happens when the provider changes it underneath the pin?

Context
Using a model to judge a model is the only way to score open-ended quality at 39,000 judgements per gate run. But a judge is a measuring instrument, and an instrument whose calibration changes without notice invalidates every measurement taken with it. Provider-side updates to an endpoint that a customer believes is pinned are a documented reality, not a hypothetical. Under ADR-01 such a change is a frame change nobody recorded, which is the worst case the whole design exists to prevent.
Decision
The judge is pinned to an explicit model version and decoding configuration and is an axis of the frame. The platform does not assume the pin holds: it continuously re-scores a fixed calibration set with the pinned judge and alarms when the judge's own output distribution or its agreement with human labels shifts beyond a threshold. A detected shift retires the frame and quarantines runs scored inside the drift window.
How it is realised on Google Cloud
A scheduled job re-scores the calibration set on a fixed cadence and writes the result to BigQuery as a first-class monitored signal, surfaced on the operations view alongside availability and cost. Judge rationales are stored with every score so a disputed verdict can be inspected rather than merely re-run.
Options weighed
  • ChosenPin, and verify the pin continuously: Treats the judge as an instrument under calibration control. Costs a standing re-score bill and an alerting path.
  • RejectedPin and trust the provider: Makes the platform's central guarantee depend on a third party's change management, undetectably.
  • DeferredSelf-host the judge so the weights cannot change: Removes drift entirely and is the strongest answer. Deferred on cost and on the capability gap against frontier judges; revisit as open-weight judges close it.
Consequences
What it buys
  • Silent instrument drift becomes a detected incident with a defined response, rather than a slow corruption of the series.
  • Frame retirement is automatic on detection, so affected scores are quarantined rather than quietly trusted.
What it costs
  • A continuous re-scoring bill that buys no verdicts, only confidence that the verdicts are comparable.
  • False drift alarms interrupt gating, and the threshold that separates real drift from sampling noise is itself a tuning problem.
Choose differently when
Self-hosting an open-weight judge of adequate quality removes the drift class entirely and makes the monitor a much cheaper regression check. That is the most likely change to this record within a few years.
Why it holds up over time
Calibration control over a measuring instrument is a principle from metrology, not from machine learning, and it long predates and will outlive any specific judge model.
LessonIf you measure with something you do not control, monitor the something. A pin you cannot verify is a hope with a version number.
Shown on views14 18 15
ADR-09

A judge may block a release only above a published agreement threshold

Accepted

How good does a model judge have to be before it is allowed to stop a release?

Context
A judge with poor agreement against human preference is not measuring quality; it is measuring its own idiosyncrasies at scale and with great confidence. Yet judges are indispensable at these volumes, and a rule that admits only perfect judges admits none. The question is therefore not whether to use one but what authority to grant it, and at what evidentiary standard.
Decision
Every judge is calibrated against human labels on a named calibration set before it may gate. Agreement is published as a named statistic, re-measured for every judge version. A judge at or above 0.75 Cohen's κ may block; between 0.65 and 0.75 it may block only with human adjudication; below 0.65 it is inadmissible for gating and may produce observational scores only. The threshold is a property of the scorer row, read by the gate, not a convention people remember.
How it is realised on Google Cloud
`scorer.kappa_vs_human` and `scorer.gate_admissible` are columns the gate engine reads at decision time. The calibration set holds at least 1,200 human-labelled examples per rubric and is refreshed at least every six months. Raters see blinded pairs and never learn which output came from the candidate.
Options weighed
  • ChosenPublished κ threshold, admissibility as data: Makes judge authority auditable and revocable. Costs a standing human labelling programme.
  • RejectedUse the judge, report agreement, let teams decide: Authority without a standard. In practice the judge blocks and nobody checks the statistic.
  • RejectedHuman-only gating: Correct and unaffordable: 39,000 judgements per gate run against 40 reviewer-hours per week.
  • DeferredEnsemble of judges with disagreement routed to humans: Raises reliability and multiplies the dominant cost. Phase 3, once single-judge agreement is characterised.
Consequences
What it buys
  • The judge's authority is earned, measured and revocable, which is what makes an automated block defensible to the engineer it stops.
  • A degraded judge loses blocking rights automatically rather than after someone notices.
What it costs
  • A permanent human labelling programme is required whether or not anything is going wrong.
  • κ is an imperfect summary of agreement and can mask systematic disagreement on the slices that matter most.
Choose differently when
If judges reached agreement levels comparable to inter-rater agreement among humans themselves, the threshold would become a formality and the calibration programme could shrink to periodic spot checks. Conversely, evidence that κ hides slice-level disagreement would push toward per-slice admissibility.
Why it holds up over time
Requiring an automated decision-maker to demonstrate agreement with human judgment before it is granted authority is a governance pattern that will apply to far more than evaluation judges.
LessonGrant authority in proportion to demonstrated accuracy, and store the demonstration where the enforcement code can read it.
Shown on views14 18 21
ADR-10

Known judge pathologies are countered structurally, not by prompt wording

Accepted

How are position bias, verbosity bias and self-preference handled?

Context
Model judges exhibit well-documented systematic biases: preferring the first option presented, preferring longer answers, and preferring outputs from their own model family. These are not noise that averages out — they are directional errors that survive large samples, and a rubric instructing the judge to ignore length does not reliably make it do so. If a candidate happens to be more verbose than the incumbent, an uncorrected judge will report an improvement that does not exist.
Decision
Position bias is countered by evaluating both orderings of every pairwise comparison and combining. Verbosity bias is measured and reported as a standing statistic rather than assumed away. Self-preference is treated as disqualifying: a judge may not gate a candidate from its own model family. Human raters always see blinded pairs.
How it is realised on Google Cloud
The scoring pipeline issues two judge calls per pairwise comparison with the order swapped — which is why the gate run costs ~39,000 judge calls for 6,500 examples. Family affinity between judge and candidate is checked at plan time and blocks admissibility rather than warning.
Options weighed
  • ChosenStructural controls: both orderings, family exclusion, blinding: Doubles judge cost, which is the dominant cost. Bought because the bias is directional and would otherwise be indistinguishable from a real gain.
  • RejectedInstruct the judge to be unbiased in the rubric: Cheap, popular and not reliably effective. It documents an intention rather than enforcing a control.
  • RejectedCorrect statistically for measured bias: Requires a stable bias estimate, and the bias moves with the judge version — which is the thing ADR-08 says not to assume.
Consequences
What it buys
  • A verbosity-driven apparent improvement is caught rather than shipped, which is one of the most common false positives in LLM evaluation.
  • A judge from the same family as a candidate cannot quietly favour it.
What it costs
  • Judge cost doubles for every pairwise comparison, and judge inference is assumed to be ≤ 55% of run cost.
  • Family exclusion reduces the pool of admissible judges, which can be limiting when the best available judge shares a family with the primary model.
Choose differently when
If a judge were demonstrated to be order- and length-invariant across versions, single-ordering evaluation would halve the dominant cost. That demonstration would have to be repeated per version, which is what makes it unattractive today.
Why it holds up over time
The specific pathologies may change as judges improve, but the principle — counter a known systematic bias structurally rather than by asking nicely — applies to any automated evaluator.
LessonA directional bias does not average out with more samples. Design the measurement so the bias cancels, or measure and report it; never instruct it away.
Shown on views13 14

The decisionHow evidence becomes a verdict, and what happens when there is not enough of it.

ADR-11

The verdict is three-valued: PASS, BLOCK and INSUFFICIENT_EVIDENCE

Accepted

What does the platform return when a run did not finish, or finished with too many harness errors to trust?

Context
A two-valued gate forces every incomplete run into one of two wrong answers. Returning PASS ships a candidate nobody measured. Returning BLOCK is safer but indistinguishable from a real regression, which trains engineers to retry until green — and a gate people retry past is not a gate. The distinction between 'this is worse' and 'we do not know' is the one the deployment pipeline most needs.
Decision
Three values. INSUFFICIENT_EVIDENCE is returned when a run is incomplete, when the harness error rate exceeds its declared budget, when a required judge was unavailable, or when a gate-bearing slice went unevaluated. The pipeline treats it as a stop, not as a retryable failure, and the verdict names what is missing.
How it is realised on Google Cloud
The gate engine evaluates completeness before it evaluates deltas. `run.harness_error_rate` is persisted by the harness and read as an admissibility precondition. Every verdict ships with the evidence it rests on: suites run, examples scored, slices evaluated, scorer and judge versions, and a confidence interval on every reported delta.
Options weighed
  • ChosenThree-valued verdict with named gaps: Makes 'we do not know' a first-class answer. Costs a third code path in every consumer.
  • RejectedTwo-valued, incomplete runs block: Conflates a regression with an outage, and teaches engineers that blocks are often spurious.
  • RejectedTwo-valued, incomplete runs pass with a warning: A warning in a pipeline log is a pass. This is how an unevaluated candidate reaches users.
Consequences
What it buys
  • An infrastructure problem is diagnosed as one instead of being argued about as a quality regression.
  • The block rate stays meaningful as a metric, because it is not inflated by harness flakiness.
What it costs
  • Every consumer of the verdict must handle a third case, and the temptation to map it onto one of the other two is permanent.
  • A platform having a bad day stops releases rather than degrading, which is deliberate and occasionally very unpopular.
Choose differently when
Nothing reasonable flips this. If harness reliability became high enough that incomplete runs effectively never occurred, the third value would be unused rather than wrong — and would still be the correct thing to return on the day it recurs.
Why it holds up over time
Distinguishing a negative result from an absent one is a principle of measurement rather than of software, and it will apply to any automated gate in any domain.
LessonAbsence of evidence must be representable, or it will be silently encoded as whichever answer is cheaper that day.
Shown on views08 12 17
ADR-12

Gates are evaluated per slice against a declared gate-bearing set

Accepted

How does the platform gate on cohorts without blocking most neutral releases by chance?

Context
A headline average hides a collapse in one language behind gains everywhere else, so per-slice gating is necessary. But 34 gate-bearing slices tested independently at α = 0.05 will produce at least one false block in roughly four out of five fully-neutral releases. Correcting for multiple comparisons restores honesty and destroys sensitivity on small slices. Growing slices to restore power multiplies the cost of every run. Every available answer is a trade, and the design encodes a preference between a false block and a missed regression whether or not anyone states it.
Decision
The gate-bearing slice set is declared in advance and kept small — 34 slices against 18 suites — and each is chosen because it carries a product commitment rather than because it is measurable. Deltas are evaluated as paired comparisons against the incumbent on the same examples, which recovers substantial power. No gate blocks on a difference it cannot distinguish from noise at the declared confidence level. The preference between false blocks and missed regressions is stated explicitly: false-block rate ≤ 5%.
How it is realised on Google Cloud
`gate` rows carry slice, strength and alpha, so the trade is data rather than code. Suite size is derived from a power requirement — detect a 2 percentage-point regression at ≥ 90% power, α = 0.05 — which is what sets the 6,500-example gating suite rather than convenience.
Options weighed
  • ChosenSmall declared slice set, paired design, stated error preference: Honest about the trade and bounded in cost. A regression in an ungated slice still ships, which is the accepted risk.
  • RejectedGate every slice with multiple-comparison correction: Statistically clean and practically blind: after correction, small slices detect nothing worth detecting.
  • RejectedGate on the aggregate only: Cheap, sensitive and exactly the failure the platform exists to prevent.
  • DeferredGrow every slice until all can be gated at full power: Correct and multiplies run cost several-fold. Revisit if inference cost falls substantially.
Consequences
What it buys
  • The multiple-comparisons cost is bounded and known rather than accumulating invisibly as teams add slices.
  • Suite size is derived from a stated detection requirement, so 'is the suite big enough' has an answer.
What it costs
  • A regression confined to an ungated slice ships. That is a real, accepted exposure and it should be reviewed as the slice set changes.
  • The paired design constrains how datasets may be refreshed, since pairing requires the same examples on both sides.
Choose differently when
If the false-block rate proved much lower than modelled, or if run cost fell enough to grow every slice, the gate-bearing set could widen substantially. Evidence that regressions routinely land in ungated slices would force the same change at higher cost.
Why it holds up over time
Multiple comparisons is a permanent property of testing many hypotheses at once. The specific slice set will churn; the discipline of declaring it in advance will not.
LessonAny system that gates on many metrics has already chosen between false alarms and missed faults. Make the choice explicit and numeric, or it is made by accident.
Shown on views11 12 18
ADR-13

Guardrail gates block regardless of quality gain, and safety guardrails are never waivable

Accepted

Can a large enough improvement in helpfulness justify a small regression in safety, latency or cost?

Context
Any scalar quality score will eventually be improved by a candidate that is also less safe, slower or more expensive, and a single composite metric will happily trade one for the other. A candidate that is wittier and less safe is not a better candidate. Separately, waivers are necessary — a genuine emergency, a known-false positive — and a waiver mechanism that applies to everything is an off switch for the gate.
Decision
Guardrail gates — safety violation rate, benign refusal rate, p95 response latency, cost per request, tool-call error rate — block independently of the quality result and are never traded against it. Every other blocking gate may be waived by a named approver with a stated reason and an expiry. Safety guardrail gates have no waiver path at all.
How it is realised on Google Cloud
Guardrails are evaluated as a separate pass with their own thresholds before quality deltas are considered. The waiver API refuses a waiver against a safety gate as a matter of code rather than of permission, so there is no role that can grant one. Active waivers appear on a standing register, and waiver rate is a monitored metric.
Options weighed
  • ChosenIndependent guardrails, safety non-waivable: Removes the possibility of trading safety for helpfulness. Costs genuine flexibility in a real emergency.
  • RejectedComposite score with weighted safety term: A sufficiently large helpfulness gain outvotes safety, which is the exact outcome to prevent.
  • RejectedSafety waivable by a senior approver: Creates a role whose existence is a standing target, and a precedent that is used a second time more easily than a first.
Consequences
What it buys
  • There is no code path by which a safety regression reaches users because something else improved a lot.
  • The waiver register makes quality debt visible and expiring rather than permanent.
What it costs
  • A false positive on a safety gate stops a release with no override, which will at some point be the wrong outcome for a real incident.
  • That pressure moves onto the safety scorer's accuracy, which becomes a critical component in its own right.
Choose differently when
None on the safety rule. The non-safety guardrails could reasonably become tunable per release class — a latency regression may be acceptable for a capability release and not for a routine one — which is a refinement rather than a reversal.
Why it holds up over time
Separating vetoes from trade-offs is a governance pattern older than software. As AI safety expectations become regulatory rather than voluntary, a non-waivable path becomes an asset rather than an inconvenience.
LessonIf a constraint must never be traded away, it cannot participate in a scalar score, and it cannot have an override — because a mechanism that exists will be used.
Shown on views12 18 21
ADR-14

Fail closed is a property of the pipeline's contract, not of the platform's availability

Accepted

What happens to releases when the evaluation platform is unavailable during a release window?

Context
The obvious design makes the platform highly available and treats an outage as a degraded mode. But availability engineering cannot reach 100%, and the behaviour on the worst day is what the whole gate is worth. A gate with a bypass is a gate that will be bypassed on the day it matters most — typically during the incident that makes someone want to ship a fix quickly. Shipping an unevaluated candidate to 40 million users is a worse outcome than a delayed release.
Decision
The deployment pipeline will not proceed without an affirmative PASS. A pipeline that cannot reach the gate does not release. There is no bypass, no timeout-to-proceed and no break-glass release path in the platform. The gate is also protected as a production control: author and approver of a gate change must be different people, and no long-lived credential exists anywhere in the policy path.
How it is realised on Google Cloud
Fail-closed is implemented in the pipeline's contract rather than in the evaluation service, so no outage of the service can change it. Policy lives in Git with enforced two-person review; Cloud Build authenticates through Workload Identity Federation for short-lived tokens only; every gate change and waiver is written immutably.
Options weighed
  • ChosenFail closed in the consumer's contract: The property survives any failure of the platform, including a total one. Costs release availability.
  • RejectedFail closed implemented inside the evaluation service: A service that is down cannot enforce anything. The guarantee has to live where it still holds when the platform does not.
  • RejectedTimeout-to-proceed after a bounded wait: Converts an availability incident into an unevaluated release, quietly and on a schedule.
  • RejectedBreak-glass release with post-hoc evaluation: The mechanism will be used during exactly the incidents where judgement is worst.
Consequences
What it buys
  • The worst-case behaviour is a delayed release rather than an unmeasured one, and that property does not depend on the platform being up.
  • Gate integrity is enforced by review and short-lived identity rather than by trust in operators.
What it costs
  • Evaluation platform availability becomes release availability, which raises the operational stakes of a system that is otherwise off the user path.
  • A genuine emergency fix waits for the gate, and there is no sanctioned way around that.
Choose differently when
A strong argument could be made for a narrow exception covering rollbacks to a previously-passed incumbent, which is a release to a candidate that already has a verdict. That is a refinement worth considering and is deliberately not in the MVP.
Why it holds up over time
Placing a safety property in the consumer's contract rather than the provider's implementation is a general availability principle: a guarantee that depends on a component being up is not a guarantee.
LessonDecide what happens on the worst day, and implement it somewhere the worst day cannot reach.
Shown on views08 17 21

Offline and onlineThe proxy, the truth, and how each earns its authority.

ADR-15

Offline gates entry to exposure; online guardrails gate rollout and trigger rollback

Accepted

Does online evidence stop a release, or only observe one?

Context
Offline scores are fast, safe and measure a proxy whose predictive validity is itself uncertain. Online behaviour is what actually matters and is slow, confounded by concurrent changes, and requires exposing real users to the candidate before it is cleared — which is the thing the gate exists to avoid. Choosing either alone gives up something the platform was built for.
Decision
Staged exposure. Offline gates entry to shadow and canary. Online guardrail metrics are monitored continuously during exposure and trigger automatic rollback on a declared threshold breach, without waiting for a scheduled analysis. Online evidence gates progression to full rollout. Metrics and thresholds are declared before exposure begins, never chosen after the data arrives.
How it is realised on Google Cloud
Guardrail evaluation runs against serving telemetry in BigQuery and emits a rollback trigger to the deployment pipeline; breach to rollback initiation is targeted at ≤ 5 minutes p99. User feedback signals — explicit ratings, regeneration rate, abandonment, copy-and-edit behaviour — are treated as biased signals to be interpreted, never as labels.
Options weighed
  • ChosenOffline gates entry, online gates rollout, auto-rollback armed: Bounds the exposure of a bad candidate while keeping the decision anchored in real behaviour.
  • RejectedOffline gating only: Ships on a proxy and discovers the truth from users, which is the journey in view 05.
  • RejectedOnline gating only: Every candidate reaches users before it is cleared, which makes the gate a formality.
  • RejectedThresholds chosen after inspecting canary data: Guarantees a favourable reading, because the threshold is fitted to the result.
Consequences
What it buys
  • A bad candidate's exposure is bounded by canary size and rollback latency rather than by how quickly someone notices.
  • Offline suites acquire an external validity check, which ADR-16 turns into a retirement criterion.
What it costs
  • Real users meet candidates that offline evaluation cleared but online evidence will reject — a deliberate, bounded exposure.
  • Canary size must be large enough to detect the regressions that matter, which is a statistical requirement in tension with limiting exposure.
Choose differently when
If measured offline-online correlation became strong enough across all gate-bearing slices, the canary could shrink materially. Persistently weak correlation would push blocking authority toward online evidence and reduce offline gating to a smoke test.
Why it holds up over time
Proxy-then-truth staging is how every measurement programme with an expensive ground truth works, from drug trials to search ranking. It will outlive any particular metric set.
LessonDeclare the decision rule before seeing the data. A threshold chosen afterwards is a description of the result, not a test of it.
Shown on views05 17 19
ADR-16

Suites justify themselves by predicting online outcomes, and cached scores must not assert false determinism

Accepted

How does the platform know a suite is worth running, and when may a score be reused rather than recomputed?

Context
Offline suites accumulate. Each was added for a good reason, each costs money on every run, and nothing ever removes one — so cost grows monotonically while the marginal information from the eighteenth suite is unknown. Separately, caching by (candidate, example, frame) is the single largest cost lever available and would make re-baselining nearly free. But a cached score for a candidate sampling at non-zero temperature asserts a determinism the candidate does not have, and a cached judge score assumes the pinned judge has not silently moved.
Decision
Offline-online correlation is measured per suite — the degree to which a suite's offline delta predicted the online outcome — and reported against that suite's cost. A suite that has never predicted anything is a visible candidate for retirement. Score caching is permitted only for candidates running at temperature zero, and only within a frame whose judge-drift monitor is current. Every other cache read is a miss.
How it is realised on Google Cloud
Correlation is computed in BigQuery over the verdict and online-outcome history and stored on `suite.online_correlation`. The cache probe in the scoring pipeline checks the candidate's decoding configuration before consulting Memorystore, so the determinism condition is enforced in the pipeline rather than trusted.
Options weighed
  • ChosenCorrelation-driven retirement, determinism-gated caching: Keeps cost tied to demonstrated value and keeps the cache honest. Costs a slow feedback loop and forgoes caching on stochastic suites.
  • RejectedCache everything by content hash: Large saving bought by asserting a determinism that does not exist, which silently narrows measured variance to zero.
  • RejectedNo cache at all: Safe and forfeits the only lever large enough to make frequent re-baselining affordable.
  • RejectedRetire suites on a fixed schedule: Removes suites by age rather than by value, and the oldest suite may be the one that works.
Consequences
What it buys
  • The corpus can shrink as well as grow, which is the only defence against unbounded evaluation cost.
  • Re-baselining a scorer-only change becomes substantially cheaper wherever suites can honestly run at temperature zero.
What it costs
  • Correlation needs many releases before it is meaningful, so retirement decisions lag suite addition by a long way.
  • Running gating suites at temperature zero may not represent production behaviour, which is an open question the cache depends on.
Choose differently when
If gating at temperature zero were shown to mis-measure production behaviour, caching would be confined to deterministic scorers over stored traces — still useful, much smaller. If variance across generations proved negligible, caching could widen considerably.
Why it holds up over time
Requiring a measurement to demonstrate predictive value, and requiring a cache to state what it assumes, are both durable disciplines independent of the technology underneath.
LessonA cache is a claim that nothing relevant changed. Write down what 'relevant' means, and enforce it, or the cache is quietly fabricating data.
Shown on views13 18 19

Data, cost and safetyUser data under an immutable corpus, and running generated code at volume without an unbounded bill.

ADR-17

Production examples are redacted at admission, and erasure is a tombstone with bounded reproducibility

Accepted

How can dataset versions be immutable while a user retains the right to have their data erased?

Context
ADR-03 requires dataset versions never to change; privacy obligations require a user's data to be erasable wherever it exists. These are in direct conflict. Deleting the example mutates a version and silently changes every score computed from it. Keeping it honours comparability and breaches the obligation. Tombstoning preserves aggregate comparability but makes the verdict no longer fully reproducible from artefacts, which contradicts the reproducibility claim in the requirement.
Decision
Production-derived content is redacted or pseudonymised at admission, before the example is durable, and the redaction version is recorded. Every example carries its lawful basis, consent state and retention limit. An erasure request tombstones the example: content is removed; identity, slice labels and derived scores are retained. The consequence is stated openly rather than hidden — aggregate comparability survives, full reproducibility from artefacts does not, and this remains an open question rather than a solved one.
How it is realised on Google Cloud
Sensitive Data Protection applies versioned inspection templates at the admission stage of the data flow. `example.tombstoned_at` makes the state first-class and auditable. The corpus sits in its own project inside a VPC Service Controls perimeter, with every raw trace access logged and attributable.
Options weighed
  • ChosenRedact at admission, tombstone on erasure, state the limit: Honours the obligation and bounds the damage to the comparability claim. The residual gap is real and named.
  • RejectedHard delete the example and its scores: Mutates a dataset version and silently changes historical aggregates, which is worse than a bounded gap.
  • DeferredRefuse production-derived content entirely; synthesise or license everything: Resolves the conflict completely and gives up the rolling set's representativeness. Genuinely worth revisiting if obligations tighten.
  • RejectedKeep the example and rely on the lawful basis: Bets the platform's legal position on an interpretation, for a comparability benefit.
Consequences
What it buys
  • There is no path by which raw production content becomes a durable dataset example, which shrinks the exposure to what redaction misses.
  • Erasure is a first-class auditable state rather than a deletion nobody can account for.
What it costs
  • A verdict resting on a tombstoned example cannot be fully reconstructed from artefacts, weakening the reproducibility claim in ADR-04.
  • Redaction is imperfect, and an over-redacted example may no longer be a valid test of the behaviour it was collected for.
Choose differently when
If synthesised or licensed material were shown to carry the gating load without losing representativeness, refusing production-derived content entirely becomes the better architecture and removes this conflict rather than managing it.
Why it holds up over time
The tension between immutable evidence and a right to erasure is structural and will intensify. Naming the residual gap is what lets a future team make a different trade knowingly.
LessonWhen two requirements genuinely cannot both be satisfied, implement the lesser compromise and document precisely what was given up. An unstated compromise is discovered later, by someone who assumed it did not exist.
Shown on views09 10 11 20
ADR-18

The harness is an untrusted workload, and every run carries a hard cost ceiling

Accepted

How should a system that executes model-generated tool calls thousands of times an hour be contained, and what stops a misconfigured run spending without limit?

Context
The evaluation harness does something unusual: it takes text a model wrote and executes it against tools, at volume, unsupervised, including inputs specifically designed to probe edge cases. Treating that as an internal batch job is a category error — it is closer to running untrusted user-submitted code. Separately, a fan-out pipeline with a bug in its work planner can generate an unbounded bill faster than any alerting loop can respond, and an alarm after the money is spent is not a control.
Decision
Model output and its tool calls are untrusted content. Tool execution happens in gVisor-isolated pods with egress denied and side-effect-free stubs, on a network path with no route to production systems. All outbound inference leaves through an allowlisting egress proxy. Separately, every run carries a cost ceiling enforced by the harness itself: the run halts at the ceiling and reports, rather than alarming afterwards.
How it is realised on Google Cloud
Sandbox pods run under gVisor with egress deny by default; the execution plane holds workload identity that can read the corpus and write traces, and cannot read a human label, write a verdict or delete a dataset version. Per-run cost is metered in-process against the ceiling set by the run planner; per-team monthly budgets are enforced at admission.
Options weighed
  • ChosenKernel-isolated sandbox, egress allowlist, in-harness cost ceiling: Proportionate to running generated code at volume. Costs some performance and a more complex execution environment.
  • RejectedPlain containers with network policy: Adequate for trusted workloads. This one executes text an adversary could have influenced through a prompt.
  • RejectedCost alerting rather than a ceiling: An alert fires after the spend. The ceiling is the only control that acts before it.
  • RejectedReal tools instead of stubs, for fidelity: Higher fidelity bought by giving model-generated calls real side effects. Not a trade worth making.
Consequences
What it buys
  • A prompt-injected tool call cannot reach an arbitrary host or produce a real side effect.
  • A runaway run is halted rather than discovered on an invoice, which makes experimentation safe to encourage.
What it costs
  • gVisor adds syscall overhead to a workload that is already the platform's largest compute consumer.
  • Stubbed tools measure tool-call correctness rather than end-to-end tool behaviour, which is a genuine fidelity gap.
Choose differently when
If a class of tools were provably side-effect-free and network-isolated by their own design, running them directly would recover fidelity at no risk. The isolation requirement would remain for everything else.
Why it holds up over time
Treating model output as untrusted input is becoming the default stance across the industry, and will apply anywhere an agent's output reaches an execution surface. This record will read as obvious sooner than most.
LessonClassify a workload by what it executes, not by who owns it. Code generated by a model and executed unsupervised is untrusted code, whoever deployed the pipeline.
Shown on views07 13 16 20

Every package used, in one table

The terms this package uses in a specific way, and what each one is doing in the architecture.

PackageWhat it isWhat it does hereConsidered instead
Comparison frame The tuple (dataset version × scorer version × judge version × harness version) under which a score was produced. Part of a score's identity. Two scores from different frames may not be compared, which is the architecture's defining rule. Treating these as metadata, which makes the rule advisory and therefore absent.
Release candidate A fully pinned configuration: model, prompt, tools, retrieval index, decoding parameters, safety filter. The subject of every score, so that a quality change is attributable to a specific change. Attributing scores to a model version, which confounds a prompt edit with a model upgrade.
Incumbent The candidate currently serving production traffic. The baseline every gate compares against, maintained by the deployment pipeline and re-scored on every frame change. An absolute threshold, which answers 'is this good enough' rather than 'is this better'.
Re-baseline Re-scoring the incumbent in a newly registered frame. The budgeted, recurring cost of changing any measurement axis. Gating is suspended until it completes. Carrying the old score forward, which is the forbidden cross-frame comparison by another route.
Gate-bearing slice A declared subset of the corpus — language, task type, cohort, safety category — on which a regression blocks. Declared in advance so the multiple-comparisons cost is bounded and known rather than discovered. Gating every slice, which produces a false block on most neutral releases.
Guardrail gate A gate that blocks regardless of any quality improvement: safety violation rate, benign refusal rate, latency, cost, tool-call errors. Prevents a candidate that is wittier and less safe from being scored as better. Safety guardrails have no waiver path. Folding safety into the aggregate quality score, where a large enough gain can outvote it.
INSUFFICIENT_EVIDENCE A verdict distinct from BLOCK, returned when a run did not complete, a judge was unavailable, or the harness error rate exceeded budget. Keeps absence of evidence from being read as a pass. The pipeline treats it as a stop. A two-valued verdict, under which an incomplete run either blocks wrongly or passes dangerously.
Harness error A failure of the evaluation machinery — sandbox timeout, provider 5xx, expired credential — as opposed to a wrong answer from the model. Classified separately and excluded from scoring, because scoring infrastructure failures as model failures corrupts every number in the run. Counting any non-success as a model failure, which makes a flaky dependency look like a regression.
Contamination canary A subset of examples never published in any form. A published-versus-canary score gap reveals that a candidate has seen the golden set, which otherwise looks like a large genuine improvement. Trusting that a training corpus excluded the benchmark, which is unverifiable from outside.
Judge admissibility Whether a judge's measured agreement with human labels is high enough for it to block a release. Stored on the scorer row and read by the gate, so authority is data rather than convention. Using a judge because it is available, which grants unearned authority to an uncalibrated instrument.
Confound register A record of changes — UI, traffic mix, infrastructure — that overlapped a candidate's exposure window. Lets the platform refuse to attribute an online movement to a candidate, rather than guessing under pressure. Attributing every online change to the most recent model release, which is how the wrong thing gets rolled back.
Tombstone Removal of an example's content while retaining its identity, slice labels and derived scores. The erasure path under an immutable corpus. It preserves aggregate comparability and bounds full reproducibility. Deleting the example, which silently changes every score computed from it.
Open svg/<view>.svg or drawio/<view>.drawio in draw.io Desktop or at app.diagrams.net to edit. The SVG carries the diagram inside it, so it is both the picture and the source. This folder is self-contained — copy it whole and every link still resolves.