Use when the user wants to draft, scope, or formalize a feature for shipcode — "write a PRD for X", "let's plan X", "scope this out", "what should X do", or when a GitHub issue body needs to be fleshed out before the pipeline plans it. Writes a PRD that maps cleanly onto shipcode's pipeline (objective / acceptanceCriteria / outOfScope / estimatedComplexity) so the planner agent can consume it without re-elicitation. Do NOT use for code edits, debugging, or PR reviews.
A PRD in shipcode is the input contract for the pipeline's plan phase. A good PRD is what lets the planner agent produce a usable plan in one shot instead of burning turns asking the user "what did you mean by X?". A bad PRD causes planner thrash, review rejection, and verification failures downstream.
Storage Location
The GitHub issue body IS the PRD. There is no local sidecar file, no .shipcode/prds/ directory, no SQLite-only draft. One document per work item, one location: the body of a GitHub issue in the project's connected repo.
Create a PRD by creating a GitHub issue whose body is clean PRD markdown.
Edit a PRD by editing that issue's body.
Version history is GitHub's issue edit history — no manual updated field bumping.
The pipeline reads the issue body verbatim (packages/pipeline/src/pipeline.ts:581 — const prompt = \GitHub Issue #${issue.number}: ${issue.title}\n\n${issue.body ?? ''}``) and feeds it into the planner agent. What you write in the issue body is exactly what the planner sees.
If shipcode's onboarding has not been completed (no GitHub repo connected), you cannot write a PRD yet. Complete onboarding first — shipcode is mandatory-GitHub by design.
Native GitHub Metadata
Do not put YAML frontmatter at the top of GitHub issue bodies. GitHub renders
issue-body frontmatter as visible noise and already has native places for this
metadata.
Use native GitHub and Projects fields instead:
Issue type:Feature, Bug, or Task.
Project status:Backlog, In Progress, Human Review, Done, or Deferred.
Project priority:P0, P1, P2, or P3.
Project complexity:Low, Medium, or High.
Project blast radius:Contained, Cross-package, Cross-app, or Infra.
Rules:
The PRD body starts with # PRD: <name> and contains only human-readable PRD content.
Put card/list summaries in the issue title, project fields, or a short Executive Summary, not in hidden metadata.
If the author cannot estimate complexity, set the project field to Medium and explain why in Risks & Open Questions.
Draft is workflow state, not body text. Keep draft PRDs off the runnable kanban path through project status or app state.
Issue Title Style
The GitHub issue title is what the board shows most of the time. Keep it short.
Prefer 4-7 words when possible.
Prefer an imperative verb + object shape: Add pipeline checkpoints, Track CI blockers on issues, Expose model selectors in SettingsPanel.
Put the detail in the Executive Summary and body, not in the title.
Avoid titles chained together with and / while / during unless the feature is truly one inseparable unit.
Avoid titles that restate the full implementation loop. The title names the work item; the PRD explains it.
Keep the # PRD: name aligned with the final issue title's slugified form. If you shorten the title, shorten the PRD heading too.
Bad:
Open draft PR during execution and ingest PR feedback into stabilization loop
Treat CI failures as blocker state on GitHub issue tasks
Better:
Add draft PR feedback loop
Track CI blockers on issues
Required Sections
Every shipcode PRD must have these sections, in this order. Missing sections fail quality gate.
# PRD: <name>
## Executive Summary
<2–4 sentences. What is this feature, why now, who wins.>
## Problem Statement
<The concrete pain. Reference real incidents, real users, real metrics where possible.
Avoid "users might want..." — if you can't name the user, you don't have a problem yet.>
## Goals
- <measurable, verifiable goal>
- <measurable, verifiable goal>
## Non-Goals
- <thing this explicitly does NOT do — the more you list, the less scope creep downstream>
## User Stories
- As a <role>, I want <capability> so that <outcome>.
- Each story ends with "**Acceptance:**" followed by 1–3 concrete checks.
## System Specification
<Observable system contract for the feature. Include user-visible states, data
contracts, permissions/trust boundaries, failure behavior, and integration
points. Do not name files, functions, libraries, or implementation details.>
## Functional Requirements
<Numbered list. Each item must be verifiable by reading code or running it.
NO implementation details — "the system must do X", not "use Zustand to do X".>
## Non-Functional Requirements
<Performance, accessibility, error-handling, offline, observability.
Only list the ones that actually matter for this feature.>
## Feature Phase Breakdown
<Exactly three product-level phases, in order. These are the phases the planner
must translate into the three ordered ShipCodePlan steps.
1. Foundation/spec plumbing — contracts, persistence, configuration, or shared
surfaces needed before behavior can be implemented.
2. Primary feature behavior — the actual user/system capability.
3. Hardening/verification/shipping polish — tests, error handling,
observability, docs, or UI polish needed to ship confidently.
Each phase must include: purpose, in-scope behavior, out-of-scope behavior, and
a concrete completion signal.>
## Success Criteria
<The bar the pipeline's verification phase will check against.
Every bullet here becomes an entry in `PlanStructured.acceptanceCriteria`
(`packages/shared/src/types.ts:10`). Write them like test assertions.>
## Out of Scope
<Becomes `PlanStructured.outOfScope`. Be ruthless. Future-proofs the review phase.>
## Dependencies
<Other PRDs, packages, external APIs, feature flags. Reference by path or URL.>
## Verification Plan
<How the verifier will know this shipped correctly.
`tests`: list the test files/suites that must exist and pass.
`manual`: list the manual QA steps a human will run post-merge.
`both`: both sections.
Shipcode's verification phase (`packages/pipeline/src/pipeline.ts:380`) runs
`buildVerificationPrompt(plan, diff, plan.acceptanceCriteria)` — the clearer
this section is, the fewer verification retries you burn.>
## QA State
<Optional but required for features where ShipCode should collect browser QA evidence.
Include a fenced JSON block matching `FeatureQaState`.
Use `visualAssertions` for layout or placement requirements that should be proven by Playwright.
For example: target selector, route, assertion (`top-left-of-container`, `not-overlapping`, etc.),
container/reference selector, tolerance, and viewport.
Set `selectorReadiness` to `ready` only when stable selectors are part of the contract.>
## Risks & Open Questions
<Unknowns, edge cases, things that could kill the plan mid-execution.
Open questions get tracked here until answered, then deleted.>
Mapping to Shipcode's Pipeline
A PRD is read by the planner agent. Every section has a downstream consumer:
PRD section
Feeds
Consumer
Executive Summary
PlanStructured.objective
Plan display, PR title, kanban card
System Specification
Plan objective, dependencies, step rationale
Planner + reviewer
Goals + Functional Requirements
Plan steps
Planner agent decomposition
Feature Phase Breakdown
Exactly three ordered plan steps
Planner + task graph execution
Success Criteria
PlanStructured.acceptanceCriteria
Verification phase
Out of Scope
PlanStructured.outOfScope
Review phase (rejects scope creep)
Project complexity field
PlanStructured.estimatedComplexity
Review rubric, retry budget
Verification Plan
buildVerificationPrompt(...) input
Verification phase
Non-Goals + Out of Scope
Review gate
Reviewer rejects patches that violate these
Do not write sections that describe files to change, function names, or implementation choices. Those belong in the plan, not the PRD. If the PRD author can't resist writing pseudo-code, put it under "Risks & Open Questions" as "I suspect we'll need to touch X" — not as a requirement.
Quality Gates
Before marking a PRD ready for the pipeline to consume, every one of these must be true:
No placeholder text (TODO, TBD, <fill this in>) remains in any section.
Goals has at least one measurable bullet.
Success Criteria has at least one bullet, and every bullet is verifiable without judgement — it either passes or fails. "Feels fast" is not verifiable. "p95 latency < 300ms on the issues query" is.
Out of Scope has at least one bullet. Empty Out of Scope is a tell that the author didn't scope the feature.
User Stories has at least one story with explicit Acceptance bullets.
System Specification names the observable states, data contracts, permissions/trust boundaries, and failure behavior that matter for the feature.
Feature Phase Breakdown contains exactly three ordered phases, and each phase has a purpose, scope, and completion signal.
Every external dependency in Dependencies is named (package, PRD path, or URL), not described vaguely.
Verification Plan names either test file paths, suite names, or concrete manual steps — not "write some tests".
If any gate fails, keep it in draft/deferred workflow state and do not offer "Start pipeline" in the kanban.
Workflow
When the user says "write a PRD for X"
Verify GitHub is connected. The user must have completed shipcode onboarding with a repo selected. If not, stop and tell them to finish onboarding first — there is no other place a PRD can live.
Do not start writing immediately. Run a short elicitation pass first — you need answers before section-filling is meaningful:
What problem does this solve, and for whom specifically?
What does success look like — how would we measure it?
What is explicitly out of scope?
What's the complexity gut feel (low/medium/high) and why?
Any hard constraints — deadlines, other projects in flight, package boundaries?
Check for an existing issue. Run gh issue list --search "<keywords>" --state all in the target repo. If a matching issue already exists, ask whether to edit it or create a fresh one.
Kebab-case the PRD name. If the proposed name has spaces, camelCase, or punctuation, kebab-case it: "Notification Center" → notification-center. This slug goes in the # PRD: heading.
Compress the issue title before writing the body. Default to a short imperative title, then derive the # PRD: heading from that final title. Put nuance in the Executive Summary, not the title.
Draft the PRD body using the template above, in a scratch buffer. Fill every required section. If you can't fill a section, ask the user — don't hallucinate requirements.
Run the quality gates against the draft. If any fail, keep the issue in draft/deferred workflow state and tell the user which gates failed. If they all pass, mark it ready through native project/app state.
Create the GitHub issue. Preferred: use the desktop app's Create PRD modal (which calls the github:create-issue IPC handler — the handler wraps gh issue create and upserts the cache). Alternative for CLI contexts: gh issue create --title "<Human Readable Title>" --body-file - with the PRD markdown piped on stdin.
Confirm the outcome to the user with the issue URL. Suggest next step: "Ready to hand this to the planner? Click Start pipeline in the kanban, or say: plan issue #N".
When the user says "plan the X PRD"
Fetch the current issue body via the cache (github_issue_cache.body) or gh issue view <N> --json body --jq .body if the cache may be stale. Read it fully before producing anything.
Verify the issue is ready through native project/app state — never plan a draft/deferred issue.
Translate directly: Executive Summary → objective, Feature Phase Breakdown → exactly three ordered plan steps, Success Criteria → acceptanceCriteria, Out of Scope → outOfScope, project complexity → estimatedComplexity.
The plan phase owns file changes and step breakdown — do not copy those out of the PRD (there shouldn't be any).
When the user says "update the X PRD"
Fetch the current issue body (prefer gh issue view <N> --json body --jq .body to guarantee freshness).
Make the requested edit in a scratch buffer.
Write it back with gh issue edit <N> --body-file - (piping on stdin) or via the github:edit-issue-body IPC handler from the desktop app. GitHub tracks the edit history automatically.
If the change invalidates an in-flight plan (new acceptance criterion, new out-of-scope item), flag that explicitly to the user — they may want to kill the thread and re-plan. The local github_issue_cache.body will be refreshed automatically by the IPC handler; for pure CLI edits, tell the user to click "Refresh from GitHub" in IssueDetail before starting a new plan run.
Anti-Patterns
Observed failure modes from prior sessions — do not repeat:
PRD full of implementation details. Writing use TanStack Query v5 for caching in Functional Requirements. The PRD describes the what; the plan owns the how. This leaks into review and causes the reviewer to flag the plan for violating the PRD, which the planner then "fixes" by copying the implementation detail verbatim. Dead loop.
Success Criteria written as vibes. "Users should find the flow intuitive." Unverifiable → verification retries forever.
Empty Out of Scope. Always a sign the author is planning to sneak scope in later. Force the listing.
Authoring a PRD before the GitHub repo is connected. If onboarding isn't complete, there is nowhere to put the PRD — finish onboarding first. Do not draft PRDs into scratch files as a workaround; they become orphan documents that drift out of sync the moment the repo is connected.
Editing github_issue_cache.body directly in SQLite. The cache is downstream of GitHub, not upstream. Every manual DB edit is overwritten on the next github:refresh-issues call. Always edit via gh issue edit or the github:edit-issue-body IPC handler.
Creating a GitHub issue without running the quality gates first. Quality gates exist because half-formed PRDs thrash the planner and burn verification retries. Running them after you've already created the issue means the issue is public before the gates pass — embarrassing and harder to fix than running them first.
Writing a PRD for something you should just ticket. A typo fix does not need a PRD. A dependency bump does not need a PRD. Reserve PRDs for features and architectural changes that will run through the plan / review / verify / ship pipeline.
Minimal Example
The text below is the exact issue body that gets pushed to gh issue create --body-file - (or, equivalently, pasted into the Create PRD modal's body field). GitHub metadata belongs in native fields, not in this body.
# PRD: copy-issue-url-action
## Executive Summary
Users working in the kanban frequently need to paste an issue URL into Slack,
commit messages, or an external ticketing tool. Today the only way to get the
URL is to click into the issue, then copy from the header — three clicks and
a context switch. Add a "Copy URL" action to the kanban card's context menu
so it takes one click.
## Problem Statement
Observed on 2026-04-09: the user mentioned needing to paste an issue URL
into a Slack thread five times in a single session, each requiring a detour
through IssueDetail. This is pure friction — the URL is already known.
## Goals
- Right-clicking a kanban card shows a context menu with "Copy URL".
- Clicking "Copy URL" writes the issue's GitHub URL to the clipboard and
shows a toast confirming the copy.
## Non-Goals
- Copying anything other than the URL (title, body, ID — all separate actions
if demand appears).
- A multi-select "copy all URLs" bulk action.
- Keyboard shortcut for copy — mouse-only for v1.
## User Stories
- As a developer pasting issue links into Slack, I want to copy an issue's
URL without leaving the kanban, so that I don't break my flow.
**Acceptance:**
- Right-click on a kanban card surfaces a context menu including "Copy URL".
- Clicking it results in the URL being on the system clipboard.
- A toast appears within 200ms confirming the copy.
## System Specification
- Cards expose a context menu action surface without changing click-to-open
behavior or drag behavior.
- The copied value is the canonical GitHub issue URL for the card's project
and issue number.
- Clipboard failures surface a user-visible error state instead of failing
silently.
## Functional Requirements
1. The kanban card component must support a right-click context menu.
2. The context menu must include an action labeled "Copy URL".
3. The URL written to the clipboard must be the canonical GitHub issue URL
(the `html_url` returned by the GitHub API, or a deterministically
constructed `https://github.com/<owner>/<repo>/issues/<N>` equivalent).
4. The toast notification must use the existing UI toast primitive.
## Non-Functional Requirements
- Clipboard write must succeed or fail cleanly — no silent failures. On
permission denial, surface an error toast.
## Feature Phase Breakdown
1. Foundation/spec plumbing — identify the existing kanban action surface,
URL source, and toast primitive; completion signal is a plan that names the
exact data source and reusable UI primitive.
2. Primary feature behavior — add the context menu action and clipboard write;
completion signal is a card action that copies the correct URL.
3. Hardening/verification/shipping polish — cover success and failure paths;
completion signal is passing focused tests plus manual paste verification.
## Success Criteria
- Right-clicking any kanban card opens a context menu with a "Copy URL" item.
- Clicking "Copy URL" puts the exact string `https://github.com/<owner>/<repo>/issues/<N>`
on the clipboard for that issue.
- A success toast appears when the copy succeeds.
- An error toast appears if the clipboard API rejects the write.
## Out of Scope
- Copying other fields (title, body, branch name).
- Bulk selection + copy.
- Keyboard shortcut bindings.
- A "Share" action that opens the URL in the browser.
## Dependencies
- The existing UI toast primitive (`@shipcode/ui`).
- `github_issue_cache.issue_number` and the project's `github_repo` for URL
construction.
## Verification Plan
- **tests:** `apps/desktop/src/renderer/components/KanbanBoard.test.tsx` —
add a test that simulates a right-click and asserts the context menu
includes a "Copy URL" item wired to a mocked clipboard write.
- **manual:** right-click three cards from different projects, paste the
clipboard into a browser tab, verify the URL loads the correct issue.
## Risks & Open Questions
- Electron's clipboard API vs the web `navigator.clipboard` — which one does
the renderer use today? Check the existing implementation before writing
new clipboard code.
- Do we need a focus-management consideration so that the context menu
doesn't fight with drag-and-drop handlers on the same card?
Note: no created, updated, status, complexity, or blast radius fields in the body — GitHub and the project board track those natively. No file path — the PRD lives in the issue body itself. The entire text block above (starting from # PRD:) is what gets pasted into gh issue create --body-file -.
1---2name: writing-prds-33description: Use when the user wants to draft, scope, or formalize a feature for shipcode — "write a PRD for X", "let's plan X", "scope this out", "what should X do", or when a GitHub issue body needs to be fleshed out before the pipeline plans it. Writes a PRD that maps cleanly onto shipcode's pipeline (objective / acceptanceCriteria / outOfScope / estimatedComplexity) so the planner agent can consume it without re-elicitation. Do NOT use for code edits, debugging, or PR reviews.4---56# Writing Shipcode PRDs78A PRD in shipcode is the input contract for the pipeline's **plan** phase. A good PRD is what lets the planner agent produce a usable plan in one shot instead of burning turns asking the user "what did you mean by X?". A bad PRD causes planner thrash, review rejection, and verification failures downstream.910## Storage Location1112**The GitHub issue body IS the PRD.** There is no local sidecar file, no `.shipcode/prds/` directory, no SQLite-only draft. One document per work item, one location: the body of a GitHub issue in the project's connected repo.1314- **Create** a PRD by creating a GitHub issue whose body is clean PRD markdown.15- **Edit** a PRD by editing that issue's body.16- **Version history** is GitHub's issue edit history — no manual `updated` field bumping.17- **The pipeline reads** the issue body verbatim (`packages/pipeline/src/pipeline.ts:581` — `const prompt = \`GitHub Issue #${issue.number}: ${issue.title}\n\n${issue.body ?? ''}\``) and feeds it into the planner agent. What you write in the issue body is exactly what the planner sees.1819If shipcode's onboarding has not been completed (no GitHub repo connected), **you cannot write a PRD yet**. Complete onboarding first — shipcode is mandatory-GitHub by design.2021## Native GitHub Metadata2223Do not put YAML frontmatter at the top of GitHub issue bodies. GitHub renders24issue-body frontmatter as visible noise and already has native places for this25metadata.2627Use native GitHub and Projects fields instead:2829- **Issue type:** `Feature`, `Bug`, or `Task`.30- **Project status:** `Backlog`, `In Progress`, `Human Review`, `Done`, or `Deferred`.31- **Project priority:** `P0`, `P1`, `P2`, or `P3`.32- **Project complexity:** `Low`, `Medium`, or `High`.33- **Project blast radius:** `Contained`, `Cross-package`, `Cross-app`, or `Infra`.3435Rules:3637- The PRD body starts with `# PRD: <name>` and contains only human-readable PRD content.38- Put card/list summaries in the issue title, project fields, or a short Executive Summary, not in hidden metadata.39- If the author cannot estimate complexity, set the project field to `Medium` and explain why in Risks & Open Questions.40- `Draft` is workflow state, not body text. Keep draft PRDs off the runnable kanban path through project status or app state.4142## Issue Title Style4344The GitHub issue title is what the board shows most of the time. Keep it short.4546- Prefer **4-7 words** when possible.47- Prefer an **imperative verb + object** shape: `Add pipeline checkpoints`, `Track CI blockers on issues`, `Expose model selectors in SettingsPanel`.48- Put the detail in the Executive Summary and body, not in the title.49- Avoid titles chained together with `and` / `while` / `during` unless the feature is truly one inseparable unit.50- Avoid titles that restate the full implementation loop. The title names the work item; the PRD explains it.51- Keep the `# PRD:` name aligned with the final issue title's slugified form. If you shorten the title, shorten the PRD heading too.5253Bad:5455- `Open draft PR during execution and ingest PR feedback into stabilization loop`56- `Treat CI failures as blocker state on GitHub issue tasks`5758Better:5960- `Add draft PR feedback loop`61- `Track CI blockers on issues`6263## Required Sections6465Every shipcode PRD must have these sections, in this order. Missing sections fail quality gate.6667```markdown68# PRD: <name>6970## Executive Summary71<2–4 sentences. What is this feature, why now, who wins.>7273## Problem Statement74<The concrete pain. Reference real incidents, real users, real metrics where possible.75Avoid "users might want..." — if you can't name the user, you don't have a problem yet.>7677## Goals78- <measurable, verifiable goal>79- <measurable, verifiable goal>8081## Non-Goals82- <thing this explicitly does NOT do — the more you list, the less scope creep downstream>8384## User Stories85- As a <role>, I want <capability> so that <outcome>.86- Each story ends with "**Acceptance:**" followed by 1–3 concrete checks.8788## System Specification89<Observable system contract for the feature. Include user-visible states, data90contracts, permissions/trust boundaries, failure behavior, and integration91points. Do not name files, functions, libraries, or implementation details.>9293## Functional Requirements94<Numbered list. Each item must be verifiable by reading code or running it.95NO implementation details — "the system must do X", not "use Zustand to do X".>9697## Non-Functional Requirements98<Performance, accessibility, error-handling, offline, observability.99Only list the ones that actually matter for this feature.>100101## Feature Phase Breakdown102<Exactly three product-level phases, in order. These are the phases the planner103must translate into the three ordered ShipCodePlan steps.1041. Foundation/spec plumbing — contracts, persistence, configuration, or shared105 surfaces needed before behavior can be implemented.1062. Primary feature behavior — the actual user/system capability.1073. Hardening/verification/shipping polish — tests, error handling,108 observability, docs, or UI polish needed to ship confidently.109Each phase must include: purpose, in-scope behavior, out-of-scope behavior, and110a concrete completion signal.>111112## Success Criteria113<The bar the pipeline's verification phase will check against.114Every bullet here becomes an entry in `PlanStructured.acceptanceCriteria`115(`packages/shared/src/types.ts:10`). Write them like test assertions.>116117## Out of Scope118<Becomes `PlanStructured.outOfScope`. Be ruthless. Future-proofs the review phase.>119120## Dependencies121<Other PRDs, packages, external APIs, feature flags. Reference by path or URL.>122123## Verification Plan124<How the verifier will know this shipped correctly.125`tests`: list the test files/suites that must exist and pass.126`manual`: list the manual QA steps a human will run post-merge.127`both`: both sections.128Shipcode's verification phase (`packages/pipeline/src/pipeline.ts:380`) runs129`buildVerificationPrompt(plan, diff, plan.acceptanceCriteria)` — the clearer130this section is, the fewer verification retries you burn.>131132## QA State133<Optional but required for features where ShipCode should collect browser QA evidence.134Include a fenced JSON block matching `FeatureQaState`.135Use `visualAssertions` for layout or placement requirements that should be proven by Playwright.136For example: target selector, route, assertion (`top-left-of-container`, `not-overlapping`, etc.),137container/reference selector, tolerance, and viewport.138Set `selectorReadiness` to `ready` only when stable selectors are part of the contract.>139140## Risks & Open Questions141<Unknowns, edge cases, things that could kill the plan mid-execution.142Open questions get tracked here until answered, then deleted.>143```144145## Mapping to Shipcode's Pipeline146147A PRD is read by the planner agent. Every section has a downstream consumer:148149| PRD section | Feeds | Consumer |150|---|---|---|151| Executive Summary | `PlanStructured.objective` | Plan display, PR title, kanban card |152| System Specification | Plan `objective`, `dependencies`, step rationale | Planner + reviewer |153| Goals + Functional Requirements | Plan `steps` | Planner agent decomposition |154| Feature Phase Breakdown | Exactly three ordered plan steps | Planner + task graph execution |155| Success Criteria | `PlanStructured.acceptanceCriteria` | Verification phase |156| Out of Scope | `PlanStructured.outOfScope` | Review phase (rejects scope creep) |157| Project complexity field | `PlanStructured.estimatedComplexity` | Review rubric, retry budget |158| Verification Plan | `buildVerificationPrompt(...)` input | Verification phase |159| Non-Goals + Out of Scope | Review gate | Reviewer rejects patches that violate these |160161**Do not write sections that describe files to change, function names, or implementation choices.** Those belong in the plan, not the PRD. If the PRD author can't resist writing pseudo-code, put it under "Risks & Open Questions" as "I suspect we'll need to touch X" — not as a requirement.162163## Quality Gates164165Before marking a PRD ready for the pipeline to consume, every one of these must be true:166167- [ ] No placeholder text (`TODO`, `TBD`, `<fill this in>`) remains in any section.168- [ ] `Goals` has at least one measurable bullet.169- [ ] `Success Criteria` has at least one bullet, and every bullet is **verifiable without judgement** — it either passes or fails. "Feels fast" is not verifiable. "p95 latency < 300ms on the issues query" is.170- [ ] `Out of Scope` has at least one bullet. Empty `Out of Scope` is a tell that the author didn't scope the feature.171- [ ] `User Stories` has at least one story with explicit Acceptance bullets.172- [ ] `System Specification` names the observable states, data contracts, permissions/trust boundaries, and failure behavior that matter for the feature.173- [ ] `Feature Phase Breakdown` contains exactly three ordered phases, and each phase has a purpose, scope, and completion signal.174- [ ] Every external dependency in `Dependencies` is named (package, PRD path, or URL), not described vaguely.175- [ ] `Verification Plan` names either test file paths, suite names, or concrete manual steps — not "write some tests".176177If any gate fails, keep it in draft/deferred workflow state and do not offer "Start pipeline" in the kanban.178179## Workflow180181### When the user says "write a PRD for X"1821831. **Verify GitHub is connected.** The user must have completed shipcode onboarding with a repo selected. If not, stop and tell them to finish onboarding first — there is no other place a PRD can live.1841852. **Do not start writing immediately.** Run a short elicitation pass first — you need answers before section-filling is meaningful:186 - What problem does this solve, and for whom specifically?187 - What does success look like — how would we measure it?188 - What is explicitly out of scope?189 - What's the complexity gut feel (low/medium/high) and why?190 - Any hard constraints — deadlines, other projects in flight, package boundaries?1911923. **Check for an existing issue.** Run `gh issue list --search "<keywords>" --state all` in the target repo. If a matching issue already exists, ask whether to edit it or create a fresh one.1931944. **Kebab-case the PRD name.** If the proposed name has spaces, camelCase, or punctuation, kebab-case it: `"Notification Center"` → `notification-center`. This slug goes in the `# PRD:` heading.1951965. **Compress the issue title before writing the body.** Default to a short imperative title, then derive the `# PRD:` heading from that final title. Put nuance in the Executive Summary, not the title.1971986. **Draft the PRD body** using the template above, in a scratch buffer. Fill every required section. If you can't fill a section, ask the user — don't hallucinate requirements.1992007. **Run the quality gates** against the draft. If any fail, keep the issue in draft/deferred workflow state and tell the user which gates failed. If they all pass, mark it ready through native project/app state.2012028. **Create the GitHub issue.** Preferred: use the desktop app's Create PRD modal (which calls the `github:create-issue` IPC handler — the handler wraps `gh issue create` and upserts the cache). Alternative for CLI contexts: `gh issue create --title "<Human Readable Title>" --body-file -` with the PRD markdown piped on stdin.2032049. **Confirm the outcome** to the user with the issue URL. Suggest next step: "Ready to hand this to the planner? Click Start pipeline in the kanban, or say: plan issue #N".205206### When the user says "plan the X PRD"2072081. Fetch the current issue body via the cache (`github_issue_cache.body`) or `gh issue view <N> --json body --jq .body` if the cache may be stale. Read it fully before producing anything.2092. Verify the issue is ready through native project/app state — never plan a draft/deferred issue.2103. Translate directly: Executive Summary → objective, Feature Phase Breakdown → exactly three ordered plan steps, Success Criteria → acceptanceCriteria, Out of Scope → outOfScope, project complexity → estimatedComplexity.2114. The plan phase owns file changes and step breakdown — do not copy those out of the PRD (there shouldn't be any).212213### When the user says "update the X PRD"2142151. Fetch the current issue body (prefer `gh issue view <N> --json body --jq .body` to guarantee freshness).2162. Make the requested edit in a scratch buffer.2173. Write it back with `gh issue edit <N> --body-file -` (piping on stdin) or via the `github:edit-issue-body` IPC handler from the desktop app. GitHub tracks the edit history automatically.2184. If the change invalidates an in-flight plan (new acceptance criterion, new out-of-scope item), flag that explicitly to the user — they may want to kill the thread and re-plan. The local `github_issue_cache.body` will be refreshed automatically by the IPC handler; for pure CLI edits, tell the user to click "Refresh from GitHub" in IssueDetail before starting a new plan run.219220## Anti-Patterns221222Observed failure modes from prior sessions — do not repeat:223224- **PRD full of implementation details.** Writing `use TanStack Query v5 for caching` in Functional Requirements. The PRD describes the *what*; the plan owns the *how*. This leaks into review and causes the reviewer to flag the plan for violating the PRD, which the planner then "fixes" by copying the implementation detail verbatim. Dead loop.225- **Success Criteria written as vibes.** "Users should find the flow intuitive." Unverifiable → verification retries forever.226- **Empty Out of Scope.** Always a sign the author is planning to sneak scope in later. Force the listing.227- **Authoring a PRD before the GitHub repo is connected.** If onboarding isn't complete, there is nowhere to put the PRD — finish onboarding first. Do not draft PRDs into scratch files as a workaround; they become orphan documents that drift out of sync the moment the repo is connected.228- **Editing `github_issue_cache.body` directly in SQLite.** The cache is downstream of GitHub, not upstream. Every manual DB edit is overwritten on the next `github:refresh-issues` call. Always edit via `gh issue edit` or the `github:edit-issue-body` IPC handler.229- **Creating a GitHub issue without running the quality gates first.** Quality gates exist because half-formed PRDs thrash the planner and burn verification retries. Running them after you've already created the issue means the issue is public before the gates pass — embarrassing and harder to fix than running them first.230- **Writing a PRD for something you should just ticket.** A typo fix does not need a PRD. A dependency bump does not need a PRD. Reserve PRDs for features and architectural changes that will run through the plan / review / verify / ship pipeline.231232## Minimal Example233234The text below is the exact issue body that gets pushed to `gh issue create --body-file -` (or, equivalently, pasted into the Create PRD modal's body field). GitHub metadata belongs in native fields, not in this body.235236```markdown237# PRD: copy-issue-url-action238239## Executive Summary240Users working in the kanban frequently need to paste an issue URL into Slack,241commit messages, or an external ticketing tool. Today the only way to get the242URL is to click into the issue, then copy from the header — three clicks and243a context switch. Add a "Copy URL" action to the kanban card's context menu244so it takes one click.245246## Problem Statement247Observed on 2026-04-09: the user mentioned needing to paste an issue URL248into a Slack thread five times in a single session, each requiring a detour249through IssueDetail. This is pure friction — the URL is already known.250251## Goals252- Right-clicking a kanban card shows a context menu with "Copy URL".253- Clicking "Copy URL" writes the issue's GitHub URL to the clipboard and254 shows a toast confirming the copy.255256## Non-Goals257- Copying anything other than the URL (title, body, ID — all separate actions258 if demand appears).259- A multi-select "copy all URLs" bulk action.260- Keyboard shortcut for copy — mouse-only for v1.261262## User Stories263- As a developer pasting issue links into Slack, I want to copy an issue's264 URL without leaving the kanban, so that I don't break my flow.265 **Acceptance:**266 - Right-click on a kanban card surfaces a context menu including "Copy URL".267 - Clicking it results in the URL being on the system clipboard.268 - A toast appears within 200ms confirming the copy.269270## System Specification271- Cards expose a context menu action surface without changing click-to-open272 behavior or drag behavior.273- The copied value is the canonical GitHub issue URL for the card's project274 and issue number.275- Clipboard failures surface a user-visible error state instead of failing276 silently.277278## Functional Requirements2791. The kanban card component must support a right-click context menu.2802. The context menu must include an action labeled "Copy URL".2813. The URL written to the clipboard must be the canonical GitHub issue URL282 (the `html_url` returned by the GitHub API, or a deterministically283 constructed `https://github.com/<owner>/<repo>/issues/<N>` equivalent).2844. The toast notification must use the existing UI toast primitive.285286## Non-Functional Requirements287- Clipboard write must succeed or fail cleanly — no silent failures. On288 permission denial, surface an error toast.289290## Feature Phase Breakdown2911. Foundation/spec plumbing — identify the existing kanban action surface,292 URL source, and toast primitive; completion signal is a plan that names the293 exact data source and reusable UI primitive.2942. Primary feature behavior — add the context menu action and clipboard write;295 completion signal is a card action that copies the correct URL.2963. Hardening/verification/shipping polish — cover success and failure paths;297 completion signal is passing focused tests plus manual paste verification.298299## Success Criteria300- Right-clicking any kanban card opens a context menu with a "Copy URL" item.301- Clicking "Copy URL" puts the exact string `https://github.com/<owner>/<repo>/issues/<N>`302 on the clipboard for that issue.303- A success toast appears when the copy succeeds.304- An error toast appears if the clipboard API rejects the write.305306## Out of Scope307- Copying other fields (title, body, branch name).308- Bulk selection + copy.309- Keyboard shortcut bindings.310- A "Share" action that opens the URL in the browser.311312## Dependencies313- The existing UI toast primitive (`@shipcode/ui`).314- `github_issue_cache.issue_number` and the project's `github_repo` for URL315 construction.316317## Verification Plan318- **tests:** `apps/desktop/src/renderer/components/KanbanBoard.test.tsx` —319 add a test that simulates a right-click and asserts the context menu320 includes a "Copy URL" item wired to a mocked clipboard write.321- **manual:** right-click three cards from different projects, paste the322 clipboard into a browser tab, verify the URL loads the correct issue.323324## Risks & Open Questions325- Electron's clipboard API vs the web `navigator.clipboard` — which one does326 the renderer use today? Check the existing implementation before writing327 new clipboard code.328- Do we need a focus-management consideration so that the context menu329 doesn't fight with drag-and-drop handlers on the same card?330```331332Note: no `created`, `updated`, `status`, `complexity`, or `blast radius` fields in the body — GitHub and the project board track those natively. No file path — the PRD lives in the issue body itself. The entire text block above (starting from `# PRD:`) is what gets pasted into `gh issue create --body-file -`.
Run npx skillmds@latest add shipshitdev/writing-prds-3 in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Use when the user wants to draft, scope, or formalize a feature for shipcode — "write a PRD for X", "let's plan X", "scope this out", "what should X do", or when a GitHub issue body needs to be fleshed out before the pipeline plans it. Writes a PRD that maps cleanly onto shipcode's pipeline (objective / acceptanceCriteria / outOfScope / estimatedComplexity) so the planner agent can consume it without re-elicitation. Do NOT use for code edits, debugging, or PR reviews. It is listed under Product & Planning on SkillMD.
This skill has not completed SkillMD's automated safety review yet. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
shipshitdev (@shipshitdev) published this skill. Their other Agent Skills are listed on their SkillMD profile.