| name | refine-issue |
| description | Deepen an existing GitHub issue with codebase research — sharpen acceptance criteria, add implementation hints, and decompose into sub-tasks if needed. Triggers: /refine-issue, refine issue, sharpen issue |
| argument-hint | <#issue-number> |
| license | MIT |
| metadata | {"version":"1.1.1","tags":["issue","refine","planning","research"],"author":"benjamcalvin"} |
Refine Issue
Refine GitHub issue: $ARGUMENTS
Context
- Issue: !
gh issue view $0 --json number,title,body,labels,state,comments --jq '{number, title, body, labels: [.labels[].name], state, comment_count: (.comments | length)}'
- Issue comments: !
gh issue view $0 --comments 2>/dev/null || echo "NO_COMMENTS"
- Current branch: !
git branch --show-current
Instructions
You refine existing GitHub issues by grounding them in codebase reality. Unlike /cleanup-issue (which fixes form), you improve substance — adding technical context, sharpening acceptance criteria, and decomposing large tasks.
The goal: after refinement, an AI agent can implement the issue without any codebase exploration of its own.
Refinement adds depth at the right altitude, not everywhere. Issues descend through three layers: Problem stays at behavior altitude (plain domain language, no code identifiers), Solution stays at design altitude (component and operation names, no files/functions/lines), and file paths and line numbers live in Technical Context and PR decomposition tables — with one exception: an acceptance criterion may name the contract under test, but not where to find it. Research findings land in the layer they belong to — grounding an issue in the codebase must not mean pushing file.go:line references into Problem or Solution. If the existing issue already mixes altitudes, restore the separation as you refine.
Step 1: Parse the Target
Extract the issue number from $ARGUMENTS. If no valid issue number is found, use AskUserQuestion to ask for one.
Step 2: Understand the Issue
Read the issue body and comments from Context above. Identify:
- Type: bug, feature, chore, refactor, docs, test
- Claimed scope: What does the issue say needs to change?
- Gaps: What would an implementer need to know that isn't stated?
Step 3: Research the Codebase
This is the core value of refinement. Explore the codebase to fill knowledge gaps.
-
Locate affected code. Use Glob/Grep/Read to find the modules, files, and functions the issue touches. Record exact paths and line numbers.
-
Find existing patterns. Search for analogous implementations. If the issue asks for "add pagination to the users endpoint," find another endpoint that already has pagination and note the pattern.
-
Map the blast radius. What other code depends on the files being changed? What tests exercise them? Run:
- Grep for imports/references to affected modules
- Identify test files that cover the affected code
-
Check related work. Search for related issues and PRs:
gh issue list --state all --search "<relevant keywords>" --limit 10
gh pr list --state all --search "<relevant keywords>" --limit 10
Note anything relevant (prior attempts, related features, known constraints).
-
Read referenced specs. If the task touches a domain with documentation in the repo, read it.
Step 4: Refine the Issue
Apply refinements based on your research:
4a: Sharpen Acceptance Criteria
Replace vague criteria with specific, testable ones grounded in actual code:
- Before: "Pagination should work"
- After: "When
GET /api/users?page=2&limit=10 is called, the response includes pagination.total_count, pagination.page, and pagination.per_page fields"
Each criterion should be independently verifiable and name the observable contract precisely (an endpoint, a function signature). Locational detail discovered during research — which file implements the pattern, which lines to mirror — goes in Technical Context, not the criterion: the criterion states what must be true, Technical Context states where to look. Cite a spec or related issue at the end of a bullet, never mid-clause.
4b: Add Technical Context
Add or enhance the Technical Context section:
## Technical Context
- **Key files:**
- `path/to/main/file.go:L10-L45` — primary function to modify
- `path/to/test_file.go` — existing test coverage
- `path/to/related.go:L20` — analogous implementation to follow
- **Patterns to follow:** <describe the existing pattern with file references>
- **Dependencies:** <modules that import/use the affected code>
- **Constraints:** <discovered limitations — e.g., "this module has no external deps, keep it that way">
4c: Decompose if Needed
If the issue spans more than one logical change — independent concerns, or layers that must land in sequence — add a "Proposed PRs" section that gives each its own PR. A batch of small, independent, same-kind housekeeping changes may stay a single PR:
## Proposed PRs
### PR 1: <imperative title>
**What:** <1-2 sentences>
**Files:**
| File | Change |
|------|--------|
| `path/to/file` | <what changes and why> |
**Acceptance criteria:**
- [ ] <criteria specific to this PR>
---
### PR 2: <imperative title>
**Depends on:** PR 1
<same structure>
### Dependency Order
<which PRs can be parallelized, which must be sequential>
4d: Add Verification Hints
If not already present, add or enhance the Verification section:
## Verification
- **Automated tests:** <which criteria map to tests, what test patterns to use>
- **Existing test suite:** <specific test commands or files that must continue to pass>
- **Manual checks:** <only if truly needed>
Step 5: Validate
Before presenting, verify:
- Every acceptance criterion names a real, observable contract (verified against the code, not guessed)
- Technical context has exact file paths (not guesses)
- Patterns to follow are actual patterns in the codebase
- Decomposition (if any) has clear dependency ordering
- No new requirements were invented — only existing intent was sharpened
- Altitude check: refinement did not push code identifiers into Problem or Solution; file/function/line references live only in Technical Context (and PR decomposition tables)
- Skim test: the first sentence of each section, read in order, still forms a correct summary at descending altitude
Step 6: Present and Apply
Show the user the refined issue with a summary of what changed. Use AskUserQuestion with options:
- Apply — update the issue
- Edit — let the user request changes
- Cancel — discard
Update the issue:
gh issue edit <number> --body "$(cat <<'EOF'
<refined body>
EOF
)"
If the issue was decomposed into sub-issues, offer to create them:
gh issue create --title "<type>: <imperative summary>" --body "$(cat <<'EOF'
<sub-issue body>
Parent issue: #<parent-number>
EOF
)"
Report what was refined (e.g., "Sharpened 4 acceptance criteria with code references, added Technical Context section, decomposed into 2 PRs").