PRD to Issues
If running interactively (human present), output "Read PRD to Issues skill." to acknowledge. If running with --dangerously-skip-permissions (AFK/unattended), skip acknowledgement and proceed directly.
Pipeline position: /grill-me → /write-a-prd → /architect → /prd-to-issues → /do-work → shft
Use this skill to create GitHub issues from a finalized PRD or plan. Use /architect for deeper analysis and planning before issue creation.
Process
Locate the PRD — find the PRD wherever it exists (GitHub issue, local file, or in the conversation).
Explore the codebase — understand the existing architecture, conventions, and relevant code paths needed to break the work into slices.
Draft vertical slices — break the PRD into tracer bullets (vertical slices). Each slice should wire through all layers end-to-end rather than building horizontally (all backend → all UI → all routes). Phase 1 should always be the simplest possible end-to-end wiring.
Categorize each slice:
- AFK — can be implemented and PR-opened autonomously. Merging stays a human gate (someone applies
agent:merge); "AFK" does not mean auto-merged. Prefer AFK where possible.
- Human-in-the-loop (HITL) — requires human interaction such as an architectural decision, design review, or taste judgment, before or during implementation.
Create a QA issue — always create a final issue with a detailed manual QA plan for all items that require human verification. This is the last issue in the dependency chain.
Quiz the user — present the proposed breakdown and ask:
- Does the granularity feel right?
- Are the dependency relationships correct?
- Should any slices be split further?
- Are the correct slices marked as HITL vs AFK?
Create GitHub issues — create them as independent issues (not sub-issues — see Native dependencies below), then wire labels and dependencies so they enter the Sandcastle pipeline.
a. Bodies — generate each issue from the template below. Pass bodies via --body-file (a temp file, or --body-file - from a quoted here-doc <<'EOF') or the GitHub MCP mcp_github_issue_write (method create_issue, no shell escaping). Do not put Markdown bodies with backticks in unquoted shell variables or here-docs — the shell executes command substitutions and corrupts the body.
b. Pipeline labels — this is how the issues actually enter the pipeline (full contract: instructions/sandcastle-pipeline.instructions.md):
- First unblocked AFK slice →
Sandcastle (starts review → plan → implement → PR autonomously).
- Other AFK slices that have blockers →
agent:queued (agent-promote-queued flips them to agent:implement when their blockers close).
- HITL slices, and any unblocked-but-not-first AFK slice → no pipeline label (a human starts them).
agent:queued only auto-releases when a blocker closes, so an unblocked slice can't be queued — nothing would release it. Give exactly one unblocked slice the Sandcastle start and leave other unblocked ones unlabeled to bound the blast radius (N Sandcastle labels = N concurrent agent runs against the proxy). You run locally with your own gh PAT, so labels you apply do trigger workflows — inside a workflow, label writes need AGENT_PAT because GITHUB_TOKEN-applied labels don't re-trigger.
c. Native dependencies — encode "blocked by" as native GitHub issue dependencies, never body text. agent-promote-queued reads the native blockedBy/blocking relation and refuses sub-issues (hence independent issues, not children). Add each edge with the blocking issue's REST numeric id (gh api repos/$OWNER/$REPO/issues/N --jq .id — not gh issue view --json id, which returns the GraphQL node id), never its issue number:
# $DEP blocked_by $BLOCKER (issue_id = the blocking issue's DB id)
MSYS_NO_PATHCONV=1 gh api -X POST "repos/$OWNER/$REPO/issues/$DEP/dependencies/blocked_by" -F issue_id="$BLOCKER_DB_ID"
The **Blocked by:** #N line in the template is human-readable only — the native edge is what the automation reads.
# [Slice Title]
**Type:** AFK | HITL
**Parent PRD:** #[issue-number]
**Blocked by:** #[issue-number], #[issue-number]
## Description
[What this slice accomplishes end-to-end]
## Acceptance Criteria
- [ ] [Specific, testable criteria]
Pipeline handoff
The created issues plug into the Sandcastle label state machine — full contract in
instructions/sandcastle-pipeline.instructions.md. In short: Sandcastle on the first AFK slice
starts the autonomous chain (review → plan → implement → PR); agent:queued + native deps let
agent-promote-queued release dependents as blockers close; and merge stays a human gate
(agent:merge) at the end of every PR. HITL slices wait for a human to apply Sandcastle.
Handoff
After issues are created, offer:
/do-work — start implementing the first slice
- Save plan to
working/ — if context is high or multi-session work, follow the standard handoff protocol (@~/dotfiles/instructions/handoff.instructions.md) to persist the issue list and dependency order. Include @-references to the parent PRD issue.
1---2name: prd-to-issues3description: Break a PRD into independently grabbable GitHub issues with dependency relationships. Use when asked to 'break this PRD into issues', 'create issues from PRD', 'plan the work', 'create a kanban', or after writing a PRD to prepare work for execution.4---56# PRD to Issues78If running interactively (human present), output "Read PRD to Issues skill." to acknowledge. If running with --dangerously-skip-permissions (AFK/unattended), skip acknowledgement and proceed directly.910Pipeline position: `/grill-me` → `/write-a-prd` → `/architect` → **`/prd-to-issues`** → `/do-work` → `shft`1112Use this skill to create GitHub issues from a finalized PRD or plan. Use `/architect` for deeper analysis and planning before issue creation.1314## Process15161. **Locate the PRD** — find the PRD wherever it exists (GitHub issue, local file, or in the conversation).17182. **Explore the codebase** — understand the existing architecture, conventions, and relevant code paths needed to break the work into slices.19203. **Draft vertical slices** — break the PRD into tracer bullets (vertical slices). Each slice should wire through all layers end-to-end rather than building horizontally (all backend → all UI → all routes). Phase 1 should always be the simplest possible end-to-end wiring.21224. **Categorize each slice:**23 - **AFK** — can be implemented and PR-opened autonomously. Merging stays a human gate (someone applies `agent:merge`); "AFK" does **not** mean auto-merged. Prefer AFK where possible.24 - **Human-in-the-loop (HITL)** — requires human interaction such as an architectural decision, design review, or taste judgment, before or during implementation.25265. **Create a QA issue** — always create a final issue with a detailed manual QA plan for all items that require human verification. This is the last issue in the dependency chain.27286. **Quiz the user** — present the proposed breakdown and ask:29 - Does the granularity feel right?30 - Are the dependency relationships correct?31 - Should any slices be split further?32 - Are the correct slices marked as HITL vs AFK?33347. **Create GitHub issues** — create them as **independent issues** (not sub-issues — see *Native dependencies* below), then wire labels and dependencies so they enter the Sandcastle pipeline.3536 **a. Bodies** — generate each issue from the template below. Pass bodies via `--body-file` (a temp file, or `--body-file -` from a quoted here-doc `<<'EOF'`) or the GitHub MCP `mcp_github_issue_write` (method `create_issue`, no shell escaping). Do **not** put Markdown bodies with backticks in unquoted shell variables or here-docs — the shell executes command substitutions and corrupts the body.3738 **b. Pipeline labels** — this is how the issues actually enter the pipeline (full contract: `instructions/sandcastle-pipeline.instructions.md`):39 - First **unblocked AFK** slice → `Sandcastle` (starts review → plan → implement → PR autonomously).40 - Other **AFK** slices that have blockers → `agent:queued` (`agent-promote-queued` flips them to `agent:implement` when their blockers close).41 - **HITL** slices, and any unblocked-but-not-first AFK slice → no pipeline label (a human starts them).4243 `agent:queued` only auto-releases when a *blocker closes*, so an unblocked slice can't be queued — nothing would release it. Give exactly one unblocked slice the `Sandcastle` start and leave other unblocked ones unlabeled to bound the blast radius (N `Sandcastle` labels = N concurrent agent runs against the proxy). You run locally with your own `gh` PAT, so labels you apply **do** trigger workflows — inside a workflow, label writes need `AGENT_PAT` because `GITHUB_TOKEN`-applied labels don't re-trigger.4445 **c. Native dependencies** — encode "blocked by" as **native GitHub issue dependencies**, never body text. `agent-promote-queued` reads the native `blockedBy`/`blocking` relation and **refuses sub-issues** (hence independent issues, not children). Add each edge with the blocking issue's **REST numeric id** (`gh api repos/$OWNER/$REPO/issues/N --jq .id` — *not* `gh issue view --json id`, which returns the GraphQL node id), never its issue number:4647 ```bash48 # $DEP blocked_by $BLOCKER (issue_id = the blocking issue's DB id)49 MSYS_NO_PATHCONV=1 gh api -X POST "repos/$OWNER/$REPO/issues/$DEP/dependencies/blocked_by" -F issue_id="$BLOCKER_DB_ID"50 ```5152 The `**Blocked by:** #N` line in the template is human-readable only — the native edge is what the automation reads.5354```markdown55# [Slice Title]5657**Type:** AFK | HITL58**Parent PRD:** #[issue-number]59**Blocked by:** #[issue-number], #[issue-number]6061## Description6263[What this slice accomplishes end-to-end]6465## Acceptance Criteria6667- [ ] [Specific, testable criteria]68```6970## Pipeline handoff7172The created issues plug into the Sandcastle label state machine — full contract in73`instructions/sandcastle-pipeline.instructions.md`. In short: `Sandcastle` on the first AFK slice74starts the autonomous chain (review → plan → implement → PR); `agent:queued` + native deps let75`agent-promote-queued` release dependents as blockers close; and **merge stays a human gate**76(`agent:merge`) at the end of every PR. HITL slices wait for a human to apply `Sandcastle`.7778## Handoff7980After issues are created, offer:81821. `/do-work` — start implementing the first slice832. **Save plan to `working/`** — if context is high or multi-session work, follow the standard handoff protocol (`@~/dotfiles/instructions/handoff.instructions.md`) to persist the issue list and dependency order. Include @-references to the parent PRD issue.