merge-when-green
Skill1 starsChanged 3 months agoMITView on GitHub
The one primitive that replaces sleep-then-poll around a merge (/foundry:merge-when-green <pr>). Polls `gh pr checks <pr>` and `gh pr view <pr> --json mergeStateStatus` and merges via the single already-permitted `gh pr merge <pr> --squash` shape the instant every check has concluded pass AND mergeStateStatus is CLEAN; blocks naming a failing check or a behind-main state (remediation `git rebase origin/main`); escalates ONCE with evidence when no check will ever report at all. Trigger instead of a hand-rolled sleep-then-retry loop, whenever a PR's checks need to be waited on before merging — "wait for PR <n> to go green and merge it", "/foundry:merge-when-green <pr>", or a driver about to land an atom whose checks are still pending.
1 other project uses a version of this.
Adopted by
Most recently taken up by
- magicpro97/vibeflowtheir own version, first seen Oct 25, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- magicpro97/vibeflow★ 9same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository71 other files it gives its agents.
- AGENTS.mdAGENTS.md
- llms.txtllms.txt
- amendSkill
- auditSkill
- authorize-releaseSkill
- authorizeSkill
- certify-localSkill
- certify-stagingSkill
- coherence-checkSkill
- command-deckSkill
- contextSkill
- cut-releaseSkill
- dashboards-as-codeSkill
- data-tier-cutoverSkill
- decommission-gateSkill
- deploy-statusSkill
- dispatchSkill
- doctorSkill
- drift-sweepSkill
- env-hygieneSkill
- extract-specSkill
- fleetSkill
- grounding-conformanceSkill
- id-applySkill
- id-architectSkill
- id-baselineSkill
- id-discoverSkill
- id-documentSkill
- id-driftSkill
- id-impactSkill
- id-implementSkill
- id-importSkill
- id-planSkill
- id-promoteSkill
- id-reviewSkill
- id-rollbackSkill
- id-simulateSkill
- id-syncSkill
- id-testSkill
- id-validateSkill
- id-verifySkill
- indexSkill
- infra-sandboxed-applySkill
- initSkill
- intakeSkill
- learn-captureSkill
- learn-distillSkill
- mode-autonomousSkill
- mode-interactiveSkill
- modeSkill
- post-upgradeSkill
- releaseSkill
- relockSkill
- report-citation-graphSkill
- reposSkill
- research-captureSkill
- research-firstSkill
- revertSkill
- sd-debugSkill
- sd-discoverSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
1 rule. About 0 are common, 0 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 51
Never construct
--adminaround this primitive: If a PR is genuinely stuck behind a required-review or admin-bypass need, that is an …
≈ “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
/foundry:merge-when-green
The mechanical half is scripts/foundry-merge-when-green.py. It is the primitive
skills/mode-autonomous/SKILL.md and skills/command-deck/tick-prompt.template.md's LANDING
guidance now point at, in place of a driver guessing a wake_seconds interval and re-checking
gh pr checks by hand — measured at 90 sleep-blocks and 83 "pending checks" refusals across a
single release, plus one permanent deadlock where no check ever reported at all.
When to trigger
- "wait for PR
<n>to go green and merge it", "/foundry:merge-when-green<pr>". - A driver (
/foundry:mode-autonomous, a command-deck tick) is about to land an atom whose PR has checks still pending, rather than reasoning about polling itself. - Never as a substitute for
hooks/foundry-git-discipline.sh's owngh pr mergeclause — this CLI's merge call is the SAME plain, already-permitted shape that clause admits on a checks-green query (gh pr merge <pr> --squash, never--admin). It grants nothing the clause did not already allow; it only waits correctly before asking.
Procedure
- Run the CLI directly for a short wait, or arm a native
Monitorin--watchmode for anything that might outlast a single turn:python3 "${CLAUDE_PLUGIN_ROOT}/scripts/foundry-merge-when-green.py" <pr> --release <id> --watch--release <id>is auto-derived (the single active release's own manifest) when omitted, but name it explicitly when you already know it.--watchprints one JSON line per observed state change (status: "waiting"for every non-terminal poll) and exits on the terminal line (merged/blocked/escalate) — arm aMonitoron the running process rather than sleeping and re-invoking it; each stdout line is a notification, so the session sees a state change the moment it happens instead of guessing an interval. - Hand the terminal JSON line to the tick report, unmodified. Its
statusis exactly one of:"merged"— done;merge_commitcarries the squash commit'soid."blocked"(exit 3) —reasonnames the failing check, or a non-CLEANmergeStateStatus; a behind-main state carriesremediation: "git rebase origin/main". Report as Next Task work (fix the check / rebase), never a blocker — this is the driver's own queue, not an operator escalation."escalate"(exit 4) — no check has reported for--no-checks-grace-minminutes (default 5) and the repo has no workflow configured at all, so waiting is provably pointless. This carrieswhy_operator: "external-provisioning"and anevidenceobject (the empty checks list + the workflow list) — feed it tofoundry_blocker_check.pyas a candidate blocker (skills/command-deck/tick-prompt.template.md§5c), never re-run in a loop hoping for a different answer.
- Never construct
--adminaround this primitive. If a PR is genuinely stuck behind a required-review or admin-bypass need, that is an operator decision (gh pr merge --adminby the operator's own hand, or a re-authorization), not something this CLI or its caller works around.
Inputs
<pr>— a literal PR number, never a shell variable or the current branch's PR (mirrors the discipline hook's own refusal of an ambient PR selector).--release <id>(branch-and-worktree-discipline, AC-BWD-5, v1.16.0; optional) — enforces the release manifest'sintegration_branch(context/branch-discipline.md, rule 3): if release<id>'s manifest names one AND this PR's real base (gh pr view <pr> --json baseRefName) is literallymaininstead of it, refuses BEFORE polling —blocked(exit 3),remediation: "gh pr edit <pr> --base <integration_branch>". Auto-derived when omitted (round-2 review finding 4): the SINGLE.foundry/releases/*/release.yamlmanifest whosestate == "active"AND whoseintegration_branchis set — so the autonomous callers above, which never pass--releaseexplicitly in their own LANDING guidance, still get the refusal. Zero or more than one active candidate is not a refusal, just a derivation miss (one line to stderr saying why, never onto the one-JSON-line-on-stdout contract). Pass--releaseexplicitly to override the derivation or resolve an ambiguity. Never refuses a hotfix PR (any base other thanmain), and never refuses when the named/derived release carries nointegration_branch. Retargeting re-pins thebtb-gatessecurity-review label (recorded here, not a new AC):security-reviewed:<head12>- <base8>'sbase8is derived from the base ref name itself (.github/workflows/btb-gates-base.yml), so a PR moved frommainontorelease/<version>needs its label re-applied against the release branch's own hash — seedocs/how-to/branching-and-cleanup.mdfor the mechanism and the branch-protection-tier trade-off (an unprotected release branch reads merge floor tier B/advisory; checks still gate this CLI's own merge either way).--timeout-min(default 60) — the whole run's wall-clock budget; on expiry without a terminal state, exitsblockedwithreason: "timed out...".--poll-interval-sec(default, and production floor, 20) — how often the two live queries run.--no-checks-grace-min(default 5) — how long a genuinely empty checks list is tolerated before the escalate evidence-gathering fires.--watch— prints one line per state change instead of one terminal line; pair with a nativeMonitor.
Residual (recorded, not silently narrowed)
AC-MWG-2's "no workflow whose paths match the PR's changed files" is implemented as "the repo has
zero workflows configured at all" — the unconditionally correct special case of that condition
that does not require fetching and parsing every workflow's own trigger paths/paths-ignore
filters (a materially larger feature). A repo with one or more configured workflows never
escalates through this path even when none of them would ever trigger on the PR's specific
changed files; that finer partition is deferred to a follow-up atom. See
scripts/foundry-merge-when-green.py's own module docstring.
A zero-checks poll never merges even when mergeStateStatus already reads CLEAN — left as-is,
fail-closed by design: no CI reporting at all means there is no merge floor to have gone green.
Anti-patterns
- Sleeping an arbitrary interval and re-running
gh pr checksby hand. That is exactly the measured failure this primitive replaces — use the CLI's own poll loop (or--watch+Monitor), never a bespoke wait. - Retrying past an
escalateverdict. It fired once, with evidence, because no check will ever report; re-running the same command in a loop cannot change that answer. - Treating
blockedas a blocker. A failing check or a behind-main state is this driver's own Next Task, not an operator escalation — onlyescalate(why_operator: external-provisioning) is.
See also
hooks/foundry-git-discipline.sh— thegh pr mergeclause this CLI's own merge call is admitted by; never a new exemption.skills/mode-autonomous/SKILL.md— the driver whose LANDING guidance now points here instead of a hand-rolled poll.skills/command-deck/tick-prompt.template.md— the tick's own LANDING section, same pointer.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
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.

