Chapter 9: Anatomy of a Perfect Specification
Learning Objectives
By the end of this chapter, you will be able to:
- Identify and apply the ten components of a complete specification
- Write each component with sufficient precision for AI implementation
- Produce a complete specification for a feature from problem statement through security requirements
- Recognize and avoid common specification anti-patterns
- Evaluate specification quality using a structured scoring rubric
- Understand how AI agents use each specification section differently
Why Specification Anatomy Matters
Imagine you're commissioning a custom house. You could tell the builder: "I want a nice house with a kitchen and bedrooms." The result would depend entirely on the builder's interpretation. Or you could provide blueprints: foundation dimensions, room layouts, electrical schematics, material specifications, load-bearing requirements, and finish schedules. The blueprints eliminate interpretation — the builder knows exactly what to construct.
A specification is the blueprint for software. The more complete and precise it is, the less the implementer (human or AI) must guess. In Spec-Driven Development, where AI generates implementation from specifications, the quality of the specification directly determines the quality of the output.
This chapter teaches you the anatomy of a perfect specification — the ten components that, when present and well-written, produce implementations that match intent.
The Ten Components of a Complete Specification
Every complete specification includes these ten components. Some features may have minimal content in certain sections (e.g., a simple feature might have few dependencies), but the structure ensures nothing is forgotten.
| # | Component | Purpose |
|---|---|---|
| 1 | Problem Statement | Why this feature exists; who experiences the pain |
| 2 | User Journeys | Concrete scenarios from the user's perspective |
| 3 | Functional Requirements | What the system must do (capabilities) |
| 4 | Non-Functional Requirements | How well it must do it (quality attributes) |
| 5 | Acceptance Criteria | Testable conditions that define "done" |
| 6 | Edge Cases | Boundary conditions, error paths, unusual inputs |
| 7 | Constraints | What the system must NOT do; hard limits |
| 8 | Dependencies | What this feature requires from other systems |
| 9 | Observability | What to log, measure, and alert on |
| 10 | Security Requirements | Authentication, authorization, data protection |
We'll walk through each component in detail, then assemble a complete example.
Component 1: Problem Statement
The problem statement answers: Why does this feature exist? Who experiences the problem? What is the cost of not solving it?
Why It Matters
AI agents that understand the why produce better solutions than those that only know the what. When an AI understands that a password reset flow exists because users forget passwords and need a secure, low-friction recovery path, it can make better decisions about token expiry, rate limiting, and error messaging than an AI that only knows "implement password reset."
Structure
## Problem
[1-3 sentences describing the problem]
- **Who**: [User role or persona]
- **Pain**: [What they experience]
- **Impact**: [Consequence of not solving]
Example
## Problem
Users who forget their passwords have no self-service recovery path. They must contact support,
which creates support ticket volume and delays account access. Support-assisted resets also
introduce security risk (social engineering) and poor user experience.
- **Who**: Any authenticated user who has forgotten their password
- **Pain**: Cannot log in; must wait for support; no 24/7 recovery option
- **Impact**: Support costs, user churn, security incidents from manual resets
Anti-Pattern: Solution Disguised as Problem
Bad: "We need a password reset feature." (This is a solution, not a problem.)
Good: "Users who forget passwords cannot recover access without support intervention." (This describes the problem.)
Component 2: User Journeys
User journeys are narrative descriptions of how a user accomplishes a goal. They ground the specification in real usage and prevent building features that are technically correct but don't match how users actually work.
Why It Matters
User journeys provide context that acceptance criteria alone cannot. They describe the emotional arc (frustration → relief), the sequence of steps, and the decision points. AI uses this to prioritize UX considerations and handle "soft" requirements like messaging tone.
Structure
## User Journeys
### Journey 1: [Name]
[2-5 sentence narrative of the user's path from start to goal]
### Journey 2: [Name]
[Alternative or error path]
Example
## User Journeys
### Journey 1: Successful Password Reset
Maria tries to log in but realizes she's forgotten her password. She clicks "Forgot password?"
on the login form. She enters her email and receives a reset link within a minute. She clicks
the link (valid for 1 hour), enters a new password twice, and is redirected to the dashboard.
She can now log in with her new password.
### Journey 2: Expired or Invalid Link
David requests a password reset but doesn't check his email for several hours. When he clicks
the link, it has expired. He sees a clear message: "This link has expired. Request a new one."
He can request a new link without leaving the page. No confusing error; no dead end.
### Journey 3: Rate-Limited Request
An attacker (or forgetful user) requests resets repeatedly. After 3 requests in 15 minutes,
the system shows: "Too many requests. Try again in 15 minutes." The user understands the
wait; the attacker is throttled.
Component 3: Functional Requirements
Functional requirements are the capabilities the system must provide. They answer: What can the user or system do?
Why It Matters
Functional requirements are the primary input for AI implementation. They define the feature surface — the APIs, UI elements, and behaviors. Vague requirements ("user can reset password") force guessing. Precise requirements ("user can request reset by email; receives time-limited link; can set new password via link") enable direct implementation.
Structure
## Functional Requirements
### FR-1: [Capability Name]
[Precise description of the capability]
### FR-2: [Capability Name]
...
Example
## Functional Requirements
### FR-1: Request Password Reset
User can request a password reset by submitting their registered email address. System validates
that the email exists in the user table. If it exists, system generates a cryptographically
secure token, stores it with expiry (1 hour), and sends an email containing a link with the
token. If email does not exist, system returns the same generic response (no email enumeration).
### FR-2: Validate Reset Token
User can access the reset link. System validates the token: exists, not expired, not already
used. If valid, system displays the password reset form. If invalid, system displays the
expired/invalid message and offers "Request new link" action.
### FR-3: Set New Password
User can submit a new password (with confirmation) from the reset form. System validates
password strength (min 12 chars, complexity rules). If valid, system updates the password,
invalidates the token, invalidates all existing sessions for that user, and redirects to
login with success message. If invalid, system shows validation errors.
### FR-4: Rate Limiting
System limits password reset requests to 3 per email per 15 minutes. System limits token
validation attempts to 5 per token per IP per 15 minutes. Exceeding limits returns 429
with Retry-After header.
Component 4: Non-Functional Requirements
Non-functional requirements define quality attributes: performance, security, availability, scalability. They answer: How well must the system perform?
Why It Matters
Without NFRs, AI will implement "correct" behavior that may be too slow, insecure, or fragile. NFRs guide architectural decisions (caching, rate limiting, encryption) and provide measurable success criteria.
Structure
## Non-Functional Requirements
### NFR-1: [Attribute] — [Measurable target]
[Description]
### NFR-2: ...
Example
## Non-Functional Requirements
### NFR-1: Latency — Email sent within 30 seconds
Password reset email must be queued and sent within 30 seconds of request. User-facing
confirmation shown immediately; email delivery is async.
### NFR-2: Security — Token entropy
Reset tokens must be at least 256 bits of entropy. Use cryptographically secure random
generation (e.g., `crypto.randomBytes(32)`).
### NFR-3: Availability — No single point of failure
Reset flow must work if email service is temporarily unavailable. Queue the email; retry
with exponential backoff. User sees "Check your email" regardless; no user-facing failure
for transient email issues.
Component 5: Acceptance Criteria
Acceptance criteria are testable conditions that define "done." They are the primary input for test generation and validation.
Why It Matters
Acceptance criteria are the contract between specification and implementation. Each criterion should be verifiable: Given X, When Y, Then Z. AI uses these to generate tests; they also serve as the validation checklist.
Structure
## Acceptance Criteria
- **AC-1**: Given [precondition], When [action], Then [expected result]
- **AC-2**: ...
Example
## Acceptance Criteria
- **AC-1**: Given a valid registered email, When user submits reset request, Then user sees
"Check your email" message and receives email within 60 seconds
- **AC-2**: Given an unregistered email, When user submits reset request, Then user sees
"Check your email" message (no enumeration; same UX as valid email)
- **AC-3**: Given a valid reset token, When user clicks link and submits new password, Then
password is updated and user is redirected to login with success message
- **AC-4**: Given an expired token, When user clicks link, Then user sees "Link expired"
message with option to request new link
- **AC-5**: Given 4 reset requests in 15 minutes for same email, When user submits 4th
request, Then user sees rate limit message and receives 429
- **AC-6**: Given user completes password reset, When user attempts to use old password,
Then login fails; when user uses new password, Then login succeeds
Component 6: Edge Cases
Edge cases are boundary conditions, error paths, and unusual inputs that the system must handle correctly. They are often the source of bugs when omitted.
Why It Matters
AI tends to implement happy paths well. Edge cases are where implementations often fail. Explicitly listing edge cases ensures they are considered during implementation and testing.
Structure
## Edge Cases
| Case | Condition | Expected Behavior |
|------|-----------|-------------------|
| EC-1 | [Condition] | [Behavior] |
| EC-2 | ... | ... |
Example
## Edge Cases
| Case | Condition | Expected Behavior |
|------|-----------|-------------------|
| EC-1 | User submits empty email | Validation error: "Email is required" |
| EC-2 | User submits invalid email format | Validation error: "Enter a valid email" |
| EC-3 | User requests reset for email with special chars | Normalized and processed; no injection |
| EC-4 | Token used twice (double-click, back button) | Second use fails with "already used" |
| EC-5 | User changes password mid-session | All other sessions invalidated; user logged out |
| EC-6 | User submits password that doesn't match confirmation | Validation error: "Passwords must match" |
| EC-7 | User submits weak password | Validation error with strength requirements |
| EC-8 | Token in URL logged or shared | Token single-use; expires after use |
| EC-9 | User has no email (legacy account) | Reset not available; show "Contact support" |
Component 7: Constraints
Constraints define what the system must NOT do; hard limits; inviolable rules.
Why It Matters
Without constraints, AI may add features (e.g., "remember me" on reset page, social login) that weren't requested. Constraints prevent scope creep and enforce architectural boundaries.
Structure
## Constraints
- **C-1**: [Constraint]
- **C-2**: ...
Example
## Constraints
- **C-1**: Must not reveal whether an email is registered (no user enumeration)
- **C-2**: Must not allow password reset without email verification (no phone-based reset)
- **C-3**: Must not allow token reuse (single-use only)
- **C-4**: Must not persist reset tokens beyond 24 hours (cleanup job)
- **C-5**: Must not allow password reset for accounts without verified email
- **C-6**: Must not allow concurrent reset flows for same user (invalidate previous on new request)
Component 8: Dependencies
Dependencies define what this feature requires from other systems, services, or features.
Why It Matters
AI needs to know what exists (email service, user table, auth system) to implement correctly. Dependencies also surface integration risks and ordering requirements.
Structure
## Dependencies
### Internal
- [Dependency name]: [What is required]
### External
- [Service/system]: [What is required]
Example
## Dependencies
### Internal
- **User Service**: Must provide `getUserByEmail(email)` and `updatePassword(userId, hash)`
- **Auth Service**: Must provide `invalidateSession(userId)` for session invalidation
- **Token Store**: Must provide `createToken(userId, type, ttl)` and `consumeToken(tokenId)`
### External
- **Email Service**: Must send transactional emails; template `password-reset` with
`{reset_link, expires_at}`; must support queue/retry
Component 9: Observability
Observability defines what to log, what to measure, and what to alert on.
Why It Matters
AI implementations often omit logging and metrics. Explicit observability requirements ensure production systems are debuggable and monitorable.
Structure
## Observability
### Logs
- [Event]: [What to log]
### Metrics
- [Metric name]: [Description]
### Alerts
- [Condition]: [Action]
Example
## Observability
### Logs
- **Reset requested**: userId (hashed), timestamp, rate limit status
- **Token consumed**: userId, timestamp, success/failure
- **Rate limit exceeded**: email (hashed), IP, timestamp
### Metrics
- `password_reset_requests_total`: Counter of reset requests
- `password_reset_success_total`: Counter of successful resets
- `password_reset_rate_limited_total`: Counter of rate-limited requests
- `password_reset_email_delivery_seconds`: Histogram of email send latency
### Alerts
- **High rate limit rate**: If >50% of requests rate-limited in 5 min, alert
- **Email delivery failure**: If email delivery fails 3 consecutive times, alert
Component 10: Security Requirements
Security requirements define authentication, authorization, data protection, and audit requirements.
Why It Matters
Security is often an afterthought. Explicit security requirements ensure AI implements proper token handling, encryption, and access control.
Structure
## Security Requirements
- **SEC-1**: [Requirement]
- **SEC-2**: ...
Example
## Security Requirements
- **SEC-1**: Reset tokens must be stored hashed (e.g., SHA-256) — never store plaintext
- **SEC-2**: Reset link must use HTTPS only
- **SEC-3**: Reset form must use CSRF token
- **SEC-4**: Password must be hashed with bcrypt (cost factor 12) before storage
- **SEC-5**: No sensitive data in logs (no plaintext tokens, passwords, or emails)
- **SEC-6**: Audit log: password reset completed (userId, timestamp, IP)
Complete Example: Password Reset Specification
Here is the full specification assembled from the components above:
# Feature: Password Reset
## Problem
Users who forget their passwords have no self-service recovery path. They must contact support,
which creates support ticket volume and delays account access. Support-assisted resets also
introduce security risk (social engineering) and poor user experience.
- **Who**: Any authenticated user who has forgotten their password
- **Pain**: Cannot log in; must wait for support; no 24/7 recovery option
- **Impact**: Support costs, user churn, security incidents from manual resets
## User Journeys
### Journey 1: Successful Password Reset
Maria tries to log in but realizes she's forgotten her password. She clicks "Forgot password?"
on the login form. She enters her email and receives a reset link within a minute. She clicks
the link (valid for 1 hour), enters a new password twice, and is redirected to the dashboard.
### Journey 2: Expired or Invalid Link
David requests a reset but doesn't check his email for hours. When he clicks the link, it
has expired. He sees "This link has expired. Request a new one." He can request a new link.
### Journey 3: Rate-Limited Request
After 3 requests in 15 minutes, the system shows "Too many requests. Try again in 15 minutes."
## Functional Requirements
### FR-1: Request Password Reset
User submits registered email. System validates existence. If exists: generate secure token,
store with 1-hour expiry, send email. If not exists: same generic response (no enumeration).
### FR-2: Validate Reset Token
User accesses link. System validates: exists, not expired, not used. Valid → show form.
Invalid → show expired message + "Request new link."
### FR-3: Set New Password
User submits new password. System validates strength. If valid: update password, invalidate
token, invalidate all sessions, redirect to login. If invalid: show validation errors.
### FR-4: Rate Limiting
3 requests per email per 15 min. 5 validation attempts per token per IP per 15 min. 429 + Retry-After.
## Non-Functional Requirements
### NFR-1: Latency — Email queued within 30 seconds
### NFR-2: Security — Token entropy ≥256 bits
### NFR-3: Availability — Queue and retry on email failure
## Acceptance Criteria
- **AC-1**: Valid email → "Check your email" + email within 60s
- **AC-2**: Invalid email → same "Check your email" (no enumeration)
- **AC-3**: Valid token + new password → password updated, redirect to login
- **AC-4**: Expired token → "Link expired" + request new link
- **AC-5**: 4th request in 15 min → rate limit message, 429
- **AC-6**: After reset → old password fails, new password succeeds
## Edge Cases
| Case | Condition | Expected Behavior |
|------|-----------|-------------------|
| EC-1 | Empty email | "Email is required" |
| EC-2 | Invalid format | "Enter a valid email" |
| EC-3 | Token used twice | "Already used" |
| EC-4 | Weak password | Show strength requirements |
| EC-5 | No verified email | "Contact support" |
## Constraints
- **C-1**: No user enumeration
- **C-2**: Email verification only (no phone)
- **C-3**: Token single-use
- **C-4**: Token cleanup after 24h
- **C-5**: Must have verified email
- **C-6**: New request invalidates previous token
## Dependencies
### Internal
- User Service: getUserByEmail, updatePassword
- Auth Service: invalidateSession
- Token Store: createToken, consumeToken
### External
- Email Service: send transactional, template password-reset
## Observability
### Logs
Reset requested, token consumed, rate limit exceeded
### Metrics
password_reset_requests_total, password_reset_success_total, password_reset_rate_limited_total
### Alerts
High rate limit rate, email delivery failure
## Security Requirements
- **SEC-1**: Tokens stored hashed
- **SEC-2**: HTTPS only
- **SEC-3**: CSRF token on form
- **SEC-4**: bcrypt (cost 12) for password
- **SEC-5**: No sensitive data in logs
- **SEC-6**: Audit log for completed resets
How AI Uses Each Section Differently
Understanding how AI uses each section helps you prioritize and write more effectively:
| Section | AI Usage |
|---|---|
| Problem | Informs UX decisions, error messaging; helps prioritize edge cases |
| User Journeys | Guides flow implementation; suggests UX patterns |
| Functional Requirements | Primary implementation source; defines APIs, UI, logic |
| Non-Functional Requirements | Drives architecture (caching, rate limiting, encryption) |
| Acceptance Criteria | Generates tests; validation checklist |
| Edge Cases | Ensures error handling; boundary conditions |
| Constraints | Prevents scope creep; enforces boundaries |
| Dependencies | Determines imports, service calls; integration points |
| Observability | Adds logging, metrics, instrumentation |
| Security | Adds auth checks, encryption, validation |
Reasoning Models (o1, o3, Claude 3.7 Thinking) vs. Standard Models
The industry has seen a massive shift toward reasoning models that use reinforcement learning during inference. These models "think" before they type.
In Spec-Driven Development, reasoning models require a slightly different approach:
- Standard Models: Need step-by-step instructions. They do well with the Functional Requirements and User Journeys.
- Reasoning Models: Thrive on constraints and validation. They perform exceptionally well with robust Acceptance Criteria, Edge Cases, and hard Constraints. They don't need you to hold their hand through the how—they just need an airtight specification of the what and what not to do.
When writing specs for reasoning models, over-invest in Component 5 (Acceptance Criteria) and Component 7 (Constraints).
Tutorial: Write a Complete "Team Invitation" Specification
Let's write a complete specification for a "Team Invitation" feature step-by-step. This feature allows users to invite others to join a team in the collaboration platform.
Step 1: Problem Statement
# Feature: Team Invitation
## Problem
Team owners need to grow their teams by inviting new members. Without an invitation system,
they must manually add users (requiring admin access) or share credentials (insecure).
Invitations provide a controlled, auditable way to onboard new team members.
- **Who**: Team owners and admins
- **Pain**: No way to invite users; must use workarounds
- **Impact**: Slow onboarding; security risks; poor scalability
Step 2: User Journeys
## User Journeys
### Journey 1: Successful Invitation
Alice (team owner) invites bob@example.com. Bob receives an email with an invite link.
Bob clicks the link, creates an account (or logs in), and accepts the invitation. Bob
appears in the team member list with "Member" role.
### Journey 2: Invitation Expired
Bob receives an invite but doesn't act for 7 days. The link expires. Bob sees "Invitation
expired" and can request a new invitation from Alice.
### Journey 3: Invitation Declined
Bob clicks the link but chooses "Decline." The invitation is removed. Alice is notified
(optional). Bob can be invited again later.
### Journey 4: Already a Member
Alice invites bob@example.com, but Bob is already a team member. System shows "Already
a member" and does not send duplicate email.
Step 3: Functional Requirements
## Functional Requirements
### FR-1: Send Invitation
Team owner/admin can invite by email. System validates: email format, not already member,
not already invited (pending). If valid: create invitation record, send email with link,
show "Invitation sent." If invalid: show specific error.
### FR-2: Accept Invitation
User clicks link with valid token. If not logged in: redirect to signup/login, then back
to accept. If logged in: show "Join [Team Name]?" with Accept/Decline. On Accept: add
user to team with default role (Member), invalidate token, redirect to team.
### FR-3: Decline Invitation
User clicks Decline. System invalidates token, records decline. Optionally notify inviter.
### FR-4: Resend Invitation
Team owner can resend invitation to pending invite. New token generated; previous invalidated.
Same 7-day expiry.
### FR-5: Cancel Invitation
Team owner can cancel pending invitation. Token invalidated; invitation removed.
Step 4: Non-Functional Requirements
## Non-Functional Requirements
### NFR-1: Latency — Invitation email within 60 seconds
### NFR-2: Invitation limit — 50 pending invitations per team
### NFR-3: Rate limit — 10 invitations per team per hour
Step 5: Acceptance Criteria
## Acceptance Criteria
- **AC-1**: Given valid email, When owner sends invite, Then user receives email within 60s
- **AC-2**: Given user clicks valid link and accepts, When user clicks Accept, Then user
joins team and sees team dashboard
- **AC-3**: Given user clicks valid link and declines, When user clicks Decline, Then
invitation is removed
- **AC-4**: Given expired invitation link, When user clicks, Then "Invitation expired" shown
- **AC-5**: Given email already in team, When owner invites, Then "Already a member" shown
- **AC-6**: Given 51st pending invitation, When owner invites, Then "Limit reached" shown
- **AC-7**: Given owner cancels invitation, When invitee clicks link, Then "Invalid invitation"
Step 6: Edge Cases
## Edge Cases
| Case | Condition | Expected Behavior |
|------|-----------|-------------------|
| EC-1 | Invite own email | "Cannot invite yourself" |
| EC-2 | Invite duplicate pending | "Already invited" |
| EC-3 | User already in team | "Already a member" |
| EC-4 | Token used twice (double-click) | Second use fails gracefully |
| EC-5 | Inviter removed from team | Pending invites remain; new owner can cancel |
| EC-6 | Team deleted | All pending invites invalidated |
Step 7: Constraints
## Constraints
- **C-1**: Only team owners and admins can invite
- **C-2**: Invitation expires in 7 days
- **C-3**: Must not reveal whether email is registered (accept flow shows team name)
- **C-4**: Default role: Member (no admin invite via this flow)
- **C-5**: One invitation per email per team at a time
Step 8: Dependencies
## Dependencies
### Internal
- **Team Service**: getTeam, addMember, getMemberByEmail
- **User Service**: getUserByEmail, createUser (if signup)
- **Invitation Store**: create, getByToken, consume, cancel
### External
- **Email Service**: send transactional, template team-invitation
Step 9: Observability
## Observability
### Logs
- Invitation sent: teamId, inviterId, inviteeEmail (hashed), timestamp
- Invitation accepted: teamId, userId, timestamp
- Invitation declined: teamId, inviteeEmail (hashed), timestamp
### Metrics
- team_invitations_sent_total
- team_invitations_accepted_total
- team_invitations_declined_total
- team_invitations_expired_total
### Alerts
- High decline rate (>50% in 24h): possible UX issue
Step 10: Security Requirements
## Security Requirements
- **SEC-1**: Invitation tokens hashed; 256-bit entropy
- **SEC-2**: HTTPS only for invitation links
- **SEC-3**: CSRF token on Accept/Decline forms
- **SEC-4**: Audit log: invitation sent, accepted, declined, cancelled
- **SEC-5**: No enumeration: same response for invalid/expired token
Common Specification Anti-Patterns
Anti-Pattern 1: Premature Implementation Detail
Bad: "Use a REST API with POST to /api/invitations and validate with a JWT middleware."
Why it's bad: Specifies how instead of what. Ties the spec to a specific technology. AI may over-constrain or conflict with other constraints.
Good: "User can send an invitation by email. System validates and sends invite. API must be authenticated."
Anti-Pattern 2: Missing Edge Cases
Bad: "User can reset password by email." (No mention of expired links, rate limiting, invalid tokens.)
Why it's bad: AI implements happy path only. Edge cases cause bugs in production.
Good: "See Edge Cases section" with explicit EC-1 through EC-9.
Anti-Pattern 3: Untestable Criteria
Bad: "The system should be fast and user-friendly."
Why it's bad: "Fast" and "user-friendly" are not testable. AI cannot validate.
Good: "p95 latency < 200ms" and "Error messages use plain language, no technical jargon."
Anti-Pattern 4: Vague Requirements
Bad: "Handle errors appropriately."
Why it's bad: No guidance. AI invents behavior.
Good: "On validation error: return 400 with field-level errors. On server error: return 500 with generic message. Log full error server-side."
Anti-Pattern 5: Implicit Dependencies
Bad: (No Dependencies section; assumes AI will infer.)
Why it's bad: AI may miss integrations or use wrong services.
Good: Explicit Dependencies section listing internal and external requirements.
Anti-Pattern 6: No Non-Goals
Bad: (No explicit scope; AI may add "related" features.)
Why it's bad: Scope creep. AI adds bulk invite, invite by link, role selection, etc.
Good: "Non-Goals: Bulk invite, invite by shareable link, role selection at invite time."
Specification Quality Scoring Rubric
Use this rubric to evaluate specification quality. Score each dimension 1-10. Total score is the average.
| Dimension | 1-3 (Poor) | 4-6 (Adequate) | 7-10 (Excellent) |
|---|---|---|---|
| Completeness | Missing 4+ components | Missing 1-3 components | All 10 components present |
| Precision | Vague; requires guessing | Some ambiguity | Implementable without questions |
| Testability | Acceptance criteria untestable | Some testable | All criteria testable |
| Edge Cases | None or trivial | Some covered | Comprehensive list |
| Constraints | None or implicit | Some stated | Explicit; prevents scope creep |
| Consistency | Contradictions | Minor inconsistencies | Internally consistent |
| AI Readability | Unstructured prose | Partial structure | Clear headings, structure |
Scoring Guide
- 70-100: Excellent. Ready for AI implementation.
- 50-69: Good. Review weak dimensions before implementation.
- 30-49: Adequate. Significant gaps; expect implementation questions.
- 0-29: Poor. Rewrite before implementation.
Self-Assessment Checklist
Before handing a spec to AI, verify:
- Problem statement explains why
- User journeys cover happy path and key error paths
- Functional requirements are precise (no "appropriate," "properly")
- NFRs are measurable
- Every acceptance criterion is Given/When/Then testable
- Edge cases cover boundaries, errors, empty inputs
- Constraints explicitly state what NOT to do
- Dependencies listed (internal and external)
- Observability: logs, metrics, alerts
- Security: auth, encryption, audit
Try With AI
Prompt 1: Specification Gap Analysis
"I'm going to give you a feature specification. Evaluate it against the 10 components: Problem, User Journeys, Functional Requirements, Non-Functional Requirements, Acceptance Criteria, Edge Cases, Constraints, Dependencies, Observability, Security. For each component, rate 1-10 and explain what's missing or what could be improved. Give me a total score and a prioritized list of improvements."
Prompt 2: Anti-Pattern Detection
"Review this specification for anti-patterns: premature implementation detail, missing edge cases, untestable criteria, vague requirements, implicit dependencies, missing non-goals. List each anti-pattern you find with the exact text and a suggested replacement."
Prompt 3: Specification Expansion
"I have a minimal specification with [list components]. Expand it into a complete 10-component specification. Add the missing components. For each component you add, explain your reasoning. Do not add implementation details — keep it at the 'what' level."
Prompt 4: Rubric Self-Check
"Score this specification using the rubric: Completeness, Precision, Testability, Edge Cases, Constraints, Consistency, AI Readability. Give a score 1-10 for each and an overall average. Suggest specific improvements to raise each dimension by at least 1 point."
Practice Exercises
Exercise 1: Component Audit
Take an existing specification from your project (or a public one). For each of the 10 components, either (a) extract it if present, or (b) write it if missing. Document what you found vs. what you added.
Expected outcome: A complete specification with all 10 components. You will discover gaps in most existing specs.
Exercise 2: Anti-Pattern Rewrite
Take a poorly written specification (e.g., "Build a login form" as a single sentence). Rewrite it to include all 10 components and avoid all 6 anti-patterns. Compare the two versions.
Expected outcome: The rewritten spec should be 5-10x longer and unambiguous. You will see how much implicit content exists in "simple" features.
Exercise 3: Rubric Scoring
Write a specification for a feature of your choice. Then score it using the rubric. For any dimension scoring below 7, revise the spec until it reaches 7+. Repeat until all dimensions are 7+.
Expected outcome: A specification that scores 70+ on the rubric. You will internalize the quality bar for "production-ready" specs.
Key Takeaways
-
Ten components define a complete specification: Problem, User Journeys, Functional Requirements, Non-Functional Requirements, Acceptance Criteria, Edge Cases, Constraints, Dependencies, Observability, Security.
-
Each component serves a distinct purpose for AI. Problem provides context; Functional Requirements drive implementation; Acceptance Criteria generate tests; Constraints prevent scope creep.
-
Precision over brevity. A specification that is long but precise produces better implementations than a short, vague one.
-
Edge cases are where bugs hide. Explicitly listing them ensures AI implements error handling.
-
Anti-patterns undermine quality: premature implementation detail, missing edge cases, untestable criteria, vague requirements, implicit dependencies, no non-goals.
-
The rubric provides a structured way to evaluate and improve specification quality before implementation.
Chapter Quiz
-
What are the ten components of a complete specification, and in one sentence each, what is the purpose of each?
-
Why is it important to avoid "solution disguised as problem" in the Problem Statement? Give an example of bad vs. good.
-
What is the difference between Functional Requirements and Non-Functional Requirements? Give one example of each for a login feature.
-
Why are Edge Cases a separate component rather than being folded into Acceptance Criteria?
-
Name three specification anti-patterns and explain why each is harmful.
-
How does the Dependencies section help AI implement a feature correctly?
-
What is the purpose of the Observability section, and what three sub-elements does it typically include?
-
Using the rubric, how would you score a specification that has all 10 components but uses vague language like "handle errors appropriately" and "should be fast"?