name: work-on-issue description: Pick up a GitHub issue, implement it, and submit a PR. The standard workflow for any assigned task.
Skill: Work on a GitHub Issue
When to use
When you are assigned a GitHub issue to implement (feature, bug fix, refactoring, or documentation task).
Steps
1. Read the issue
- Read the full issue body: description, acceptance criteria, implementation notes, file references
- If the issue is a sub-issue of an epic, read the epic for architectural context
- Check for dependencies (
Depends on #X) — do not start if dependencies are unresolved
2. Check the project board
- Use the
next-issueskill to query the board and confirm this issue is next in the stack rank - Note the issue's Priority, Phase, and Effort fields for context
- Confirm the issue is in
Todostatus (not blocked or already in progress)
3. Create a branch
# From main, create a branch tied to the issue number
git checkout main
git pull origin main
git checkout -b feat/issue-{N}-short-description
Use the appropriate type prefix: feat/, fix/, docs/, refactor/, test/, chore/
4. Implement the change
- Follow the project's code standards (see
AGENTS.mdand.github/copilot-instructions.md) - Use existing skills where applicable:
- Adding a buffer? → See the
add-new-bufferskill - Adding a command? → See the
add-new-commandskill - Architectural decision? → See the
create-adrskill - Design document needed? → See the
create-rfcskill
- Adding a buffer? → See the
- Make minimal, surgical changes — don't refactor unrelated code
- Write tests for new functionality
- Filing a new issue along the way? → See the
create-issueskill - Need to triage / label? → See the
triage-issueskill
5. Run quality checks
cargo fmt --check
cargo clippy -- -D warnings
cargo test
All three must pass before committing.
6. Commit with conventional format
git add .
git commit -m "feat(scope): brief description
Detailed explanation of what changed and why.
Closes #N"
- Use the conventional commit types:
feat,fix,docs,refactor,test,chore - Reference the issue in the commit footer with
Closes #N - For partial work toward an epic, use
Part of #Ninstead
7. Push and create a PR
git push origin feat/issue-{N}-short-description
Then create the PR. Always use a PowerShell here-string for the body — backtick is PowerShell's escape character, so any backtick-quoted code in a markdown body will corrupt or crash if passed as an inline string literal.
# Single-quoted here-string: backticks, $vars, and quotes are all literal.
# The closing '@ MUST be at column 0 (no leading spaces).
$body = @'
## Summary
Closes #N — one-paragraph description.
## Changes
- `src/ui/app.rs`: what changed
- `src/ui/keybindings.rs`: what changed
## Manual Testing
(see below for how to fill this section)
## Tests
- N unit tests, N integration tests
## Quality
- `cargo fmt` ✅
- `cargo clippy -- -D warnings` ✅
- `cargo test` ✅
'@
gh pr create --title "feat(scope): description" --body $body --base main
PR requirements:
- Title in conventional commit format (
feat(scope): description) Closes #Nin the body- A
## Manual Testingsection (see guidance below) - Screenshots or terminal output for UI changes
- Note any testing done beyond automated tests
⚠️ After creating the PR — stop and wait for the Copilot review.
copilot-pull-request-reviewerruns asynchronously aftergh pr createand typically takes several minutes. Do not runcode-review-validationuntil the bot has posted its review. Checking immediately will show zero comments even when feedback is incoming — that is not a signal that the PR is clean. Pause the session and resume once the review appears, or poll withgh pr view <N> --json reviewsuntil the bot's entry is present.
How to write the ## Manual Testing section
This section tells a human reviewer exactly how to verify the change beyond cargo test. Every PR must include it — either with real steps or an explicit N/A with reasoning.
If the change has observable behavior (new keybinding, new buffer, new message, visual change, config change):
Write 2–5 short, imperative steps a reviewer can follow. Include:
- Setup (if any, beyond
cargo run) - What to do (keys to press, commands to run, config to edit)
- What to expect (exact message text, visual state, behavior)
Example for a keybinding change:
## Manual Testing
1. `cargo run`
2. Navigate to the episode list
3. Select an episode and press `m` → status should change to ✓ Played
4. Press `u` on the same episode → status should revert to unplayed
5. Quit and reopen → played/unplayed status should persist
Example for a config/storage change:
## Manual Testing
1. `cargo run` — confirm app starts without errors
2. Open `~/.config/podcast-tui/config.json` and add `"quit": ["C-q"]`
3. Restart the app → pressing `C-q` should quit, `q` should still quit (default not removed)
4. Delete the config file → app should start with all defaults
If the change is internal/infrastructure (parser, trait, data model, refactor with no UI effect):
Write N/A followed by a short reason explaining why there's nothing a human can manually verify yet:
## Manual Testing
N/A — key notation parser is not wired to the keybinding system yet.
Consumers will be added in #97 and #98.
## Manual Testing
N/A — internal refactor of storage trait; no change to observable behavior.
All behavior is covered by the 12 unit tests above.
Rules:
- Never leave the section blank or omit it entirely
- Never write vague steps like "verify it works" — be specific about what "works" looks like
- If the PR touches both internal and UI code, write steps for the UI-observable parts
- For bug fixes, include the reproduction steps and confirm the fix: "Before: X happened. After: Y happens."
8. Update changelog (if user-facing)
If the change is user-facing, update CHANGELOG.md following the update-changelog skill before pushing. Add the entry to [Unreleased] and include it in the same commit as the code change. This is what prevents changelog gaps when multiple releases are cut quickly.
Tips
- One issue per branch — don't combine unrelated changes
- If you discover a bug or improvement while working, file a new issue for it
- If the issue is unclear or missing acceptance criteria, ask for clarification before coding
- Check
src/constants.rsbefore hardcoding any values