---
title: "Gate by Consequence"
description: "Add a durable eve approval tool and connect deterministic routing policy to the point where public API work must wait before implementation."
canonical_url: "https://vercel.com/academy/creating-a-software-factory/gate-by-consequence"
md_url: "https://vercel.com/academy/creating-a-software-factory/gate-by-consequence.md"
docset_id: "vercel-academy"
doc_version: "1.0"
last_updated: "2026-08-29T01:48:00.770Z"
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>

# Gate by Consequence

# Gate by consequence

A clear public API specification is still a consequential compatibility decision. The Investigator can document the risks and test plan, but a person must approve the specification before implementation.

```text
bug + supported evidence       → Builder
public API + supported evidence → human approval → Builder
```

More evidence can improve the decision, but it does not transfer approval authority.

## Pause Before Consequence

Pause high-consequence specifications for human approval before the Builder begins.

## Hands-on Exercise 5.1

Create `agent/tools/approve_spec.ts`:

```ts title="agent/tools/approve_spec.ts"
import { defineTool } from "eve/tools";
import { always } from "eve/tools/approval";
import { z } from "zod";

export default defineTool({
  approval: always(),
  description:
    "Pause a high-risk work order and ask a person to approve its specification before implementation begins.",
  execute(input) {
    return {
      approved: true,
      criteriaCount: input.acceptanceCriteria.length,
      workOrderId: input.workOrderId,
    };
  },
  inputSchema: z.object({
    acceptanceCriteria: z.array(z.string()).min(1),
    approach: z.string().min(1),
    risks: z.array(z.string()),
    workOrderId: z.string().min(1),
  }),
});
```

`always()` turns the tool call into a durable pause. Its `execute` function runs only after approval, so a resumed session can continue with the same work order and evidence.

Update the public API lane in `agent/instructions.md`:

```md title="agent/instructions.md"
For a public API route, delegate to the Investigator first. If its disposition is `proceed`, call `approve_spec` with the work order id, proposed approach, risks, and acceptance criteria. Do not call the Builder until the approval result returns.
```

The bug lane does not call this tool unless deterministic policy marked the bug high risk. Only routes that cross a configured consequence boundary use the gate.

## Try It

Inspect the manifest:

```bash
pnpm typecheck
pnpm exec eve info
```

The root agent should now expose five tools. Invoke the delivery-priority case:

```bash
pnpm exec eve invoke "$(cat fixtures/issues/public-api-example.md)"
```

The session should park at `approve_spec` after investigation and before any Builder call.

Compare it with the uppercase-channel bug. Supported medium-risk bug work may continue without this pause. Both routes still require independent verification before a draft pull request.

\*\*Note: Deny the specification\*\*

Deny the pending public API request. Resume the session and confirm that no branch is created. A denied approval is a completed decision, not an error to retry around.

\*\*Warning: The Builder starts while approval is pending\*\*

Call `approve_spec` before delegation. The tool result does not exist until a person approves the pending request.

\*\*Warning: Every lane waits for approval\*\*

Use the work order's deterministic route. A universal gate discards the selective part of selective autonomy.

## Commit

```bash
git add agent/tools/approve_spec.ts agent/instructions.md
git commit -m "feat(factory): gate consequential work"
```

## Done-When

- [ ] Public API work reaches investigation before approval
- [ ] Approval displays the supported specification and risks
- [ ] The session parks without losing its work order
- [ ] The Builder receives no work before approval
- [ ] Supported medium-risk bugs keep their shorter route

The approval can survive a redeploy and resume the exact work order. Approved work may now become a draft, never a merge.

## Solution

The exercise contains the complete approval tool. The root procedure calls it only for a route whose policy requires approval, after investigation and before Builder delegation.


---

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