Skip to content
fx-blog

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.

Harry4 min readAdvanced
  • Verification
MarkdownSave

Key takeaways

  • The board shows each feature's ten steps, every state as an icon, a colour and a word, read from files and never written.
  • The platform × type matrix shows what nobody has tested and marks inferred cells.
  • The Agents tab lists the Claude Code chats and subagents that recently worked on the project, with their task and last action, read from Claude Code's own session files.
  • The report's overall verdict is derived from its gate rows, and npm run qa:lint rejects a report that disagrees with them.
  • The dev deploy gate waits for a passing report dated after the shipped commit's G8 run, a GO sign-off, or a named human's written waiver.
Contents

TL;DR Without a QA release gate, "can we ship?" is answered by whoever sounds most sure in a chat. Only here: the report's overall is derived from its gate rows, npm run qa:lint rejects a report that disagrees, and the dev deploy step (G10) reads that file. Orders checkout does not ship until it says pass in a report dated after the shipped commit's G8 run.

Do this: Draft the Quality gates table for your next release: one row per gate, a target, and the file or run that decides it.

Part 3 left orders checkout with two red tests, two quarantined cases (one expired), two open defects, and all of it in files that no one can see at a glance. Ask "may it ship?" in a chat and you get a feeling. Open the board on that exact state instead, then follow the verdict to the deploy gate.

This series, in four parts:

  1. A QA Pipeline Your AI Agent Can't Fake
  2. Your First stlc Run: Checkout From Docs to Scripts
  3. When a Test Goes Red: Triage, the Heal Guard and Quarantine
  4. The QA Board and the Release Gate (you are here)

The board shows where checkout stands

STLC: Open Board puts the feature, a ring of cases passed and ten steps from knowledge to sign-off in one tab.

The top of the stlc board for orders checkout: step 6 of 10, 6 of 12 cases passed, 2 failing, 2 blocked, the Run step red, and tiles for cases, defects, quarantine and pass rate

For checkout it reads 6 of 12 passed, 2 failing, 2 blocked, 2 not run, with 2 open defects and 2 quarantined cases, one expired. Under it sit a platform × type matrix of what nobody has tested, and an Agents tab listing the Claude Code chats and subagents that recently worked on the project, with their task and last action.

The verdict is computed, not written

Run /qa-report orders on this state and the report's front matter is what the deploy step reads. The sample below is what the rules produce for checkout; the fixture holds no orders report yet.

yamlreports/orders/2026-10-15-report.md (sample)
---
slug: orders
date: 2026-10-15
shipped_sha: 3b9d0e1
runs: [2026-10-12-0900, 2026-10-13-1000]
overall: fail
---

The agent does not fill in overall. The Quality gates table has one row per gate with a target, the actual value, a verdict and the evidence. overall is fail if any row fails, not evaluable if any row cannot be judged, and pass only otherwise. npm run qa:lint rejects a report that disagrees with its rows.

For checkout, the Functional row (target: 0 failing P0/P1 cases) fails: TC-E2E-ORDERS-001 (P0) and TC-INT-ORDERS-001 (P1) are red. However confident the summary, the row decides.

What it takes to ship checkout

The dev bundle's deploy gate, G10, stays blocked until one of three things holds:

  1. The latest report says overall: pass and is dated after the shipped commit's G8 run.
  2. A release sign-off that includes the feature says GO.
  3. A named human waives QA, in writing.

Checkout meets none today. The empty-list defect needs a fix and a passing run. The uat seed needs the tax migration. The rounding defect needs its three-line unit case to pass, and then a new report must derive pass. A waiver carries a name, so someone owns that decision.

The loop on orders checkout: the dev release writes qa-handoff.md, stlc writes the report, G10 reads overall, and an escaped bug comes back through /qa-escape as cases

Checkout ships when a report newer than the G8 run says overall: pass, and lint makes sure the rows agree.

Try it

textPaste into your AI
Draft the Quality gates table my next release should pass: one row per gate with a target and the file or run that would decide it. Then tell me which rows I could not fill today, and why.

Read this with your AI

textPaste into your AI
Read the post "The QA Board and the Release Gate".
1. Summarise it in 5 bullets for an engineering manager.
2. Ask me 3 questions to check I understood; wait, then correct me.
3. Describe what would have to be true for orders checkout to ship, using only the files the post names.

FAQ

Where does the Agents tab get its data?

From Claude Code's own session transcripts on your machine, read-only, filtered to the project you have open and to recent activity. It shows each chat and the subagents it spawned.

How does stlc connect to the development pipeline?

The dev bundle writes qa-handoff.md at release and QA starts from it, keeping its requirement ids. QA's report verdict gates the dev deploy step, and escaped production bugs come back through /qa-escape.

Sources

  1. The stlc VS Code board (editor/vscode-stlc)
  2. stlc CONTRACTS.md §16: the report the dev bundle parses

Was this useful?

Only you and the owner see your answer and rating. Send private feedback

Enjoyed it? Support fx-blog with a coffee.

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.

4 min readBeginner

Comments

Oldest first

No comments yet. Start the conversation.

You sign in first; what you typed stays here. · 0 / 2,000