# Done-Test Checks: AI Agents and LLM Features

**Check library, version 1.** Rows to lift into the [done-test template](https://mangrove.co.uk/templates/done-test-template.md). Take what applies, delete the rest, and put a number in every threshold.

## The problem this solves

A done-test has to be binary. An AI feature is probabilistic. "The agent answers correctly" is not a check, it is an opinion with a demo attached, and it is how AI projects end up in dispute: the demo went well, the system went live, and nobody agreed in advance what "well enough" meant.

**A probabilistic system becomes binary the moment you freeze the evaluation set.** Agree a labelled dataset, agree a threshold, pin the harness, and acceptance is arithmetic. Everything below is built on that.

Two consequences worth accepting before you start:

- **The eval set is a client input with a date**, like any other. Somebody has to label it, and it has to come from real data rather than examples invented for the purpose. Put it in the spec's inputs table.
- **The eval set defines the product.** If the set does not contain the hard cases, the threshold is meaningless. Argue about the set now; it is much cheaper than arguing about the system later.

## Accuracy and behaviour

| ID | Check | Evidence | Pass |
|---|---|---|---|
| A1 | On the [N]-item labelled evaluation set at Appendix A, the agent scores at or above [threshold] on [named metric: exact match / F1 / rubric score] | Eval harness run live | |
| A2 | Every answer cites the source it came from. Zero uncited claims across the evaluation set | Eval output | |
| A3 | On the [N]-item adversarial set at Appendix B, zero responses contain [prohibited output: leaked personal data, advice outside scope, fabricated citation] | Eval output | |
| A4 | Below a confidence of [threshold], or on the held-out ambiguous set, the agent escalates to a human rather than answering | Eval output | |
| A5 | Refusal behaviour: on the [N] out-of-scope prompts at Appendix C, the agent declines and routes to [destination] | Eval output | |

**On A1.** Name the metric and say who labels ties. "Rubric score" needs the rubric attached, and it needs at least two independent scorers on a sample, or you have swapped one opinion for another.

## Reproducibility

The check that makes every other check mean something. Without it, a passing run is not evidence, because the next run is a different system.

| ID | Check | Evidence | Pass |
|---|---|---|---|
| R1 | The evaluation runs from a pinned model version, fixed temperature and fixed seed, recorded in the repo, and two consecutive runs produce the same score | Two runs shown live | |
| R2 | The eval harness is in the repository and runs in CI, so any change to prompts, retrieval or model configuration re-scores automatically | CI run shown | |
| R3 | Prompts, system messages and retrieval configuration are version-controlled, not held in a console | Repo walkthrough | |

## Performance and economics

| ID | Check | Evidence | Pass |
|---|---|---|---|
| E1 | p95 response latency under [N]s at [concurrency]. Mean latency is not an acceptable substitute | Load-test output | |
| E2 | Unit cost at [volume, e.g. 1,000 operations] at or under £[X], measured from provider billing rather than estimated | Billing dashboard | |
| E3 | Token or request volume per operation stays within [N], so cost does not scale faster than usage | Metrics dashboard | |
| E4 | Rate limits and quota headroom are documented, with behaviour defined at the ceiling | Configuration walkthrough | |

**On E2.** This is the check that catches the feature which works and is uneconomic. It is worth more than any accuracy row, because an uneconomic feature is switched off in month two whatever it scores.

## Failure and degradation

| ID | Check | Evidence | Pass |
|---|---|---|---|
| D1 | When the model provider is unavailable, the system degrades in the defined way ([queue / fall back to [model] / fail visibly]) and never returns a silently wrong answer | Provider failure simulated live | |
| D2 | Timeouts, retries and backoff are configured, and a stuck operation cannot hold a user request open beyond [N]s | Configuration + live test | |
| D3 | Every agent action that changes data is logged with its inputs, outputs and the model version that produced it, and the log is queryable | Live query | |
| D4 | Actions with irreversible effect ([sending, paying, deleting, publishing]) require confirmation or run inside a reversible window of [N] | Live walkthrough | |

**On D3.** For any regulated context, and for most disputes, this is the row you will be most glad you wrote. "What did it do and why" has to be answerable months later.

## Data handling

| ID | Check | Evidence | Pass |
|---|---|---|---|
| P1 | Personal data sent to the model provider is limited to [named fields], with the rest redacted before the call | Live walkthrough with logging shown | |
| P2 | The provider contract excludes the client's data from training, and the retention setting is [N] days | Provider configuration + contract clause | |
| P3 | Retrieval only reaches documents the requesting user is entitled to see | Live test with two permission levels | |

**On P3.** Retrieval-augmented systems leak by default, because the index does not know about your permission model unless someone made it. Test it with two accounts, live.

## Lifecycle

The rows nobody writes, and the ones that cause the argument eighteen months later.

| ID | Check | Evidence | Pass |
|---|---|---|---|
| L1 | The model version in production is recorded, and the named owner for re-qualification when the provider deprecates it is [name] | Written in the runbook | |
| L2 | Re-running the evaluation set after a model or prompt change is a documented procedure any engineer can follow | Runbook walkthrough, performed by the client's engineer | |
| L3 | The threshold at which the system is taken out of service, and who decides, is written down | Runbook | |

**On L1.** Providers retire models on their timetable, not yours. Agree now who pays to re-qualify, or you will be agreeing it under time pressure with the old model already switched off.

## Appendices to attach

| | What it is | Who provides it | By when |
|---|---|---|---|
| A | Labelled evaluation set, [N] items, drawn from real data | | |
| B | Adversarial set, [N] items | | |
| C | Out-of-scope prompt set, [N] items | | |
| D | Scoring rubric, where a metric is judgement-based | | |
