---
title: "Test the Stopping Rules"
description: "Strengthen the classification contract, test all four deterministic routes, and verify that unclear work stops before any repository specialist receives the request."
canonical_url: "https://vercel.com/academy/creating-a-software-factory/test-the-stopping-rules"
md_url: "https://vercel.com/academy/creating-a-software-factory/test-the-stopping-rules.md"
docset_id: "vercel-academy"
doc_version: "1.0"
last_updated: "2026-08-29T01:48:00.587Z"
content_type: "lesson"
course: "creating-a-software-factory"
course_title: "Creating a Software Factory"
prerequisites:  []
---

<agent-instructions>
Vercel Academy — structured learning, not reference docs.
Lessons are sequenced.
Adapt commands to the human's actual environment (OS, package manager, shell, editor) — detect from project context or ask, don't assume.
The lesson shows one path; if the human's project diverges, adapt concepts to their setup.
Preserve the learning goal over literal steps.
Quizzes are pedagogical — engage, don't spoil.
Quiz answers are included for your reference.
</agent-instructions>

# Test the Stopping Rules

# Test the stopping rules

Open the routing suite and ask a less glamorous question: which requests are guaranteed to go nowhere? Shipping has a demo. Stopping needs tests.

```ts
expect(routeClassification(unclear)).toMatchObject({ lane: "manual" });
expect(routeClassification(publicApi)).toMatchObject({
  lane: "public-api",
  approvalRequired: true,
});
```

## Make Stopping a Tested Behavior

Protect clarification, short-lane, investigation, and approval decisions with deterministic tests.

## Hands-on Exercise 2.3

Start with a relationship the basic schema cannot express. An unclear classification needs at least one useful question, while actionable work must not carry clarification questions.

Extend `classificationSchema` with `superRefine`:

```ts title="agent/lib/classification.ts"
.superRefine((classification, ctx) => {
  if (!classification.actionable && classification.questions.length === 0) {
    ctx.addIssue({
      code: "custom",
      message: "Unclear work must include at least one focused question.",
      path: ["questions"],
    });
  }

  if (classification.actionable && classification.questions.length > 0) {
    ctx.addIssue({
      code: "custom",
      message: "Actionable work cannot include clarification questions.",
      path: ["questions"],
    });
  }
});
```

Add both failures to `agent/lib/classification.test.ts`. We want malformed decisions to fail before policy receives them.

Now create `agent/lib/routing.test.ts`. Give each case a reason to exist:

```ts title="agent/lib/routing.test.ts"
it("asks what the webhook docs get wrong", () => {
  expect(routeClassification({
    actionable: false,
    confidence: 0.4,
    questions: ["Which retry behavior should the README describe?"],
    rationale: "The requested documentation outcome is missing.",
    risk: "low",
    type: "documentation",
  })).toMatchObject({ approvalRequired: true, lane: "manual" });
});
```

Add cases for a low-risk documentation correction, the uppercase-channel bug, and exported delivery priority. The false empty-message report still belongs in the bug lane here because the repository evidence has not been checked yet.

That distinction matters. Routing decides whether the selected lane requires investigation. Investigation determines whether repository evidence supports the claim.

Update `agent/instructions.md` so a manual route returns focused questions and stops before any subagent is called.

## Try It

Run the full deterministic suite:

```bash
pnpm test
pnpm typecheck
```

The routing file should report four passing cases:

```text
✓ agent/lib/routing.test.ts (4 tests)
```

Then read each test name without looking at its input. The names should tell a reviewer which authority boundary broke.

\*\*Note: Break the public API gate\*\*

Change the public API route to `approvalRequired: false`. One targeted test should fail. If several unrelated tests fail, the suite is describing implementation details instead of policy.

\*\*Warning: The false report stops at routing\*\*

A plausible bug should reach investigation. The factory cannot reject a repository claim before inspecting the repository.

\*\*Warning: Unclear work has no question\*\*

Return a focused question in `questions`. A manual lane without a useful response turns safety into a dead end.

## Commit

```bash
git add agent/lib agent/instructions.md
git commit -m "test(factory): protect stopping rules"
```

## Done-When

- [ ] Unclear classifications contain a focused question
- [ ] Actionable classifications contain no questions
- [ ] Low-risk documentation can use the short lane
- [ ] Plausible bugs reach investigation
- [ ] Public API changes require approval

The route tests define which requests may continue. The repository gets the next vote.

## Solution

The completed route suite has the four cases listed in **Done-When**. Compare `agent/lib/classification.test.ts` and `agent/lib/routing.test.ts` with the `solution` branch if a boundary does not fail independently.


---

[Full course index](/academy/llms.txt) · [Sitemap](/academy/sitemap.md)
