From gh-sdlc
GitHub issue creation and hierarchy standards (part of gh-sdlc). Provides formatting rules for issues — only applies when issues are actually being created as part of the /gh-sdlc workflow. Does NOT auto-activate on its own.
How this skill is triggered — by the user, by Claude, or both
Slash command
/gh-sdlc:issue-policyThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
**Decompose work into atomic, trackable units. Every non-trivial change requires an issue.**
Decompose work into atomic, trackable units. Every non-trivial change requires an issue.
--assignee "@me") unless user explicitly opted out| Requires Issue | Optional |
|---|---|
| New features | Typo corrections |
| Bug fixes needing investigation | Formatting-only changes |
| Architectural changes | Routine dependency bumps |
| Multi-file refactoring | Comment additions |
| Substantial documentation | |
| Performance optimization | |
| Security patches |
Component: Imperative action description
Examples:
Project: Initialize `uv` with `discord.py` dependenciesBot: Implement core client with intents configurationCommands: Add slash command registration systemUse inline codeblocks (backtick wrapping) for filenames, flags, tool/package names, and directory paths in titles. See commit-policy for the full codeblock usage guide.
Child issues use the same format — no bracket prefixes. Parent-child relationships are expressed via sub-issue linking (GraphQL API), not title conventions.
Every issue body MUST contain these sections in order:
Explain WHAT needs to be done and WHY. Provide context for the change.
Define exact closure conditions. Use checkboxes:
- [ ] Criterion one
- [ ] Criterion two
- [ ] All tests pass
List specific files, modules, or systems affected:
**Files:** `src/auth/`, `tests/test_auth.py`
**Dependencies:** `pyjwt>=2.0`
After a --- separator, include a Mermaid diagram:
---
## Sub-Issues
` ` `mermaid
graph TD
A[#1 Parent Feature] --> B[#2 Child One]
A --> C[#3 Child Two]
A --> D[#4 Child Three]
` ` `
Maximum 2 levels: Parent → Child. If deeper decomposition needed, create a new parent.
Use GitHub's native relationship features to formally link issues. This replaces informal "see #N" references.
After creating parent and child issues, link them as sub-issues via the GraphQL API:
# Get issue node IDs
PARENT_ID=$(gh issue view <parent-number> --json id -q '.id')
CHILD_ID=$(gh issue view <child-number> --json id -q '.id')
# Add child as sub-issue of parent
gh api graphql -f query='
mutation {
addSubIssue(input: {
issueId: "'$PARENT_ID'"
subIssueId: "'$CHILD_ID'"
}) {
issue { id }
subIssue { id }
}
}'
Rules:
gh api graphql -f query='
mutation {
removeSubIssue(input: {
issueId: "'$PARENT_ID'"
subIssueId: "'$CHILD_ID'"
}) {
issue { id }
subIssue { id }
}
}'
Use dependency relationships when issues have execution-order constraints:
Dependencies are managed via the GitHub UI (Relationships sidebar) or the MCP server's sub_issue_write tool. Apply when:
Rules:
blocked labelgraph TD
A[#1 Initial Bot Implementation] --> B[#2 Project Setup]
A --> C[#3 Core Bot Client]
A --> D[#4 Command System]
A --> E[#5 Logging Setup]
Rules:
graph TD (top-down) formatNodeID[#issue-number Title]| Type | Pattern |
|---|---|
| Parent feature | feature/parent-number-description |
| Child feature | feature/parent-number/child-number-description |
| Standalone bugfix | bugfix/issue-number-description |
| Hotfix | hotfix/description |
Examples:
feature/1-initial-bot-implementationfeature/1/2-project-setupfeature/1/3-core-bot-clientbugfix/56-null-pointer-handlerRule: When child issues exist, ALWAYS create corresponding sub-branches. Every child issue gets its own feature/parent/child-description branch — no exceptions. Sub-branches mirror sub-issues: if you decomposed the issue, decompose the branch.
Creation → Decomposition → Implementation → Integration → Closure
Commits referencing issues use: gh-<issue-number>: description
Apply labels consistently:
feature, bug, enhancement, documentationP0-critical, P1-high, P2-medium, P3-lowneeds-triage, in-progress, blockedAlways use --body-file to pass issue bodies — never inline markdown in --body "..." because backticks, code blocks, and special characters get mangled by shell interpretation.
When the title contains backtick-wrapped names, use single quotes with raw backticks — never backslash-escape them inside single quotes (see commit-policy for details).
# Write body to temp file (markdown is preserved exactly)
cat > /tmp/issue-body.md <<'EOF'
## Problem Statement
Description of what needs to be done and why.
## Acceptance Criteria
- [ ] Criterion one
- [ ] Criterion two
## Technical Scope
**Files:** `src/module/`, `tests/test_module.py`
EOF
gh issue create \
--title "Component: Action description" \
--body-file /tmp/issue-body.md \
--label "feature" \
--milestone "vX.Y" \
--assignee "@me"
rm /tmp/issue-body.md
After creating child issues, ALWAYS link them as sub-issues of the parent (see "Issue Relationships" above).
Tick acceptance criteria checkboxes as work progresses. When a criterion is satisfied (code written, test passing, feature working), update the issue body to mark it [x].
# Fetch current body, apply sed, write to temp file, update via --body-file
gh issue view <number> --json body -q .body \
| sed 's/- \[ \] Criterion text/- [x] Criterion text/' \
> /tmp/updated-body.md
gh issue edit <number> --body-file /tmp/updated-body.md
- [ ] ~~N/A: no external API~~ Criterion text)npx claudepluginhub achxy/dotclaude --plugin gh-sdlcManages GitHub issue hierarchies: add/remove/create sub-issues, check completion status/progress, list deps, set blocking/blocked-by relationships.
Manages full GitHub issue lifecycle: create with conventional commit titles, sub-issues, cross-repo links, edit/view/list, dump trees to markdown/YAML, push from files, comment/label/close.
Creates structured GitHub issues with TDD principles, labels, templates, and auto-closing keywords. Analyzes repo, detects duplicates/templates, handles epics/bugs/PR tasks.