Two Ways to Direct Coding Agents

Boon aka Hwee-Boon Yar April 11, 2026
Source

I work with coding agents in two modes. For larger features, I write a detailed spec before any code. For smaller tasks, I skip the spec and set guardrails instead. Both work — they solve different problems.

FULL SPEC

For new features or anything with non-obvious architectural decisions, I write everything out first — data flow, DB schema, API shape, edge cases. I have a spec skill that interviews me about all of this before any code gets written. What comes out is a document like:

Data Model

  • users table with email, hashed_password, created_at
  • sessions table with user_id, token, expires_at
  • No soft deletes — hard delete on account removal

API

  • POST /auth/register — validate, hash, insert, return session token
  • POST /auth/login — verify, create session, return token
  • Auth middleware checks session token on protected routes

Edge Cases

  • Duplicate email returns 409, not a generic error
  • Expired sessions return 401, frontend sends user to login

The agent follows this. It doesn't get to suggest alternatives or rethink things during execution. This eliminates drift — there's no room to wander.

GUARDRAILS INSTEAD OF A SPEC

For smaller tasks — bug fixes, refactors, wiring up something that follows an existing pattern — I skip the full spec. I describe the problem and add constraints. A real prompt looks like:

The /auth/login endpoint returns 500 when the email doesn't exist. It should return 401 with { error: "invalid_credentials" }.

Constraints:

  • Do not modify the database schema
  • Do not change more than 20 lines
  • Keep changes in src/routes/auth.ts
  • Run the existing auth tests after fixing

The constraints keep the agent from over-engineering it. "Do not modify the database schema" prevents the agent from deciding it needs a login_attempts table. "Keep changes in src/routes/auth.ts" stops it from refactoring the error handling across three files.

I couple these with validation — linting, type checks, tests — to catch anything that goes outside the boundaries.

WHEN I USE WHICH

New system, multiple services, design decisions that affect the whole project? Full spec. A bug in a well-understood module, or a refactor that follows an existing pattern? Guardrails and go.

The gray area is medium-sized tasks — adding a feature to an existing system where the pattern is clear but there are a few decisions to make. I usually start with guardrails and tighten them if the agent drifts. If I find myself adding more than four or five constraints, that's a sign I should write a spec instead.

Discussion in the ATmosphere

Loading comments...