To PRD
Synthesize a complete Product Requirements Document from context. No interview required. Start with test seams, end with explicit out-of-scope boundaries.
No Interview — Synthesize from Context
Unlike Grill with Docs, the To PRD skill synthesizes a PRD from existing context — conversation history, codebase exploration, existing documentation, and any artifacts already in scope. You do not ask the human a series of questions. You write the PRD and let the human correct it.
Why no interview?
The one exception: if context is genuinely insufficient (no codebase, no prior conversation, no specification), ask for the one piece of information that would allow synthesis to proceed. Never ask for more than one piece of information at a time.
Step 1: Sketch Test Seams First
Before writing any PRD section, sketch the test seams. This constrains the implementation decisions you will make and ensures the PRD describes something testable.
A PRD that cannot be tested is either describing something that cannot be built, or describing something that can only be validated manually. Both are architectural problems. Sketching test seams before writing requirements forces clarity.
- If you cannot describe a test for a requirement, the requirement is too vague.
- If the test requires access to production infrastructure, the seam is too low.
- If the test requires a human in the loop, the feature may be acceptable but should be noted as requiring manual validation.
When sketching seams, look for existing interfaces in the codebase that can be used as test surfaces. Do not design new seams unless existing ones are insufficient.
// Seam sketch for a PRD on: "Add email notifications for order status changes"
// Existing seam (preferred):
// The OrderService already emits events via an EventEmitter.
// The test seam is: subscribe to the EventEmitter in a test,
// trigger an order state change, assert that the correct event
// was emitted with the correct payload.
// The EmailService (which sends email) is injected via interface,
// so we can substitute a MockEmailService in tests.
// Seam sketch:
// - OrderService.on('status_changed', handler) — existing seam
// - EmailService (interface) — existing seam, MockEmailService for tests
// - Template rendering — test by asserting rendered output matches snapshot
// No new seams required.When you must introduce a new seam, place it as high as possible — at the boundary between the feature you are building and the rest of the system, not deep inside the implementation.
- Test the notification feature through its public API, not through internal functions.
- Test the email rendering through the rendered output, not through template internals.
- Test the order status change through the observable state change, not through database queries.
Full PRD Template
A complete PRD has six sections. Every section is required unless explicitly marked optional.
A single paragraph, 2-4 sentences. Describes the current pain point, who experiences it, and why it matters. Does not describe the solution.
## Problem Statement
Users who place orders cannot tell whether their order is being
processed or has stalled. Support volume has increased 40% this
quarter, with the most common query being "where is my order?"
This indicates the product is failing to communicate order progress
to users at the moments they most need it.A brief description of what will be built. Does not include implementation details. Scoped to what is in this PRD, not future work.
## Solution
Add automated email notifications at each order status transition:
pending, processing, shipped, and delivered. Each notification
includes the current status, an order summary, and a link to the
order detail page. Notifications are sent immediately on status
change and do not require user action.User stories are the bulk of the PRD. Each story describes one observable behavior from the user's perspective. Stories should be:
- Granular enough that each story can become one or two implementation issues.
- Testable: each story implies a clear acceptance test.
- Written from the user's perspective, not the system's.
- Grouped by user role or flow when the feature touches multiple roles.
## User Stories
### Order Status Notifications
**US-1: Pending confirmation**
As a buyer, when I place an order, I receive a confirmation email
within 1 minute that includes my order number, a summary of items,
and the total price.
Acceptance criteria:
- Email is sent within 60 seconds of order creation
- Email includes: order number, item names, quantities, unit prices, subtotal, tax, total
- Email includes a link to the order detail page
- Email subject line is: "Order #[number] confirmed"
**US-2: Processing notification**
As a buyer, when my order moves to "processing" status, I receive
an email notifying me that my order is being prepared.
Acceptance criteria:
- Email sent within 60 seconds of status change to "processing"
- Email includes: order number, estimated processing time if available
- Email subject: "Your order #[number] is being prepared"
**US-3: Shipped notification**
As a buyer, when my order ships, I receive an email with tracking
information.
Acceptance criteria:
- Email sent within 60 seconds of status change to "shipped"
- Email includes: order number, carrier name, tracking number, tracking URL
- Tracking URL is valid and links to the carrier's tracking page
- Email subject: "Your order #[number] has shipped"
**US-4: Delivered notification**
As a buyer, when my order is marked delivered, I receive a
confirmation email.
Acceptance criteria:
- Email sent within 60 seconds of status change to "delivered"
- Email includes: order number, delivery confirmation, support contact
- Email subject: "Your order #[number] has been delivered"
**US-5: Notification deliverability**
As a buyer, I receive notifications at the email address I used
when placing the order, not at any other email address.
Acceptance criteria:
- Notification is sent to the email on the order, not the current account email if they differ
- If the email address is invalid, the failure is logged and does not block order processing
**US-6: No duplicate notifications**
As a buyer, I do not receive duplicate notifications for the same
status change.
Acceptance criteria:
- If a status changes twice in rapid succession (e.g., due to a system retry), only one notification is sent
- Idempotency key is derived from order ID + status + timestamp (floor to minute)This section captures architectural decisions that affect implementation. These are decisions that narrow the solution space without specifying file paths, function names, or implementation details.
No file paths or line numbers
## Implementation Decisions
**Email delivery**
Use a transactional email provider via an injected EmailService
interface. The provider choice is an infrastructure decision, not
a product decision. The EmailService interface must support:
send(to, subject, htmlBody, textBody) and return a delivery ID.
**Notification trigger**
Notifications are triggered by order status change events, not by
polling the database. The event emission point is the OrderService
status update method.
**Template rendering**
Email templates are rendered server-side as HTML + plain text pairs.
Templates are versioned alongside the codebase, not stored in a
database. Template content is the responsibility of this PRD;
template styling is out of scope.
**Retry behavior**
If the EmailService fails to deliver a notification, the failure
is logged. Retries are the responsibility of the EmailService
provider (e.g., provider-level retry), not the application.
**Rate limiting**
No application-level rate limiting is added for notifications in
this iteration. If a single order generates rapid status changes
due to a system bug, the idempotency key (US-6) prevents duplicate
sends.Describes the testing strategy for this feature. References seam sketches from the pre-PRD work.
## Testing Decisions
**Unit tests**
- Notification trigger logic: test by substituting MockEmailService
at the EmailService seam. Assert correct email is triggered for
each status transition.
- Template rendering: snapshot test each template with representative
order data. Include edge cases: very long item names, international
characters, zero-item orders (should not exist but must not crash).
**Integration tests**
- End-to-end status change to email delivery: test with a sandboxed
email provider (e.g., Mailpit in CI) that captures sends without
delivering. Assert the email reaches the sandbox for each status.
**No manual QA required for**
- Email content formatting (covered by snapshot tests)
- Timing (covered by unit tests that check trigger is called)
**Manual QA required for**
- Email rendering in major email clients (Outlook, Gmail, Apple Mail)
— visual rendering cannot be automated reliably. One manual check
per template before launch.Every PRD must have an explicit out-of-scope section. This is as important as the user stories — it prevents scope creep and gives the implementation team a clear boundary.
## Out of Scope
The following are explicitly excluded from this PRD. They may be
addressed in future iterations but must not be built as part of
this work.
- SMS or push notification channels (email only in this iteration)
- User preference management (opt-out, notification frequency settings)
- In-app notification center
- Notification analytics or open-rate tracking
- Retroactive notifications for historical status changes
- Admin-triggered manual notifications
- Localization or multi-language support
- B2B order notifications (wholesale portal uses a different flow)
- Notification scheduling (delayed send, send-at-optimal-time)Any context, constraints, or risks that do not fit the above sections. This section is optional but common.
## Further Notes
**Known constraint:** The current email provider has a 10 req/sec
rate limit on the sending API. Under current order volume this is
not a concern, but if order volume exceeds 600/min the notification
system will need a queue. This is not in scope now but should be
noted in the architecture as a future seam.
**Dependency:** The OrderService event system was built for internal
use and is not formally documented. Whoever implements US-1 through
US-4 should verify the event payload format with the OrderService
team before finalizing the template rendering.The Prototype Snippet Exception
Implementation decisions in a PRD must not reference file paths or function names — except in one case.
If a key algorithmic or structural decision was explored in a prototype, you may include a brief prototype snippet in the Implementation Decisions section to convey the decision concretely. The snippet must:
- Be clearly marked as a prototype reference, not production code.
- Convey a single concept, not an implementation blueprint.
- Be short: under 20 lines.
- Not reference file paths, class names, or function signatures that will appear in production.
**Implementation Decision: Idempotency key structure**
The prototype established that the idempotency key should be derived
from order ID + status + time bucket (5-minute floor). This prevents
duplicates from rapid successive status changes while allowing
legitimate re-notification after a time gap.
Prototype reference:
// orderId + status + 5-minute time bucket
const idempotencyKey = `notify:${orderId}:${status}:${
Math.floor(Date.now() / (5 * 60 * 1000))
}`;
The production implementation should use this structure but may use
different serialization or hashing.