Read when: changing Clownfish PR repair automation, ClawSweeper review integration, comment routing, duplicate dispatch guards, or generated-PR marking.
Clownfish-created PRs and maintainer-opted existing PRs should keep improving after they are opened. When ClawSweeper reviews an opted-in PR and leaves actionable feedback, Clownfish can dispatch the backing job again and update the existing branch when safe. It must not create another PR for the same issue cluster unless the source branch cannot be safely updated, and it must not react to ordinary contributor comments.
The loop is intentionally small:
- Clownfish opens
clownfish/<cluster-id>or a maintainer comments/clownfish automergeon any open PR. - Clownfish dispatches ClawSweeper's item-specific
repository_dispatchlane to review that PR head. - The comment router sees trusted ClawSweeper feedback.
- Clownfish dispatches the existing or adopted job through
cluster-worker.yml. - The repair worker pushes another commit to the source branch if it finds a safe, narrow fix, or opens a credited replacement when the source branch cannot be safely updated.
- ClawSweeper reviews the updated PR again.
There are two accepted input lanes.
Maintainer commands:
- author association must be
OWNER,MEMBER, orCOLLABORATORby default; - when GitHub App tokens return a weaker association for a maintainer, the
router falls back to repository collaborator permission and accepts
admin,maintain, orwriteby default; - supported commands are
/clownfish fix ci,/clownfish address review,/clownfish rebase,/clownfish automerge,/clownfish status,/clownfish explain, and/clownfish stop; - commands from contributors are ignored without a reply.
Trusted automation:
- author login must be in
CLOWNFISH_TRUSTED_BOTS; - default trusted bot logins are
clawsweeper[bot]andopenclaw-clawsweeper[bot]; - the target must be a Clownfish PR or a PR labeled
clownfish:automerge; - the action becomes
clawsweeper_auto_repair.
The trusted automation lane exists only for review bots we control. It does
not treat random @clownfish, @openclaw-clownfish, or contributor prose as
permission to spend workers or push commits.
ClawSweeper comments are meant to be readable by maintainers and parseable by Clownfish. The visible text should say whether the PR needs changes, what change is required before merge, what acceptance criteria would prove the fix, what evidence was checked, and what risk remains.
The hidden markers at the bottom are the automation contract. Clownfish should prefer markers over prose whenever they exist. The action marker is omitted for pass, approved, needs-human, failed, or inconclusive reviews.
The router considers a PR to be from Clownfish when any of these are true:
- branch starts with
clownfish/; - the PR has the
clownfishlabel; - PR author login is in
CLOWNFISH_AUTHOR_LOGINS.
The branch prefix is the durable identity because it maps directly back to the cluster id and job path. The label and author checks are compatibility markers for already-open PRs and dashboard tools.
Maintainers can opt any open PR into the bounded merge loop with:
/clownfish automerge
The command adds clownfish:automerge, asks ClawSweeper to review the current
PR head, creates a durable adopted Clownfish job when the PR is not already
backed by one, and leaves an idempotent comment. The adopted job lives at
jobs/<owner>/inbox/automerge-<owner>-<repo>-<pr>.md; it lets the normal
repair worker update the contributor branch when GitHub says that is safe, or
open a credited replacement when it is not. /clownfish stop pauses the loop
by adding clownfish:human-review.
If the repair worker completes without an executable fix artifact, the executor posts an idempotent outcome comment on the opted-in PR. That comment records that no branch push, rebase, replacement PR, merge, or ClawSweeper re-review was started, and includes the worker summary plus planned/skipped actions.
Automerge has two explicit gates:
CLOWNFISH_ALLOW_MERGE=1
CLOWNFISH_ALLOW_AUTOMERGE=1If ClawSweeper passes the exact current head while either gate is closed,
Clownfish labels the PR clownfish:merge-ready and comments instead of
merging.
Preferred ClawSweeper comments should include hidden verdict and action markers:
<!-- clawsweeper-verdict:needs-changes sha=<head-sha> finding=<id> -->
<!-- clawsweeper-action:fix-required sha=<head-sha> finding=<id> -->Positive or human-only reviews should use a verdict marker without a repair action:
<!-- clawsweeper-verdict:pass sha=<head-sha> -->
<!-- clawsweeper-verdict:needs-human sha=<head-sha> -->Accepted marker actions:
fix-requiredrepair-requiredaddress-reviewfix-ci
Accepted repair verdicts:
needs-changeschanges-requestedfix-requiredrepair-required
pass, approved, and no-changes verdicts never repair. On a PR opted into
clownfish:automerge, a pass verdict for the exact current head can merge only
after required checks, mergeability, review state, and both merge gates are
green. needs-human still wakes the bounded repair/rebase loop for an opted-in
PR so Clownfish can reconcile conflicts, failing checks, and review follow-up
before asking again. human-review and /clownfish stop pause automerge by
adding clownfish:human-review.
The router also has a conservative fallback for current ClawSweeper review
comments. It only applies to trusted bot authors and looks for phrases like
keep this PR open, needs follow-up, still missing, unresolved review,
or failing checks. It ignores positive summaries such as no actionable,
looks good, safe to merge, and no findings.
The marker is still the preferred contract. It is easier to audit and safer than relying on prose.
Clownfish has three layers of duplicate protection:
- job creation checks for an existing open PR or branch before writing a new job;
- the comment router writes an idempotency marker in its reply and records
processed comment versions in
results/comment-router.json; - trusted ClawSweeper repairs are capped per PR and per PR head SHA.
The default caps are five automatic repair iterations per PR and one auto-repair dispatch per PR head SHA:
CLOWNFISH_CLAWSWEEPER_MAX_REPAIRS_PER_PR=5
CLOWNFISH_CLAWSWEEPER_MAX_REPAIRS_PER_HEAD=1That means many ClawSweeper comments on the same commit trigger at most one repair run. If Clownfish pushes a new commit, the PR head SHA changes and a new ClawSweeper finding can trigger one more repair run, until the PR reaches five automatic ClawSweeper-triggered repair iterations. The per-PR cap is total across all head SHAs and stops the automatic review/repair loop even when every iteration produces a new commit.
Runs for the same job path and mode share the cluster-worker.yml concurrency
group, so repeated dispatches queue instead of racing the same branch.
ClawSweeper edits one durable review comment in place. The router keys its
ledger by comment id plus updated_at, and response markers include the target
PR head SHA, so an edited ClawSweeper comment can trigger a new repair after
Clownfish has pushed a new commit while unchanged comment versions remain
idempotent.
The router does not dispatch when:
- the comment author is not trusted automation and is not a maintainer;
- the issue or PR is closed;
- the target is not a PR;
- the PR is neither a Clownfish PR nor labeled
clownfish:automerge; - the PR cannot be mapped to or adopted into a job file;
- the same comment version was already processed;
- the same PR already reached the total auto-repair cap;
- the same PR head SHA already reached the per-head auto-repair cap;
- the ClawSweeper marker names a stale PR head SHA.
Automerge also refuses to merge when:
clownfish:automergeis missing;clownfish:human-reviewis present;- the pass marker does not name the reviewed head SHA;
- the PR is draft, not based on
main, not mergeable, or has non-green checks; - GitHub reports requested changes or required review;
CLOWNFISH_ALLOW_MERGEorCLOWNFISH_ALLOW_AUTOMERGEis not1.
For trusted automation comments, these blocked cases are silent skips. That keeps Clownfish from replying to every ordinary contributor PR that ClawSweeper reviews.
Security-sensitive reports stay out of this lane. Those should be routed to the central OpenClaw security process rather than auto-repaired from review comments. The automerge planner does not infer security status from prose; it uses explicit security labels or structured ClawSweeper security markers such as:
<!-- clawsweeper-security:security-sensitive item=<pr> sha=<head-sha> -->Workflow:
.github/workflows/comment-router.yml
Scripts:
scripts/comment-router.mjsscripts/comment-router-core.mjsscripts/comment-router-utils.mjs
Durable state:
results/comment-router.jsonresults/comment-router-latest.json
Important knobs:
CLOWNFISH_COMMENT_ROUTER_EXECUTE=1enables scheduled writes and dispatches;CLOWNFISH_TRUSTED_BOTScontrols trusted automation authors;CLOWNFISH_AUTHOR_LOGINScontrols PR author identities treated as Clownfish;CLOWNFISH_CLAWSWEEPER_MAX_REPAIRS_PER_PRcontrols total automatic repair iterations per PR; default5.CLOWNFISH_CLAWSWEEPER_MAX_REPAIRS_PER_HEADcontrols per-head repair caps; default1.
Syntax and workflow checks:
node --check scripts/comment-router.mjs
node --check scripts/comment-router-core.mjs
node --check scripts/comment-router-utils.mjs
actionlint .github/workflows/comment-router.ymlDry-run the router against live recent comments:
npm run comment-router -- \
--repo openclaw/openclaw \
--lookback-minutes 180 \
--max-comments 100The scheduled workflow remains dry unless CLOWNFISH_COMMENT_ROUTER_EXECUTE=1
is set or a maintainer manually dispatches the workflow with execute=true.