Skip to content

Part 02 / Shipping Workflows

How to Write Spec Files for AI Coding: Template and Worked Example

Keep requirements beside your code, reuse a Markdown template, and verify changes against a concrete component spec.

On this page

A spec file is a Markdown document that records what a feature should do, its boundaries, and how you will verify it. Keep it beside the implementation, explicitly include it in your AI coding task, and update it with the code. That gives future sessions a durable starting point.

Download the AI coding spec template, fill in the sections below, then use the prompt at the end of this guide. No account required.

When a spec file helps

Use one when a component has meaningful rules, a feature will span several sessions, or another developer needs to understand why a decision was made. A small typo fix rarely needs its own spec.

A file does not enforce itself. An agent can overlook instructions, and a spec can become stale. Explicitly reference the file and turn its acceptance criteria into tests and review checks.

The Spec to PR workflow covers the full delivery loop. This guide focuses on keeping requirements useful between sessions.

Start with the template

# Spec: [feature or component]
 
## Overview
What should this do, and for whom?
 
## Inputs
List props, user actions, and data dependencies.
 
## Outputs
Describe rendered UI, return values, or side effects.
 
## Behaviour / Logic
Describe the rules in terms a reviewer can verify.
 
## Constraints
Record compatibility, accessibility, performance, and project conventions.
 
## Edge Cases
List empty, invalid, loading, and failure states that apply.
 
## Acceptance Criteria
- Given [starting condition], when [action], then [observable result].
 
## Not in scope
Explicitly exclude adjacent changes.
 
## Verification
Commands and manual checks that demonstrate the behaviour.

Describe observable behaviour. “Support empty results” is less useful than “When the result list is empty, show an explanation and a clear-filter action.” Name the constraints that would otherwise tempt an agent to expand the task.

Worked example: this site's header

This is the specification for the header in this repository at the time of this update. It describes the current navigation, including its limitations. It is a component example, not a claim that this exact header suits every project.

# Spec: Header
 
**File:** `src/components/layout/Header.tsx`
 
## Overview
A fixed navigation bar for AI Field Notes, shared across every page.
 
## Inputs
No props. Navigation labels and destinations are defined in the component.
 
## Outputs
- Home link labelled AI Field Notes, pointing to `/`.
- Main navigation: Guides (`/guides`), Tools (`/tools`),
  Updates (`/chapters/what-is-happening`), Search (`/search`).
 
## Behaviour / Logic
Links use Next.js Link. The header is fixed at the top with a 3.5rem height.
Navigation links wrap within the available width on narrow screens.
No active-route indicator or route-dependent state is implemented.
 
## Constraints
Use existing typography, colour, and border tokens. Render as a Server Component.
The root layout offsets the main content by the header height.
Every link must remain reachable by keyboard and have a visible label.
 
## Edge Cases
Verify the navigation at 320px width and with long page titles below it.
Long titles must not change the header width or cover its links.
 
## Acceptance Criteria
- Home navigates to `/`.
- Each labelled navigation link resolves to its stated destination.
- All links remain visible without horizontal page overflow at 320px.
 
## Not in scope
A mobile menu, active-route highlighting, authentication, or theme controls.
 
## Verification
Open the homepage and a chapter at desktop and mobile widths.
Tab through the navigation and follow all four destinations.

Notice what it makes explicit: the link destinations, fixed positioning, and absence of route-dependent state. These details prevent a routine navigation edit from turning into an unrequested menu or theme redesign.

Change the spec before changing the behaviour

Suppose you want to add a Resources link later. First decide its destination and record it in the outputs and acceptance criteria. Then ask:

Read Header.spec.md and Header.tsx. The spec now includes a Resources link.
Explain the smallest implementation change and how you will verify it.
Implement that change using the existing styles.
Do not add an active-route indicator or mobile menu.
Check all links at desktop and 320px widths, and report what you verified.

This is an illustrative future change; the current header does not include a Resources link. If the extra item no longer fits, revise the layout requirement with that evidence instead of silently clipping navigation.

Two ways to work

Spec first: when the requirement is clear, update the document, request a plan, implement, and verify against the acceptance criteria.

Explore first: when the requirement is unclear, discuss the tradeoffs in chat. Once you decide, record the agreed behaviour in the spec before implementation. Do not preserve every abandoned idea as a requirement.

Keep the document close to the code

src/components/layout/
  Header.tsx
  Header.spec.md

Use the same naming approach for a route or utility with non-obvious behaviour. Follow your repository's test-file conventions: this Markdown file documents requirements; executable tests still belong in the test suite.

For recurring project-wide rules, use agent instructions and skills instead of copying the same conventions into every feature spec.

Review code and spec together

Before merging, check that every acceptance criterion has a test or a recorded manual check. Compare the written inputs and outputs with the actual code. Remove claims about behaviour that no longer exists.

Do not ask an agent to rewrite the spec simply to match any code it produced: compare both with the approved requirement first. A disagreement can indicate an implementation bug.

A useful closing prompt:

Compare the diff with the spec's acceptance criteria.
List any mismatch, untested edge case, or change outside the stated scope.
Fix implementation errors. Update the spec only for agreed behaviour changes.
Report the verification commands and their outcomes.

Next, take the spec through a complete PR workflow, or copy a workflow recipe.