Roxabi Boilerplate
Processes

Issue Management

GitHub project setup, issue lifecycle, triage, labels, board automation, and dependencies

Issue Lifecycle

Create → Triage → Prioritize → Assign → Implement → Review → Close

Project Board Setup

Create the project

gh project create --owner @me --title "My Project"

Status columns

StatusDescription
BacklogNot yet started, waiting to be picked up
AnalysisBeing researched / analyzed
SpecsSpecification in progress or done
In ProgressActive development (has worktree/branch)
ReviewIn code review / PR open
DoneCompleted and merged

Custom fields

Add these in Project Settings > Fields:

FieldTypeValues
PrioritySingle selectP0 - Urgent, P1 - High, P2 - Medium, P3 - Low
SizeSingle selectXS, S, M, L, XL

Labels

Labels are included in the template repo. To create them manually:

# Type labels
gh label create setup --color "0E8A16" --description "Infrastructure & setup"
gh label create feature --color "A2EEEF" --description "New feature"
gh label create bug --color "D73A4A" --description "Bug fix"
gh label create dx --color "1D76DB" --description "Developer Experience"
gh label create docs --color "D4C5F9" --description "Documentation"
gh label create ai --color "FBCA04" --description "AI agents & skills"
gh label create workflow --color "C2E0C6" --description "Workflow & processes"

# Priority labels
gh label create P0 --color "7A0000" --description "Priority 0 - Urgent (blocking)"
gh label create P1 --color "B60205" --description "Priority 1 - High"
gh label create P2 --color "D93F0B" --description "Priority 2 - Medium"
gh label create P3 --color "FBCA04" --description "Priority 3 - Low"

# Status labels
gh label create blocked --color "B60205" --description "Issue is blocked by another issue"

# Size labels
gh label create XS --color "E6E6E6" --description "Size: Extra Small"
gh label create S --color "C5DEF5" --description "Size: Small"
gh label create M --color "BFD4F2" --description "Size: Medium"
gh label create L --color "7057FF" --description "Size: Large"
gh label create XL --color "D876E3" --description "Size: Extra Large"

Creating Issues

From Templates

Use the provided GitHub templates:

  • Bug Report: For reporting bugs with reproduction steps
  • Feature Request: For proposing new features

From the CLI

Use /issue-triage create to create an issue, add it to the project board, and set all fields in one shot:

bun .claude/skills/issue-triage/triage.ts create \
  --title "feat: notification preferences" \
  --body "Allow users to configure notification channels" \
  --label "feature" \
  --size M --priority High \
  --status Backlog \
  --parent 163 \
  --blocked-by 42

Minimum Requirements

Every issue should have:

  • Clear, actionable title
  • Description with context and acceptance criteria
  • Related issues linked (if any)

Triage

Triage ensures every issue has a Size and Priority assigned.

Size

SizeDescriptionExample
XSTrivial change, <1 hourTypo fix, config tweak
SSmall task, <4 hoursSingle file change, simple feature
MMedium task, 1-2 daysMulti-file feature, requires testing
LLarge task, 3-5 daysComplex feature, architectural changes
XLVery large, >1 weekMajor refactor, new system

Priority

PriorityLabelDescriptionAction
UrgentP0Blocking or criticalDo immediately
HighP1Important for current milestoneDo this sprint
MediumP2Should be done soonPlan for next sprint
LowP3Nice to haveBacklog

Triage Process

Use the /issue-triage skill to list untriaged issues, set fields, create new issues, and manage parent/child relationships:

# List issues missing Size or Priority
bun .claude/skills/issue-triage/triage.ts list

# Set size, priority, and status
bun .claude/skills/issue-triage/triage.ts set 42 --size M --priority High
bun .claude/skills/issue-triage/triage.ts set 42 --status "In Progress"

# Create a new issue with full setup
bun .claude/skills/issue-triage/triage.ts create \
  --title "feat: avatar upload" \
  --size M --priority High --parent 163

# Manage parent/child (sub-issue) relationships
bun .claude/skills/issue-triage/triage.ts set 164 --parent 163
bun .claude/skills/issue-triage/triage.ts set 163 --add-child 164,165
bun .claude/skills/issue-triage/triage.ts set 164 --rm-parent

# Manage blocked-by dependencies
bun .claude/skills/issue-triage/triage.ts set 91 --blocked-by 117
bun .claude/skills/issue-triage/triage.ts set 91 --rm-blocked-by 117

Project Board Automation

The GitHub Project board uses built-in workflows to automate status transitions. All 8 workflows are enabled:

WorkflowTriggerAction
Item added to projectIssue/PR added to boardSet Status = Backlog
Auto-add to projectIssue/PR created in repoAdd to project board
Auto-add sub-issues to projectSub-issue createdAdd to project board
Item closedIssue/PR closed (not planned)Set Status = Done
Auto-close issueIssue marked Done on boardClose the GitHub issue
Pull request mergedPR mergedSet Status = Done
Pull request linked to issuePR linked to issueSet Status = In Progress
Auto-archive itemsItem closed for 2+ weeksArchive from board

Configuration

Workflow rules are UI-only — the GitHub API does not support creating, updating, or reading workflow configuration. Only name and enabled status are exposed via GraphQL.

To view or edit workflows: Project Settings > Workflows

# Read-only: list workflow names and enabled status
gh api graphql -f query='query($pid: ID!) {
  node(id: $pid) { ... on ProjectV2 {
    workflows(first: 20) { nodes { name enabled } }
  }}
}' -f pid="PVT_kwHODEqYK84BOId3"

Blockers & Dependencies

Adding a Blocker

When an issue blocks another, use the /issue-triage skill (preferred) or the raw GraphQL API:

# Preferred — via /issue-triage
bun .claude/skills/issue-triage/triage.ts set 51 --blocked-by 19
bun .claude/skills/issue-triage/triage.ts set 19 --blocks 51

If using the API directly:

  1. Use GitHub's native blockedBy dependency (source of truth):

    # Make #51 blocked by #19
    gh api graphql \
      -F query='mutation($issueId: ID!, $blockingId: ID!) {
        addBlockedBy(input: { issueId: $issueId, blockingIssueId: $blockingId }) {
          issue { number }
          blockingIssue { number }
        }
      }' \
      -f issueId="$(gh api repos/OWNER/REPO/issues/51 --jq '.node_id')" \
      -f blockingId="$(gh api repos/OWNER/REPO/issues/19 --jq '.node_id')"
  2. Add the blocked label to the blocked issue:

    gh issue edit <number> --add-label "blocked"
  3. Reference the blocked issue in the blocker's body (e.g., "Blocker for #19")

Resolving a Blocker

When a blocking issue is closed:

  1. Remove the blocked label from previously blocked issues:

    gh issue edit <number> --remove-label "blocked"
  2. Verify unblocked issues are ready to work on

Viewing Dependencies

Use the /issues skill to see the full dependency graph:

.claude/skills/issues/fetch_issues.sh

The output shows block status for each issue:

IconMeaning
Ready — no open blockers
Blocked — waiting on other issues
🔓Blocking — other issues depend on this

Labels Reference

Type Labels

LabelColorDescription
setupgreenInfrastructure & setup
featurecyanNew feature
bugredBug fix
dxblueDeveloper Experience
docspurpleDocumentation
aiyellowAI agents & skills
workflowgreenWorkflow & processes
blocked-Issue is blocked by another issue

Priority labels (P0P3) and Size labels (XSXL) mirror the project board fields. See Triage for definitions.


Best Practices

  • One issue per concern: Don't bundle unrelated changes
  • Link related issues: Use GitHub references (#42) and blockedBy
  • Close with PR: Reference the issue in your PR (Closes #42)
  • Update status: Move issues on the project board as work progresses
  • Break down XL: Issues sized XL should be broken into smaller issues

We use cookies to improve your experience. You can accept all, reject all, or customize your preferences.