SDD Design Doc Template
Use the design doc after the change proposal is reviewable. The purpose is to decide how the behavior will be implemented without losing the constraints from the spec.
# Design Doc Spec: Owner: Status: Draft | Review | Approved ## Context - Link to the approved spec or change proposal. ## Architecture Decision - Chosen approach: - Why this approach: - Alternatives rejected: ## Interfaces - API: - Events: - Database: - UI states: ## Constraints - Compatibility: - Security: - Performance: - Operational limits: ## Rollout Plan - Phase 1: - Phase 2: - Stop signal: - Rollback:
When to use this template
- The spec affects APIs, databases, queues, permissions, or release sequencing.
- The team needs to compare two implementation approaches before coding.
- Generated code needs a narrower architecture boundary.
- A reviewer needs to understand why an alternative was rejected.
What a filled version looks like
The template becomes useful after it carries a real decision, owner, and evidence. This is the level of specificity to aim for.
## Architecture Decision - Chosen approach: keep refund creation synchronous, move provider confirmation to async worker. - Why: support needs an immediate pending state, while provider timeout can resolve later. - Rejected: retry provider call inside request path because it increases duplicate risk.
Field note: where the architecture choice belongs
A refund spec is approved, but engineers disagree about whether provider confirmation should happen inside the request path or in a worker. The design doc is where that trade-off belongs, not in the task list.
Common failure: If the trade-off stays implicit, implementation can drift toward the fastest local change: retrying provider calls synchronously and making duplicate behavior harder to reason about.
- Reviewer action: Ask reviewers to challenge the rejected alternative, the interface list, and the stop signal before coding starts.
- Evidence bar: Good evidence includes a sequence diagram or written event order plus tests proving pending state, worker retry, and rollback behavior.
How to adapt this template without making it generic
Do not only replace the title and date. A useful version turns every placeholder into a reviewable decision: who owns the change, which behavior must be true, which scope is explicitly excluded, and what evidence must exist before merge. If a field cannot be filled yet, keep it as an open question instead of burying the uncertainty in prose.
When you use this design.md, start with the part most likely to cause rework. For many teams that is not the implementation step; it is the boundary, exception, compatibility rule, or release evidence. The earlier the template exposes those decisions, the less room an AI coding tool or rushed engineer has to broaden the change silently.
- Use it when: The spec affects APIs, databases, queues, permissions, or release sequencing.
- Review for: The chosen approach points back to the approved spec.
- Strong wording target: Keep the refund request path idempotent. Create one local refund row, enqueue provider confirmation, block support from creating another refund while status is pending_provider_confirmation, and stop rollout if duplicate attempts exceed 0.5%.
Suggested review path
Use the first pass to review scope: the goal should be singular, the non-goals should block common expansions, and the affected systems should be named. Use the second pass to review testability: acceptance criteria should describe state, trigger, and observable result, not a vague wish that the product feels better. Use the third pass to review evidence: tests, screenshots, logs, metrics, or manual checks should prove each criterion.
Before giving this template to an AI coding tool, ask a human reviewer to confirm allowed files, interfaces that must not change, migration order, and stop signals. The AI should receive an executable spec, not a prompt that looks complete while still leaving the risky decisions implicit.
- Before implementation: confirm open questions do not block behavior decisions.
- During implementation: map every task back to a criterion or constraint in this file.
- Before merge: prove the result with evidence, not only with a "tests passed" sentence.
Review before implementation
- The chosen approach points back to the approved spec.
- Interfaces list concrete endpoints, events, tables, or UI states.
- Rejected alternatives include the reason, not just the name.
- Rollout and rollback are specific enough for release review.
Weak vs strong wording
Weak
Use a worker and add tests.
Strong
Keep the refund request path idempotent. Create one local refund row, enqueue provider confirmation, block support from creating another refund while status is pending_provider_confirmation, and stop rollout if duplicate attempts exceed 0.5%.
When the template stops being empty
The easiest way for a template page to become thin is to provide a clean skeleton without showing how to judge the filled result. A useful version answers three questions: why this change is worth doing now, which scope is explicitly excluded, and which evidence proves the implementation did not drift.
When you use the template for real work, attach the final file to the pull request and mark any section that changed during implementation. A spec is not a one-time document; it should move with the implementation evidence. Readers copying this template should also copy that habit: every sentence that sounds like a decision should be reviewable and traceable.
- Minimum evidence: at least one automated test or contract fixture.
- Higher-risk evidence: add screenshots, log queries, metrics, or rollback signals.
- Follow-up evidence: give known gaps an owner and review date.
Where it fits in a complete SDD packet
Do not push every decision into the same file. design.md should own the layer it is best at: making one category of decision reviewable, linkable, and updateable. Scope, design, tasks, and evidence should connect to each other, but they should not swallow each other. When implementation reveals new facts, the team should know exactly which artifact needs to change.
In practice, use this template as one step in a short chain: write the spec or proposal, add design or tasks only when the work needs them, then feed evidence back into the pull request. Readers copying the template should copy that chain as well. A polished standalone template does not improve delivery by itself; a traceable set of artifacts does.
If the template becomes a team standard, keep one filled example in the repository instead of only publishing an empty skeleton. The example teaches new contributors what "specific enough" looks like and gives AI coding tools a better pattern to follow.
- Upstream input: a concrete user problem, system constraint, and known failure mode.
- Downstream output: executable tasks, review questions, test evidence, or release gates.
- Maintenance habit: update the matching spec file whenever implementation changes a decision.
FAQ
Should every spec get a design doc?
No. Use it when implementation choices create real risk. A small UI copy change can skip this step.
What belongs here instead of the spec?
Keep product behavior in the spec. Put architecture choices, trade-offs, constraints, interfaces, and rollout order in the design doc.
How do AI agents use it?
Give the agent the spec plus this design doc and require changed files to map back to the approved interfaces and constraints.
Related resources
Editorial note
This template is written for spec-driven development workflows. The example is illustrative and should be adapted to your domain.
- Author: Daniel Marsh
- Editorial policy: How we review and update content
Tip: keep it under /docs/specs/ or /.specs/, then update it in the same pull request as implementation changes. Last updated: May 19, 2026.