원클릭으로
prd-authoring
PRD format conventions, boundary rules, and template references. Load when writing or reviewing product requirements.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
PRD format conventions, boundary rules, and template references. Load when writing or reviewing product requirements.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
TDD cycle process and design-check decision tree for feature implementation. Load when implementing features using test-driven development.
Install or update the claude-pod tooling — the claude-pod command, the pod Dockerfile, the default config, the IDE-oracle preflight, and the egress filter pair — from this repo's tools/claude-pod/ into ~/.local/bin and ~/.config/claude-pod. Thin front-end for tools/claude-pod/install.sh: run its check mode to show drift, apply only on the user's approval. Use when the user asks to install claude-pod, set up the container pod, or update the pod script or image definition. Examples: "install claude-pod", "update the pod tooling", "set up the claude container".
Install or update the harness-stats tooling — harness-statusline.sh, cache-report.sh, and the cache-report skill — from this repo's tools/harness-stats/ into the user's ~/.claude/ directory. Thin front-end for tools/harness-stats/install.sh: run its check mode to show drift, apply only on the user's approval. Use when the user asks to install the cache tooling, set up the statusline, update the harness-stats scripts, or reconfigure cache reporting. Examples: "set up the statusline", "install harness-stats", "update the cache tooling".
Generate a per-agent cache-efficiency report for the current Claude Code session. Use when the user asks about cache stats, cache efficiency, prompt-cache performance, token savings, or whether subagents are using cache effectively. Examples: "show cache report", "how's the cache doing", "cache stats", "are subagents efficient", "which agents are wasting cache", "session token breakdown".
Periodic multi-angle improvement review of the reference. Always fans out all five read-only research agents in parallel — maintainer tooling, documentation, runtime cost, source duplication, consumer surface — so cross-angle tension informs the synthesis. Every agent carries the challenge charter: question the design against the README's stated philosophy, recommend removals that pay for themselves. Judges findings by the resilience-first doctrine; a settled ADR decision is rebuttable with a new argument, never silently suppressed. "/review-harness challenge" drops the ADR anchoring from the agent prompts for a zero-based outside look. Adversarially verifies structural findings and delivers one prioritized report. Assessment only — never edits. Complements /audit-harness, which gates defects against the current bar. Root-only (Claude Code).
Build, test, format, and lint requirements that must pass before code review. Load when checking implementation completeness or running the quality gate.
| name | prd-authoring |
| description | PRD format conventions, boundary rules, and template references. Load when writing or reviewing product requirements. |
| compatibility | ["claude-code","github-copilot","opencode","junie-cli"] |
| reads | ["docs/prd.md","docs/ubiquitous-language.md"] |
| metadata | {"version":"1.0","author":"team"} |
This skill operates inside the middle loop of the four-nested-loop pipeline (inner / middle / outer / architectural). A prd-entry record scopes one slice for the inner loop to implement. See agentic-harness.md for the loop model and the slice definition.
The PRD lives at docs/prd.md. The canonical domain vocabulary lives at docs/ubiquitous-language.md.
The ubiquitous language is durable memory — the agent's vocabulary across sessions and across other developers' agent teams. Treat it as load-bearing.
Inline updates. Domain terms resolve during the root elicitation (agentic-harness.md § Conversations Stay in Root); root loads this skill for it. A term has resolved when the human has committed to a specific word for a specific concept and the conversation has used it intentionally. Root carries every resolved term in the distillate; the product-requirements-expert appends them to docs/ubiquitous-language.md at dispatch, before drafting. Do not drop a resolved term from the distillate; do not defer an append to a second-use gate.
Term-drift challenge. When the human introduces a term that conflicts with an existing entry in docs/ubiquitous-language.md, root calls it out mid-conversation: name the existing definition, name the apparent new meaning, ask which is intended. A drift that reaches the dispatch unresolved returns as pushback, never absorbed silently into the PRD.
Entry format. Each entry has a one-sentence definition; an optional Relationships: line; an optional Avoid: line listing terms-not-to-use for the same concept. An example dialogue at the bottom of the file shows several terms interacting in a worked exchange. See docs/ubiquitous-language.md itself for the format header.
Forbidden: drafting the PRD with terms not in docs/ubiquitous-language.md. If a needed term is missing, write it first.
The PRD describes what the system does. It must not contain how. It must not contain why — rationale lives in ADRs, referenced via the **ADR:** link.
Litmus test (what/how): If it would change when switching to another language, it belongs in docs/system-design.md, not the PRD.
Litmus test (state/history): If it explains why a decision was made (alternatives considered, trade-offs evaluated), it belongs in an ADR, not the PRD.
Discuss the how; record only the what. The boundary governs what you write, not what you discuss. Explore freely how the system might work — that is how the human discovers what they mean. The record carries only requirements and non-goals, never a how. Do not park implementation ideas in the handoff. Mechanism is the design stage's responsibility; the human, present there too, can raise an idea worth keeping. Recording a how, even as a note, pre-empts that stage and leaks mechanism into the requirement.
When the PRD needs to reference implementation details:
**Design:** See [system-design.md#section](system-design.md#section)
When the PRD needs to reference the rationale for a decision:
**ADR:** See [ADR: Title](adr/YYYY-MM-DD-title.md)
Requirements live in docs/prd.md. Each REQ-XX-NNN captures one coherent product capability — what users eventually get. A requirement may carry many acceptance criteria and may take multiple sessions to fully implement. The PRD is the durable, current-complete-state projection of what the system does; it is not segmented by slices.
Slices live in .scratch/handoff.jsonl as prd-entry records. Each record is one unit of implementation work the inner loop can complete in one cycle. Multiple prd-entry records may target the same req_id over time — each shipping one slice of the requirement.
A prd-entry record may carry a subset of its REQ-XX-NNN's acceptance_criteria — the subset that's being implemented in this round. The PRD entry stays domain-coherent; the handoff record stays inner-loop-sized.
The slice rule applies to prd-entry records (units of work), not to REQ entries (units of intent). Each prd-entry is a right-sized vertical slice — it cuts through every architectural layer the behavior actually touches, and is small enough to ship in one inner-loop sequence while large enough that coordination overhead pays for itself.
A right-sized vertical slice satisfies all six:
acceptance_criteria you include ship as a single unit — no useful subset ships earlier.title would make sense to a stranger reading it cold — "User can log in with email and password," not "Add a login handler").Both ends of the size range are failure modes:
acceptance_criteria could ship standalone and be useful, append a second prd-entry record covering the second slice (same req_id if the REQ holds together — you're slicing one requirement across multiple work cycles; a new req_id if the REQ itself needs splitting); (2) if the slice spans multiple deliverable surfaces, split by surface — each surface becomes its own prd-entry.prd-entry covering the combined work instead of two trivial ones. Siblings may share a req_id or live under related REQs.Slice-sizing is enforced at this skill (write-time, when authoring a prd-entry); the next skill applies the same tests at selection time. See agentic-harness.md for the full loop model and the two-layer model.
| Pattern | Severity | Fix |
|---|---|---|
| Implementation code blocks in the PRD | Critical | Move to system-design.md, link from PRD |
| Framework- or language-specific constructs | Critical | Describe behavior, not mechanism |
| Rationale prose (paragraphs explaining why a requirement or non-goal exists) | Critical | Move reasoning to an ADR; reference via the **ADR:** link (link only, no inline reasoning) |
| A blanket exemption that tells reviewers to skip a check (e.g. "doc-reviewers may skip the rationale-prose check here") | Critical | A document cannot grant itself an exemption. Fix the content or raise a per-instance escalation; never disable a reviewer check wholesale |
| Mechanism tables — CLI flag tables, exit-code tables, output-directory layouts, on-disk/file-format schemas | High | Move to system-design.md; state the behavior in prose and link with **Design:** |
Per-requirement contract scaffolding (Input / Output / Constraints / Depends On blocks) | High | Field tables in disguise — state the outcome in a "Done when" bullet; the signature lives in source, the constant in system-design.md |
| Internal code references (type, method, variable names) | High | Use behavioral language |
| Algorithm formulas or pseudocode | High | State behavioral constraints, move formulas to system-design.md |
| Low-level implementation constructs (concurrency primitives, regex, framework APIs) | High | Describe behavior, not mechanism |
| Hardcoded constant values | Medium | Reference a Constants section in system-design.md (create the section on first constant) |
The PRD is narrative prose, not a catalog of structured entries. Write each capability area as a few sentences a newcomer reads top to bottom, and annotate each requirement inline with its ID where the prose expresses it. The prose carries intent; a short "Done when" list carries the bounded, testable contract.
This keeps the PRD human-readable and agent-parseable at once. It retires the per-requirement scaffolding — Input, Output, Constraints, Depends On — that duplicated the prd-entry handoff record and rotted against source (those are field tables in disguise; see § Prohibited Patterns).
... the tool runs as one command `[REQ-XX-NNN]`, and discovers configuration by precedence `[REQ-XX-MMM]`. IDs follow REQ-[A-Z]+-[0-9]{3} — exactly three digits, the pattern every handoff schema and gate enforces.<a id="req-xx-nnn"></a> (lowercase, hyphenated) on its own line, so ADRs and system-design deep-link to prd.md#req-xx-nnn.[REQ-ID] and states one bounded outcome in plain given/when/then language. The bullet is the contract — the prose is context, the bullet is what "done" means and what the fresh-eyes reviewer judges against. Every REQ-ID must appear in at least one bullet (the doctor's req-acceptance check enforces this).**ADR:** [ADR: Title](adr/...) for the decision trail; **Design:** [system-design.md#section](system-design.md#section) for mechanism. Each only when it exists.**Edge cases:** list beside "Done when", one bounded case per item. The numbering is stable and citable: test comments reference it, the test-reviewer checks each number has a dedicated test, and the system-design expert verifies the design accounts for each. This list is the "documented edge cases" every downstream stage names.<a id="req-xx-nnn"></a>
The tool runs as a single automatic command: one invocation reads transcripts,
updates the manifest, and regenerates every report `[REQ-XX-NNN]`. Configuration
resolves by precedence — an explicit flag wins, otherwise built-in defaults
apply, and a flag pointing at a missing file is materialized, not failed
`[REQ-XX-MMM]`.
**Done when:**
- `[REQ-XX-NNN]` a no-flag run scans the default input, writes the reports, and
prints a one-screen summary; an unknown flag exits with a usage error.
- `[REQ-XX-MMM]` a flag value overrides the built-in default; a missing flagged
path is created with defaults, not an error.
**ADR:** [ADR: CLI surface](adr/2026-01-01-cli-surface.md) · **Design:** [system-design.md#cli](system-design.md#cli)
A requirement is active by being in the narrative — there is no per-requirement Status field and no synonym set to maintain. Retire a requirement by moving its ID to a ## Superseded list that maps it to its successor (or the reason it was withdrawn), so existing links still resolve. Never renumber an ID. The **ADR:** link is mandatory whenever an ADR records the decision behind the requirement; the **Design:** link is mandatory whenever the requirement defers a mechanism to system-design.md.
Before working on the dispatch's main task, audit every type: "prd-autofix" record in .scratch/handoff.jsonl whose ts is later than your most recent type: "prd-entry" record (or any such record if you have not yet appended one). handoff.py audit-autofix (the code-quality-gate skill's autofix audit) has already re-checked the allowlist bounds mechanically; your job is the judgement check.
For each record, decide whether the change is legitimately mechanical:
For every illegitimate record:
docs/prd.md yourself — you own the file.prd-entry for the affected req_id, noting the rejection in notes: "autofix-rejected: <handoff.jsonl line N>: <reason>". The design re-triage this triggers is deliberate — a semantic PRD change always re-enters the pipeline at Gate 1.If every audited record is legitimate, skip silently — no entry needed. If the log contains no prd-autofix records, skip silently.
When a feature is approved, append one record to .scratch/handoff.jsonl describing the scope. The record is the structured contract that system-design-expert consumes; the markdown PRD entry in docs/prd.md remains the human-authored source of truth.
File: .scratch/handoff.jsonl (append-only; one JSON object per line, terminated by \n).
Schema: schemas/scratch/prd-entry.schema.json. The routing gate (handoff-routing Gate 1) validates each record at the product-requirements-expert→system-design-expert transition; malformed records bounce back to you without consuming a system-design-expert dispatch.
Required fields:
| Field | Type | Notes |
|---|---|---|
type | "prd-entry" | Discriminator. |
req_id | string ^REQ-[A-Z]+-[0-9]{3}$ | Matches the PRD heading. |
ts | ISO 8601 string | Stamped by append; never composed by the author. |
author | "product-requirements-expert" | Pinned. |
title | string | Short requirement title. |
summary | string ≤ 400 chars | One- or two-sentence statement. No implementation details. |
acceptance_criteria | array of strings | Testable conditions. At least one. |
file_targets | array of strings | Paths likely to be touched. At least one. Best-effort; system-design-expert may revise. |
test_names | array of strings matching test_name_pattern from scripts/layout.toml | Test functions/methods expected to exist, matching test_name_pattern. At least one. Naming school: docs/testing-principles.md § Test Naming. |
Optional fields: non_goals, dependencies (other req_ids), notes.
Append-only discipline: Append records via python3 scripts/handoff.py append prd-entry (heredoc form per the handoff-append skill). Never edit, reorder, or delete prior records. If a prior record has a mistake, append a new record that supersedes it.
Why JSONL, not markdown: the structural-rejection gate this enables converts system-design-expert retries into cheap upstream bounces before a subagent dispatch is consumed.
{"type":"prd-entry","req_id":"REQ-XX-099","author":"product-requirements-expert","title":"Cache miss diagnostics","summary":"Surface per-component cache miss rate so operators can spot reinjection hotspots.","acceptance_criteria":["report renders the cache-miss-rate per component","value matches cache-creation / (cache-creation + cache-read)"],"file_targets":["report/summary","report/summary_test"],"test_names":["<name matching test_name_pattern>"],"non_goals":["historical trend"]}
The test_names value is a placeholder: use names matching this project's test_name_pattern in scripts/layout.toml — the append gate rejects any other shape.
Follow the writing standards in the document-writing skill — the language-agnostic rulebook the doc-reviewer enforces.