Revi → Billy on this repo — the operating habit
When Revi (bots/review-pr) reviews a pull request of this repository and leaves findings, the habit is to comment /billy on the PR and let the fixer work — not to hand-fix the findings in an interactive session. iterion is a code factory; its own PRs are the first place its review→fix loop must earn its keep. Every /billy run here is a dogfood run: monitor it, fix the frictions it surfaces (bot or engine), and write the bilan.
This runbook is the habit; the mechanics live in merge-gate.md (gate, reconciler, two-bots-one-context) and bots/branch-improve-loop/README.md (the campaign shape). For the three-way picture — Revi, Billy, and Vetty (dep-update-guard) sharing one gate — see merge-gate.md's "Revi / Billy / Vetty — one gate, three roles": what is wired (disjoint ownership, the ~4s claim window, the produces:/consumes: hand-off), what is not yet (the pause notice naming a parked run's role, a "fixer in flight" signal before its first push), and the operator rules this file's session-discipline section below also lives by.
The command
On the PR, comment:
/billy(aliases: /improve, /branch-improve-loop; optional free text after the command lands in scope_notes). The commenter must hold maintainer+ on the repo (min_replier_role on the command — verified live via the forge permission API, not from the payload).
There is deliberately no PR-open auto-launch for Billy: opening a PR only ever auto-REVIEWS it (Revi). Billy runs on a deliberate command — and, since 2026-08-28, on a red gate: the zero-touch lane (auto_fix_on_gate_failure — a red gate launches the fixer by itself, merge-gate.md#autofix) is enabled on this repo, the manual habit having proven smooth. A red revi/review relaunches the fixer without a comment, bounded by the lane's own brakes (one attempt per head sha, five unattended passes per PR, the hold label). /billy remains the way to start a pass when the gate is green or the lane's passes are spent. One gotcha when flipping the flag: the repo-bots PATCH requires the FULL bot_ids list in the payload (omitting it is a 400, not "keep as is").
Corollary of the lane: before hand-fixing a red PR, check no fixer run is already in flight on it (iterion remote runs list or the gate's pending link) — a manual push while the fixer works recreates the mid-run-push collision the session discipline below warns about.
What the command seeds — you type nothing else
The webhook tail resolves everything from the PR and the repo integration:
prior_review— the latest review of this PR, findings + ready-made replacements, seeded through the kind-matched hand-off (consumes: kind: reviewin Billy's manifest ←produces:in Revi's; pkg/server/webhooks_handoff.go). Billy re-checks every finding against the current diff rather than trusting a stale verdict, and still runs fine when no review exists.push_branch/pr_url— his commits are pushed onto the PR's source branch, and his finding ledger (per finding id: fixed / refused-with-argument / deferred) is posted as a comment ON the PR.gate_context+ publish grant — from the integration'slaunch_vars(revi/reviewhere), so he can post his own gate count on the head he pushed.
What to expect on the PR
Billy verifies each prior finding, fixes the real ones one commit per fix (build+test before each commit), and pushes onto the PR branch.
He posts the ledger comment and a gate status on the head he pushed — a count, never a judgement; a green from Billy says so in its description.
His push is a
synchronize, so Revi re-reviews the new head and its independent verdict supersedes minutes later. A finding Billy contested (with an argument, in the ledger) is handed to the next review as pushback — and to you: a contested finding keeps the gate red until a human decides (/revi approve [reason], maintainer-gated).That third step is not free — it needs
review_on_syncon the repo's webhook config. The orchestrator derives it ON whenever a bot of the webhook gates merges (declares thestatusesscope) and the gate is not disabled, unless an operator pinned the value (pkg/forge/orchestrator.go,ReviewOnSyncPinned); a repo that only ever auto-reviews on open has it off, and Billy's push there ends the loop until someone comments/revi. Check it before concluding the loop is broken:iterion remote api GET /api/teams/<team-id>/webhooks→review_on_sync.While Billy runs, the PR looks untouched —
revi/reviewstays green on the OLD head and no status says a fixer is at work: the only signals are the run itself (iterion remote runs list, the run console) and, when he parks on a quota, the platform's pause notice. That notice is written for a review and currently mislabels a parked fixer ("Review paused … a new push restarts it sooner" — a push is exactly what NOT to do while he works; SocialGouv/iterion#650). Nothing is wrong: wait for his push, or for thependingclaim that follows it.
Session discipline (the gotchas)
- Don't work on the PR branch while Billy runs — he pushes onto it. After his push,
git pullbefore resuming any local work on that branch. - Only invoke him on PRs you own (or with the author's accord): he rewrites their branch.
- Monitor, don't fire-and-forget: the run console link is on the
pendinggate status; oriterion remote runs/ theremote_run_logMCP tool. Proof of a good run = ledger comment + commits on the branch + gate status on the new head + Revi's re-review landing after it. - He posts nothing? Check the run's inputs for
forge_publish_urlandgate_contextbefore blaming the bot (merge-gate.md). - Usage caps park runs: a review or fix run that dies on
usage cap: … windowisfailed_resumablewith the usage-window retry armed — it resumes at the provider reset by itself (usage-caps.md). Don't relaunch it by hand. - A death is not a loss — the pod's commits are BANKED on
iterion/run-<run-id>(final_branch/final_commiton the run doc; the richer chain of successive attempts wins). But a resume re-clones the branch head and restarts the campaign from scratch, redoing the banked work (SocialGouv/iterion#652). If the retry cannot finish in the budget left, deliver the banked chain by hand: fast-forward it onto the PR branch AFTER the full validation (task check,-race, conformance — a chain committed in stride is not gate-verified and can be red), say so on the PR, and letreview_on_syncre-review the head. - Never bare-resume a duration death on cloud. The consumed duration axis rides the checkpoint, so
iterion remote runs resumerestarts and dies at the 110 % exit-grace ceiling (15 min of pod for nothing). The cloud resume endpoint has no budget-override fields; raise the cap by resuming with the bot source inline:POST /api/runs/<id>/resumewith{"source": <main.bot with a larger max_duration>, "force": true}— the checkpoint restarts insidecampaign, the plan phases are not re-paid. - When the WEEKLY cap parks the gate, the reset can be days out and the review's
pendingclaim blocks the PR that long. The documented maintainer override (/revi approve, merge-gate.md) currently fails on a GitHub App integration (set commit status: forge: insufficient scope, SocialGouv/iterion#662): the fallbacks are the admin's own status write on the head (same context, "approved by @user: reason" in the description, the comment astarget_url) or the admin merge-queue bypass. - "Don't hand-fix" assumes Billy can run. When the weekly cap is hard-blocking, the reset can be days out and the habit has no path: fix the findings yourself, say so on the PR against their finding ids, and write the bilan for the launches that failed. Same when he burns his duration cap without banking a commit — on a repo whose verify gate re-runs the whole build+test (~10 min a pass here), 2h30 buys few passes, so a run sitting at
runningwith nothing pushed is worth cancelling rather than waiting out (measured 2026-08-30: 2h31 for zero commits, see bot-runs/branch-improve-loop.md).
Dogfood duty
Every /billy run on this repo gets a dated bilan in docs/bot-runs/branch-improve-loop.md (newest-first — status, method, result, value, frictions, lessons). A friction found here is a defect to fix in stride — in the bot (bots/branch-improve-loop/) or the engine — that is the point of running the loop on ourselves.
The 2026-09-03 run on the watchdog PR (#646) is the reference for the banked-chain delivery and the weekly-cap wall: bot-runs/branch-improve-loop.md.
