One ready-for-agent issue implemented end-to-end per invocation, then stop.
Compose with /loop for recurrence (/loop /implement-issues,
/loop 1h /implement-issues); /loop owns pacing. Never schedule yourself.
This is the middle leg of the loop pipeline:
process-issues -> implement-issues -> process-prs
(ready-for- (non-draft PR, (review +
agent issue) Closes #N) recommend-* verdict, you merge)
State derives entirely from GitHub (labels, assignees, branches, open PRs), so a
tick is idempotent: with no grabbable issue it costs one gh issue list and
exits.
Rails
- Never merge. The PR is opened for review; merging stays the maintainer's
hand (and
/process-prs's verdict is a recommendation, not an action). - Never ship a guess. If the brief is underspecified or the work can't reach green, abort and demote (see below), never open a speculative PR.
- The finalize gates are mandatory, not optional.
/review-fixand/recommitrun on every change before the PR opens, whatever its size, and/verifyruns whenever the change is behavioral and a smoke is practical. "It's a one-line / test-only / obviously-correct change" is not grounds to skip/review-fixor/recommit, and a manual diff read is not a substitute for/review-fix. That rationalization is exactly how unreviewed AI-slop lands in a PR. Skipping a gate that applies is a process violation; if one genuinely cannot run, say so explicitly in the report rather than silently dropping it. - Never take an issue owned by another loop. Only unassigned issues are grabbable; assignment is the ownership signal.
- Never touch clean-room / relicensing issues. Those are owned by their own dispatcher and run under a protocol that forbids reading the prior implementation. This pass reads the brief and explores the codebase normally, which would contaminate such work. The unassigned-only rail keeps it out, but treat this as a hard boundary.
- Every issue comment starts with a disclaimer:
> *This was generated by AI during implementation.*.
0. Preflight
- Abort if not a git repo, or if there is no GitHub remote. This skill is
GitHub-only (
gh, issues, pull requests). - If the repo has no
ready-for-agentlabel, there is nothing to do; exit.
1. Pick and claim one issue
Grabbable = ready-for-agent and unassigned and not owned by another
active loop and has no existing branch or open PR for it.
gh issue list --state open --label ready-for-agent \
--json number,title,createdAt,assignees \
--jq '[.[] | select((.assignees | length) == 0)] | sort_by(.createdAt) | .[0]'
(gh issue list --assignee "" does not filter to unassigned, so the
unassigned check lives in the jq.)
Take the oldest grabbable issue. If none, report and exit.
- The issue must carry an agent brief (the
triageskill'sAGENT-BRIEF.mdcontract). If it hasready-for-agentbut no brief, that is a gate violation: comment, removeready-for-agent, applyneeds-triage, and stop. Do not implement from a bare title. - Claim it: create the conventional branch in an isolated worktree with
git wt feat/<N>-slug(orfix/<N>-slugper the issue's category; ignored files travel into the worktree), and assign the issue to yourself (gh issue edit <N> --add-assignee @me). The branch and the assignee are the claim, so a later tick or another loop skips it.
2. Implement and finalize
Work entirely in the worktree, treating the agent brief as the contract (the issue body is context); run the steps below in order:
- Implement the brief. Read code before changing it; touch only what the brief
requires; respect any ADRs /
CONTEXT.md. - Get the full test suite and lint/typecheck green.
- Confirm every acceptance criterion in the brief is satisfied.
- Run
/review-fix specification compliance, correctness, and repository standards.cleanpasses the gate;incompleteaborts and demotes under step 4. A hand review does not count. - If the working tree is dirty, run
git-hunk skills get core logical-commitsand usegit-hunkto commit the implementation and review repairs as logical commits. Then/recommitthe branch into its final commit sequence. /verifywhenever the change is behavioral and a smoke is practical (the skill picks the method per project type). This is the one conditional gate: skip it only when the change is non-behavioral (e.g. test-only or docs) or no smoke is practical, and note the reason in the report.
3. Open the PR
/sending-pull-request: push and open a non-draft PR (the branch is already
conventional, so no rename is needed), body Closes #N, assignee
the git user, and no verdict label (/process-prs applies that during its
independent review). /sending-pull-request drafts PRs it opens autonomously by
default, so pass an explicit ready (non-draft) request to override that;
otherwise the
PR lands as a draft and /process-prs's non-draft queue never picks it up.
Record the PR url in the report and stop.
4. Abort and demote
If the brief proves underspecified mid-implementation, or the work cannot reach green:
- Remove the worktree and branch (releases the claim, leaves no cruft).
- Unassign the issue (
gh issue edit <N> --remove-assignee @me). - Post a disclaimer-prefixed comment naming the specific blocker (the ambiguous requirement, the failing behavior, what a human must decide).
- Demote by swapping the labels with
gh issue edit <N> --remove-label ready-for-agent --add-label <state>(GitHub labels are additive, soready-for-agentmust be removed explicitly).<state>isneeds-infoif it needs the reporter, orready-for-humanif it needs a maintainer decision or a human to get it green.
No PR. The demoted issue re-enters the pipeline rather than dying silently.
Report
End with one line for /loop: the issue implemented and the PR url, the
abort + demotion, or "no unassigned ready-for-agent issue this tick." If a
finalize gate was skipped or could not run, note which and why alongside that
line.
Composition
Consumes /process-issues's ready-for-agent output and produces a PR that
/process-prs finalizes and verdicts. Three single-purpose passes, each
/loop-paced, none ever merging: triage, implement, finalize.