From 640c3ae393dc1bf78c1f235d3a50ac5437e60266 Mon Sep 17 00:00:00 2001 From: fredericrous Date: Thu, 8 Oct 2026 20:05:13 +0200 Subject: [PATCH] feat(skills): merge on green after the push worktree-task gains F9, which runs merge-when-green on every PR the finish opened instead of stopping at an open PR; teardown moves to F10 so a red check can still be fixed in the worktree. The skill and CLAUDE.md say so, citing work.merge-on-green (decisions#47). Co-Authored-By: Claude Opus 5.5 --- dot_claude/CLAUDE.md.tmpl | 7 +++++ .../skills/merge-when-green/SKILL.md.tmpl | 2 +- dot_claude/skills/worktree-task/SKILL.md | 26 ++++++++++++++++--- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/dot_claude/CLAUDE.md.tmpl b/dot_claude/CLAUDE.md.tmpl index 1843995..5a7317c 100644 --- a/dot_claude/CLAUDE.md.tmpl +++ b/dot_claude/CLAUDE.md.tmpl @@ -157,6 +157,13 @@ status,conclusion` (or `gh pr checks `) until `status=completed` and and the merge in one compound command — read the poll result first. Use the `merge-when-green` skill for this instead of improvising the poll loop. +**Merge your own implementation PRs on green; do not stop at an open PR.** +The fleet decision is `work.merge-on-green`, and `aval rule work.merge-on-green` +has the wording. worktree-task F9 runs it once CI is green and the +implementation review is settled. A PR that must wait for another PR or a +release says `merge-after:` and stays open. Releases still happen only on +request. + ## Forgejo API ({{ .forge.host }}) The self-hosted forge is fully usable from this machine — opening/merging PRs, diff --git a/dot_claude/skills/merge-when-green/SKILL.md.tmpl b/dot_claude/skills/merge-when-green/SKILL.md.tmpl index c44962d..b240b44 100644 --- a/dot_claude/skills/merge-when-green/SKILL.md.tmpl +++ b/dot_claude/skills/merge-when-green/SKILL.md.tmpl @@ -1,6 +1,6 @@ --- name: merge-when-green -description: Poll a PR's checks until they pass, then merge it — GitHub (gh) AND Forgejo/{{ .forge.host }} (curl API recipe inside). Use for EVERY PR merge, whenever asked to "merge", "merge when green" or "merge once CI passes" — never gh pr merge --auto, never a hand-written poll loop or curl to /merge. +description: Poll a PR's checks until they pass, then merge it — GitHub (gh) AND Forgejo/{{ .forge.host }} (curl API recipe inside). Use for EVERY PR merge: whenever asked to "merge", "merge when green" or "merge once CI passes", AND without being asked, for every implementation PR an agent opened (worktree-task F9, work.merge-on-green) — never gh pr merge --auto, never a hand-written poll loop or curl to /merge. --- # merge-when-green diff --git a/dot_claude/skills/worktree-task/SKILL.md b/dot_claude/skills/worktree-task/SKILL.md index 1f36c54..02bbef7 100644 --- a/dot_claude/skills/worktree-task/SKILL.md +++ b/dot_claude/skills/worktree-task/SKILL.md @@ -283,9 +283,27 @@ below names one of them. - An approval given before the person had a guide is not informed. Hold the push, give the guide, and ask again. - **F8.** Any code change or rebase after F4 returns to F1. -- **F9. Teardown: required, and the finish is not done without it.** Run it - only after the push succeeds (confirmed with `git ls-remote`). It is - never "cleanup for later": skipping it has left merged worktrees behind. +- **F9. Merge on green** (`work.merge-on-green`). Do not stop at an open pull + request, and do not ask: run the `merge-when-green` skill on every + implementation PR this finish opened. It merges once every check on the + head has completed with success, and only when all of these hold: + - the F4b review is `approve`, or `approve-with-changes` with every + finding fixed or named deliberate; + - any `merge-after: #` in the PR body has merged, with its + release out when it names one; + - the person has not said to hold it. + + A red check is a failure under the F2 budget. Read the log, fix it in this + worktree, and return to F1; the next F4b is a fresh round 1 on the new + tree. Keep the worktree until the merge, for exactly this. + + A PR that must wait for a release, or for another PR, stays open with its + `merge-after:` line, and the report says what it waits for. Never cut the + release yourself (`work.release-on-request`). +- **F10. Teardown: required, and the finish is not done without it.** Run it + after the merge in F9, or once the push succeeds (confirmed with + `git ls-remote`) for a PR that F9 left open. It is never "cleanup for + later": skipping it has left merged worktrees behind. 1. Remove this worktree from the **primary** checkout (not from inside itself), using `git -C` so no `cd` persists: ```bash @@ -305,7 +323,7 @@ below names one of them. 3. In the report, say what was removed and what the sweep kept, one line each. -- One implementation pull request per repo per plan (`work.one-implementation-pr-per-repo-per-plan`); merge it with the `merge-when-green` skill. That skill's step 6 fast-forwards the live checkout after the merge, so this finish does not touch it: before the merge there is nothing new on `origin/main` to bring in. +- One implementation pull request per repo per plan (`work.one-implementation-pr-per-repo-per-plan`); F9 merges it with the `merge-when-green` skill (`work.merge-on-green`). That skill's step 6 fast-forwards the live checkout after the merge, so this finish does not touch it: before the merge there is nothing new on `origin/main` to bring in. - A release (`tag-release`) ends with the same sweep, because a worktree becomes sweepable only once its PR is in a release tag. No release unless the person asks for one (`work.release-on-request`).