| name | ardi |
| description | Drive one PR to clean. |
| user-invocable | true |
| allowed-tools | ["Bash","Agent","Read","Edit","Write"] |
ARDI --- ARD + Iterate (single PR/MR)
Drive one PR/MR to a clean review verdict by looping: read every review → ARD every
finding from every reviewer → push → post summary → re-request review from those
reviewers → repeat until every reviewer's latest verdict is clean.
A later all-clear from one reviewer does not clear another reviewer's standing
not-clean, even with mwc active (ai-config#2274).
Procedure
- Identify and claim the PR/MR.
Use the current branch's open MR, or the one the user specified.
Post a brief claim comment (
COMMENT_PR) so a parallel @claude CI run or another person doesn't start a colliding session.
The body carries a real blank line before the disclosure marker --- \n inside a bash double-quoted string is the two characters, not a newline:
gh pr comment <N> --body "Driving this PR to clean --- please hold off until done.
_Posted by Claude Code (AI agent) --- not written by a human._" # COMMENT_PR
Skip if your most recent comment already says so and is still live --- claims expire 2 hours after the most recent push or comment, and an expired one needs reasserting, per claim-pr.
(COMMENT_PR and the other bracketed tokens below are abstract operation tokens --- resolve to your model's tool via tool-mappings.md.)
-
Read every review, not only the latest.
Pull the most recent reviewer comment --- the @claude bot's, or a human's ---
and every other review that still has a standing verdict.
Don't trust earlier cached verdicts --- actively poll until a review appears that references the commit you just pushed, then read that one.
If one review is all-clear and another raises findings or nits, the findings
win: ARD the union, then request fresh reviews.
Do not merge on the all-clear, even with mwc (ai-config#2274).
gh pr checks (PR_CHECKS) / glab ci list going green is about CI state, not the review verdict --- always parse the latest review body for findings.
A user question about this PR that is not the word "status" still requires
this fetch (see pr-status).
Don't answer the chat question from session memory while a review comment
sits unread.
When the user provides a specific review link/ID (e.g. #pullrequestreview-4761444085): Fetch that review directly via the GitHub API using its ID.
Many bot reviews have a generic overview body but the actual findings live in inline comments on specific lines --- don't rely on the top-level review body alone.
Fetch both the review overview and its inline comments:
gh api "repos/<owner>/<repo>/pulls/<N>/reviews/<review-id>" --jq '{state, body}'
gh api "repos/<owner>/<repo>/pulls/<N>/comments" --paginate --jq '.[] | select(.pull_request_review_id == <review-id>) | {line: (.line // .original_line), body}'
The comments endpoint returns pages oldest-first -- without --paginate
a later review's inline comments can sit past the first page and never
reach the filter, making a review with real findings look empty.
-
GitHub:
Filter on the body marker, not on an author login.
Do not take | last as the only review to ARD
(ai-config#2274).
Claude, Antigravity, and skip notices can all post as github-actions[bot],
so a login filter silently drops a standing not-clean.
gh api repos/<owner>/<repo>/issues/<N>/comments --paginate \
| jq -s '[.[][] | select(.body | test("\\*\\*Claude finished|### Verdict|Antigravity Agent Report"; "i"))] | .[] | {created: .created_at, user: .user.login, body: .body}' # READ_PR_COMMENTS
Completed Claude runs start the body with **Claude finished.
Read every matching comment, not only the newest.
A later all-clear from a different reviewer does not clear another
reviewer's standing not-clean.
For a reviewer (any login), also gather comments with the
skill's step 1 ( plus the inline-thread API).
Per-round checklist
Pause point: before advancing to the next round.
Do-Confirm; per
shared/workflow/skill-checklists.md.
- Repeat from step 2 until the PR/MR is fully clean (see The bar: "fully clean" -- zero findings and all CI workflows and check runs green and completed and every inline thread resolved).
Don't exit on a clean review body alone.
Fix broken CI/workflows too
If the PR's CI checks are failing (not just the review), investigate and fix them as part of the ARDI loop --- don't declare "clean" with red CI.
This includes:
- Workflow syntax errors --- fix them in this repo.
- Upstream template bugs --- if the failure is in a reusable workflow from
a shared CI library (e.g., HACtions) or a GitHub Action, file an issue (or open a PR) upstream using
the
sup skill, then either pin a working version or apply a local
workaround until the upstream fix lands.
- Flaky / infra failures --- retry once; if it persists, investigate root
cause.
The goal is green CI + clean review, not just clean review.
Delegating sidecar work
Some steps benefit from a subagent rather than blocking the round on the main
thread --- investigating a CI failure whose cause isn't obvious (see above),
verifying a reviewer's factual claim before Addressing/Rebutting it, or
checking a sibling PR for a merge conflict during the opportunistic sweep.
Delegate that via the Agent tool and keep driving the round itself (ARD,
push, post summary, re-request review) on the main thread.
For a judgment-heavy sidecar task (a subtle root-cause hunt, adjudicating a deadlocked rebuttal before escalating to a human), give the subagent a stronger model via the Agent tool's model parameter (e.g. model: 'opus').
Symmetrically, drop to a cheaper/faster tier (model: 'fable' or 'haiku') for a mechanical sidecar task --- see select-model's decision tree for both directions.
For a heavy fan-out investigation/verification pass, prefer a separately-billed provider (e.g. the codex CLI) first when available --- see delegate-to-codex.
The bar: "fully clean"
The loop ends only at fully clean, which means both:
- All CI workflows and check runs are green and completed --- every check,
not just required ones and not just the review job; never still queued or
in progress (see Fix broken CI/workflows too above, and
shared/workflow/fully-clean.md for the check-run-vs-workflow-run and
API-casing gotchas).
- Every reviewer's latest verdict is totally clean --- zero flagged items under any heading.
"Looks good" / "no findings" / "approved" with no follow-on bullets.
Every item that wasn't directly Addressed is either Deferred to a tracked issue or Rebutted with a rebuttal that actually convinced the reviewer (they didn't re-raise it on the next round).
A rebuttal the reviewer still disputes does not count as clean.
Don't stop at "ready with one minor nit."
A later all-clear from one reviewer does not clear another reviewer's standing
not-clean, even with
mwc (ai-config#2274).
That review must be a genuine posted verdict at the current head, from an external reviewer if one is reachable -- check availability again right before declaring clean, not just at the round where self-review first started; an inferred "probably clean" from green CI and resolved threads does not satisfy this.
Threads: at fully-clean, every inline review thread is resolved, and
the only conversation left open is the final all-clear exchange --- the
reviewer's all-clear comment (usually a top-level PR comment, not an inline
thread) and your reply to it. (Thread mechanics live in the ard skill, step
4b.)
Fully-clean exit checklist
Pause point: before declaring "clean" or reporting the PR ready.
Do-Confirm; per
shared/workflow/skill-checklists.md.
Stopping conditions
There is no round limit.
Always request another review.
The loop on a single PR ends on exactly three things:
- A totally clean review on the latest pushed commit -- no nits, no non-blocking comments, everything Addressed or agreed Deferred, evaluating the exact HEAD SHA currently on the branch.
Crucial: Pushing fixes for a review starts a new review cycle. The ARDI loop is NEVER finished when you push fixes for a finding-bearing review or post an ARD summary. You must wait for the new review run evaluating your latest pushed commit to post, fetch and parse that review, and confirm it contains zero findings before ending the loop. See The bar: "fully clean".
- Nothing actionable remains --- every open item has been escalated to a human and is waiting on their decision, so there is no next action you can take.
Not "some items are deadlocked"; all of them.
- The user says stop.
Nothing else.
Not a round count, not a sense that findings are getting smaller, not a judgment that the reviewer is nitpicking.
Deadlock is per-item, and it does not stop the loop.
If you and the reviewer can't reach consensus on one finding (your rebuttal didn't convince them, and their re-raise didn't convince you), escalate that item to a human reviewer rather than looping on it or unilaterally overriding.
Request the repository owner via the request-pr-review skill, @-mention them in a comment summarizing the impasse, and surface the open item to the user.
The raw gh pr edit <N> --add-reviewer <reviewer> form bypasses that skill and so does not inherit its Lacaedemon/sparta exception.
In sparta, escalate to the user in chat rather than requesting a reviewer at all.
Then keep driving the PR: address every other finding, push, and request the next review.
Only when every remaining item is an escalated deadlock does condition 2 above fire, and even then the loop resumes the moment the human rules.
Sweep-level scheduling is a different question
ardia and gia drive many PRs.
When one of those is waiting on a human --- a deadlocked item, a blocked dependency, an unresolvable conflict --- the sweep records it and moves to the next PR so the batch keeps moving.
That is scheduling, not a stopping condition for the loop: the sweep returns when the human rules, and nothing about it licenses accepting unaddressed findings on the PR itself.
"Asymptotic noise" is an anti-pattern, not a signal
This skill used to carry a guard saying that after 3-4 rounds of new nits you should surface the pattern and ask whether to continue.
That guard is removed, and reasoning of that shape must not be reintroduced.
It fails three ways:
- It fires on round count, not on finding quality.
A round producing genuine, reproducible correctness bugs is indistinguishable from a round producing style churn if all you count is rounds.
- It reads as diligence, which is exactly why it goes unexamined. Stopping
to ask feels like respecting the user's time.
- It hands triage back to the user --- the precise move
address-every-comment already forbids for individual findings.
The guard reintroduced at loop scale the thing that fragment bans at item scale.
The tell is any sentence of the form "the reviewer keeps finding things, so maybe we should stop."
Replace it with another review request.
Two things that are not this anti-pattern and stay:
- The per-item hold.
When a reviewer re-raises one already-deferred item verbatim each round, reply once pointing at the tracked issue and hold on that item, while continuing to fix every new finding.
That is about not re-litigating one item; it never stops the loop.
- Reporting the round count.
Saying "round 7, 23 findings, all Addressed" is useful information.
Attaching "shall I stop?" to it is the anti-pattern.
(ai-config#1029 is the case record: six rounds, 23 findings, all Addressed, with rounds 2-6 each finding real bugs in earlier rounds' own fixes --- including CRLF silently disabling a failure path repo-wide, a --compare reporting a zero delta, and a traversal-order-dependent measurement.
The loop stopped to ask twice under the old guard; both times the answer was to keep going, and the next round found four more real bugs.)
On clean
Post an unclaim comment (COMMENT_PR) to unblock any parallel sessions that backed off in step 1:
gh pr comment <N> --body "Done --- PR is free.
_Posted by Claude Code (AI agent) --- not written by a human._" # COMMENT_PR
Then run ums, before reporting ready.
The clean verdict is still a proactive-UMS checkpoint for this PR, not the
merge, but it is not the first one: run a pass when you read the review,
including a Rebut/Defer round, rather than holding everything for the
verdict.
See CLAUDE.md's "Run UMS proactively, as learnings accumulate".
The loop's whole point is that it ends here and hands the merge to a human,
so a pass deferred to the merge is deferred to a moment this session may
never see.
Everything the review lifecycle taught -- recurring findings, corrections,
guidance given along the way -- is complete as of the verdict.
Always provide a clickable link to the MR/PR in the final message.
Report the final verdict and round count. Don't merge unless asked.