Skip to content

Verifying agent-written code means building checks strong enough that a green run can be trusted without a human reading every line.

An agent opens a pull request with 600 changed lines and 40 new tests, all green. Reading it costs an afternoon; merging on green trusts tests written by the agent that had to pass them. This section is for developers and tech leads who want a third option: make the checks worth trusting, then review the evidence instead of the diff.

Read top to bottom: a strong suite the agent can edit proves nothing.

Your questionPageWhy it comes here
Do these tests catch bugs at all?Oracle strengthThe bar every other page builds on.
Can the agent change the tests to make them pass?Protect the oracleKeeps the decisive checks out of the agent’s reach.
Which tests should the agent write for each layer?Unit, integration, API, end-to-endTests written from acceptance criteria, not from the code.
Does the running app behave, not only the code?Browser verification for agentsScreenshots and traces as evidence.
Does the agent itself keep behaving across model or prompt changes?Continuous evalsRegression tests for the agent harness, run in CI.
What about behaviour that examples cannot capture?Property-based tests, model-graded checksInvariants the agent cannot game, and rubric judges for copy and visuals.
It works, but will it stay maintainable and safe?Fitness functions, slop detection, dependency checks, code quality gatesGates for erosion, plausible-but-wrong code and invented packages.
The code has no tests yet.Characterization testsPin today’s behaviour before an agent refactors it.
Do I need a specialist gate?Accessibility, performance, security, error injection, mobile, test dataAdd when the product needs them.

Pick the module the agent changes most. The first prompt measures what its tests catch and changes nothing.

If no mutation tool is configured, the setup is npm i -D @stryker-mutator/core (Stryker 10.0.0), pip install mutmut (mutmut 3.8.0) or cargo install cargo-mutants (cargo-mutants 27.1.0); oracle strength covers configuration.

The second prompt writes failing tests from executable acceptance criteria before the implementation.

Save the first prompt as prompts/oracle-audit.md; the headless commands below read it from there. The prompts work in every tool; only running them differs.

Paste the prompt into an interactive claude session, or run it headless. claude -p starts in Manual permission mode (auto mode on third-party providers or with telemetry off, from v2.1.285, where a classifier decides), so add --permission-mode dontAsk to deny Bash calls it cannot ask about on every provider, and allow the test and mutation commands explicitly (here for a JS/TS project): claude -p "$(cat prompts/oracle-audit.md)" --permission-mode dontAsk --allowedTools "Bash(npx stryker *)" "Bash(npm test *)" (flags: 2.1.283; the v2.1.285 change: Claude Code changelog, checked 2026-10-12). For the failing-tests prompt, which writes files, pass --permission-mode acceptEdits instead. To stop the agent editing tests in the second prompt, add deny rules for your test paths as shown in protect the oracle. Tool-specific setup is in testing with Claude Code.

How do you know the tests are trustworthy without reading them?

Section titled “How do you know the tests are trustworthy without reading them?”

Four signals replace reading every test.

SignalGood enough whenOwner
Mutation score on the changed codeSurviving mutants are listed and each one is killed or explainedDeveloper who runs the agent
Criterion-to-test mappingEvery acceptance criterion has a test with a recorded failing runDeveloper; reviewer spot-checks
Oracle protectionTest and CI config changes need a code owner’s approvalTech lead
Flake rateFlaky tests are quarantined, not retried until greenTech lead

These signals go into the pull request’s evidence bundle, which the reviewer signs off; the argument is in evidence, not diffs.

What breaks when agents write their own tests?

Section titled “What breaks when agents write their own tests?”

The suite is green but bugs still reach production. The tests assert on implementation details or mocks. Recovery: run the audit prompt, then have the agent kill each surviving mutant with a behaviour assertion.

The agent loosened a test to make it pass. A toBe(19.99) became toBeCloseTo(20, 0) inside a “fix”. Recovery: revert the test change and put test paths behind deny rules and CODEOWNERS.

A coverage target became the goal. Agents chasing a percentage add tests that execute lines without checking them. Recovery: replace the coverage target with the criterion-to-test mapping and the mutation score on changed code.

The suite got slow and flaky after a batch of generated tests. Recovery: drop tests that kill no mutant the rest of the suite misses, and quarantine any test whose result changes between identical runs.