You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(loop): rebase — automated rebase-after-sibling-merge for unmergeable bot PRs (issue #96, part 3)
Adds pr-rebase.sh (detects bot PRs that went mergeable=CONFLICTING against
base, excluding feedback/comment-fix/ci-fix candidates, with a per-base-commit
anti-livelock budget of 2 attempts before escalating to needs-human) and wires
it into loop-tick.sh's verdict chain (rebase sits between ci-fix and advance),
loop-daemon.sh's transient unit naming, and loop-event.sh's driver-prompt
builder (label claude-rebasing, rebase onto base, force-push-with-lease on
clean, abort+escalate on conflict). Also threads rebase_prs into
loop-census.sh's cadence telemetry so a rebase-only backlog still ticks FAST,
and updates pr-loop.md/pr-loop-self.md's STEP 0 docs to match.
Copy file name to clipboardExpand all lines: .claude/commands/pr-loop.md
+6-5Lines changed: 6 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -23,18 +23,19 @@ Prompt to use (the tick logic, with adaptive STEP 0):
23
23
24
24
> Run one tick of the autonomous PR loop. ALL `gh` interaction (yours and every agent's) MUST run as the bot via `.claude/scripts/bot-gh.sh` — never bare `gh`; only `git` commits/pushes stay as the owner.
25
25
>
26
-
> STEP 0 — run the tick. Invoke, as a REAL bash tool call, exactly: `bash ${CLAUDE_PLUGIN_ROOT:-.claude}/scripts/loop-tick.sh`. This one script runs census, then notify-poll.sh, merge-ready.sh, pr-feedback.sh, pr-comment-fix.sh, and pr-ci-fix.sh, IN ORDER, with their full output, and ends with exactly one machine-readable verdict line as the LAST line of output: `action=none`, `action=advance issue=N`, `action=feedback pr=N`, `action=comment-fix pr=N`, or `action=ci-fix pr=N`. That verdict line is the SOLE source of truth for what to do next: never hand-count open PRs, planned issues, feedback PRs, comment-fix PRs, or CI-red PRs yourself, and never skip this invocation because the tick "looks quiet" — it must run, and its output must be read, on every single tick with no exceptions.
26
+
> STEP 0 — run the tick. Invoke, as a REAL bash tool call, exactly: `bash ${CLAUDE_PLUGIN_ROOT:-.claude}/scripts/loop-tick.sh`. This one script runs census, then notify-poll.sh, merge-ready.sh, pr-feedback.sh, pr-comment-fix.sh, pr-ci-fix.sh, and pr-rebase.sh, IN ORDER, with their full output, and ends with exactly one machine-readable verdict line as the LAST line of output: `action=none`, `action=advance issue=N`, `action=feedback pr=N`, `action=comment-fix pr=N`, `action=ci-fix pr=N`, or `action=rebase pr=N`. That verdict line is the SOLE source of truth for what to do next: never hand-count open PRs, planned issues, feedback PRs, comment-fix PRs, CI-red PRs, or unmergeable PRs yourself, and never skip this invocation because the tick "looks quiet" — it must run, and its output must be read, on every single tick with no exceptions.
27
27
>
28
-
> CADENCE: the script's `=== 1/6 loop-census.sh ===` section includes a line `cadence=FAST|WATCH|IDLE cron=<expr>` — this is the desired cadence; consume it as-is, do NOT re-derive it from counts. If this cron job's current schedule differs from that `cron=<expr>`, CronDelete this job and CronCreate a durable replacement with this SAME prompt at the desired schedule.
28
+
> CADENCE: the script's `=== 1/7 loop-census.sh ===` section includes a line `cadence=FAST|WATCH|IDLE cron=<expr>` — this is the desired cadence; consume it as-is, do NOT re-derive it from counts. If this cron job's current schedule differs from that `cron=<expr>`, CronDelete this job and CronCreate a durable replacement with this SAME prompt at the desired schedule.
29
29
>
30
-
> Then obey the verdict line (the tick already ran poll/merge/feedback-detection/comment-fix-detection/ci-fix-detection above — do not re-run those scripts). Precedence when more than one is ready: `feedback` > `comment-fix` > `ci-fix` > `advance` (a PR with unaddressed feedback outranks everything; a PR with an unresolved qualifying review-comment thread outranks a CI fix or a fresh advance):
30
+
> Then obey the verdict line (the tick already ran poll/merge/feedback-detection/comment-fix-detection/ci-fix-detection/rebase-detection above — do not re-run those scripts). Precedence when more than one is ready: `feedback` > `comment-fix` > `ci-fix` > `rebase` > `advance` (a PR with unaddressed feedback outranks everything; a PR with an unresolved qualifying review-comment thread outranks a CI fix, a rebase, or a fresh advance; a CI fix outranks a rebase or a fresh advance; an unmergeable PR needing a rebase outranks only a fresh advance):
31
31
> -`action=feedback pr=N` → address PR N's feedback: run orchestrator → worktree implementer → reviewer lenses (per .claude/gates.json) on the SAME branch, push to update the PR in place, and post the `<!-- claude-addressed -->` marker comment via bot-gh.sh. Do NOT merge.
32
-
> -`action=comment-fix pr=N` → address PR N's unresolved review-comment thread(s): label the PR `claude-comment-fixing` via bot-gh.sh first (in-flight guard), then run orchestrator → worktree implementer on the SAME branch (checkout the PR's existing branch, do NOT create a new one) → reviewer lenses (per .claude/gates.json), push to update the PR in place. For each thread you actually addressed, resolve it on GitHub and post a bot comment containing `<!-- claude-comment-addressed:<thread-id>:<attempt> -->` for each (the real thread id and attempt number from the `5/6 pr-comment-fix.sh` section above) so pr-comment-fix.sh's cursor recognizes it as addressed. Do NOT merge, and do NOT force-push.
32
+
> -`action=comment-fix pr=N` → address PR N's unresolved review-comment thread(s): label the PR `claude-comment-fixing` via bot-gh.sh first (in-flight guard), then run orchestrator → worktree implementer on the SAME branch (checkout the PR's existing branch, do NOT create a new one) → reviewer lenses (per .claude/gates.json), push to update the PR in place. For each thread you actually addressed, resolve it on GitHub and post a bot comment containing `<!-- claude-comment-addressed:<thread-id>:<attempt> -->` for each (the real thread id and attempt number from the `5/7 pr-comment-fix.sh` section above) so pr-comment-fix.sh's cursor recognizes it as addressed. Do NOT merge, and do NOT force-push.
33
33
> -`action=ci-fix pr=N` → fix PR N's failing CI: label the PR `claude-ci-fixing` via bot-gh.sh first (in-flight guard), then run orchestrator → worktree implementer on the SAME branch (checkout the PR's existing branch, do NOT create a new one) → reviewer lenses (per .claude/gates.json) to fix the failure, push to update the PR in place. After pushing, query the PR's current head SHA (`bot-gh.sh pr view N --json headRefOid`) and post a bot comment containing exactly `<!-- claude-ci-addressed:<head-sha> -->` (the real SHA substituted in) so pr-ci-fix.sh's cursor recognizes this head as already addressed. Do NOT merge, and do NOT force-push.
34
+
> -`action=rebase pr=N` → rebase PR N onto base: label the PR `claude-rebasing` via bot-gh.sh first (in-flight guard), checkout the PR's EXISTING branch/worktree (do NOT create a new one), `git fetch` then `git rebase origin/<baseBranch>`. On a CLEAN rebase: `git push --force-with-lease`, rerun the adapter's gates, and post a bot comment containing `<!-- claude-rebase-attempted:<base-sha>:<attempt> -->` (the real base SHA and attempt number from the `7/7 pr-rebase.sh` section above) so pr-rebase.sh's cursor recognizes this attempt. On a CONFLICT: `git rebase --abort` (never leave the worktree mid-rebase), label the PR `needs-human`, and post a comment explaining the conflict (also containing the same marker). NEVER merge, and NEVER force-push anything but this bot-owned branch.
34
35
> -`action=advance issue=N` → advance issue N through the orchestrator (scope → worktree implementer → gate.sh gates → reviewer lenses → bot PR). One issue in flight at a time. `backlog` issues are owner-unapproved: never pick them, and if you file an issue yourself, label it `backlog` — NEVER `planned` (that label is the owner's formal approval and is assigned by the owner alone; see docs/USAGE.md → "Autonomous loop & the issue queue").
35
36
> -`action=none` → reply exactly one line: "No actionable activity." This is the ONLY path to that phrase — never reply it without loop-tick.sh having actually been invoked (and its output read) earlier in this same turn.
36
37
>
37
-
> Token discipline: only read docs/USAGE.md and .claude/agents/* when the verdict actually requires orchestrating agents (advance/feedback/ci-fix); an `action=none` tick needs only the script's own output. Keep the tick report to a few lines — it is telemetry, not documentation.
38
+
> Token discipline: only read docs/USAGE.md and .claude/agents/* when the verdict actually requires orchestrating agents (advance/feedback/ci-fix/rebase); an `action=none` tick needs only the script's own output. Keep the tick report to a few lines — it is telemetry, not documentation.
38
39
39
40
## 2. Run one tick now
40
41
Execute the tick logic above immediately so the loop doesn't wait for the next cron fire. Report what happened (polled items, merges, feedback addressed, issue advanced — or "No actionable activity").
0 commit comments