AC
Chapter 03The Human in the Loop

Spec writing

The spec is the interface between human intent and agent execution. Tight spec = clean run.

35 minLesson 2 of 5

The most important thing you write when working with an AI coding agent isn't code. It's the spec.

A tight spec produces clean, focused work. Claude reads it, understands the boundaries, and executes within them. A vague spec produces wandering — the agent guesses at your intent, makes assumptions, and builds something that looks right but misses the point.

I've run hundreds of tasks through Claude Code at this point. The pattern is clear: the quality of the output is a direct function of the quality of the input. And the input isn't a prompt. It's a spec.

The three parts of a good spec

Every spec I write has three sections. No more, no less.

What

The end result you want. Describe the outcome, not the implementation steps. Let the agent figure out the how — that's what it's good at.

Constraints

What NOT to touch. What patterns to follow. What to avoid. This is where you prevent the agent from making "creative" decisions you'll have to undo.

Acceptance criteria

How to verify it's done. Concrete, testable conditions. "The build passes." "The test covers edge case X." "The page renders Y." No subjective language.

That's it. What, Constraints, Acceptance criteria. If your spec has these three things and nothing else, it's probably good enough.

Bad spec vs good spec

The difference is night and day. Here's a real example.

Bad spec
Add authentication to the app.

What kind of auth? Where does it go? What provider? What pages need protection? What happens after login? Claude will answer all of these questions by guessing. And its guesses won't match your intent.

Good spec
Add magic link auth via Supabase.

What:
- Users enter email on /auth/login
- They receive a magic link via Supabase Auth
- On click, they're redirected to /admin

Constraints:
- Don't modify existing components
- Use @jd/ui components for the login page
- Use @jd/db/server for the Supabase client
- Follow the existing middleware pattern in middleware.ts

Acceptance criteria:
- /admin/* routes redirect to /auth/login when not authenticated
- After magic link click, user lands on /admin
- Build passes with no type errors
- Login page matches existing design system

The good spec is 15 lines. It took me two minutes to write. It saved me 30 minutes of corrections, undone changes, and frustrated re-prompting.

Strong spec
Weak spec
Add a /api/users endpoint that returns paginated results with cursor-based pagination
Add a users API
Use the existing AuthGuard middleware for protection
Make it secure
Return 404 with { error: 'not_found' } for missing users
Handle errors
Write tests covering the happy path and auth failure
Add tests

Search first, spec second

This is an ECC principle I follow religiously: before writing a spec, research first.

Does a solution already exist in the codebase? Is there an npm package that handles this? An MCP server? A Claude Code skill? The best spec starts with understanding what you already have.

I've watched developers spec entire features from scratch, only to discover that 80% of the work was already done in a utils file they didn't know about. Or that there's a Supabase feature that handles the exact use case. Or that a teammate already built the component three months ago.

Research before speccing
> "Search the codebase for any existing auth-related code.
   Check middleware.ts, any auth/ directories, and the
   Supabase client setup. Don't change anything — just
   report what exists."

[Claude reports: middleware.ts has route protection logic,
 @jd/db/server has createClient(), no login page exists yet]

> "Good. Now here's the spec..."

The research took 30 seconds. The spec was better for it. Claude didn't have to reinvent patterns that already existed — it could follow them.

A search-first skill can formalize this with a decision matrix. After research, you choose one of four paths:

  • Adopt — an existing library or package handles it. Install and configure.
  • Extend — existing code handles 60%+. Build on top of what is there.
  • Compose — combine 2-3 existing pieces into the solution. Glue code only.
  • Build — nothing exists. Spec from scratch.

Most tasks land on Extend or Compose. Building from scratch is the exception, not the default. The research step ensures you know which path you are on before you write a single line of spec.

Plan before execute

For complex features, don't jump from spec to implementation. Use the planner pattern.

Write the spec. Enter plan mode. Let Claude propose a phased breakdown. Review the breakdown. Refine the spec if needed. Only then approve the implementation.

This is the ECC planner agent pattern: the plan includes risk assessment, dependency mapping, and a worked example of expected output. It's overkill for a 5-minute task, but for anything that touches multiple files or critical systems, it's essential.

Spec to plan to execution
1. You write the spec (2 min)
2. Claude proposes a plan (30 sec)
3. You review and adjust (2 min)
4. Claude implements the approved plan (10 min)
5. You review the output (5 min)

Total: ~20 min for a feature that would take 2 hours manually

The spec is the interface between your intent and the agent's execution. The plan is the checkpoint between the spec and reality. Together, they give you control without typing every line.

Spec evolution

Your first spec is rarely perfect. And that's fine.

Write it. Let Claude plan. Review the plan. If the plan reveals gaps in your spec — things you forgot to constrain, acceptance criteria you missed — update the spec and re-plan. This loop is normal and fast.

I typically go through 1-2 refinement cycles on complex tasks. The first spec captures 80% of what I want. The plan surfaces the remaining 20%. The second spec captures everything.

The spec is a living document for the duration of the task. Once the task ships, the spec doesn't matter anymore. What matters is that it was tight enough to produce clean work while the agent was running.

This is the fundamental skill of agentic coding. Not prompting. Not coding. Speccing. Get this right and everything else follows.