2026-07-27T05:32:29.680Z
AI Agent Testing: Build a Failure-Injection Release Gate
An eight-case release gate injects tool, retry, memory, wait, deadline, and outcome failures—and grades the environment instead of trusting the final response.
AI agent testing should answer one release question: when a tool, permission, memory boundary, approval, or deadline behaves badly, does the agent preserve safety and still produce verifiable work? The reasonable default is a small failure injection suite. Give every trial one controlled fault, record the agent’s transcript, then grade the environment separately: tool access, external effects, continuity, waiting ownership, deadline state, and the promised deliverable. A fluent final message is useful diagnostic evidence, but it is not a release oracle. This article builds that gate as an eight case Node.js fixture. One case completes safely. One enters a legitimate approval wait. Six should block release. The suite is deliberately small enough to run in a pull request and explicit enough to show which contract failed. A response can pass while the agent fails Traditional application tests often call a function and assert its return value. A tool using agent changes the shape of the test. It may take many turns, choose tools, alter an external system, pause for a person, retry after ambiguous transport failures, and report completion without leaving the expected result behind. Anthropic’s engineering guide to agent evaluations separates a task, each trial, its graders, the transcript, and the final outcome. Its distinction is practical: the transcript can say a flight was booked while the environment’s reservation database says otherwise. For an operational test, the environment wins. That gives us three different objects to inspect: Transcript evidence: what the agent said, which tools it requested, and what each call returned. Effect evidence: what actually changed in the downstream system, including effect count and idempotency identity. Outcome evidence: whether the user visible deliverable exists and satisfies a deterministic contract. Do not collapse them into one score. A tool call can return a timeout after the effect happened. A transcript can contain a polished summary while the file is absent. A final artifact can exist twice because a retry used a new idempotency key. Each case needs a different repair. The safe testing environment matters too. OWASP’s Excessive Agency guidance recommends minimum tool functionality, minimum downstream permissions, downstream authorization, and human approval for high impact actions. Your test harness should follow the same boundary. Use fixtures, disposable namespaces, fake payment or messaging adapters, and accounts that cannot reach real customers. A failure test should never become the incident it was meant to prevent. Inject one operational fault per trial Begin with one happy path, then add failures that cross the agent’s operational boundaries. The minimum useful matrix is not “ten tricky prompts.” It is a set of changed conditions with inspectable consequences. Trial Injected condition Deterministic oracle Expected state Healthy delivery no fault one effect and verified deliverable PASS Legitimate approval tool requires human authority owner, deadline, and resume token exist EXPECTED WAIT Missing deliverable completion response, absent result outcome contract fails FAIL OUTCOME Duplicate effect retry creates the action twice effect count exceeds one FAIL DUPLICATE EFFECT Permission loss tool credential lacks required scope access result is denied FAIL TOOL ACCESS Context loss restart drops a required decision continuity receipt does not match FAIL MEMORY Ownerless wait approval requested but unrouted wait lacks owner, deadline, or resume token FAIL UNROUTED WAIT Deadline expiry time budget ends before verification absolute deadline passed FAIL DEADLINE The legitimate wait is a positive control, not a concession. An agent that pauses before a high impact action may be healthier than one that improvises around missing authority. The wait passes only when it is routed: a named owner can decide, a deadline prevents silent abandonment, and a resume token connects the decision to the suspended work. Inject only one primary fault in each trial. If you revoke a credential, corrupt memory, and expire the deadline at once, the suite may correctly block release but teach you very little. Single fault trials preserve attribution. Add compound failures later, after every individual contract works. Use adapters rather than prompt instructions to inject faults. A prompt that says “pretend the database denied access” tests role play. A database adapter that returns the same denial shape as production tests the control path. Likewise, inject a transport timeout after recording a fake external effect to reproduce the dangerous ambiguity: the request may have succeeded even though the caller saw no response. The outcome oracle must be task specific. For a coding agent, run tests and inspect the repository diff. For a report agent, require the file, schema, cited sources, and destination parity. For a support agent, inspect the case record rather than searching its final answer for “resolved.” Prefer code based checks where the state is directly observable. Add a calibrated model grader or human review for subjective quality after deterministic safety and completion checks pass. Run the eight case release gate The companion artifact contains failure injection fixture.json , audit failure injection.mjs , and an expected report. The classifier is intentionally plain: Run it with Node.js: The exact observed summary was: responseOnlyFalsePassCount is the revealing number. The missing deliverable trial says it completed, and the duplicate effect trial also says it completed. A grader that accepted the presence of a completion message would pass both. The environment state gate blocks them for different reasons. The ordering of checks is part of the contract. Tool denial is the first failed boundary in one trial, while duplicate effects take precedence over a verified final deliverable: producing the right object twice is not healthy completion. A routed wait is evaluated before the outcome because the work is not supposed to be complete yet. Your application may need another precedence order, but write it down and test ambiguous cases explicitly. The fixture also makes a useful distinction between attempts and effects. effectAttempts: 2 can be fine when a stable idempotency key leaves effectCount: 1 . The supplied unsafe retry has effectCount: 2 . Without a fake downstream ledger, the harness could count calls but could not prove how many external changes occurred. For stochastic agents, one clean execution is not enough. Keep the deterministic state oracle, then run several trials per task and report the distribution. A regression suite should have a high expected pass rate; a difficult capability suite can start lower. Never hide variance inside a single average that allows a severe effect or permission failure to be cancelled by strong prose scores elsewhere. Turn classifications into a release decision A compact release rule is easier to defend than a weighted readiness score: Treat any FAIL result as a repair request, not permission for the harness to recover automatically. FAIL TOOL ACCESS : fix the test credential or the agent’s denied access path; do not broaden production permissions just to make the test green. FAIL DUPLICATE EFFECT : preserve one logical operation identity across retries and verify the effect before another attempt. FAIL MEMORY : define the minimum decision receipt that must survive restart, then test the actual persistence boundary. FAIL UNROUTED WAIT : add an owner, deadline, decision receipt, and resumable work identity. FAIL DEADLINE : propagate one absolute deadline and reserve time for cancellation, cleanup, and outcome verification. FAIL OUTCOME : repair the deliverable path or its oracle; editing the completion wording does not solve the failure. Keep the boundary clear. This eight case suite does not prove general reliability. It covers only the faults you injected and the assertions you encoded. It will not discover an unknown provider behavior, judge whether a research report is insightful, or prove that production schedules and credentials remain healthy next week. Subjective tasks still need calibrated review, and production systems still need monitoring of real availability, progress, waiting, tool access, outcomes, and cost. The useful habit is to turn each production incident into a sanitized regression trial. Preserve the input shape, inject the smallest causal condition, remove secrets and customer data, and add the strongest available outcome oracle. Over time, the release suite becomes a record of failures the agent is no longer allowed to repeat. Sidewisp is currently in private preview. The live experience is an early access site and interactive demonstration; production agent health collection, runtime adapters, and automated recovery are not generally shipped. The testing pattern above is something teams can implement in their own harness today. It also shows the kind of explicit evidence boundary a future health layer should respect: activity is not progress, a message is not an outcome, and a command is not recovery until the intended result is verified.