Verify in fresh context
A review performed by the Builder would reuse the same context and assumptions that produced the patch. The Verifier instead checks the real branch in a separate sandbox.
specification + pushed diff + command evidence → independent verdictThe Verifier may use Builder evidence to choose where to look. It reruns the checks and judges each acceptance criterion itself.
Give the Branch a Fresh Reviewer
Create a read-only Verifier that approves, rejects, or requests changes from a fresh sandbox.
Hands-on Exercise 4.3
Create agent/subagents/verifier/sandbox.ts with the repository sandbox helpers. Then create agent/subagents/verifier/tools/checkout_branch.ts from the Builder's checkout tool. Its description should say that the real diff will be verified.
Create agent/subagents/verifier/agent.ts. Give it a structured verdict:
verdict: {
enum: ["approve", "request-changes", "reject"],
type: "string",
},
criteria: {
items: {
additionalProperties: false,
properties: {
criterion: { type: "string" },
evidence: { type: "string" },
passed: { type: "boolean" },
},
required: ["criterion", "passed", "evidence"],
type: "object",
},
type: "array",
},
blockingFindings: { items: { type: "string" }, type: "array" },Add a riskAssessment for compatibility, performance, security, and side effects. Add exact verification commands plus a final summary. Require every field.
Each risk property uses the same explicit scale:
riskAssessment: {
additionalProperties: false,
properties: {
compatibility: { enum: ["none", "low", "medium", "high"], type: "string" },
performance: { enum: ["none", "low", "medium", "high"], type: "string" },
security: { enum: ["none", "low", "medium", "high"], type: "string" },
sideEffects: { enum: ["none", "low", "medium", "high"], type: "string" },
},
required: ["compatibility", "performance", "security", "sideEffects"],
type: "object",
},
verification: {
items: {
additionalProperties: false,
properties: {
command: { type: "string" },
result: { type: "string" },
},
required: ["command", "result"],
type: "object",
},
type: "array",
},
summary: { type: "string" },Create agent/subagents/verifier/instructions.md:
# Verifier
You are an independent quality gate. You receive the source issue, approved specification, acceptance criteria, branch name, and Builder evidence. You do not receive the Builder's private reasoning.
Call `checkout_branch`, inspect the real diff against the base branch, and run the cheapest relevant checks again. Judge every acceptance criterion individually with evidence from the diff or command output.
Use `request-changes` for specific fixable problems and `reject` when the approved approach itself is invalid. Never modify files.Add the Verifier handoff to root instructions. If it requests changes, send its blocking findings back to the Builder on the same branch. Allow two revision cycles before handing the work to a person.
Try It
Run discovery:
pnpm typecheck
pnpm exec eve infoThe factory should report three subagents. Run the uppercase-channel case:
pnpm exec eve invoke "$(cat fixtures/issues/bug-example.md)"Inspect the verification result. Every acceptance criterion must have its own passed value and evidence.
Change the candidate test so it does not cover uppercase input, then verify again. The Verifier should request changes even if the Builder's original command exited zero.
Commit
git add agent/subagents/verifier agent/instructions.md
git commit -m "feat(factory): verify in fresh context"Done-When
- eve discovers a separate Verifier
- The Verifier checks out the pushed candidate branch
- Every acceptance criterion receives evidence
- Builder checks are rerun independently
- Revision loops stop after two failed attempts
Independent verification establishes whether the branch satisfies its specification. The final section applies human approval at consequential decision points.
Solution
The exercise contains the complete contract, instructions, and two-cycle revision boundary. Compare agent/subagents/verifier/agent.ts and the root handoff with the solution branch if discovery or structured output fails.
Was this helpful?