← All posts
·6 min read

PRD Template for AI Coding Agents (Free, Copy-Paste)

A copy-paste PRD template tuned for AI coding agents like Claude Code, Cursor, and Codex — with the failure-states and out-of-scope sections that stop agents from hallucinating.

If you're here, you probably typed prd template for ai coding agents into Google, clicked the first result, found it was a template written for humans in meetings, and bounced. That's the whole problem. The PRD format that works for a stakeholder review does not work for a Claude Code or Cursor session. The sections that matter are different.

This post is the template. It's below. Copy it into a markdown file in your repo as specs/<feature>.md, fill it out, and point your agent at it.

The gap between a human PRD and an agent PRD

A traditional PRD is written for executives, cross-functional partners, and engineers who will use judgment. It leads with business rationale, personas, and success metrics. It's 2-5 pages.

An AI coding agent doesn't care about business rationale. It cares about:

  • What must be built, concretely, with testable criteria
  • What must NOT be built (the single most-skipped section in human PRDs)
  • What can go wrong, and what the code should do when it does
  • What other parts of the system this touches

A human engineer skimming a PRD will infer the rest from context. An agent interprets ambiguity by inventing scope — and it invents it confidently, fast, in commits you then have to unwind.

So: you need a different template.

The template

Copy this whole block into specs/<feature-name>.md:

# [Feature name]

## Goal

One sentence. Outcome-oriented, not feature-oriented.

Good: "Users who refund an order receive confirmation within 30 seconds and the refund appears in the order's timeline."
Bad: "Add a refund endpoint to the API."

## User Stories

As a [persona], I can [action], so that [benefit].

Each story gets 2-4 acceptance criteria that are specific, testable, and binary (pass/fail, not "works well").

- As a logged-in customer, I can request a full refund on a completed order, so that my money is returned to the original payment method.
  - Refund request returns 200 within 5 seconds
  - Order status transitions to "refunding"
  - Email receipt sent to the address on the order
  - Refund appears in the order's audit timeline with actor + timestamp
- [more stories...]

## Acceptance Criteria

System-level criteria that don't belong to a single user story. Testable.

- Refund amount cannot exceed original charge amount
- Partial refunds leave the order in "partially_refunded" state
- Refund events are idempotent — duplicate requests within 60s return the same refund ID

## Edge Cases

Specific scenarios. Each one is a scenario + expected behavior.

- Customer requests refund on an order that's already fully refunded → 409 Conflict with a clear message
- Customer requests refund on an order that was charged in a different currency than the store default → refund in the original currency
- Customer requests refund during a Stripe outage → request is queued, customer sees "refund pending" UI
- Customer requests refund on a gift order (shipped to a different recipient) → refund goes to the purchaser, not the recipient

## Failure States

When things break, what does the code do? Each failure state has trigger, behavior, and recovery.

- Trigger: Stripe API returns 503
  - Behavior: queue the refund request, mark the order "refund_pending"
  - Recovery: background job retries with exponential backoff for 1 hour; after that, surface the error to support

- Trigger: database write succeeds but confirmation email fails
  - Behavior: refund is still valid (DB is the source of truth)
  - Recovery: queue email for retry; do not surface the email failure to the customer

- Trigger: webhook from Stripe is duplicated
  - Behavior: idempotency key on the refund record rejects the duplicate
  - Recovery: log and continue

## Dependencies

- Stripe API v2024-06-20 or newer (partial_refunds support)
- `src/services/stripe.ts` service (already exists)
- `OrderV2` schema from PR #487

## Out of Scope

This is the section that saves you. List things a reader might EXPECT to be in scope but aren't.

- Refund reason capture (no text field for "why")
- Admin-initiated refunds (this spec covers customer-initiated only)
- Refund to a different payment method than the original
- Refund policy enforcement (30-day limit, etc.) — handled in a separate spec

## Verification Criteria

How a reviewer will confirm this ships correctly. Each criterion is a test or inspection.

- Unit tests cover all failure states above (automated)
- Integration test: refund through the full Stripe test-mode flow (automated)
- Manual: verify the refund email renders correctly in the 3 supported locales
- Manual: confirm audit timeline shows the refund with correct actor attribution

That's the template. The sections are ordered by how much they matter to an agent: goal and user stories tell it what to build, acceptance criteria and edge cases tell it when to stop, failure states tell it what error handling to add, out-of-scope tells it what NOT to touch.

How to use it with Claude Code or Cursor

Paste the filled-out template into specs/<feature>.md in your repo. Then, at the start of your session:

Follow the spec at specs/refund-flow.md exactly. Every acceptance criterion must be testable. Every failure state must have matching error handling. Do not extend scope beyond what's listed. If you encounter something the spec doesn't cover, stop and ask.

That single instruction, with a real spec behind it, is the difference between an agent that ships the feature and an agent that invents half of it.

If you use an MCP-compatible editor (Claude Code, Cursor, Windsurf), you can skip the paste entirely by connecting ClearSpec's MCP server — the agent pulls the latest version of the spec directly on every request, so you're never working off a stale copy.

The three sections people skip (don't)

In every spec review I've done, the three sections that are missing or thin are:

  1. Out of scope. Everyone remembers to list what they want; almost nobody lists what they don't. Agents read the absence as permission. If you don't say "do NOT rewrite the payment service," the agent might rewrite the payment service.
  2. Failure states. Engineers have an instinct for error handling; agents don't. The code that comes out of a spec without failure states is the code that throws unhandled exceptions in production at 3 AM.
  3. Verification criteria. Not the same as acceptance criteria. Acceptance criteria describe behavior; verification criteria describe how you'll confirm that behavior. "Unit test covers refund-over-original-amount rejection" is a verification criterion. "Refund cannot exceed original charge" is an acceptance criterion.

If your template is missing any of these, copy the version above, not the shorter one you saw on LinkedIn.

The 60-second version

Writing this by hand takes 20-40 minutes for a medium-sized feature. If you want that time back, ClearSpec generates the whole structure from a one-line description. You type "add returns flow with partial refunds," it asks 2-3 clarifying questions (gift-return routing, refund policy, original-payment-method constraint), and fills the template in about 60 seconds. Connect your GitHub repo and it references your actual file paths — src/services/stripe.ts instead of YourPaymentService.js.

Free tier is 5 specs/month, no credit card. If you've written more than two specs by hand this month, you've already spent more time than ClearSpec costs.

Related posts