Creating GitHub Issues
Create focused, self-contained GitHub issues that an external contributor could implement without additional context.
Decision Flow
Work requested
│
▼
Single clear goal? ──yes──> Create single issue
│
no
│
▼
Spans multiple layers? ──yes──> Create epic with sub-issues
Scope Boundaries (CRITICAL)
Stick to what was requested. Create issues ONLY for the requested feature. Do NOT expand into adjacent features.
When Feature X depends on Feature Y:
- Create minimal stub for Y (just enough to unblock X)
- ASK user if they want a separate epic for Y
ASK before proceeding when:
- Adjacent features detected
- Ambiguous boundaries
- Multiple interpretations possible
- Feature seems too large (10+ issues)
Workflow
1. Clarify Scope
ASK user about boundaries before drafting.
2. Review Preference
Use AskUserQuestion:
- "Review first" (Recommended): Create preview file in scratchpad for feedback before creating issues
- "Create directly": Create issues immediately with
needs-reviewlabel added viagh issue edit <num> --add-label "needs-review"after creation
3. Create Issues (Single Script)
Use GraphQL API for reliable creation (see ./graphql-api.md).
CRITICAL: Execute ALL operations in a SINGLE bash script to minimize permission prompts. This includes:
- Getting repo info
- Getting repo ID
- Creating epic
- Creating all sub-issues
- Linking sub-issues to epic
- Adding labels
bash1#!/bin/bash 2# ALL OPERATIONS IN ONE SCRIPT - Single permission prompt 3 4set -e 5 6# 1. Get repo info 7REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner) 8OWNER=$(echo "$REPO" | cut -d'/' -f1) 9NAME=$(echo "$REPO" | cut -d'/' -f2) 10 11# 2. Get repo ID 12REPO_ID=$(gh api graphql -f query="query { repository(owner: \"$OWNER\", name: \"$NAME\") { id } }" -q '.data.repository.id') 13 14# 3. Create epic 15EPIC=$(gh api graphql -f query=' 16mutation($repoId: ID!, $title: String!, $body: String!) { 17 createIssue(input: { repositoryId: $repoId, title: $title, body: $body }) { 18 issue { number id } 19 } 20}' -f repoId="$REPO_ID" -f title="[Context] Epic: Feature Name" -f body="$(cat <<'EOF' 21## Objective 22Epic description here... 23 24## Sub-Issues 25- [ ] Sub-issue 1 26- [ ] Sub-issue 2 27EOF 28)") 29EPIC_NUM=$(echo "$EPIC" | jq -r '.data.createIssue.issue.number') 30EPIC_ID=$(echo "$EPIC" | jq -r '.data.createIssue.issue.id') 31 32# 4. Create sub-issues 33ISSUE1=$(gh api graphql -f query=' 34mutation($repoId: ID!, $title: String!, $body: String!) { 35 createIssue(input: { repositoryId: $repoId, title: $title, body: $body }) { 36 issue { number id } 37 } 38}' -f repoId="$REPO_ID" -f title="[Context] Sub-issue 1" -f body="Issue body...") 39ISSUE1_NUM=$(echo "$ISSUE1" | jq -r '.data.createIssue.issue.number') 40ISSUE1_ID=$(echo "$ISSUE1" | jq -r '.data.createIssue.issue.id') 41 42# Continue for all sub-issues... 43 44# 5. Link sub-issues (attempt - may not be available on all repos) 45gh api graphql \ 46 -H "GraphQL-Features: sub_issues" \ 47 -f query='mutation($parentId: ID!, $childId: ID!) { 48 addSubIssue(input: { issueId: $parentId, subIssueId: $childId }) { 49 issue { number } 50 } 51 }' \ 52 -f parentId="$EPIC_ID" \ 53 -f childId="$ISSUE1_ID" 2>/dev/null || true 54 55# 6. Add labels 56for issue in $EPIC_NUM $ISSUE1_NUM; do 57 gh issue edit "$issue" --add-label "needs-review" --repo "$REPO" 2>/dev/null || true 58done 59 60echo "Created Epic #$EPIC_NUM with sub-issues"
Issue Structure
Title Convention
Issue titles MUST include context prefix from the user's request. Extract the context (e.g., "Seller", "Buyer", "Payments") and prefix all issues:
[Context] Issue title
Examples:
- User asks: "create issues for the Seller" →
[Seller] Seller Registration,[Seller] Create Product Listing - User asks: "create issues for checkout flow" →
[Checkout] Cart Summary,[Checkout] Payment Processing - Epic title:
[Seller] Epic: Seller Experience
Required Sections
Every issue MUST include:
| Section | Purpose |
|---|---|
| Objective | Single, clear goal (one sentence) |
| Scope | What's included |
| Acceptance Criteria | Checkboxes for "done" |
| Out of Scope | Explicit boundaries |
| How to Test | Verification steps |
Optional: Examples, Technical Notes, Dependencies, Related
Common Mistakes
| Mistake | Fix |
|---|---|
| Vague objective | Specific goal with measurable outcome |
| Missing acceptance criteria | Add checkboxes |
| Expanding into adjacent features | ASK if separate epic needed |
| Using only labels to link issues | Use GraphQL addSubIssue |
Reference Files
Load these on-demand as needed:
./graphql-api.md- GraphQL mutations for creating issues and sub-issues (RECOMMENDED)./cli-reference.md- Quick gh CLI commands reference./templates.md- Issue body templates and examples