# Capstone: Your Verification Pack

Course: [Testing & Verification](https://www.devtutorials.ai/learn/testing-verification) · Section: Verification as a System
Source: https://www.devtutorials.ai/learn/testing-verification/verification-system/capstone

> Use every gate at once. Run your guard, fail-first, mutation, secret and escaping checks on ten seeded AI changes, accept or reject each with cited evidence, verify a new function to an 80% mutation score, and build a verification pack from your own project's answers.

## Your Turn to Be the Gate

This is the last lesson of the TypeScript course. You will use everything at once.

An agent made ten changes to the shop app. Every change says "done". Some are, some are not.

Your job:

1. Run the gates you built on the risky changes.
2. Accept or reject all ten, and cite the evidence for each rejection.
3. Verify one new change yourself, to a mutation score of 80%.
4. Build the verification pack for **your own** project, and check it.

**Simple lesson:** a verification pack is only useful if you can use it on real changes. This lesson proves you can.

### A Real-World Example

Think about a quality inspector at a factory gate.

- Ten boxes arrive. Each has a label: "Checked ✓".
- The inspector does not trust the label. They open each box.
- They use the same tools every time: a scale, a ruler, a checklist.
- Some boxes pass. Some go back, with a note that says exactly what was wrong.

You are the inspector. Your gates are the tools. The note is your cited evidence.

## What You Will Learn

In this lesson, you will:

1. Run six of your gates on real AI changes.
2. Accept or reject ten AI changes using evidence, not summaries.
3. Name the gate that catches each rejected change.
4. Verify a new function to a mutation score of 80%.
5. Answer seven questions about your project, and export a pack built from your answers.

## Run the Gates

Each lab runs one gate from an earlier lesson on one of the ten changes.

### Change 1: the Guard

Press **▶ Run tests**.

- **Red:** the guard finds `it.skip` in the diff.
- **The decision:** reject. Cite "test-diff guard: added .skip".

### Change 3: Fail First and Mutation

Press **↺ Run on old code**, then **▶ Run tests**, then **🧬 Run mutation**.

- **Old code:** red. The test can see the change.
- **New code:** green.
- **Mutants:** read the score. One test is a good start. Add an edge test at ₹2000 (exactly where the cap starts) to kill more.

### Change 3: Is It Done?

Press **▶ Run tests**. Green.

- **The definition of done** from **Verification Gates for Agents** finds no missing evidence.
- **The decision:** accept.

### Change 7: Coverage vs Mutation

Press **🧬 Run mutation**.

- **Every line runs**, so coverage looks perfect.
- **The mutation score is low.** `toBeGreaterThan(0)` accepts almost any answer.
- **The decision:** reject. Cite "mutation score below the threshold".

### Change 6: Secrets

Press **▶ Run tests**.

- **Red:** a secret value is typed into `config.ts`.
- **Look closely:** `keyId` reads from `process.env`. That line is safe. The `secret` line is not.

### Change 10: User Text in HTML

Press **▶ Run tests**.

- **Red:** the review text goes into the HTML as it is.
- **The decision:** reject. Cite "escaping test fails with a script tag".

**Cite the evidence, not a feeling.**

- Weak: "This looks risky."
- Strong: "Rejected: the secret scanner found a value on line 3 of config.ts."

A clear note lets the agent, or a teammate, fix exactly that.

**Simple lesson:** run the gate, read the result, write it down.

## Decide on All Ten

Here are all ten changes, with the evidence each agent showed.

<figure className="ver-fig">
<svg viewBox="0 0 640 170" role="img" aria-labelledby="ver-fig-ten" style={{ width: "100%", maxWidth: 640, height: "auto" }}>
  <title id="ver-fig-ten">Animation: ten boxes labelled done pass through a row of gates. Three come out green and accepted. Seven are stopped in red, each by a different gate.</title>
  <g style={{ fontFamily: "var(--sans)", fontSize: 11, fontWeight: 700 }}>
    <g>
      <rect x="20" y="20" width="44" height="26" rx="5" style={{ fill: "var(--ver-amber-soft)", stroke: "var(--ver-amber)" }} /><text x="42" y="37" textAnchor="middle" style={{ fill: "var(--ink)" }}>1</text>
      <rect x="20" y="52" width="44" height="26" rx="5" style={{ fill: "var(--ver-amber-soft)", stroke: "var(--ver-amber)" }} /><text x="42" y="69" textAnchor="middle" style={{ fill: "var(--ink)" }}>2</text>
      <rect x="20" y="84" width="44" height="26" rx="5" style={{ fill: "var(--ver-amber-soft)", stroke: "var(--ver-amber)" }} /><text x="42" y="101" textAnchor="middle" style={{ fill: "var(--ink)" }}>…</text>
      <rect x="20" y="116" width="44" height="26" rx="5" style={{ fill: "var(--ver-amber-soft)", stroke: "var(--ver-amber)" }} /><text x="42" y="133" textAnchor="middle" style={{ fill: "var(--ink)" }}>10</text>
    </g>
    <text x="42" y="160" textAnchor="middle" style={{ fill: "var(--muted)" }}>"done ✅"</text>
    <rect x="150" y="15" width="300" height="130" rx="12" style={{ fill: "var(--ver-slate-soft)", stroke: "var(--ver-slate)" }} />
    <text x="300" y="38" textAnchor="middle" style={{ fill: "var(--ink)", fontSize: 13 }}>Your gates</text>
    <text x="300" y="62" textAnchor="middle" style={{ fill: "var(--ink)", fontWeight: 400 }}>guard · fail first · mutation</text>
    <text x="300" y="82" textAnchor="middle" style={{ fill: "var(--ink)", fontWeight: 400 }}>contract · flow · characterization</text>
    <text x="300" y="102" textAnchor="middle" style={{ fill: "var(--ink)", fontWeight: 400 }}>secrets · packages · escaping</text>
    <circle r="7" cy="80" style={{ fill: "var(--accent)" }}><animate attributeName="cx" values="64;150;450" dur="3s" repeatCount="indefinite" /></circle>
    <rect x="490" y="30" width="130" height="40" rx="8" style={{ fill: "var(--ver-green-soft)", stroke: "var(--ver-green)" }} />
    <text x="555" y="55" textAnchor="middle" style={{ fill: "var(--ver-green)" }}>3 accepted</text>
    <rect x="490" y="90" width="130" height="40" rx="8" style={{ fill: "var(--ver-red-soft)", stroke: "var(--ver-red)" }} />
    <text x="555" y="115" textAnchor="middle" style={{ fill: "var(--ver-red)" }}>7 rejected, with reasons</text>
  </g>
</svg>
<figcaption>Every change goes through the same gates. Only the evidence decides.</figcaption>
</figure>

In the first exercise, you decide on all ten. To pass, you need 9 of 10 right, and you must not reject a good change.

**Rejecting everything is not safe.** A reviewer who rejects every change blocks good work and gets ignored. Three of these changes have strong evidence. Accept them.

**Simple lesson:** accept with evidence, reject with evidence.

## Build Your Own Pack

Now make the pack for **your** project. Each answer changes the files:

- **New or existing project:** an existing project gets the characterization rule for AI refactors.
- **Test runner:** the CI file and the Stryker config use your runner.
- **CI:** GitHub Actions or Azure Pipelines.
- **Mocking policy:** "mock the edges" or the stricter rule.
- **Critical paths:** these get a flow test rule and a higher mutation score.
- **Threshold and tools:** as in **User-Flow Checks**.

Press **✓ Check the pack** before you download.

- **It checks that every JSON file parses,** and that each pack has the policy, the review skill, the hooks and a CI file.
- **Then download,** unzip it in your repo, and read every file before you commit it.

**Try it on a real change first.** Install the pack on a branch. Ask your agent for a small change, then add `.skip` to a test yourself. The guard hook should block it. Hook formats change, so check them against your tool's docs.

**Simple lesson:** your pack is the course, turned into files your agent follows every day.

## What You Have Built

Across this course, you climbed the whole evidence ladder:

| Rung | Evidence | Lesson |
|---|---|---|
| 1–2 | Claims, diffs, type checks | **Done Is a Claim**, **Reading an AI Diff**, **Reviewing AI Code** |
| 3–4 | Tests that pass, and fail first | **Spec First: Tests Before Code** |
| 5 | Mutants killed | **Auditing AI-Written Tests** |
| 6 | Properties on random inputs | **Property-Based Testing** |
| 7 | Contracts and user flows | **Integration and Contract Tests**, **User-Flow Checks** |
| 8 | Gates, pins and security checks around review | **Verification Gates for Agents**, **Characterization Tests**, **Security and Dependency Checks** |

**Simple lesson:** "done" is a claim. You now know how to prove it, or catch it.

## TL;DR

1. **Run the gates** on each change: guard, fail first, mutation, contract, flow, secrets, packages, escaping.
2. **Accept or reject with evidence.** Cite the gate and the result.
3. **Do not reject everything.** Good changes with strong evidence should pass.
4. **Verify new code** to a mutation score you set.
5. **Build your pack** from your project's answers, check it, and try it on a real change.

## Common mistakes

| Mistake | Wrong idea | Correct idea | What goes wrong |
|---|---|---|---|
| Trusting the summary | "It says payments work." | Run the gates on the diff. | A live key ships in config.ts. |
| Rejecting everything | "Safer to block it all." | Accept changes with strong evidence. | Good work is blocked, and the reviewer is ignored. |
| Vague reasons | "Looks risky." | Name the gate and the result. | Nobody knows what to fix. |
| Downloading without checking | "The pack is fine." | Check it, read it, try it on a branch. | A broken hook blocks every edit. |
| One pack for every project | "Copy the course pack as it is." | Answer the questions for your project. | The wrong test runner or CI file. |

## Check Your Understanding

## Exercises

## What to Remember

- Every change goes through the same gates. Only the evidence decides.
- Accept with evidence. Reject with evidence. Cite the gate.
- Do not reject good changes just to be safe.
- Build the pack from your project's answers, check it, and try it on a branch.
- "Done" is a claim. You now know how to prove it, or catch it.

## Further Reading

- [Stryker Mutator](https://stryker-mutator.io/): mutation testing for your real project.
- [fast-check](https://fast-check.dev/): property tests for your real project.
- [Claude Code hooks](https://docs.claude.com/en/docs/claude-code/hooks): check the hook format before you install the pack.
- The **Harness Engineering** and **Loop Engineering** courses on this site build on these gates.

Next: **Testing in .NET with xUnit**. The same ideas for C# and ASP.NET Core teams.
