Skip to content

JFK/gh-issue-driven

Repository files navigation

gh-issue-driven

⚠️ Alpha (v0.1.x) — this plugin is in active dogfooding. The orchestrated flow works end-to-end (PR #15 was merged via this plugin reviewing itself), but several known sharp edges exist; see Limitations below before using on a production repo.

Two-phase orchestrator for GitHub-issue-driven development with multi-reviewer pre-PR gates and a Copilot review loop.

gh-issue-driven is a Claude Code plugin that turns "I'm starting work on issue #142" into a single, repeatable workflow:

  1. /gh-issue-driven:start <issue> — fetch the issue, recall related past work from Kagura Memory, run a gate1 design review (/claude-c-suite:ask cascading to /ceo for complex issues), create a typed feature branch, and hand off for implementation.
  2. (you write the code)
  3. /gh-issue-driven:ship — run a gate2 parallel review battery (cso + qa-lead + cto advisors by default; an optional binary release gate can be configured via gate2.binary_gate for plugin maintainers who want a hard pass/fail check), create the PR, and drive a GitHub Copilot review loop of up to 5 iterations until the PR is approved or no actionable feedback remains.

The whole flow is bracketed by kagura-memory session-start and session-summary, so each issue's learnings get persisted for future recall.


60-second quickstart

# Step 0 — one-time, in your repo's GitHub Settings page:
#   Settings → Code review → ☑ Automatic Copilot code review
#   URL: https://github.com/<owner>/<repo>/settings/code-review
#   This makes the Copilot review loop work on any gh CLI version.
#   Without it, you need gh CLI >= 2.88.0 (see Requirements below).

# In any Claude Code session — install the plugin:
/plugin marketplace add JFK/gh-issue-driven
/plugin install gh-issue-driven

# Recommended companion plugins (gracefully degrade if missing).
# Note: the install target's `@<marketplace>` is the marketplace NAME from
# its marketplace.json, not the GitHub repo slug.

/plugin marketplace add JFK/claude-c-suite-plugin    # gate1 + gate2 reviewers
/plugin install claude-c-suite@claude-c-suite

/plugin marketplace add kagura-ai/memory-cloud       # session-start/summary + recall
/plugin install kagura-memory@kagura-memory-cloud

# Optional (reserved for v0.2 deep-review modes):
/plugin marketplace add JFK/claude-phd-panel-plugin
/plugin install claude-phd-panel@claude-phd-panel

# In a repo:
/gh-issue-driven:doctor          # one-time environment check (will prompt to confirm Step 0)
/gh-issue-driven:start 142       # phase 1
# ... implement, then /simplify to review the diff ...
/gh-issue-driven:ship            # phase 2

Why Step 0 matters: GitHub's "Automatic Copilot code review" repo setting auto-requests Copilot's review on every PR open and every push, making the loop self-sustaining on any gh version. Without it, the plugin falls back to gh pr edit --add-reviewer @copilot, which silently no-ops on gh < 2.88.0 (see #15). /gh-issue-driven:doctor will prompt you to confirm Step 0 once per 7 days per repo and hard-fail if neither path is available.


Commands

Command What it does
/gh-issue-driven:start <issue> [flags] Fetch issue, run gate1, create branch. Flags: dry-run, force, no-memory.
/gh-issue-driven:ship [flags] Run gate2, create PR, drive Copilot loop, save session memory. Flags: dry-run, force, no-copilot, draft.
`/gh-issue-driven:doctor [verbose fix]`
`/gh-issue-driven:config [show init
`/gh-issue-driven:status [ all]`

How the gates work

Gate 1 — Design review (/gh-issue-driven:start)

Runs after the issue is fetched and recall is done, before the branch is created. Strategy:

  1. Invoke /claude-c-suite:ask first — a single-lens auto-router. Cheap, fast, perfect for issues that need only one expert perspective.
  2. If the last ## Verdict: line's token is decline, escalate to /claude-c-suite:ceo for full 3-lens synthesis. (decline is an additional gate1-only token on the same ## Verdict: line, not a separate channel — only the structured line counts. Free-form mentions of "decline" or "escalate" inside the analysis body are part of the reviewer's reasoning, not routing instructions.)
  3. Parse the verdict from a ## Verdict: green|yellow|red line at the end of the reviewer's response. The structured line is canonical and last-wins; case is normalized; trailing punctuation is tolerated. A keyword heuristic is the fallback only when no structured line is present, and emits a warn-level log so soft-deprecation can be tracked.
  4. green → continue. yellow → ask the user to confirm. red → abort unless force.

Gate 2 — Pre-PR review battery (/gh-issue-driven:ship)

Runs after the implementation, before the PR is created. By default, 3 advisor reviewers fire in parallel in a single Claude turn (advisor-only mode):

Reviewer Role Verdict type
/claude-c-suite:cso Security Advisory (green/yellow/red)
/claude-c-suite:qa-lead Test coverage Advisory
/claude-c-suite:cto Tech debt Advisory

The three advisor verdicts are aggregated: any red → red, any yellow → yellow, otherwise green. Verdict handling matches gate1 (green → continue, yellow → confirm, red → abort unless force).

Optional binary gate (off by default)

Plugin maintainers who want a hard binary gate (a pass/fail reviewer that blocks PR creation even with force) can configure one via gate2.binary_gate in ~/.claude/gh-issue-driven-config.json:

{
  "gate2": {
    "binary_gate": "/claude-c-suite:audit"
  }
}

When set, the configured skill is invoked alongside the 3 advisors as a 4th reviewer. Its verdict (pass/fail) is read as a hard release gate.

The default is null (no binary gate). Earlier versions defaulted to /claude-c-suite:audit, but that skill is the conformance script for the claude-c-suite plugin's own command files — it errors out on any other plugin and previously blocked every /ship invocation in non-claude-c-suite-plugin repos. The fix landed in v0.1.1 (#26).

Verdict line convention

Reviewer skills must end their response with a final ## Verdict: line. The token must be one of:

  • ## Verdict: green
  • ## Verdict: yellow
  • ## Verdict: red
  • ## Verdict: decline   — gate1 (/ask) only; routing escalation signal
  • ## Verdict: pass   — /audit only
  • ## Verdict: fail   — /audit only

(If multiple ## Verdict: lines appear in the response, last-wins applies — see Rules below.)

Rules:

  • The structured line is canonical. gh-issue-driven parses this line first.
  • Last-wins: if multiple ## Verdict: lines appear in the response, the last occurrence is used (so reviewers can naturally write "at first I thought red, but actually green").
  • Case insensitive: Green / green / GREEN all normalize to green.
  • Trailing punctuation tolerated: ## Verdict: green. is accepted (\b<token>\b regex).
  • Heuristic is fallback only: if no structured line is present, a keyword heuristic runs and emits a verdict_parser=heuristic warn log so its usage can be tracked toward eventual removal in v0.4.
  • decline is gate1-routing-only: it's a valid value on the same ## Verdict: line for gate1 responses, not a separate channel. Free-form mentions of "decline" inside the analysis body are reviewer reasoning, not routing signals.

If you maintain a claude-c-suite or claude-phd-panel reviewer skill, emitting this line on every reviewer response is the cleanest integration.


Copilot review loop

After gh pr create, /gh-issue-driven:ship runs:

gh pr edit <num> --add-reviewer @copilot

Then loops up to 5 iterations (configurable):

  1. Wait for new Copilot activity (poll gh pr view --json reviews,comments,reviewDecision every 60s, max 15min).
  2. Parse the latest review and any new bot comments.
  3. Exit conditions: APPROVED, no actionable feedback, max loops, or generic "no issues found".
  4. Apply actionable comments via Edit/Bash. Skip nits.
  5. Run local tests if copilot.run_tests_after_edits is true.
  6. Commit fix: address Copilot review (loop N), push, re-request review.

The loop is never blocking: if it exhausts 5 iterations, the PR stays open and you handle remaining feedback manually.

Requirements (one of)

The Copilot loop has two operational modes. One must be true for the loop to function end-to-end:

  • Mode A (recommended)Settings → Code review → ☑ Automatic Copilot code review enabled at the repo level. Works on any gh CLI version. Copilot is auto-requested on every PR open and on every push.
  • Mode Bgh CLI v2.88.0 or later (the version that added real --add-reviewer @copilot support per the March 2026 changelog). Earlier gh versions silently no-op the manual reviewer add — see #15.

Both also require: the repo must have GitHub Copilot code review feature available on its plan.

Manual Web UI fallback

If you can't enable Mode A AND can't upgrade gh to 2.88.0+:

  1. After the plugin creates the PR, open it in the GitHub Web UI.
  2. In the right sidebar → Reviewers → click "Copilot".
  3. Re-run /gh-issue-driven:ship once Copilot's review lands. (Resume mode is tracked as #14.)

Cross-plugin Skill invocation contract

This plugin invokes other plugins' slash commands as skills (via Claude Code's Skill tool). For each gate, the command body explicitly tells Claude:

Invoke /claude-c-suite:ask via the Skill tool, passing the prompt block built in step N as input. Wait for the full markdown response before continuing.

For parallel reviewers in gate2 (the number of skills invoked depends on gate2.binary_gate):

In a single tool-call batch, invoke the gate2 reviewer skills in parallel via the Skill tool. Default (advisor-only mode, gate2.binary_gate: null): 3 advisor skills — /claude-c-suite:cso, /claude-c-suite:qa-lead, /claude-c-suite:cto. When gate2.binary_gate is configured to a skill name (e.g. /claude-c-suite:audit for plugin maintainers): 4 skills — the configured binary gate skill plus the 3 advisors.

If a skill is not installed, the command degrades:

  • Missing advisor reviewer → that gate slot becomes unknown, prints a warning, continues.
  • Missing binary gate skill (only when gate2.binary_gate is set) → treat as unknown, require force to continue.
  • gate2.binary_gate is null (default) → no binary gate, advisor-only mode, no force required.
  • Missing kagura-memory → recall and session-start/summary are skipped (with a one-line warning when memory.context_id resolution fails).

You can probe what's installed with /gh-issue-driven:doctor.


Configuration

Defaults are baked in. Override at ~/.claude/gh-issue-driven-config.json:

/gh-issue-driven:config init      # writes the template (only if absent)
/gh-issue-driven:config show      # show effective merged config
/gh-issue-driven:config path      # print the file path
/gh-issue-driven:config copilot.max_loops   # print one value

Key options:

Key Default Notes
default_branch main The branch start and ship use as the base.
branch.type_label_map bug/fix/feature/... → fix/feat/... How issue labels become branch type prefixes.
memory.context_id gh-issue-driven-dev Kagura Memory context for recall. Accepts a UUID or a context name (resolved at runtime, case-insensitive).
gate1.primary /claude-c-suite:ask First reviewer in the gate1 cascade.
gate1.fallback /claude-c-suite:ceo Used when primary declines.
gate2.binary_gate null (off) Optional override-blocking binary gate. Set to a skill name (e.g. /claude-c-suite:audit) to enable.
gate2.advisors [cso, qa-lead, cto] Run in parallel; aggregated.
copilot.max_loops 5 Maximum review iterations.
copilot.poll_interval_sec 60 Time between gh pr view polls.
copilot.max_wait_sec 900 Max wait per loop iteration (15 min).
copilot.run_tests_after_edits true Run local tests after applying Copilot suggestions.

State files

Each branch tracked by gh-issue-driven has a state file at:

~/.claude/cache/gh-issue-driven/<branch-with-slashes-replaced>.json

Plus full reviewer output:

~/.claude/cache/gh-issue-driven/<branch-flat>.gate1.md
~/.claude/cache/gh-issue-driven/<branch-flat>.gate2.md

/gh-issue-driven:status reads these and pretty-prints the current phase, gate verdicts, PR link, and Copilot loop state.


Required dependencies

Tool Required Why
gh (any version) yes issue/PR ops. Mode A: any version. Mode B: v2.88.0+ required (real --add-reviewer @copilot support landed in March 2026 — see Requirements above for the Mode A vs Mode B distinction).
git yes branch ops
jq yes JSON parsing in command bodies
python3 recommended helper for some checks
claude-c-suite recommended gate1 + gate2 reviewers (degrades gracefully)
claude-phd-panel optional reserved for v0.2 deep-review modes
kagura-memory optional session-start/summary + recall

Trying it out

The plugin includes a recommended end-to-end test workflow. In a throwaway test repo, open three issues:

  • Issue A — trivial typo fix (e.g. README typo). Expected: gate1=green via /ask, fastest path.
  • Issue B — medium feature ("add input validation to function X"). Expected: gate1=yellow with suggestions, mixed gate2 advisor verdicts.
  • Issue C — cross-cutting redesign. Expected: /ask declines → /ceo synthesis, gate2 audit may fail until conformance is fixed.

For each:

  1. /gh-issue-driven:doctor
  2. /gh-issue-driven:start <id> dry-run (verify no side effects)
  3. /gh-issue-driven:start <id> (real run)
  4. Implement the fix
  5. /gh-issue-driven:ship dry-run
  6. /gh-issue-driven:ship
  7. /gh-issue-driven:status

Limitations

gh-issue-driven is alpha software (v0.1.x). The orchestrated flow works end-to-end on real PRs (the plugin has been used to ship its own PRs against JFK/gh-issue-driven), but the following known sharp edges exist as of v0.1.1. None lose data or corrupt state, but they affect the operator experience:

  • Slow Mode A repos can false-positive silent_no_op (#23) — /gh-issue-driven:ship step 13 has a 30s bounded wait for the first Copilot signal. On repos where GitHub's "Automatic Copilot code review" auto-review takes longer than 30s (observed up to ~4 min on JFK/gh-issue-driven), the wait expires and the loop is incorrectly skipped with exit_reason=silent_no_op. The state file records the diagnosis correctly; recovery is to re-run /ship once the Copilot review lands. Architectural fix tracked in #23 (move detection into step 14's polling loop).
  • No resume mode (#14) — if /ship exits mid-loop (test failure, manual interrupt, silent_no_op), re-running it currently re-runs all gates from scratch instead of resuming where it left off.
  • memory.context_id default is a placeholder name (#12 — implemented in this release) — memory.context_id now accepts either a UUID or a context name (case-insensitive, resolved at runtime via list_contexts). The default value is gh-issue-driven-dev, an honest plugin-named placeholder. Users with kagura-memory installed should override it to either an actual context name (case-insensitive match against their existing contexts) or a UUID. Users without kagura-memory can ignore the field — recall is skipped automatically. Resolution failure (name not found, ambiguous, list_contexts errors) skips recall with a one-line warning and continues /start — the warning tells the operator what happened so the failure isn't silent. The current sharp edge is that /gh-issue-driven:doctor does not yet validate that the configured context_id resolves successfully — that's tracked as a v0.1.2 follow-up.
  • No loop state machine tests — the verdict parser and Copilot detection function are fixture-driven tested, but the 5 terminal exit_reason states in step 14's polling loop are not covered by automated tests yet (deferred to v0.2.0+ alongside #3).
  • claude-c-suite:audit cannot evaluate this plugin via its declared mechanism — the audit skill's scripts/audit.py does not exist in gh-issue-driven's layout. The de-facto baseline is lint.yml (which validates frontmatter, JSON syntax, version sync, fixture tests, and inline-jq sync). Filed as a v0.1.1 hardening tail follow-up.
  • No automated handling of secret-shaped values in PR bodies (#7) — the plugin generates PR bodies from commit messages and diff context. v0.2.0 will add a secret-scan abort.

For the full list of known issues, see the v0.1.1, v0.1.2, and v0.2.0 milestones.


Security

See SECURITY.md. TL;DR: this plugin runs git, gh, and reviewer skills. It never pushes to default branches, never force-pushes, never modifies ~/.claude/settings.json, and never auto-applies Copilot suggestions without scrutiny.


Development

See CONTRIBUTING.md.

CI runs lint.yml on every push and PR — JSON syntax, version sync, name sync, and command frontmatter parseability.


License

MIT © Fumikazu Kiyota


🤖 Built with Claude Code.

About

Two-phase Claude Code plugin for GitHub-issue-driven development with gated multi-reviewer pre-PR checks and a Copilot review loop.

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors