When a Test Goes Red: Triage, the Heal Guard and Quarantine
The cheapest fix for a red AI test is to hide it. On checkout a red test is labelled, not fixed: four triage labels, a heal guard that diffs every fix, quarantine that expires in 30 days, and a defect that closes only on a newer passing run.
Key takeaways
- A run never fixes anything: each failure gets one of four labels, FUNCTIONAL, SCRIPT, SETUP/ENV or FLAKY, with its evidence.
- FLAKY needs an observed passing re-run; a hunch does not count.
- npm run qa:heal-guard blocks a fix that removes, weakens or suppresses an assertion; a changed expected value passes only if the case says so or a named human approves.
- A quarantined test still runs and still reports its real status, for at most 30 days.
- A defect closes as fixed only after a newer verification run in which its case passed, and a recurrence re-opens the same file.
Contents
FAQ
Can the agent just add a retry to make a flaky test pass?
No. Retries, timeouts, waits, skips and toPass() are suppressed changes the heal guard never allows. A flaky case goes to quarantine in the open, with an expiry date of at most 30 days, and keeps running.
What happens when a fixed bug comes back?
The same defect is re-opened with a recurrence line, never duplicated. It can close again only after a newer verification run in which its case passed.
Sources
Only you and the owner see your answer and rating. Send private feedback
Enjoyed it? Support fx-blog with a coffee.
Related posts
The QA Board and the Release Gate
"May it ship?" should not be answered in a chat. The stlc board on orders checkout, and a QA release gate: a report verdict derived from its gate rows, rejected by lint if it disagrees, which the dev deploy step reads before checkout ships.
Your First stlc Run: Checkout From Docs to Scripts
You cannot tell whether AI-written tests cover the spec. The first stlc run on orders checkout: requirement ids, a traceability table created with zero rows where each column has one writing step, a case review, and ten scripts.
A QA Pipeline Your AI Agent Can't Fake
Forty green AI-written tests shipped a bug and nobody could say what they proved. Five questions to ask any AI test pipeline, and the route stlc takes from docs to a verdict, where a feature's state is computed from the files each step wrote.
Comments
Oldest firstNo comments yet. Start the conversation.
Part 2 ended with ten scripts for orders checkout. The first uat run came back red:
TC-INT-ORDERS-001expected atax_totalof 4.20 and got null. At 2 a.m. the agent has three cheap options: loosen the assertion sonullpasses, add a retry, or skip the test. Any of them turns the run green and hides what is wrong.This series, in four parts:
A red test gets a label, not a fix
/qa-runnever edits a test or the product. It writes each failure tofailures.mdwith the evidence and exactly one label:FUNCTIONALSCRIPTSETUP/ENVFLAKYCheckout's failure was
SETUP/ENV: the uat seed predates the tax migration. The product was fine, and loosening the assertion would have buried that. The other red test,TC-E2E-ORDERS-001, isFUNCTIONAL. The new order never appears in the list, so it goes to/qa-defectasDEF-orders-001.FLAKYneeds a re-run someone saw pass. I hold that line even for CI: a retry there is recorded asretried-in-ci, neverFLAKY, because nobody ran the one immediate, unchanged re-run the label means.The heal guard: what a fix may not do
For a
SCRIPTfailure,/qa-healrepairs the test, andnpm run qa:heal-guardchecks the diff against the base./qa-healand/qa-flakyare not done until it exits 0. You can run it yourself on any diff.skip,only,retries:,toPass()) changes are blocked, always;--human "<quote>".So changing
4.20tonull, the move an agent reaches for first, is blocked, and the verdict lands inreports/heal-guard/either way. The guard's own tests try 20 ways to fake a green heal, and each one must be blocked.Flaky tests are quarantined in the open
TC-E2E-ORDERS-002, the order list filter, fails on CI when the filter chips render late. A re-run passes, so the case is quarantined in the ledger (shortened here: the real one also hasEvidenceandReleasedcolumns):The grant lasts at most 30 days, lint fails once it expires unreleased, and the case still runs and reports its true status. Checkout's second quarantine,
TC-API-ORDERS-002, ran out on 2026-10-10 without a release. Lint flags it.A defect closes on evidence
The rounding bug from part 1 has a file now:
/qa-escapeopenedDEF-orders-002withOrigin: ESCAPED. Its escape analysis names the phase that missed it and the type that should have caught it (in this example,DESIGNand unit)./qa-defect orders --verifylooks for a run newer than every recurrence in which that case passed.Resolution: fixed (verified <run-id>).Nobody gets to call it fixed on their word. A repeat failure re-opens the same file.
Try it
Checkout now has two red tests with known causes, two quarantines (one expired) and two open defects, all in files and none easy to see at a glance. May checkout ship? Part 4, The QA Board and the Release Gate, opens the board on this exact state.
Read this with your AI