review-auto-loop
Skill1 starsChanged 16 days agoMITView on GitHub
Review Jujutsu revision changes with external reviewer agents, in waves of parallel per-domain review chains, driven by the user. Use only when the user asks for this loop by name, or gives the go for the next wave of a loop already underway; a request to review a revision, on its own, is not enough. Do NOT use to read, answer or apply a review that already exists and was written by something else; handle those directly, without this skill.
In this repository15 other files it gives its agents.
- audit-skill-runSkill
- challenge-handoffSkill
- dot-diagramsSkill
- handoffSkill
- implem-brakeSkill
- resume-handoffSkill
- review-correctnessSkill
- review-docsSkill
- review-judgeSkill
- review-readabilitySkill
- review-testsSkill
- rust-project-maintenanceSkill
- settle-discussionSkill
- summarize-changeSkill
- web-searchSkill
The file
We split this skill into the rules it gives an agent
6 rules. About 0 are common, 6 are distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈6
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 42
Write a wave report only through the script, and do not open it: run it as a trusted helper of this skill.
- Distinctive: line 44
If wave reports for the change already exist, the loop resumes from them: the wave number, the item counters and the past decisions all …
- Distinctive: line 73
Create the wave, naming its phase or its domains, or repeating the previous one:
- Distinctive: line 168
Never apply an item the user did not pick.
- Distinctive: line 171
Never run a Jujutsu command that changes the VCS state.
- Distinctive: line 172
Only a request launches a wave: an empty wave does not end the loop, and a conversation that moves on does not have to say it has.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Review auto-loop
Review the Jujutsu changes for the target revision with external reviewer agents, and apply the review items the user picks. Reviews run in waves of parallel per-domain review chains.
Domains, phases and config
Each domain maps to an item id prefix: correctness → C, readability → R, tests → T, docs → D.
By default, a wave runs two domains in parallel: phase A waves run correctness and readability, phase B waves run tests and docs. The loop's first wave runs phase A, or all four domains at once on a revision small enough that every chain is capped at one run. The loop then moves between phases as the user decides at the end of each wave.
A wave can also run any set of domains: review init takes a comma separated domain list in place of the phase letter, and the wave then runs exactly the domains it names. Read the user's request for a wave this way:
- A phase they name brings its two domains. A
<domain>=<N>on one of them overrides its cap; one on a domain outside the phase contradicts the phase: point that out and open nothing. - Domains they name without a phase, with or without
=<N>, are the wave's domains, and no other runs:correctness=1is a correctness-only wave. - "Repeat" runs the previous wave's domains again.
- On a later wave, a request naming none of these — "another pass" — is ambiguous: ask which domains to run.
Compose a wave by hand only on the user's request.
The review script settles the rest of a wave's configuration on its own: it resolves the revision, numbers the wave, and caps every chain — the code domains from the number of lines the revision adds, tests and docs at one run, one run fewer, never below one, on a domain an earlier wave already ran. Three flags of review init carry what the user asked for, in the wording of their request:
--cap <domain>=<N>overrides a cap: on the loop's first wave for the whole loop, on a later wave for that wave alone. A cap of0excludes the domain; a wave left with no domain is not opened.--repeatopens a wave over the previous wave's domains, and takes no phase or domain list.--judgeruns a judge over the wave's items,--no-judgeruns none.
The judge is a separate agent, on by default and disabled with judge=no on the skill invocation. Once every item of a wave is assessed, it reads them all at once and recommends an action on each; that recommendation becomes the item's default at step 5. The loop's first wave sets the judge for the whole loop, --no-judge there disabling it, and every later wave inherits that setting with nothing to restate. On a later wave, --judge or --no-judge overrides that wave alone.
Chains
A domain's runs within a wave form a chain. All runs of a chain use the same prompt, which designates the chain's dir as additional previous reviews: a run reads the completed captures of the runs before it, and does not raise their items again. review chain run runs the chain's next review, and once that run completes, reports the chain's end when it was the last: a run that found no item, or one reaching the cap. Launch a chain's next run as soon as the previous one completes, unless that one reported the chain's end; do not wait for its assessment.
Files
The review dir holds, per reviewed change, one wave report per wave, one chain dir per chain holding that chain's captures, one change summary per wave, and the judgment capture of every judged wave. The review script creates and names them all, and is the only thing that ever writes there. Captures are agent stdout, never annotated: a capture holding no item is a run that found none.
Write a wave report only through the script, and do not open it: run it as a trusted helper of this skill.
If wave reports for the change already exist, the loop resumes from them: the wave number, the item counters and the past decisions all derive from the review dir.
Items
Items are numbered with the domain prefix and a counter continuous across the whole loop: C7 is the seventh correctness item the loop ever produced, whatever its wave.
The claim judges the item as the reviewer wrote it — whether its diagnosis survives reading the code, and how severe what survives is — and nothing else. It never carries a course of action. Assessing an item again replaces its assessment, until the item is judged or the report formatted.
The severity follows the claim: the reviewer's own, kept when it stands, replaced when it does not, the analysis then saying what moved it. Rate it against the ## Severity sections of <SKILL_DIR>/../review-common.md and of the item's domain skill, <SKILL_DIR>/../review-<domain>/SKILL.md, reading only those sections. State it on every item rather than let silence stand for agreement. A partly-holds item is rated on what survives, not on what the reviewer claimed. does-not-hold is the one exception: no defect survives, so there is nothing to rate.
The proposal carries the course of action, never empty:
apply— the item's fix, as the item writes it, the tail revising its estimateapply-with-changes— a different change, named by the tail, and its deltadecline— no change, the tail saying whyyour-call— a choice that is genuinely the user's; each tail argument states one option, so a reply can name it
The two are independent. An item whose claim holds still gets decline when the fix costs more than the flaw it closes; one whose claim does not hold still gets apply-with-changes when checking it uncovered a different, real change. Outside your-call the proposal never hedges: "worth doing, or skip" is not a proposal, it is apply-with-changes or your-call.
The delta an apply-with-changes carries is counted, not carried over: the item's own estimate covers the fix the reviewer wrote, and the proposal is a different change. Count that change against the code as it stands, as two net line counts, production and tests, each the lines it adds minus those it removes. Test code is test files and modules, inline test blocks such as Rust #[cfg(test)] modules, fixtures and test data; everything else is production, documentation files included. A comment counts with the code it sits in. A change rewriting lines in place counts 0. A your-call option that departs from the item states both counts the same way, inside the option's text: production +3 lines, tests 0 lines.
On an apply the item's estimate stands, and the tail is a revision of that estimate, counted the same way and restating both counts: give the tail only when either of your own counts differs, the analysis then saying what moved it. Silence there is agreement, so count before staying silent.
Declining a minor item needs no defense; declining a critical one has to name what outweighs it, and when nothing does, the severity was wrong.
The decision is added once the user has picked, exactly one per item, its reasoning never empty. Deciding an item again replaces its decision. applied-with-changes means the applied change departs from the item as the reviewer wrote it, whoever asked for the departure. Taking the proposal as offered maps verdict for verdict: apply to applied, apply-with-changes to applied-with-changes, decline to declined. A your-call item, or a pick that overrides the proposal, takes the verdict the user's choice actually produced.
Wave round
Create the wave, naming its phase or its domains, or repeating the previous one:
<SKILL_DIR>/review init <REVIEW_DIR> [<PHASE|DOMAIN,...> | --repeat] --assessor <MODEL> [--revision <JJ_REVISION>] [--cap <domain>=<N> ...] [--judge | --no-judge]--assessortakes your own model under the display name your system prompt gives it, followed by your effort level, never an identifier likeclaude-opus-5:xhigh. The effort level lives in your environment, so let the shell expand it in place:--assessor "Opus 5 $CLAUDE_EFFORT"under Claude Code,--assessor "GPT 6 Astra $HAX_EFFORT"under hax,--assessor "GPT 5.6 Sol $PI_REASONING_LEVEL"under pi. A harness exposing no effort level leaves the model named alone.On the loop's first wave, name no phase or domains unless the user asked for some: the script picks them. Pass
--revisionwhen the user supplied a revision, and leave it out otherwise: the script then resolves the most recent non-empty change. It prints the change it resolved, the wave report path, then the domain of each chain it created. That change is<JJ_REVISION>for the whole loop: pass it as--revisionon every later wave, so every wave reviews that same change, whatever the working copy holds by then. Launch the chains and the change summary in parallel, in the background, one call each (a review run takes 10 to 20 minutes, the summary a few):<SKILL_DIR>/review chain run <WAVE_REPORT> <DOMAIN> <SKILL_DIR>/review summary run <WAVE_REPORT>The summary describes the change the wave reviews, in prose an external agent writes. It lands in the report at step 4, which refuses a wave whose summary is missing or still running. Do not open its capture.
Print the header:
<SKILL_DIR>/review header show <WAVE_REPORT> <RUN><RUN>is the run the display announces:1at wave launch, the just-completed run's index on later displays. The command prints the header to the user's terminal itself; once it has run, the user has seen it.At wave launch nothing follows the header but the turn's closing sentence: the wave is open and its runs under way. Everything else about the wave is in the header.
As each run completes: read the capture whose path it printed, then, unless the run also reported the chain's end, launch the chain's next run in the background with step 1's
review chain runcommand. Then print the header again (step 2 command, with the completed run's index), then write the run's items into the wave report:<SKILL_DIR>/review item import <WAVE_REPORT> <DOMAIN> <RUN> <SKILL_DIR>/review item assess <WAVE_REPORT> <ID> <CLAIM> [<SEVERITY>] <PROPOSAL> [<TAIL> ...] <<'EOF' <the analysis> EOFitem importquotes every item of the run into the report, in item order, and prints the id it gave each, which is where<ID>comes from. One form per proposal,applywith and without its tail, each taking the analysis on stdin as above:<SKILL_DIR>/review item assess <WAVE_REPORT> C3 holds major apply <SKILL_DIR>/review item assess <WAVE_REPORT> C4 holds major apply --delta-lines-prod -8 --delta-lines-tests +12 <SKILL_DIR>/review item assess <WAVE_REPORT> R2 partly-holds minor apply-with-changes --delta-lines-prod +3 --delta-lines-tests 0 '<what to do instead>' <SKILL_DIR>/review item assess <WAVE_REPORT> R5 does-not-hold decline '<why not>' <SKILL_DIR>/review item assess <WAVE_REPORT> T1 holds minor your-call '<one option>' '<another>'item assessechoes ayour-call's options under the item id, lettered in the order given: that letter is what a pick names. Assess each item by reading the code it talks about and checking its claims and its severity rather than trusting them, and write the analysis at whatever length it deserves. Flag in its analysis an item colliding with one from another domain of the wave, so the user can weigh them together; when an item duplicates one from another domain or from a past wave, say so instead of assessing it twice.When every chain has ended and every item is assessed, print the header once more; on a judged wave, launch the judge in the background first, in a call of its own, then print the header and end the turn there: it is a long agent run, and nothing else proceeds while it works.
<SKILL_DIR>/review judge run <WAVE_REPORT>It rules on every item of the wave in one run, writes its recommendations into the report, and prints them. It refuses a wave that produced no item; go straight to the format, which such a wave needs all the same.
Then write the report's top part, item index and links:
<SKILL_DIR>/review report format <WAVE_REPORT>It refuses a wave whose chains are unfinished, whose change summary is missing, or whose items are not all in the report and assessed — and, on a judged wave, not all ruled on. The command prints the wave's recap — the item total, the count per proposal verdict, and the items carrying each — to the user's terminal, a judged wave adding the same counts by judge recommendation. Then, unless the wave produced no item, open the wave report for them with
xdg-open <WAVE_REPORT>. The report is the wave's user-facing artifact: never reproduce or summarize its contents in the conversation. Nothing follows the recap but the turn's closing sentence.Let the user pick, item by item. A bare
applyresolves against that item's proposal, never against the reviewer's text:- proposed
applyorapply-with-changes— carry out the proposal - proposed
decline— the user is overriding the decline; carry out the item as the reviewer wrote it, and say so before acting - proposed
your-call— a bareapplyis not an answer; ask which option
On a judged wave every item carries a default instead: the judge's recommendation, or the item's own proposal where the judge agreed with it. A reply naming no item — "go", "ok" — settles those items at their default, and the user overrides by naming items: "go, but decline C1". A bare
applyon a named item then resolves against the recommendation rather than against the proposal, and ayour callitem is settled by the judge's lettered pick.A pick may also override the proposal with an instruction of its own, which then replaces it. If their reply asks anything, answer it and change nothing, then wait again: the next message carries the picks, or more questions. Move to step 6 only on a reply that asks nothing.
- proposed
- Apply the picked items in canonical domain order — correctness, readability, tests, docs. When two picked items collide, apply the correctness one first and adapt the other to the resulting code. Describe your changes so the user can review them.
Record the decisions, one invocation per item:
<SKILL_DIR>/review item decide <WAVE_REPORT> <ID> --verdict <VERDICT> <<'EOF' <the reasoning> EOFThe reasoning records any change of course agreed in the conversation after the assessment. Run it again for an item whose decision changes later: it replaces the decision. Never open or show the annotated report.
- Summarize the wave — what the user decided, and what the applied changes touched — then ask once which move comes next: repeat the domains this wave ran, or move to the ones it left out, named as phases when the wave ran a phase. A wave that ran every domain leaves only the repeat to offer. Ending the loop is not offered as a third: it is what happens when no wave is asked for.
- Wait. The user now reviews the changes, may ask questions or request further edits, and squashes into the reviewed revision. Launch the next wave only on their explicit go, never before: reviews must only ever see squashed state. Step 8's question is never restated; a loop nobody comes back to is over.
Rules
review header showandreview report formatare run verbatim: no pipe, no redirection, nohead/tail/grep, no output limit, alone in their call. Their output is for the user, not for you to digest, so its length is never a reason to trim it.- What
review header showandreview report formatprint reaches the user's terminal as it is printed. Never quote it back, restate its figures, or summarize it. - Issue independent operations together rather than one per turn: several tool calls in one message, several
reviewinvocations in one shell call. Theruncommands are the exception: each is a call of its own, put in the background by the harness, never by a shell&. - Never apply an item the user did not pick.
- Apply each picked item completely: carry the change through every aspect it naturally touches, even ones another domain owns — a correctness fix ships with its test, and with the cleanup or documentation update the same change calls for. Never leave part of a change undone because a later wave would cover that aspect.
- Get an explicit approval and explicit choices from the user. If an answer is ambiguous, or leaves one of your questions unanswered, ask again rather than assume a default.
- Never run a Jujutsu command that changes the VCS state. The user handles the VCS between waves.
- Only a request launches a wave: an empty wave does not end the loop, and a conversation that moves on does not have to say it has.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

