Repository context. Gather first
Collect these with individual Bash calls, one command per call, never combined into a single invocation:
- Current branch,
git branch --show-current - Recent commits,
git log --oneline -5 - Working tree status (empty = clean),
git status --porcelain | head -10
The pipe is the bound and belongs in the command. A read-time cap ("read only the first 10 entries") bounds nothing: the Bash tool returns the command's complete output into context before there is anything to decide about.
Treat a failure (not a repository, git unavailable) as an unknown value and carry on. Keep these as separate body Bash calls rather than pre-compute lines: the harness runs a skill's whole pre-compute block as one shell invocation, and a worktree-isolated session refuses a compound command that contains git. The dated record for that composition claim is the worktree skill's reference/gather-block.md, "The pre-compute block runs as one shell invocation".
Variables
Arguments: $ARGUMENTS
Purpose
Most product-feature rework comes from skipping the what for whom and why layer and jumping straight to how. /planning:prd produces the lockable product intent contract: what we are building, for which users, against what measurable success, before any engineering plan, exploration, or research begins.
This is the product-intent stage. Upstream of exploration, upstream of /planning:plan, and may run before or alongside /planning:interview depending on task shape:
/planning:prd. Answers what should we build, for whom, and why. Outcome-focused. Required for new user-facing features, business-driven changes, cross-team initiatives/planning:interview. Answers what is the engineering contract for this task. Constraint and acceptance-criteria focused. Required whenever intent is fuzzy or underspecified, regardless of source- Complementary, not redundant. A product feature usually wants both:
/planning:prd(product intent) →/planning:interview(engineering contract) → exploration → research →/planning:design→/planning:plan. Engineering-internal work skips/planning:prdentirely
The PRD is never an implementation plan. Boundaries: problem, users, success. Yes. Architecture, files, tests, code shapes. No. That is /planning:plan's job. If the user pulls toward implementation mid-PRD, anchor back to what for whom and let /planning:plan pick up after.
Cost framing: locking product intent up-front is the cheapest version of the conversation. Every later session that runs against a written PRD costs less than one that infers product goals from a half-formed thought.
Trigger conditions. When to invoke /planning:prd
Invoke /planning:prd when ALL of these are true:
- The work has a user-facing surface. New feature, new screen, new flow, new public API, new external behaviour
- The change is business- or product-driven. Solves a user problem, opens a market, hits a metric. Not engineering-internal cleanup
- Alignment matters. Multiple stakeholders, cross-team work, or you want a written reference to point the future agent at
Skip conditions. When to NOT invoke /planning:prd
If ANY of these hold, do NOT write a PRD. Tell the user explicitly: "This is engineering-internal. No PRD. Recommend /planning:interview (if intent is fuzzy) or /planning:plan (if it's clear)."
- Refactors (no behaviour change)
- Infrastructure (build, CI, hooks, config, dependency bumps, lockfiles)
- Conventions (rules files, doc updates, lint rules, analyzers)
- Bug fixes (a bug already implies the desired behaviour. Fix the gap, no PRD)
- Single-team engineering work with no user-visible surface
- Tooling, scripts, internal automation
- Documentation-only changes
If ambiguous (could go either way), surface the question once and let the user pick. Never silently write a PRD for an engineering-internal task.
Action Router
Parse $ARGUMENTS to determine the action. Tier choice can be passed as the first argument; if absent, ask for it (surface rules below).
| Argument | Action | Use case |
|---|---|---|
| (empty) | Smart default | If a prior PRD exists for the topic, offer resume/revise/start-fresh. Otherwise prompt for tier + task. |
<task description> (no tier word) |
Full PRD, prompt for tier | Run skip-condition check, then ask which template tier (one-pager / consumer-feature / B2B-internal). |
one-pager <task> |
Tier 1. Thin one-pager | Small feature, single team, fast lock. ~½ page. |
consumer <task> or consumer-feature <task> |
Tier 2. Consumer feature | User-facing app feature with metrics, user stories, risk surface. ~1 page. |
b2b <task> or b2b-internal <task> |
Tier 3. B2B / internal | Stakeholders, compliance, integration, rollout, change-management. ~2 pages. |
synthesize <task> |
Synthesis-only PRD | Skip Q&A. Produce PRD from existing conversation context. Use when conversation already has rich product context and re-asking would waste the user's time. Still runs skip-condition check (Step 1) and survey (Step 2). |
review |
PRD review | Critique an existing PRD.md against template + skip-conditions. |
Tier choice rationale lives in context/templates.md. When tier is unclear from the task description, present the three tiers with one-line descriptions. Via AskUserQuestion when the plugin's use_ask_user_question user config (${user_config.use_ask_user_question}) is on (the side-by-side rendering helps the user choose without skimming docs), numbered inline prose otherwise.
The PRD process
Step 1. Skip-condition check (MANDATORY)
Before any other work, validate the request matches the trigger conditions. If it matches the skip conditions, STOP and tell the user:
"This looks engineering-internal (
<reason>). PRDs add cost without value here. Recommend:/planning:interviewfor fuzzy intent OR/planning:plandirectly if scope is clear."
Do not proceed unless the user explicitly overrides ("write the PRD anyway") OR clarifies the user-facing/business framing.
Step 2. Survey before you write
Spend the first turn grounding yourself, in parallel:
- Read the consuming project's
CLAUDE.mdandAGENTS.mdfor product direction and current modules - Climb to the nearest domain-vocabulary file (e.g.
UBIQUITOUS-LANGUAGE.md) if the project keeps one and the topic touches a known module. Walk UP from the relevant directory toward repo root and stop at the first match GlobandGrepfor keywords from$ARGUMENTSto spot existing surfacesgit log --oneline -20for recent product direction- List the project's own rules files that govern the area (architecture, modules, conventions)
- Note what the topic's contract slice
<contract_dir>/<topic-slug>/(defaultdocs/topics/) already contains, prior PRD, PLAN, design artifacts, and what its memory slice<memory_dir>/<topic-slug>/(default.work/) holds (exploration/research artifacts)
If a prior PRD.md exists for this topic, ask: resume (continue from open questions), revise (in-place edits, bump updated:), or start fresh (append a dated restart note capturing why below the PRD's frontmatter, then rewrite; the commit carrying the rewrite states the pivot rationale. The contract is branch-tracked, so git log is the history).
Survey output is a one-paragraph summary in your reply. Then transition to frontier-rounds Q&A.
Step 3. Pick the template tier
If not specified in $ARGUMENTS, surface the tier choice (card only under the use_ask_user_question opt-in; numbered prose otherwise):
| Tier | When |
|---|---|
| 1. One-pager | Small feature, single team owns it, low ambiguity. ~½ page. Sections collapsed; one-line each. |
| 2. Consumer-feature | User-facing app feature with metrics, 1-2 user stories, risk surface. ~1 page. Full sections. |
| 3. B2B-internal | Internal/B2B feature with stakeholders, compliance, integration, rollout, change-management. ~2 pages. Full sections + stakeholders, rollout, dependencies/integrations. |
Tier governs section depth, not section presence. All three tiers cover the same seven required sections (problem, goals, non-goals, users + user stories, success metrics, dependencies/risks, open questions). The difference is verbosity.
Full templates: context/templates.md. Read on demand. Keep main context light.
Step 3.5. Synthesis-only path (synthesize)
When invoked with synthesize, skip Step 4 Q&A entirely. Produce the PRD from existing conversation context. Prior discussion, explored files, research findings, user statements already captured in the session. Still runs Step 1 (skip-condition check) and Step 2 (survey grounding).
Use when conversation already contains rich product context and re-asking would waste time. The user is signaling "I've told you enough. Write it." Respect that signal.
synthesize also skips the always-on coverage prompt and reports it unexamined, per "Acceptance-criteria capture" below.
If after the survey (Step 2) a required section has NO answerable content in the conversation, note it as an open question rather than forcing Q&A. The PRD with open questions is still useful. /planning:interview or /planning:plan picks them up downstream.
Step 4. Drive frontier-rounds Q&A
Skipped when synthesize action was invoked. Go directly to Step 5.
Ask in frontier rounds: each round surfaces every open question whose prerequisites are settled as one numbered set (grouped by PRD section), each with a recommendation; a question that depends on another still open waits for the round after its prerequisite resolves. Render a round via AskUserQuestion only when the plugin's use_ask_user_question user config (${user_config.use_ask_user_question}) is on and the round is ≤4 independent questions. Inline prose otherwise.
Question shapes that recur, in priority order:
| Section | Highest-value surfacing question |
|---|---|
| Problem | "Whose problem is this, and what do they currently do instead?" |
| Goals | "If we ignore implementation, what changes for the user when this ships?" |
| Non-goals | "What is explicitly out of scope so we don't drift?" |
| Users | "Who is the primary user. One persona or many? Walk me through their day before and after." |
| User stories | "Pick the one most-important journey: as a <role> I want to <action> so that <outcome>." |
| Success metrics | "How will we know it worked? Name the metric and the threshold. Adoption %, conversion %, time saved, error rate." |
| Acceptance-criteria coverage | Asked once, per "Acceptance-criteria capture" below. Never one question per criterion. |
| Dependencies / risks | "What outside this team must exist or change for this to ship? What's the biggest risk?" |
| Open questions | "What is genuinely undecided that /planning:plan needs an answer to?" |
Stop asking once every required section has either a resolved answer or an explicit "open question with revisit trigger".
Step 5. Persist the PRD
Derive <topic-slug> from the task description or current branch name (kebab-case, ≤40 chars). The same slug /planning:interview, /planning:design, and /planning:plan will use for this topic. Write to <contract_dir>/<topic-slug>/PRD.md (default docs/topics/). The topic's contract slice, committed on the task branch as it locks; under contract_tier: local it joins the memory slice instead. Roots, tier, and precedence resolve per the topic-docs binding ${CLAUDE_PLUGIN_ROOT}/reference/topic-docs.md. PRD.md lives alongside PLAN.md (the plan skill's output) and the topic's design artifacts.
Frontmatter:
---
status: draft # draft | locked | superseded
tier: one-pager # one-pager | consumer-feature | b2b-internal
created: <ISO-8601 UTC, e.g. 2026-06-04T14:30:00Z>
updated: <ISO-8601 UTC, e.g. 2026-06-04T14:30:00Z>
---
Required sections (every tier. Verbosity varies):
- Problem. What is broken, missed, or unmet for users today
- Goals. Outcome-level, not implementation-level
- Non-goals. Explicit out-of-scope items
- Users. Primary persona(s) + 1-2 user stories in
as a <role>, I want <action>, so that <outcome>form - Success metrics. Named metric + threshold + measurement window
- Dependencies / risks. Outside-team dependencies + top 1-3 risks with mitigations
- Open questions. Anything genuinely undecided that
/planning:planneeds answered
Tier-3 (B2B) adds: Stakeholders, Rollout, Compliance / integration.
Durability over precision. PRD content describes interfaces, types, and behavioural contracts. Never file paths or line numbers, which go stale before the PRD does. Do not write as if the current implementation structure will persist; the PRD should still read true after a refactor.
Written for a product owner who scans. Each section opens with its point and carries no more words than the meaning needs: invoke /writing:be-concise via the Skill tool when the writing plugin is installed; otherwise apply that discipline inline. The seven required sections, the tier's depth, and every metric, threshold, and open question stay as they are.
Non-goals graduation edge. A non-goal that is a permanent, deliberate rejection, not a deferral, outlives the PRD: graduate it to the consuming repo's rejected-concept ledger at docs/out-of-scope/<concept>.md, one file per concept, accreting a "Prior requests" log entry each time the concept resurfaces, so future proposals of the same concept get answered by the ledger instead of relitigated. This is a consumer convention with graceful degrade: create the file lazily on first permanent rejection; when the consumer keeps no ledger, the plain Non-goals list suffices.
Test-seam sketching (where the feature will be tested, and at how few seams) is not a PRD concern. It happens in /planning:design as a design thread.
Full template structures: context/templates.md.
Optionally offer to render the finalized PRD as a self-contained HTML pitch view for non-engineer stakeholders: a static generated view, never an editor with real data bound in. PRD.md stays the tracked record. It lands in the topic-docs ephemeral tier, never the contract slice beside PRD.md; placement and rules: ${CLAUDE_PLUGIN_ROOT}/reference/topic-docs.md.
Step 6. Hand off
After writing the PRD, recommend the next step. The recommendation depends on remaining ambiguity:
- Engineering scope still fuzzy (constraints, untouchable areas, perf budget unclear) → clear context, then
/planning:interview(it will read the topic'sPRD.mdas scope) - Engineering scope is clear, codebase grounding needed →
/discovery:exploreif installed, otherwise whatever codebase-exploration capability the environment provides - Need external research (libs, APIs, comparables) →
/discovery:researchif installed, otherwise the strongest research capability available - Engineering scope clear and externals understood →
/planning:plan
Do NOT auto-clear or auto-invoke. Recommend; let the user pull the trigger.
Acceptance-criteria capture
Two behaviours ride on the moment this PRD turns product intent into verifiable statements, the Step 4 success-metrics and user-story rows and any acceptance criterion the run writes down. The first is always on; the second fires only when the consuming team's convention selects it.
Coverage prompt. Always on, asked once
While capturing those verifiable statements, ask ONE question: are they missing an
unwanted-behaviour case (an IF <trigger>, THEN <response> criterion) and a state-driven
case (a WHILE <state>, <response> criterion)? One prompt covering both, never a per-criterion
interrogation, and "neither applies" is a valid answer that closes it for the session. This runs
whatever the acceptance-criteria format resolves to, and with no convention surface present at all;
it is a coverage check, not a format. A product PRD reaches for the happy path by construction, and
this is the one question that asks what must NOT happen.
Non-interactive runs skip the ask and say so
The synthesize action skips it, along with any run that has nobody to answer: a dispatched
worker, a forked subagent, a headless invocation, or any caller that declared the run unattended. In
every one of those the ask is SKIPPED rather than blocking, and the returned summary states that
unwanted-behaviour and state-driven coverage went unexamined. Record the same line in the PRD's
Open questions section so it outlives the summary. A prompt nobody can answer must not stall the
run and must not silently vanish.
The unattended condition is declared by the caller, never sniffed. There is no supported way for
a session to observe that it is non-interactive, so never read an environment variable to decide it;
synthesize is an explicit argument, which is a declaration.
EARS tags, when the convention selects them
Resolve acceptance_criteria_format per the ladder below. Under free-text, the default and every
degrade, every section is emitted exactly as today, untagged and byte-comparable in shape to a run
with no convention surface at all. Under ears, each acceptance criterion this run emits carries a
bracketed pattern prefix on a plain bullet:
| Tag | Pattern |
|---|---|
[ubiquitous] |
an always-true requirement, no trigger and no state |
[event-driven] |
WHEN <trigger>, <response> |
[state-driven] |
WHILE <state>, <response> |
[unwanted-behaviour] |
IF <trigger>, THEN <response> |
[optional-feature] |
WHERE <feature is included>, <response> |
- [event-driven] WHEN the upload completes, the manifest is rewritten
- [unwanted-behaviour] IF the upload fails, THEN the partial manifest is discarded
The five names are exactly ubiquitous, event-driven, state-driven, unwanted-behaviour, and
optional-feature. A downstream reader matches the literal name, so a variant spelling,
unwanted-behavior, unwanted, event, is not a near miss; it is an untagged criterion that looks
tagged, and it fails silently.
Scope, stated plainly. The seven required sections carry no acceptance-criteria list of their
own, and this change adds none: the Success metrics table is a measurement with a threshold and
a window, not an EARS pattern, and it stays a table under both formats. Tags attach to acceptance
criteria this run writes as plain bullets, and the durable home for tagged criteria is the Brief
/planning:interview locks downstream. What this skill owes is the coverage question, the exact
vocabulary, and the same resolution, so that a PRD-then-interview pipeline does not change its
answer halfway through.
Resolution ladder for acceptance_criteria_format
Restated here rather than cited: an installed plugin never sees the publishing repository's convention docs, so a path citation would make that publisher a runtime dependency of this session.
1. Anchor at the repository root: `${CLAUDE_PROJECT_DIR}` when set, otherwise
`git rev-parse --show-toplevel`. Never a CWD-relative read.
2. Resolve the convention home `<home>` from the pointer line in the marked
`<!-- BEGIN GENERATED: convention-home -->` region of the root instruction file
(`AGENTS.md` canonical; `CLAUDE.md` unless it is a pure `@AGENTS.md` shim). Use the
bundled resolver where the plugin ships one; never hand-parse the root file.
3. The printed home is repo-relative: join it to the root resolved in step 1,
then read `<home>/authoring-formats/README.md` from that path and take the
key's value from its fenced YAML block.
4. Layer order is one layer deep: an explicit invocation argument, where the skill has
one, then the team convention doc, then the documented default. A convention-doc
surface has no personal overlay, so there is no further layer to consult.
5. Default: `acceptance_criteria_format` is `free-text` — emit untagged criteria,
exactly today's shape.
6. Degrade soft, and say so. No pointer line, no convention home on disk, no
`authoring-formats/README.md`, no YAML block, an absent key, or an unrecognized value
each resolve to the documented default. Name the cause in one clause and continue;
never hard-fail, and never ask the operator to create the surface mid-task.
7. Report provenance whenever the resolved value shapes output: name the key, the value,
and the layer it came from — `argument`, `team convention doc <path>`, or `default`.
This plugin ships the step-2 resolver at
bash "${CLAUDE_PLUGIN_ROOT}/lib/resolve-convention-home.sh": exit 0 prints the home on stdout,
exit 1 means no pointer line is bound, exit 2 is usage, and exit 3 is a FAIL (two pointer lines
in one region, an unterminated or nested region, an invalid pointer path, or a pointer whose
target directory does not exist). Every non-zero exit is a
step-6 degrade, free-text, cause named in one clause, never a halt and never a prompt to go create
the surface.
PRD review mode (review)
When invoked with review:
- Locate the topic's
PRD.md(use slug derivation above) - Evaluate against the seven required sections. Flag any missing or fuzzy
- Evaluate against skip-conditions. Should this PRD even exist? If engineering-internal, recommend supersession with a
/planning:interviewbrief - Check goals are outcomes, not implementations (the most common failure mode)
- Check success metrics have a measurement window and threshold, not vague language
- Present findings: what's strong, what's missing, what to revise
Complementary to /planning:devils-advocate. Review checks structure and convention; stress-test (run later against /planning:plan's plan, not the PRD) checks failure modes.
What this skill does NOT do
- Does not plan implementation. The PRD is what for whom and why. Architecture, files, tests, code is
/planning:plan's job. If you find yourself writing "we'll addXHandlerto module Y", stop and move that to the open-questions section as an architecture decision for later - Does not run exploration or research. Step 2's survey is a fast grounding pass, not deep work. If product framing requires deep external research (competitive analysis, market data), pause the PRD and recommend the research capability first
- Does not gate other skills. Engineering-internal tasks skip
/planning:prdentirely. Even product features can skip if intent is already locked elsewhere (existing roadmap doc, recent ADR, prior PRD) - Does not adversarially attack the user's product idea. Not the PRD's role. If the proposed feature has obvious product risk, surface it once in the risks section and continue. Pushback belongs in product review, not PRD authoring
- Does not write code, run tests, or modify anything outside the topic's contract and memory slices. Pure product-intent skill
- Does not export Gherkin. Named as a deferred extension point so its absence reads as a decision rather than an oversight: nothing here emits
.featurefiles orGiven/When/Thenscenarios, and the EARS tags are a bracketed prefix vocabulary on a plain bullet, not a step grammar. A Gherkin export is a separate slice against a separate contract, and none of it is built here
Composition with other skills
| When | Skill | How it composes |
|---|---|---|
| Pre-PRD: problem still rough, no candidate approach chosen | /planning:brainstorm |
Diverges cheapest→most-ambitious candidates; the resonating direction feeds this PRD |
| Pre-task: product feature, fuzzy intent | /planning:prd (this) |
Produces the topic's PRD.md |
| Pre-task: any fuzzy task. Including post-PRD constraint discovery | /planning:interview |
Produces the Brief in PLAN.md (reads PRD if present) |
| Need codebase grounding | /discovery:explore (if installed) |
Reads PRD + PLAN as scope |
| Need external evidence | /discovery:research (if installed) |
Reads PRD + PLAN as scope |
| Need design exploration (types, contracts, topology) | /planning:design |
Reads PRD + PLAN; produces design artifacts that /planning:plan consumes |
| Plan the implementation | /planning:plan |
Reads PRD + PLAN + explore + research findings |
| Stress-test the plan | /planning:devils-advocate |
Adversarial pass on /planning:plan output (not the PRD) |
/planning:prd is sister to /planning:plan: one resolves what for whom and why; the other resolves how. They share the topic slug, share the contract slice, and feed each other.
Gotchas
- Goals as outcomes, never implementations. "Add a search box" is not a goal; "users can find a song from any of its lyrics in <2 seconds" is. Most common PRD failure: goals that pre-decide the architecture
- Success metrics need a window. "Increase engagement" is not a metric; "DAU/MAU rises from X to Y over 30 days post-launch" is. If a metric has no number and no window, it can't validate the feature
- Don't write a PRD for engineering-internal work. Skip-condition check is mandatory. PRDs for refactors, hooks, lint rules waste cycles and dilute the convention
- Tier governs verbosity, not which sections exist. All three tiers have the same seven required sections. Tier-1 is one line per section; tier-3 is a full paragraph. Don't drop sections to "save time". Drop words
- The PRD is never an architecture document. When discussion drifts to implementation, anchor back to what for whom. Capture architecture questions in the open questions section for
/planning:planto resolve - Resume vs revise vs start-fresh on prior PRDs. Never silently overwrite. If scope shifted, append a dated restart note capturing why before rewriting