Create and refine the GitHub issues and epics that later sessions work — draft a standalone issue for one piece of work, or a parent tracker issue (epic) with child issues. Invoke when: planning new work, drafting or editing an issue or epic, or when asked 'let's plan X'. Counterpart to the `issue` and `epic` skills, which work already-created issues; `planning` authors them. Each issue covers one coherent thing.
89%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Low
Low-risk findings worth noting
This skill authors the work. It drafts and refines GitHub issues and epics so a later session can pick them up: a standalone issue captures one coherent piece of work; a parent tracker issue — an epic — groups child issues under one initiative. The issue and epic skills work already-created issues; planning is where those issues come from.
Every unit of work gets a GitHub issue. Each issue covers one coherent thing — not a mix of unrelated concerns. A session may plan several issues at once, but an issue may not span multiple concerns.
| Situation | Action |
|---|---|
| Starting new work | Create issue first |
| "Let's plan X" | Create detailed issue |
| New work discovered mid-session | Pause → ask about new issue |
| Quick fix / trivial change | Ask if issue needed |
1. Understand the work — the problem, the outcome, the constraints
2. Draft the issue content (leaf or tracker — see below)
3. Present the full draft — title, body, type — and wait for Josh's approval of that exact text
4. Create the issue and capture its URL
5. Verify the created issue's number, type, and state
6. Hand the URL back — don't assume the next step is working itWorking the issue is the issue and epic skills' job, not this one.
High level, always. An issue describes an outcome — what needs to be true when it's resolved. Never how. Files, function names, refactor steps, migration order, code snippets, "first do X then Y": none of it belongs in the body. If you catch yourself typing an implementation detail, delete it. The future session picking this up must investigate the code as it exists then — not follow a recipe you baked in now, which is almost certainly stale or wrong.
Body prose follows CLAUDE.md's prose and body rules — terse, lead with the payload, cap lists, one paragraph on one line. Break a line only to separate paragraphs, list items, and headings; let the display wrap the rest.
Gather what you need to describe the outcome — not how to reach it:
Do not draft an approach. Do not enumerate files. Do not sketch implementation steps. The future session picking this up needs to investigate the codebase itself, not follow a recipe you baked into the body.
The body shape depends on whether the issue is a leaf or a tracker.
Leaf issues — Task, Bug, Feature, or anything else meant to be resolved in a single PR. Body = Summary + Acceptance Criteria.
ISSUE_URL=$(gh issue create \
--repo <org>/<repo> \
--title "Brief description" \
--body "## Summary
High-level overview of what we need to achieve and why. Include only constraints that must be honored (e.g. \"must not break the public v1 API\", \"must preserve existing session behavior\"). No approach, no files, no implementation steps.
## Acceptance Criteria
- [ ] Observable outcome 1
- [ ] Observable outcome 2")
printf '%s' "$ISSUE_URL" | pbcopy # issue URL copied to clipboard
echo "$ISSUE_URL"Acceptance criteria are the source of truth for "done" on a leaf — each item should be something you can point at and verify, not an implementation task. Tests passing is assumed for any code change, so don't list it as a criterion.
When an issue originates from a Sentry issue, add a Sentry: [PRIMCLOUD-<n>](<permalink>) line to the body (short ID linked to its permalink). This is a reference, not implementation detail, so it doesn't violate the "no approach, no files" rule.
Tracker issues — Epic, or any parent issue whose purpose is to group sub-issues under one initiative. Body = Summary only. No acceptance criteria — the acceptance lives on the children. The tracker describes what the initiative is about; the sub-issues are the work.
ISSUE_URL=$(gh issue create \
--repo <org>/<repo> \
--title "Brief description" \
--body "## Summary
High-level overview of the initiative — what are we trying to achieve overall, and why. Constraints that span all children (e.g. \"no child PR may break the public v1 API\") go here.")
printf '%s' "$ISSUE_URL" | pbcopy
echo "$ISSUE_URL"Present the draft — title, body, and type — and wait for Josh's explicit approval of that exact text. Agreeing to the plan or the design is not that approval, and a draft that changes after he approves it goes back to him. Then run gh issue create, capture the URL, and verify what landed:
gh issue view <number> --repo <org>/<repo> --json number,title,issueType,state,urlHand the URL back. Don't assume the next step is starting work on it.
Once an issue is created, track it as session context:
Active Issue: #123 - Feature description
Repo: <org>/<repo>This context should be referenced:
If context compaction occurs, the issue contains the full context. Fetch it:
gh issue view <number> --repo <org>/<repo>Sometimes planning reveals work that should be split into multiple issues.
When the split is one initiative broken into pieces rather than independent deliverables, make the initiative a tracker (epic) and the pieces its children — see the tracker body shape above. Present the tracker first, then each child. Linking a child to the tracker is its own ask at the moment of linking — see the github skill's Sub-Issues section for the command.
When additional work surfaces mid-session, judge it against the acceptance criteria — not against a "scope" boundary.
If it's needed to meet acceptance criteria — it's part of the work. Do it. Don't defer under "out of scope" language.
If it's unrelated to acceptance criteria but small and adjacent — leave the code better than you found it, so do it.
If it's genuinely a separate initiative — STOP and ask:
I've discovered we also need to [X], and it's unrelated to the acceptance
criteria on #123.
Options:
1. Fold into current issue (update acceptance criteria)
2. Create a new issue and defer
3. Note it and skip
How do you want to handle this?If folding in, update the issue body so the acceptance criteria reflect the new expected outcome — don't just leave it stale.
Present the full revised title and body and wait for Josh's approval of that exact text, then apply it and verify.
# View current body
gh issue view <number> --repo <org>/<repo>
# Apply the approved body
gh issue edit <number> --repo <org>/<repo> --body-file <file>
# Verify what landed
gh issue view <number> --repo <org>/<repo> --json number,title,body,issueType,stateSame rules apply, including the present-and-approve step above before gh issue edit runs. When editing an issue that already exists:
## Approach, ## Files/Areas, ## Notes, ## Scope, or step-by-step implementation sections. They short-circuit investigation.When work is complete and approved for commit:
Title and body follow CLAUDE.md's PR rules — feat: short description, body is what/why at a high level, and it must end with Closes #<issue-number>. Present the full title and body and wait for Josh's approval of that exact text before running gh pr create.
PR_URL=$(gh pr create \
--draft \
--repo <org>/<repo> \
--title "feat: clear description" \
--body "## Summary
What was done and why.
Closes #<issue-number>")
printf '%s' "$PR_URL" | pbcopy # draft PR URL copied to clipboard, ready to paste
echo "$PR_URL"Closes LineThe Closes #123 line is what wires the PR to the issue. It:
| Action | Command |
|---|---|
| Create issue | gh issue create --repo <org>/<repo> ... |
| View issue | gh issue view <num> --repo <org>/<repo> |
| Edit issue | gh issue edit <num> --repo <org>/<repo> |
| Add comment | gh issue comment <num> --repo <org>/<repo> --body "" |
| Create PR | gh pr create --draft --repo <org>/<repo> ... Closes #N (pbcopy URL) |
## Scope section — the concept doesn't exist hereCloses #Njoshmanders/dotfiles
92186fe
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.