Blog

A spec is done when someone else can say what's out of scope

26 Oct 2026 ยท Gander

A spec is done when someone else can say what's out of scope

Here's a hypothetical, made up to show the moment. A lead writes a short spec for an agent: add email receipts when an order ships. The goals are clear. Send a receipt. Include the order number and the items. Use the existing mailer. Nothing in the list looks wrong. They hand it to the agent and move on.

Two hours later, the diff includes a new preferences table so customers can opt out of receipts, a migration, and a settings page for it. Nobody asked for any of that. The agent filled a gap that looked like unfinished work. Receipts without an opt-out felt incomplete, so it completed them. The lead never meant to touch preferences. The goals never said not to.

This is an opinion piece about writing specs that agents will execute, and here's my claim. I think a spec is done when a second person can name what the agent will not do. A list of goals is not enough. If only the author can say what is out of scope, the agent still has room to invent work, and the next reader has no cheap place to say no.

Why goals alone aren't enough

A goals-only spec looks finished. It names the thing you want. It often names a few constraints: use the existing mailer, stay in the orders service, don't change the checkout flow. Those help. They still leave a wide field of "helpful" work an agent can invent.

I think the problem is that agents are good at filling gaps. A person reading the same goals might leave the opt-out for a later ticket, or ask before adding a table. An agent tends to treat a plausible missing piece as part of the job. If the spec doesn't say the preferences system is off limits, building a small one can look like diligence rather than scope creep.

There's a second failure mode, quieter than the first. "Done" means different things to the author and the reviewer. The author meant "receipts go out when orders ship." The reviewer opens the PR and sees a preferences feature. Both can point at the same goals document and feel justified. The author says the goals are met. The reviewer says the change is bigger than what was asked. Without non-goals on the page, there's no shared place to settle that. The argument moves into the diff, where changing direction already costs more.

We've been writing more specs for agent runs than we used to, and the ones that hold up are the ones that say what not to touch. The ones that blow up almost always looked complete when they were only a list of goals.

The second-person test

Here's the test I use before I let an agent start.

Hand the spec to someone who wasn't in your head when you wrote it. A teammate. Another lead. Anyone who will later have to live with the result. Ask them one question: what will this agent not do?

If they can answer without pinging you, the spec is ready. "It won't add a preferences system. It won't touch billing. It won't migrate old orders." Those answers mean the out-of-scope edges are on the page, not only in your memory.

If they can't answer, or they invent a different set of non-goals than you had in mind, the spec isn't done. Write the non-goals down. Then hand it back and ask again. I think this is cheaper than any review that happens after code exists, because the only thing you're editing is a short list of sentences.

The point of the second person isn't ceremony. It's to catch the gap between what you meant and what the page actually says. You already know what's out of scope. The agent and the next reader don't. The test is whether the page carries that knowledge without you in the room.

What to write down

Non-goals don't need to be long. They need to be specific enough that a wrong turn is obvious.

Systems left alone. Name the services, tables, or areas the agent must not open. "Do not touch the preferences service." "Do not add tables." "Do not change the checkout API." If the agent would need a new dependency to finish a "helpful" side quest, say the dependency is out of bounds too.

Data you will not migrate. Backfills and historical fixes are where scope quietly doubles. "Receipts start from the deploy forward. No backfill of past orders." One line. It stops a whole class of invented work.

Decisions deferred. Some choices look like they belong in the same change and don't. "Opt-out of receipts is a later ticket. Do not design it here." Naming the deferral keeps the agent from solving a problem you haven't agreed to solve.

I think three to six short non-goals beat a long essay about philosophy. You're not writing a vision doc. You're drawing a fence the agent can see, and a fence a second person can check in a minute.

A made-up example of a finished short list, for the receipts case:

  • Send a receipt when an order ships, with order number and line items, through the existing mailer.
  • Do not add an opt-out, a preferences table, or a settings page.
  • Do not backfill receipts for orders that already shipped.
  • Do not change the checkout or payment paths.

The goals are still there. The non-goals are what make the goals safe to hand to something that fills gaps for a living.

Where this sits next to a brief

A brief can still have checklists: who owns it, what done looks like, which files may change. Those matter. This post is about one test that often gets skipped even when the rest of the brief is tidy.

You can have a clean brief and still leave out-of-scope unstated. The agent meets every goal and also builds the thing nobody named. The second-person test is specifically for that hole. If a teammate can't say what is out of scope, I wouldn't call the spec done, no matter how polished the goals look.

The cheap place to say no

Here's the reframe I'd leave you with. We often treat "is the spec done?" as a question about whether the goals are clear enough for the agent to start. Clear goals help. They aren't the finish line.

I think the finish line is whether someone else can say no cheaply. A non-goal on the page is a no you wrote in advance. A second person reading those non-goals is a check that the nos are real, not just private. Once the agent is deep into a preferences migration, saying no costs a revert and an apology. Before the run, saying no costs a sentence.

Write the non-goals. Hand the page to someone else. If they can name what the agent will not do, you're done. If they can't, you aren't, and the cheapest fix is still on the page.

Written by the team building Gander, live review for markdown an agent is still writing.