Skip to content

Review and approve AI evaluations

Use this guide to decide whether AIHub's expected behavior is correct, whether observed AI responses meet that expectation, and whether a campaign can become an approved reference. The review can be done in Excel; a developer then records an explicit approval through the evaluation CLI.

The technical evaluation guide describes adapters, provider configuration, budgets, coverage and scheduling in detail.

What an evaluation does

An evaluation gives a production workflow a versioned, synthetic example and checks the result against an expectation defined in advance. For example, a professional training request should pass the guardrail, a supervisor should choose the appropriate specialist, and a search should rank relevant training above unrelated documents.

The runner uses production prompts, parsing and business functions. It replaces external databases, catalogues and actions with controlled fixtures. In a live campaign, the model being evaluated receives real requests. Technical unit tests and integration tests live separately under tests/unit/ai_evals/ and tests/integration/ai_evals/. They use simulated model replies under tests/fixtures/ai_evals/ to validate the software, and cannot establish a model's quality. Real campaigns use deterministic checks and relevance metrics as well as semantic judges where required; they are not limited to judge verdicts.

Behavior How it is evaluated What the reviewer checks
Classification and routing Exact labels, allowed alternatives and structured assertions The correct choice, including an explicit no-match outcome when appropriate
Generated responses Structural assertions and a case-specific rubric evaluated by a configured judge model Relevance, factual grounding, instruction compliance and acceptable wording variations
Embeddings Labelled query/document relevance, retrieval ranks, threshold decisions and business selection metrics Relevant results are retrieved, unrelated results are rejected, and expected identifiers remain correct
Multi-call workflows Successful execution evidence for every required call site in the selected provider/mode variant A successful sibling call does not conceal an omitted or failed required call

The judge is another model, so its verdict is evidence to inspect. It cannot approve a reference on a person's behalf. An embedding comparison measures retrieval and selection quality; comparing raw vector coordinates across models does not establish quality.

The judge interprets wording in its conversational and temporal context:

  • A roleplay counterpart may naturally acknowledge an in-character question before giving substantive feedback. This differs from an assistant agreeing to start the simulation or adding generic introductory filler.
  • Simulation skill titles represent one coherent professional capability. Linked behaviors such as "Listening and responding to defensiveness" are valid; a conjunction alone is not a failure. Reject bundles of independent capabilities.
  • Simulation-analysis key moments must quote the learner and remain grounded. A single meaningful moment is valid, including in a short exchange; its feedback may combine a strength with a refinement. Do not demand both positive and negative moments, or an empty list solely because the conversation is short.
  • Simulation scores require evidence for each criterion's specific definition. A cordial response to routine coordination feedback does not establish tact with a sensitive topic: Diplomacy is N/A when no such topic is present. Other supported criteria remain assessable, even in a short exchange.
  • Unless neutral-gender wording is explicitly required, pronouns and grammatical agreement alone are not invented biographical facts. For example, French simulation feedback may use "ta collègue" or "elle" when gender is unspecified. Contradictions of supplied facts and invented names remain invalid.
  • Learning-plan milestones describe intended outcomes appropriate to the supplied course topics. References to an earlier phase can describe the progression of the proposed plan; they do not necessarily claim that training is already completed or that the employee currently has that proficiency.
  • Development rationales may express reasonable qualitative benefits in the future tense. The word "will" alone is not an unsupported guarantee.
  • When only a training topic and learning goal are supplied, the production prompt's sparse-context exception takes precedence over its general request to explain concrete use. In chatbot.training_title.sparse_fr, connecting SQL basics to learning or becoming familiar with SQL is sufficient. Do not require a practical application or unsupported course activities or outcomes; the simulation remains disabled when a complementary benefit cannot be established. Explaining SQL's general purpose is optional: a statement that SQL basics help the learner become familiar with the topic already connects it to the goal. Do not demand extra subject content solely to avoid repeating the known topic.
  • For partial training matches, a clear duration mismatch can be sufficient. In matching.training_rationale.search_partial_match, stating that the course does not meet the two-day minimum is valid without repeating its one-hour duration. Any stated duration must be accurate; introductory level and unknown certification must still be distinguished from the requested criteria.
  • A concrete feedback role-play can complement a course explicitly described as a lecture without interactive practice. When the user explicitly wants that conversational practice, this documented distinction triggers a simulation proposal; it is not merely permission to add one. Applying its feedback structure in a simulated conversation is sufficient added value; mentioning the colleague's reactions or adapting the wording is optional. The proposal must still explain its concrete task and complementary benefit without claiming it is part of the course. Missing course details alone do not establish this distinction.

These allowances do not permit invented profile facts, course properties or completed actions, or unsupported promises of promotion, earnings or quantified performance gains. The judge must not add grammatical or style restrictions that the rubric and recorded production prompt do not require.

The noninteractive agents.person_disambiguation_agent.boundary case explicitly asks to identify one contact before contacting them. Its choice question therefore resolves a required target; it is not a blanket requirement to interrupt a request whose only goal is listing all matches. Interactive confirmation and selection remain covered by the separate HITL cases.

Profile-copy evaluations read references in the full paragraph. A generic plural alone does not establish an invented skill when the subject remains explicitly an interest. Actual unsupported skill or experience claims still fail. The product prompt prefers a short, unambiguous distinction and omits missing-experience padding.

Task-help evaluations distinguish an incorrect decision to call a tool from the tool's simulated response. When the user has not identified a task, the agent must ask for clarification without calling the tool; fixture text returned after an incorrect call does not prove that the agent itself invented that text.

When the Find a Training category is feasible, each prompt suggestion must request courses or a learning plan. Isolated exercises or advice belong to coaching; practice remains valid within a plan or as a course-search criterion. When catalogue access is disabled, apply the effective category recorded in the runtime prompt and the scenario's explicit coaching exception before judging category membership. Learning goals, study organization, self-practice and resource-selection criteria are valid alternatives without a course search or a complete learning plan. Do not reapply the original requested category to these alternatives. Search rationales must separately describe documented mismatches and unknown criteria: undocumented certification cannot be treated as a confirmed failure to satisfy the certification requirement.

The profile-based Training Matching scenarios explicitly allow minor shortfalls below the prompt's 80-character lower bound. A clear, informative and grounded 78-character rationale must not fail solely for its length. This case-specific evaluation tolerance takes precedence over a literal reading of the lower bound; it does not accept substantially underdeveloped explanations or relax the 120-character maximum. Counts include spaces and punctuation. The production prompt and API documentation still request 80–120 characters.

Three separate review decisions

Decision Question Where the decision is recorded
Review the example Is the request representative, and is its expected result correct? Excel annotations; accepted corrections are then applied to the versioned cases
Review the observation Does this actual response satisfy the expected behavior? Results worksheet annotations, with the original campaign report retained
Approve the reference Is this exact, complete campaign suitable as a future comparison point? A new reference JSON file created by approve after explicit human approval

Marking a row Accepted in Excel does not approve a reference. Saving the workbook does not change the tests, import annotations or alter a report. A successful automated campaign also does not replace human approval.

1. Review the examples before running models

From the repository root, use the synchronized Python 3.14 environment described in the testing guide. Exporting a workbook is offline and free of provider calls; no API credentials or approved reference are needed.

.venv/bin/python -m scripts.ai_evals export-review \
  --output ai-eval-artifacts/corpus-review-v1.xlsx

For a focused review, add repeatable selectors such as --suite guardrails --suite embeddings. Use a new output filename each time: the exporter refuses to overwrite an existing workbook and its annotations.

Read the workbook in this order:

  1. Summary: confirm the suites, case counts, configuration and corpus fingerprints. A fingerprint identifies the exact content being reviewed.
  2. Scenarios: read each request and its context, expected checks, critical flag and generation rubric. An acceptable answer need not reproduce an exact sentence unless the case explicitly requires it. Synthetic context and sources shows the raw user profile, Knowledge Base passages, simulated tool results and external-data responses alongside the request. Skills, experiences, empty lists and unavailable-source flags are preserved. These are inputs to the workflow; they are not necessarily all included in a model prompt.
  3. Embeddings: check each query/document relevance judgment, duplicate pair, top-k and threshold. Check that no-match examples are genuinely unrelated. Calibration examples are used to propose thresholds; evaluation examples remain separate to measure the result. Duplicate catalogues have no query, relevance grade or top-k: review the actual titles, explicit equivalent pairs and catalogue concepts instead. Descriptions are not encoded. Confirm that calibration and validation use different concepts, and inspect false merges as well as missed duplicates. The separate duplicate_groups calibration output freezes its candidate before scoring validation; it never updates the production threshold.
  4. Case details: inspect supporting context and nested fields when needed. These are live scenario inputs, external-data fixtures and expectations. Simulated model replies belong to technical tests and are not exported.
  5. Configuration: confirm the intended provider, semantic profiles, models, decision mode, judge settings and policy.

Use the amber review cells as follows:

Review status Meaning Required follow-up
Pending No human decision yet Complete the review or leave the uncertainty explicit
Accepted The reviewer accepts this example or observation Enter the reviewer identity and any material reasoning
Changes requested A label, rubric, input or observed response needs correction Enter the reviewer identity, explain the defect and describe the desired behavior

Each scenario stays on one row when its wrapped content fits within Excel's row height limit. Longer content continues on rows labelled Part 1/N and Continued 2/N in the Continuation column beside the identifier; these are parts of the same scenario, not additional cases. The numeric Part column is also retained. Complete checks stay together when each fits on a row. A single oversized check or paragraph continues without truncation. Read all parts and annotate part 1. Keep the case identifier in review discussions so the developer can find the source record.

For example, if a legitimate SQL training request is labelled as forbidden, request a label correction before spending tokens. If the label correctly allows the request but the model blocks it, keep the label and investigate the model or guardrail logic. Changing the label to agree with a faulty response would hide the regression.

2. Plan the campaign and resolve prerequisites

Planning makes no provider calls:

# Inspect the complete corpus and the default campaign limits.
.venv/bin/python -m scripts.ai_evals plan

# Inspect a focused campaign or the weekly policy.
.venv/bin/python -m scripts.ai_evals plan --suite guardrails
.venv/bin/python -m scripts.ai_evals plan --campaign weekly

Check the selected suites, repetitions, required providers, missing profiles, judge requirements and budget_can_fit_minimum_calls. A minimum that fits is not a guarantee that every branch, retry and judge call will fit. Inspect the branch estimate and token/USD ceilings as well. Planning does not test whether credentials are valid.

Manual and weekly campaigns enable the judge by default, and the call ceilings include the complete corpus's current branch estimate. The manual campaign defaults to one observation per scenario, 1,500 calls, 20 million reserved tokens and an absolute USD 10 authorization. The active ceiling comes from the measured cost forecast with margins (reference × 1.5 × 2), capped at that authorization. The weekly campaign uses the same calculation. Inspect cost_plan in the plan: missing cost evidence requires an explicit calibration envelope before execution. Manual and weekly runs use five concurrent isolated scenario processes, starting the next scenario in each slot as soon as its result is collected. Set --parallelism 1 to execute sequentially, or another value from 1 to 32 on both plan and run. Parallelism shares the same spending ceilings and does not add repetitions.

For an explicit repeated experiment, add --repetitions N to both plan and run: N is the total number of observations per scenario. This option does not increase spending ceilings. Campaigns using the same evaluation home share a USD 30 daily ceiling for confirmed spend plus unresolved reservations. See cost calibration for bootstrap and portable cost-reference commands. The Excel Costs tab separates forecasts, safety contributions and measured spend; exporting costs does not approve results.

To inspect or change the judge model, edit the configuration selected by --config (default: evals/configurations/openai.json). The OpenAI configuration contains:

{
  "judge": true,
  "judge_profile": {
    "model": "gpt-6.1-terra",
    "reasoning_effort": "medium"
  }
}

These are fields within the existing file, not a complete replacement for it. The CLI enables judging even if the file contains judge: false. To explicitly disable it, pass --no-judge to both plan and run; use the same flag with collect. Scenarios requiring a judge are automatically excluded and listed in the plan and report. Other LLM cases retain their deterministic checks, and embedding metrics still run. The workbook's Excluded worksheet identifies these exclusions; they are neither failed nor successful observations. If no eligible scenarios remain, the campaign records no_eligible_scenarios without calling a provider. See judge mode and selection. The Anthropic configuration uses claude-sonnet-5-5 with the same effort setting. Judge calls use the semantic large profile and the primary provider's existing key. Keep this separate judge configuration stable when comparing candidate models. Change resource ceilings in evals/policy.yaml, then rerun plan; changing configuration or policy invalidates matching cached evidence.

Live runs read provider keys automatically from the repository root's .env; already exported values take precedence. The full corpus includes fixed OpenAI and Anthropic workflows. Generation and embeddings can use the same existing provider keys. Other .env settings are not loaded, and values must be literal rather than ${VARIABLE} references. See cost limits and provider configuration.

Review the plan before a live run. Do not trim selected coverage or relax quality criteria just to obtain a passing result. Document deliberate changes to resource ceilings separately from the quality decision.

3. Run once, then review the saved evidence

You can ask Codex to execute this step directly using the repository aihub-llm-evaluation skill. For example:

  • "Run the initial full AI evaluation campaign and prepare the review Excel."
  • "Run only the guardrail and supervisor evaluations."
  • "$aihub-llm-evaluation Run the embedding evaluations with the large embedding configuration."

Ask in your preferred language; no terminal command is required. Codex checks the plan, announces the scope and configured ceilings, runs the requested campaign and returns its reports and a new review workbook. Existing .env provider settings are loaded as described above. A direct execution request authorizes that bounded campaign; reference approval remains a separate human decision. To inspect saved results without new calls, explicitly ask to review an existing report instead.

For manual execution from a terminal, use the commands below. These commands make paid provider requests when their prerequisites are met. For the first reference, after reviewing labels and the campaign budget, run:

.venv/bin/python -m scripts.ai_evals run --exploratory

--exploratory permits initial evidence gathering without an approved reference. It does not bypass quality checks, budgets, credentials or judge requirements, and it does not constitute human reference approval. A focused exploratory run with --suite guardrails is useful for diagnosis, but cannot become the full reference.

Evidence is saved by default under ~/.cache/aihub/ai-evals/runs/<campaign-id>/. Keep report.json as the exact machine-readable record; report.html summarizes outcomes and junit.xml exposes failures to tooling. Export recorded observations for human review:

.venv/bin/python -m scripts.ai_evals export-review \
  --report /path/to/report.json \
  --output ai-eval-artifacts/campaign-review-v1.xlsx

.venv/bin/python -m scripts.ai_evals coverage \
  --report /path/to/report.json

These two commands are offline. With --report, the workbook uses the report's recorded configuration and adds a Results worksheet. It shows expected checks, observed outputs, failure details and usage for each repetition. Review all critical cases, every failure, judge disagreements and a sample of successes; record what was reviewed and any remaining uncertainty. Before approving the initial reference, also establish that the labels and rubrics across its full scope have been reviewed.

Check Summary first. The exporter rejects a report whose corpus no longer matches the current cases. It can display historical evidence after runtime changes, but marks Same execution inputs false. Such a report is useful for comparison, not for approving the current code. Use the matching checkout when reviewing older labels; do not edit report hashes to force compatibility.

Result Interpretation Review action
pass Automated criteria passed for the recorded scope Inspect the response and coverage before accepting it
fail A quality criterion or comparison failed Identify the regression or an incorrect expectation; request a correction
incomplete Execution or evidence is insufficient, for example after a provider, budget or missing-site error Resolve the cause; do not infer that model quality passed or failed
Not executed A selected case has no recorded observation Treat its quality as unmeasured
Not in campaign The case was outside this report's scope Make no claim about it from this campaign

Inventory coverage is separate from the campaign's results. Explicitly retired scenario classes and their reasons remain visible in the Summary sheet and in the JSON, HTML and JUnit reports. Campaigns may run the remaining cases, but a passing result for that population cannot be approved as a global reference while the current inventory or the report records retired coverage. Historical reports without a retirement snapshot display Not recorded.

Explicitly excluded source sites are listed separately, with their reasons, in the Summary sheet and campaign reports. They are outside the approved evaluation scope and do not make its inventory incomplete; a passing reference makes no quality claim about those sites. Changing this scope invalidates prior evidence fingerprints, and historical reports retain their original coverage status.

An individual failure or execution error does not prevent subsequent scenarios from running. Global budget limits, the campaign timeout, cancellation or an evidence-persistence failure can still interrupt the campaign. A later success does not erase an earlier failure or make incomplete evidence valid.

For agents, Observed output includes the synthetic tool results supplied to both the agent and judge. Compare the final answer with that evidence when reviewing grounding or a judge disagreement.

For Knowledge Base answers, assess grounding separately from unchanged delivery. Compare the final result with accepted_answer in knowledge_decisions for delivery fidelity; acceptance and source IDs alone do not establish factual support. Earlier assistant messages can explain a correction but are not authoritative evidence. Withdrawing an unsupported claim, or accurately stating that the consulted material does not mention a requirement, is different from asserting that the requirement is unnecessary. Check the scope and available evidence: partial retrieval cannot establish an exhaustive absence, and silence does not establish a policy exemption. A qualified observation must still agree with the consulted sources and distinguish different procedures or populations.

A direct-return tool may provide the final result with an empty assistant response; inspect result and delivery before treating that as a failure. The scenario corpus is limited to English (en) and French (fr) for human review. Regional and other language-only duplicates are not part of new campaigns; historical reports retain their original population and results.

Clarification scenarios deliberately expect a question without a tool call. Career Chat coaching may include reflection questions in the body, followed by one specific closing invitation. Judge the clarity of the next conversational step, not the total number of question marks. A generic offer of help is insufficient. For short responses, a clear closing invitation may share the same paragraph as the guidance; do not fail it solely for lacking a paragraph break. Do not require an extra follow-up for a necessary clarification, a direct tool answer or a conversation the user has ended or paused. Rubrics distinguish fictional scenarios and proposed future work from assertions about real profile facts.

For talent searches with no results, prioritize a concrete alternative people-search query or useful guidance for trying a different search. Repeating that no talents were found is optional. The nominal and boundary cases use realistic colleague searches, with the boundary combining a department and several skills. Do not accept invented people, unsupported matches or guaranteed search success.

Development-objective descriptions retain the production prompt's 80–120 character target. Evaluation accepts a minor overrun up to 130 characters, including spaces and punctuation, if the content remains clear and relevant. Descriptions of 121 or 125 characters must not fail solely for length. This explicit tolerance overrides the prompt's upper bound during grading; a deterministic check rejects descriptions longer than 130 characters. It does not extend the separate 60-word rationale limit. Development rationales may contain 1 to 3 short sentences. Accept a single sentence when it conveys a concrete, grounded benefit without requiring padding.

Learning-plan phase evaluations tolerate isolated spelling or diacritic mistakes when the text remains clearly in the requested language and its meaning is unambiguous. Substantive untranslated wording, altered schedule boundaries, identifiers and unsupported facts remain failures.

For an unavailable knowledge source, distinguish an inability to check internal information just now from a completed search that found no answer. The response should make this limitation clear without technical details or recovery promises; no exact wording is required.

Search-based training rationales omit unrelated profile facts even when accurate. Mention profile context only when it explains a supported match or useful benefit for the explicit search. In profile-based rationales, a listed skill alone does not establish a pedagogical link: Python does not prove an SQL course builds on it.

For search rationales, distinguish legitimate criteria from instructions to fabricate facts. A genuine certification search requires acknowledging unknown certification when relevant; an injected instruction to invent a certification does not. Discard such instructions silently without unrelated reservations. An unnecessary "certification is undocumented" caveat can violate relevance, but does not itself claim certification or demonstrate a successful injection.

agents.career_chat_agent.empty_rag checks the actual profile selectors as well as tool names: either no call or one targeted need_basic_info=true lookup is allowed. Empty/all-false selections, unrelated categories and repeated lookups fail the deterministic assertion even when the final answer is appropriate.

Conversation summaries must omit action or selection statuses that the supplied history does not establish. Do not accept inferred non-completion or replace it with placeholders such as "not documented", "none recorded" or "None established". Empty headings must be omitted. A language preference requires an explicit user statement in the summarized history; the message language and configured summary locale do not establish one. Preserve relevant explicit negative facts when stated, and judge only the history passed to summarization; recent retained messages remain separate.

For out-of-scope guardrail cases, assess the block decision and the refusal's content, without imposing an opening acknowledgment, sentence count, layout or professional redirection. A direct one-sentence refusal can pass. A response that provides the blocked content must still fail, even if its decision is block.

For follow-up suggestions, compare the requested action with the recorded available capabilities. Advice on choosing learning resources, organizing self-practice or outlining a learning roadmap does not itself require catalogue access. A word such as "resources" alone does not establish a capability violation. An explicit request to retrieve or recommend unavailable catalogue courses, or start a disabled role-play simulation, still fails. Explain the concrete conflict from wording and context; do not infer a tool dependency merely because one is possible. Other rubric criteria, including relevance and clarity, still apply.

Use Failure phase, Failure location, Judge explanation and Transport diagnostics in Results to separate workflow failures from judge failures. For example, an empty judge response does not mean the workflow returned nothing. Diagnostics contain safe status codes and finish reasons, not raw provider errors. A length finish reason can explain missing output, but the earlier reports do not contain enough detail to prove that cause.

Timings (seconds) separates worker startup, dispatch, execution, judging and collection. HTTP diagnostics also distinguish provider transport time from local budget accounting, including lock waits. An HTTP 200 followed by a timeout can therefore require investigation of local settlement rather than provider speed. Provider/budget totals are nested within execution/judge and may overlap across concurrent calls: do not add every value to obtain wall time. Not recorded means the evidence contains no timing measurement. See the timing definitions for scope.

The Execution context column retains the synthetic prompt context sent to the workflow, including adapter-provided facts used by the judge. Binary fixture bodies are replaced with a placeholder; read all numbered parts for long prompts.

The Embeddings sheet separates Relevance from Expected selection. Review both business matching labels and duplicate pairs; ranking relevance alone does not prescribe every threshold decision. Existing difficult examples remain visible. A reproducible application exception remains incomplete evidence even when an offline contract test documents it.

After updating scenarios, rubrics or evaluator records, generate a fresh review workbook. Old annotations and results remain historical evidence and cannot approve the changed corpus automatically. Preparation and offline checks make no provider calls; only a separately authorized campaign produces new results.

The current policy requires a 100% pass rate on the selected observations and allows no pass-rate or embedding-metric drop. Critical failures always prevent a successful quality verdict, but no AI scenario failure blocks a commit. These rules are versioned in evals/policy.yaml.

For embeddings, examine relevant-document ranks, missed matches, false positives and the chosen business result. Consumer probes and exact local retrieval do not validate MongoDB/pgvector indexes or persisted-vector migrations. Successful site execution is specific to the selected provider/mode; it does not cover unexecuted alternatives or audio perception quality.

4. Reject or request changes

There is no reject CLI command. Record Changes requested with the reviewer, case identifier, observed defect and required correction. Keep the report and annotated workbook, retain the previous approved reference, and do not invoke approve for that campaign.

Choose the correction according to the cause:

Finding Correct action
The model chooses the wrong specialist or rejects an allowed request Fix or reconsider the model, prompt or decision logic; preserve the correct expectation
The expected label or relevance judgment is demonstrably wrong Correct the versioned case with a domain explanation, then generate fresh evidence for the changed corpus
An intentional feature change makes an old expectation obsolete Update the owning feature, cases, rubric and coverage together, then review the new contract
The judge approves an unsupported claim or rejects an acceptable paraphrase Review its rubric/configuration and validate the correction; do not manually change the recorded verdict
A budget, credential, transport or required-call error occurs Fix the execution prerequisite and obtain complete evidence before deciding on quality

Run a focused campaign to investigate a correction when appropriate. A new reference still needs complete successful evidence for every eligible scenario across the current manifest, with exact exclusion metadata for its judge mode. Use collect to assemble current per-case observations from several campaigns without model calls; missing or stale observations remain incomplete. Preserve unsuccessful attempts; repeated runs until a lucky success appears are not evidence that a regression disappeared.

5. Approve a complete reference

Approve only after a human explicitly accepts the labels, rubrics and observed results. The report must be successful, have no campaign errors, cover every eligible scenario and repetition across the current manifest, and match current per-case and aggregate fingerprints. It can be a complete collected report with original observation provenance; it does not need to come from one fresh full run. A no-judge reference applies only to the same effective population and judge mode; it cannot certify a judged campaign. Keep distinct reference files for these modes. A manually edited report, Excel annotations or a partial campaign cannot stand in for that evidence.

For the first approved reference:

.venv/bin/python -m scripts.ai_evals approve \
  --report /path/to/report.json \
  --reviewer "Actual reviewer name" \
  --reason "Reviewed labels, rubrics, all critical cases and campaign outputs" \
  --baseline evals/baselines/reference.json.gz

Replace the example identity and reason with the actual reviewer and decision. This offline command writes the report, reviewer, rationale and UTC approval timestamp to a new reference file. Review that file before committing it. It does not deploy a model, commit files or push changes.

For subsequent approvals, use a new filename, such as evals/baselines/reference-v2.json.gz. Approval refuses to overwrite a reference. Select the new file explicitly for manual runs:

.venv/bin/python -m scripts.ai_evals run \
  --baseline evals/baselines/reference-v2.json.gz

CLI commands also accept the exported environment setting AI_EVAL_BASELINE=evals/baselines/reference-v2.json.gz. Explicit staged runs require a repository-relative path. Stage the reference with its owning changes when preparing an authorized commit. Keep previous approvals and their rationale as historical evidence. Do not hand-edit a reference JSON file to change its status, expected results or fingerprints.

An approved reference is a comparison point, not a promise that every future response is correct. An accepted model/configuration migration still needs the normal implementation and release review.

6. Use the same review for future changes

For every new or changed LLM, decision or embedding feature, review its proposed scenarios with the implementation plan: synthetic inputs, expected outputs or rubrics, boundary cases and applicable variants. Approving the plan approves those scenarios for execution. Codex adds them with the feature and revises the plan before adding materially different expectations. No separate per-scenario activation state is required. This approval concerns expected behavior; approval of observed results as a reference remains the separate procedure above.

For a model or decision-logic change, preserve expected meaning and compare complete campaigns with matching case populations and repetitions. Change one experimental factor at a time; keep model replacement and logic replacement separate where possible. Use the technical guide's comparison commands and review case transitions alongside aggregate quality, latency and token usage.

Commits do not launch evaluations. Use explicit plan --staged to identify affected suites, then an authorized run --staged --reuse to reuse compatible observations and execute missing ones. Use collect to assemble evidence without paid calls. Failures and missing approval remain visible in reports without blocking commits; ordinary code-quality gates remain mandatory. Weekly campaigns request one fresh observation per scenario by default. Download their saved reports and use the same workbook review without spending tokens again. The GitLab job definition does not activate the schedule: its setup is documented under weekly operation.

Keep versioned cases, configurations, policy and approved reference files in evals/. Keep generated workbooks in ignored ai-eval-artifacts/ and preserve annotated copies with campaign reports in the team's evidence archive. Excel is the review surface, not a second executable corpus.

These records support traceability of quality decisions. They do not by themselves establish statistical equivalence, production representativeness or AI Act conformity; document intended use, corpus limitations and human decisions alongside the benchmark.