Implement issues (one tick)
One
issue implemented end-to-end per invocation, then stop.
Compose with
for recurrence (
,
/loop 1h /implement-issues
);
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
and
exits.
Rails
- Never merge. The PR is opened for review; merging stays the maintainer's
hand (and '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. and
run on every change before the PR opens, whatever its size, and
runs 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
or , and a manual diff read is not a substitute for
. 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 (, issues, pull requests).
- If the repo has no label, there is nothing to do; exit.
1. Pick and claim one issue
Grabbable =
and unassigned
and not owned by another
active loop
and has no existing branch or open PR for it.
bash
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
.)
Take the oldest grabbable issue. If none, report and exit.
- The issue must carry an agent brief (the skill's
contract). If it has but no brief, that is a gate violation:
comment, remove , apply , and stop. Do not
implement from a bare title.
- Claim it: create the conventional branch in an isolated worktree with
(or per 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 / .
- Get the full test suite and lint/typecheck green.
- Confirm every acceptance criterion in the brief is satisfied.
- to a clean round (reviewers -> fixes -> re-verify; stop on a
clean round or on oscillation). Invoke the skill; a hand review of the diff
does not count.
- into a clean, logical commit sequence.
- whenever 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
: push and open a
non-draft PR (the branch is already
conventional, so no
rename is needed), body
, assignee
the git user, and
no verdict label (
applies that during its
independent review).
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
'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, so must be removed explicitly).
is if it needs the reporter, or if 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
: 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
's
output and produces a PR that
finalizes and verdicts. Three single-purpose passes, each
-paced, none ever merging: triage, implement, finalize.