agentsclimarketplace

Cli forge github

Skill Destynova2/cli-code-skills/cli-forge-github

Production-ready Claude Code skills — audit code quality, forge design docs, generate documentation, automate infrastructure. CLI = Command Line Interface + Clement Liard Initials.

Install
npx -y skills add Destynova2/cli-code-skills --skill cli-forge-github

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 5 stars5 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Audit and fix GitHub repository health: rulesets vs CI alignment, branch hygiene, PR lifecycle, release automation flow, permission issues, and transient CI failures. Detects misconfigurations that cause PRs to hang, CI to fail silently, branches to accumulate, and releases to stall. Use when the user says 'PR stuck', 'CI pending forever', 'branch cleanup', 'ruleset', 'release blocked', 'merge conflicts on sync-main', 'stale PRs', 'orphan branches', 'GitHub health', 'repo hygiene', 'required checks', 'path pruning', 'release-plz stuck', 'auto-merge not working', 'workflow scope', 'token permission'. Also triggers on 'gh api', 'rulesets', 'branch protection', 'status checks'.

SKILL.md

29.7 KB, as published. Nobody here has run it

Optimization: Heavy content lives in references/. Load on demand.

Language rule: Skill instructions are written in English. When generating user-facing output, detect the project's primary language (from README, comments, docs, commit messages) and produce the output in that language. If the project is bilingual, ask the user which language to use before proceeding.

Gotchas: Read ../gotchas.md before producing output to avoid known mistakes.

CLI Forge GitHub — Repository Health Auditor & Fixer

"The CI is green, the ruleset says pending, the PR has conflicts, the release is stuck, and 13 branches are dead. Welcome to GitHub."

Rules for the Auditor

  1. Read before touching. Always gh api the current state before proposing changes. Rulesets, branch protections, and workflows interact in non-obvious ways.
  2. Fix the root cause, not the symptom. A PR stuck on "pending" is not fixed by force-merging — find which check is missing and why.
  3. Never force-push protected branches. Detect the base and release branches (main, develop, master, trunk) and never force-push them. Use --force-with-lease on feature branches only.
  4. Prefer API over UI. Rulesets, checks, and branch cleanup are all automatable via gh api. The UI is for humans reviewing the result.
  5. Document every ruleset change. Add a comment in ci.yml explaining WHY the ruleset requires specific checks. Future you (or a teammate) will re-add the wrong checks if there's no explanation.
  6. Transient failures get a rerun, not a fix. Rate limits, runner timeouts, and network flakes are not code bugs. Rerun, don't refactor.
  7. Orphan branches are tech debt. Clean them on every release, not "when we have time".
  8. Always enable auto-merge on every PR you create. Every gh pr create is followed by gh pr merge --auto --squash (or --rebase / --merge per project policy). A PR without auto-merge is a PR somebody has to babysit — that is exactly the state this skill is designed to eliminate. The only exception is a draft PR: auto-merge is enabled when the draft is marked ready, not before. This rule applies to every agent that opens PRs through the skill (including the cli-forge-chef Sous-Chef).
  9. Always check conflicts between parallel PRs before dispatch, not after. When N commis open N parallel PRs against the same base, the file-exclusion is enforced on the commis side (cli-forge-chef PERT + Fiedler partition). On the GitHub side, this skill verifies it didn't leak: for every pair of open PRs against the same base branch, compute the intersection of their changed-files sets; any non-empty intersection is a future merge conflict and must be reported before auto-merge lands the first one. Detection is cheap; post-merge rebasing N-1 branches is not.
  10. A PR is not done until the client has the fork in it. "Auto-merge enabled" is not "merged". Any session with PRs in flight runs a post-merge landing watchdog (F9) that polls every 45 s, rebases BEHIND branches on cascade, reruns transient failures (max 2× per cause), and only declares "done" once the PR is MERGED, the release tag is cut (if applicable), orphan branches are deleted, and downstream PRs have been caught up. A brigade achieves this via the Maître d'hôtel role (cli-forge-chef references/maitre-dhotel.md); a single-agent session achieves it by calling F9 directly.

Threat model — What goes wrong

ProblemRoot causeSymptomHow often
PR pending foreverRuleset requires a check that path pruning skipped"Expected — Waiting for status to be reported"Common
Release PR in conflictrelease-plz bumps CHANGELOG.md, sync-main also touches it"This branch has conflicts"Every release
Orphan branches accumulateMerged PRs don't always delete branches10+ stale remote branchesGradual
Auto-merge doesn't triggerMissing required checks or conflict blocks itPR sits with auto-merge enabled but never mergesCommon
PR created without auto-mergecli-forge-chef Sous-Chef creates PRs but doesn't enable --autoPR is mergeable but nobody merges itCommon (multi-agent)
Multi-agent push rejecteddevelop is protected, Sous-Chef tries direct pushGH006: Protected branch update failedCommon (multi-agent)
CI fails on transient errorGitHub API rate limit, runner OOM, network timeout"error in connecting to agent.api.stepsecurity.io"Occasional
Token can't push workflow filesOAuth token lacks workflow scope"refusing to allow an OAuth App to create or update workflow"On CI file edits
Stale PRs from old sprintsFeature branches abandoned but PRs left openPR list cluttered with OPEN PRs from weeks agoGradual
Parallel PRs collide at mergeTwo commis touched the same file despite the chef's file-exclusionFirst PR merges, N-1 others block on conflict, sprint stallsCommon (multi-agent)
"Auto-merge enabled" mistaken for "merged"Operator walks away; PR drifts into BEHIND/BLOCKED after release-plz or another PR landsSeveral PRs stuck with autoMergeRequest: true but never landingCommon (multi-agent, release automation)

Input

$ARGUMENTS is the target repo:

  • owner/repo → audit that repo
  • Empty → detect from git remote get-url origin

Mitosis — Scale to repo complexity

SignalTierScope
Personal project, 1 branch, no rulesetsSBranch cleanup + CI check only
Standard project (any branching model), rulesetsMFull audit (all 8 dimensions)
Monorepo or multi-workflow with release automationLFull audit + release flow + cross-workflow analysis

Branching model detection: Before auditing, detect which model the project uses. Do NOT assume Git Flow.

DEFAULT_BRANCH=$(gh repo view --json defaultBranchRef -q '.defaultBranchRef.name' 2>/dev/null)
HAS_DEVELOP=$(git branch -r 2>/dev/null | grep -c 'origin/develop')

# github-flow: only main, no develop
# github-flow-develop: develop + main (like grob)
# gitflow: develop + main + release/* branches
# trunk: single branch, everything goes to main/master

Adapt the audit to the detected model:

  • D4 (release flow): sync-main only applies to github-flow-develop and gitflow
  • F6 (sync-main conflicts): skip entirely for github-flow and trunk
  • Branch hygiene: "orphan" definition depends on the model — in trunk, any non-main branch older than 7 days is suspect

Workflow

Phase 0 — Discover repo configuration

# Detect repo from git remote
REPO=$(gh repo view --json nameWithOwner -q '.nameWithOwner' 2>/dev/null)

# Gather state (all in parallel)
gh api repos/${REPO}/rulesets 2>/dev/null > /tmp/gh-rulesets.json
gh api repos/${REPO}/branches 2>/dev/null > /tmp/gh-branches.json
gh pr list --repo ${REPO} --state open --json number,title,headRefName,createdAt,isDraft,autoMergeRequest > /tmp/gh-prs.json
gh run list --repo ${REPO} --limit 10 --json databaseId,status,conclusion,name,headBranch,event > /tmp/gh-runs.json

Phase 1 — Audit 9 dimensions

Read references/dimensions.md for full scoring criteria. Read references/release-flow.md for D4 release flow details and failure modes.

For each dimension, detect issues and score:

#DimensionWhat to check
D1Ruleset ↔ CI alignmentDo rulesets require checks that path pruning can skip?
D2Branch hygieneOrphan remote branches? Stale local branches? Dangling worktrees?
D3PR lifecycleOpen PRs > 7 days? Auto-merge enabled but stuck? Draft PRs abandoned? Auto-merge enabled on every non-draft PR? Parallel PRs conflict-free (see §Parallel PR conflict scan)?
D4Release flowrelease-plz PR in conflict? sync-main diverged? Tag ↔ branch mismatch? See references/release-flow.md for 6 failure modes
D5CI healthRecent failures? Transient vs real? Flaky jobs?
D6Permissions & scopesCODEOWNERS valid? Token scopes sufficient? CLA configured?
D7Default branch configSquash-on-merge? Delete-branch-on-merge? Require linear history?
D8Workflow hygieneUnused workflows? Deprecated actions? Pinned action versions?
D9Prek ↔ CI alignmentLocal pre-commit/pre-push mirrors the fast CI checks? CI YAML validated locally?

Phase 2 — Fix detected issues

For each issue found, apply the fix. Read references/fixes.md for the fix catalog.

Fix priority:

  1. Blocking — PRs stuck, CI broken, release stalled → fix immediately
  2. Degrading — Orphan branches, stale PRs, config drift → fix in this pass
  3. Cosmetic — Naming, labels, descriptions → note in report, don't fix

Mandatory protocol per fix:

FOR EACH issue:
  1. IDENTIFY: which dimension, what's broken, what's the root cause
  2. VERIFY: confirm the issue exists (gh api, not assumption)
  3. FIX: apply via gh api / gh pr / git commands
  4. CONFIRM: verify the fix worked (re-check the state)
  5. DOCUMENT: if the fix changes a ruleset or CI config, add a comment explaining why

Phase 3 — Score and report

GitHub Health Score (GHS)

#DimensionMaxScoring
D1Ruleset ↔ CI alignment150: checks required but skippable. 15: all required checks always emit a status
D2Branch hygiene10-2 per orphan branch (min 0). 10: zero orphans, auto-delete on merge
D3PR lifecycle10-2 per stale PR > 7d. 10: no stale PRs, auto-merge working
D4Release flow150: release PR in conflict. 15: release-plz + sync-main + tag all clean
D5CI health15-5 per real failure (not transient). 15: all recent runs green
D6Permissions & scopes10-5 per missing CODEOWNERS or broken CLA. 10: all configured
D7Default branch config10+5 squash-on-merge, +3 delete-branch-on-merge, +2 linear history
D8Workflow hygiene15-3 per deprecated action, -2 per unpinned action. 15: all pinned, no deprecated

Score capped at 100.

GHSGradeMeaning
85-100AHealthy — repo is well-maintained
70-84BGood — minor issues, nothing blocking
50-69CNeeds attention — some PRs or releases stuck
30-49DDegraded — multiple blocking issues
0-29FBroken — PRs can't merge, CI broken, branches chaos

Output format

# GitHub Health Report — {owner/repo}

**Date:** {date}
**Branch:** {default branch}
**GHS:** {score}/100 ({grade})

## Dimension Summary

| # | Dimension | Score | Status | Issues |
|---|-----------|-------|--------|--------|
| D1 | Ruleset ↔ CI | 12/15 | Warning | 1 skippable required check |
| D2 | Branch hygiene | 4/10 | Critical | 3 orphan branches |
| D3 | PR lifecycle | 8/10 | OK | 1 PR > 7 days |
| D4 | Release flow | 15/15 | OK | — |
| D5 | CI health | 10/15 | Warning | 1 transient failure (rerun) |
| D6 | Permissions | 10/10 | OK | — |
| D7 | Default branch | 10/10 | OK | — |
| D8 | Workflow hygiene | 12/15 | Warning | 1 unpinned action |
| **Total** | | **81/100 (B)** | | |

## Issues Found & Fixes Applied

| # | Dimension | Issue | Severity | Fix | Status |
|---|-----------|-------|----------|-----|--------|
| 1 | D1 | Ruleset "Protect develop" requires Clippy but path pruning skips it | Blocking | Changed ruleset to require only `Required checks` | Fixed |
| 2 | D2 | 3 orphan branches: feat/old-1, feat/old-2, fix/stale | Degrading | `gh api -X DELETE` on each | Fixed |
| 3 | D5 | Coverage job failed (GitHub API rate limit) | Transient | Rerun: `gh run rerun --failed` | Fixed |

## Recommendations

- {specific recommendations for unfixed items}

## Branch Status

| Branch | Ahead/Behind develop | Last commit | Action |
|--------|---------------------|-------------|--------|
| main | 0 ahead, 0 behind | {date} | Synced |
| release-plz-* | 1 ahead | {date} | Auto-managed |

## PR Status

| # | Title | Age | Status | Auto-merge | Action |
|---|-------|-----|--------|------------|--------|
| #152 | release v0.36.6 | 1d | Open | No | Auto-managed by release-plz |

Common fixes catalog (summary — full in references/)

F1 — Ruleset requires skippable checks (the #153 bug)

Symptom: PR shows "Expected — Waiting for status to be reported" forever.

Root cause: Ruleset requires Clippy (ubuntu-latest) as a named check, but the CI has path pruning that skips Clippy when no Rust files changed. GitHub never receives the status → pending forever.

Fix:

# Get the ruleset ID
RULESET_ID=$(gh api repos/${REPO}/rulesets | jq '.[] | select(.name == "Protect develop") | .id')

# Replace individual job names with the summary job
gh api repos/${REPO}/rulesets/${RULESET_ID} --method PUT \
  --input <(jq '.rules |= map(
    if .type == "required_status_checks" then
      .parameters.required_status_checks = [{"context": "Required checks"}]
    else . end)' /tmp/gh-rulesets-current.json)

Prevention: Add a comment in ci.yml near the summary job:

# This is the ONLY job referenced in the GitHub ruleset "Protect develop".
# Do NOT add individual job names to the ruleset — path pruning skips them.

F2 — Release PR in conflict

Symptom: release-plz PR shows "This branch has conflicts" on CHANGELOG.md.

Root cause: release-plz bumps CHANGELOG.md, but another PR (e.g., sync-main) also touched it. release-plz doesn't auto-rebase.

Fix: Close the stale release PR. release-plz will recreate it on the next trigger.

gh pr close ${PR_NUMBER} --repo ${REPO} --comment "Stale: conflicts with develop. release-plz will recreate."

F3 — Orphan branches

Symptom: gh api repos/${REPO}/branches returns branches whose PRs are already merged.

Fix:

# For each orphan branch
gh api -X DELETE repos/${REPO}/git/refs/heads/${BRANCH} 2>/dev/null

Prevention: Enable "Automatically delete head branches" in repo settings:

gh api repos/${REPO} --method PATCH -f delete_branch_on_merge=true

F4 — Transient CI failure

Symptom: CI fails with rate limit, network timeout, or runner OOM — not a code bug.

Detection: Error message contains rate limit, timeout, OOM, connection refused, stepsecurity.

Fix:

gh run rerun ${RUN_ID} --repo ${REPO} --failed

F5 — Token lacks workflow scope

Symptom: refusing to allow an OAuth App to create or update workflow

Fix: Temporary scope elevation + push + scope removal:

gh auth refresh -s workflow
git push origin ${BRANCH}
gh auth refresh  # removes workflow scope

F6 — sync-main conflicts

Symptom: sync-main PR has conflicts on CHANGELOG.md, Cargo.toml, Cargo.lock.

Fix: Recreate the sync branch from develop, resolve conflicts with --strategy-option theirs (develop wins):

git checkout -B sync-main-v${VERSION} origin/develop
git merge origin/main --no-edit -X theirs
git push origin sync-main-v${VERSION} --force-with-lease

F7 — PR opened without auto-merge

Symptom: gh pr list --json number,autoMergeRequest returns rows with autoMergeRequest: null that are not drafts. They sit waiting for a human.

Fix — enable auto-merge on every affected PR:

# Detect the project merge policy once (squash / rebase / merge)
POLICY=$(gh api repos/${REPO} --jq '
  if .allow_squash_merge then "--squash"
  elif .allow_rebase_merge then "--rebase"
  else "--merge" end')

# Enable auto-merge on every non-draft PR missing it
gh pr list --repo ${REPO} --state open \
  --json number,isDraft,autoMergeRequest \
  --jq '.[] | select(.isDraft == false and .autoMergeRequest == null) | .number' |
while read -r PR; do
  gh pr merge ${PR} --repo ${REPO} --auto ${POLICY} || \
    echo "PR #${PR}: auto-merge failed — check for conflicts or missing required checks"
done

Prevention (for multi-agent flows): The Sous-Chef of cli-forge-chef MUST chain gh pr create with gh pr merge --auto in the same command sequence. Never open a PR without immediately enabling auto-merge — the gap is exactly where PRs go to die.

gh pr create --title "feat(auth): JWT middleware" --body "..." --base develop && \
gh pr merge --auto --squash

F8 — Parallel PR conflict scan (pre-merge)

Symptom: N commis have opened N parallel PRs against the same base. One merges cleanly; N-1 get blocked on conflict the moment it lands.

Why this happens: The chef's PERT + Fiedler partition is supposed to prevent overlapping write-sets across commis. But (a) a commis may have touched a file outside its cluster due to an unexpected refactor, (b) auto-merge from the previous sprint may have stale branches, (c) the Fiedler partition may be absent on small projects. GitHub won't tell you about the conflict until the first merge lands — by then you are stuck.

Detection — run before enabling auto-merge on a batch:

# List all open PRs against the same base
BASE=develop  # or main, per branching model
PRS=$(gh pr list --repo ${REPO} --base ${BASE} --state open \
  --json number,headRefName --jq '.[] | "\(.number) \(.headRefName)"')

# Build a map PR -> changed files
declare -A PR_FILES
while read -r NUM BRANCH; do
  FILES=$(gh pr view ${NUM} --repo ${REPO} --json files --jq '.files[].path' | sort -u | tr '\n' ' ')
  PR_FILES[${NUM}]="${FILES}"
done <<< "${PRS}"

# Compute pairwise intersections — any non-empty intersection is a future conflict
PRS_ARR=("${!PR_FILES[@]}")
for ((i=0; i<${#PRS_ARR[@]}; i++)); do
  for ((j=i+1; j<${#PRS_ARR[@]}; j++)); do
    A=${PRS_ARR[$i]}
    B=${PRS_ARR[$j]}
    OVERLAP=$(comm -12 \
      <(printf '%s\n' ${PR_FILES[$A]} | sort -u) \
      <(printf '%s\n' ${PR_FILES[$B]} | sort -u))
    if [[ -n "${OVERLAP}" ]]; then
      echo "CONFLICT: PR #${A} ↔ PR #${B} overlap on:"
      echo "${OVERLAP}" | sed 's/^/  /'
    fi
  done
done

Partition-aware severity (when .claude/tangle-partition.json exists):

A blind overlap is not all equally bad. Read the partition exported by cli-audit-tangle (same file the chef used to assign commis) and classify each overlap:

PART=.claude/tangle-partition.json
# A file that is a declared boundary function is an EXPECTED fan-in:
# the PERT already sequenced the plats that bridge it — lower severity.
BOUNDARY=$(jq -r '.boundary_functions[]?' "${PART}" 2>/dev/null | sort -u)
  • Overlap on a boundary fileexpected. The two plats were always going to meet here; the PERT sequenced them. Sequence per the PERT and move on.
  • Overlap on a non-boundary file between PRs assigned to different clusterscross-cluster leak: a commis escaped its assigned cluster (an unplanned refactor). This is the high-severity case — report it back to the chef as a file-exclusion breach, not just a routine rebase. It will recur next sprint unless the cluster assignment or the commis scope is fixed.
  • No partition present (small project) → fall back to treating every overlap as a plain future conflict.

Exit actions, in order of preference:

  1. Sequence the two conflicting PRs — pick one (lowest slack in the PERT, cf. cli-forge-chef pert-computation.md §4) and disable auto-merge on the other until the first lands, then rebase the loser:
    gh pr merge ${LOSER_PR} --disable-auto --repo ${REPO}
    # After the winner lands:
    gh pr checkout ${LOSER_PR} && git rebase origin/${BASE} && git push --force-with-lease
    gh pr merge ${LOSER_PR} --auto --squash
    
  2. Split the conflicting file out of one of the PRs — if the overlap is a single file that one commis touched incidentally, the cleanest fix is to revert that file on one branch.
  3. Merge the two PRs into one — only if the commits are small enough that a combined review is realistic.

Running this scan proactively:

  • Multi-agent sprints (cli-forge-chef): the Sous-Chef runs the scan after every new PR is opened, before calling gh pr merge --auto. This is the structural defence — it catches any leak from the chef's file-exclusion.
  • Repo audit mode: include the scan in Phase 1 Dimension D3 check when there are ≥ 2 open PRs against the same base. Report each pair under D3 — PR lifecycle.

F9 — Post-merge landing watchdog (the "fork in the client" loop)

Symptom: PRs have auto-merge enabled but never actually land. gh pr list shows several open PRs, each with autoMergeRequest: true. The operator assumed "auto-merge enabled" meant "done" and walked away.

Root cause: Auto-merge is necessary but not sufficient. It waits for CLEAN + required checks; it does NOT rebase BEHIND branches when main moves, it does NOT rerun transient failures, it does NOT verify the release tag was cut. Every time release-plz or another PR lands, the remaining PRs drift into BEHIND, and auto-merge quietly gives up.

Fix — the polling loop:

#!/usr/bin/env bash
# F9 — Post-merge landing watchdog.
# Run this loop for as long as there is at least one in-flight PR.

set -euo pipefail
REPO=${REPO:-$(gh repo view --json nameWithOwner --jq .nameWithOwner)}
BASE=${BASE:-$(gh repo view --json defaultBranchRef --jq .defaultBranchRef.name)}
POLICY=$(gh api repos/${REPO} --jq '
  if .allow_squash_merge then "squash"
  elif .allow_rebase_merge then "rebase"
  else "merge" end')

declare -A RELAUNCHES   # transient retries per run_id
declare -A FIRST_SEEN   # first-seen timestamp per PR

while true; do
  IN_FLIGHT=$(gh pr list --repo ${REPO} --base ${BASE} --state open \
    --json number,headRefName,mergeStateStatus,autoMergeRequest,updatedAt \
    --jq '.[] | select(.autoMergeRequest != null) | "\(.number)\t\(.headRefName)\t\(.mergeStateStatus)"')

  [[ -z "${IN_FLIGHT}" ]] && { echo "No in-flight PRs, watchdog exiting"; break; }

  while IFS=$'\t' read -r PR BRANCH STATE; do
    FIRST_SEEN[$PR]=${FIRST_SEEN[$PR]:-$(date +%s)}
    AGE=$(( $(date +%s) - ${FIRST_SEEN[$PR]} ))

    # Timeout: 2 hours stuck = escalate
    if (( AGE > 7200 )); then
      echo "ESCALADE: PR #${PR} stuck ${AGE}s"
      continue
    fi

    case "${STATE}" in
      MERGED)
        # Service 5 (Encaissement) — handled out-of-loop below
        ;;
      CLEAN|HAS_HOOKS|UNSTABLE)
        : # wait, auto-merge will fire
        ;;
      BEHIND)
        echo "Rattrapage: PR #${PR}"
        git fetch origin >/dev/null 2>&1
        git checkout ${BRANCH} 2>/dev/null || git checkout -b ${BRANCH} origin/${BRANCH}
        if git rebase origin/${BASE} 2>/dev/null; then
          git push --force-with-lease origin ${BRANCH}
          gh pr merge ${PR} --repo ${REPO} --auto --${POLICY} || true
        else
          git rebase --abort
          echo "Renvoi: PR #${PR} has rebase conflicts — manual resolution needed"
          gh pr merge ${PR} --repo ${REPO} --disable-auto
        fi
        ;;
      BLOCKED)
        # Look for transient failures
        FAILED=$(gh pr view ${PR} --repo ${REPO} --json statusCheckRollup \
          --jq '.statusCheckRollup[] | select(.conclusion == "FAILURE") | .detailsUrl' \
          | grep -oE 'runs/[0-9]+' | cut -d/ -f2 | sort -u)
        for RUN in ${FAILED}; do
          if gh run view ${RUN} --repo ${REPO} --log 2>/dev/null \
              | grep -qE 'rate limit|timeout|OOM|connection refused|stepsecurity'; then
            RELAUNCHES[$RUN]=$(( ${RELAUNCHES[$RUN]:-0} + 1 ))
            if (( ${RELAUNCHES[$RUN]} <= 2 )); then
              echo "Relance ${RELAUNCHES[$RUN]}/2: run ${RUN}"
              gh run rerun ${RUN} --repo ${REPO} --failed
            else
              echo "ESCALADE: run ${RUN} transient failed 3 times in a row"
            fi
          else
            echo "Renvoi: PR #${PR} real failure on run ${RUN}"
            gh pr merge ${PR} --repo ${REPO} --disable-auto
          fi
        done
        ;;
      DIRTY)
        # Merge conflict — try rebase, else disable auto-merge
        git fetch origin >/dev/null 2>&1
        git checkout ${BRANCH} 2>/dev/null || git checkout -b ${BRANCH} origin/${BRANCH}
        if git rebase origin/${BASE} 2>/dev/null; then
          git push --force-with-lease origin ${BRANCH}
          gh pr merge ${PR} --repo ${REPO} --auto --${POLICY}
        else
          git rebase --abort
          echo "Renvoi: PR #${PR} DIRTY, rebase conflicts — manual resolution"
          gh pr merge ${PR} --repo ${REPO} --disable-auto
        fi
        ;;
    esac
  done <<< "${IN_FLIGHT}"

  # Handle newly-merged PRs — cascade rattrapage on the rest
  JUST_MERGED=$(gh pr list --repo ${REPO} --base ${BASE} --state merged --limit 5 \
    --json number,mergedAt --jq '.[] | select(.mergedAt > "'$(date -u -d '@'$(( $(date +%s) - 60 )) +%FT%TZ)'") | .number')
  if [[ -n "${JUST_MERGED}" ]]; then
    echo "Cascade rattrapage after: ${JUST_MERGED}"
    # The outer loop picks them up on the next iteration (BEHIND will appear)
  fi

  sleep 45
done

Exit conditions:

  • In-flight list is empty → the loop exits cleanly. All plats are served.
  • Any PR escalated (timeout > 2 h, or 3 transient reruns on the same run) → the loop reports it and continues with the rest; the operator handles the escalade manually.

Where to run it:

  • Brigade mode: the Maître d'hôtel runs a smarter version of this as its whole purpose (see cli-forge-chef references/maitre-dhotel.md). Do not run F9 separately in a brigade session — the two would race.
  • Single-agent mode: the agent runs F9 in a background bash (run_in_background: true) immediately after opening a batch of parallel PRs. The agent can keep working on the next task; F9 reports back when the batch is done.
  • Repo audit mode: F9 is the fix for any open PR in D3 with autoMergeRequest: true but not CLEAN.

Anti-patterns

#Anti-patternProblemFix
G1Individual checks in rulesetsPath pruning skips them → eternal pendingUse a summary job as the single required check
G2No auto-delete branchesOrphans accumulate after every PR mergeEnable delete_branch_on_merge
G3Force-merge to unblockSkips the broken check instead of fixing the root causeFind why the check is missing
G4Manual sync-mainConflict-prone, error-prone, forgottenAutomate with a workflow triggered on tag push
G5Unpinned actionsactions/checkout@v4 could change behaviorPin to SHA: actions/checkout@<sha>
G6workflow scope left activeSecurity risk — any gh call can modify CIgh auth refresh immediately after push
G7Stale release-plz PRsConflict with develop, never auto-resolveClose and let release-plz recreate
G8No CI comment in rulesetsNext dev re-adds individual checks to the rulesetComment in ci.yml explaining the design
G9PR opened without auto-mergeSomebody has to babysit it — exactly what this skill eliminatesChain gh pr create with gh pr merge --auto, always. F7 fix
G10No pre-merge conflict scan on parallel PRsFirst PR lands, N-1 others freeze on conflictRun F8 before every batch auto-merge. Sequence or rebase the losers
G11Walking away after gh pr merge --autoPRs stall on BEHIND/BLOCKED forever. Operator returns hours later to manual rebasingRun F9 (post-merge landing watchdog). In a brigade, spawn the Maître d'hôtel. "Auto-merge enabled" is not "merged"

Dynamic Handoffs

Condition detectedRecommendWhy
CI YAML has optimization opportunities/cli-forge-pipelinePipeline optimization (parallelism, caching, pruning)
Deprecated GitHub Actions detected/cli-audit-syncCheck if README/docs reference the old action versions
Branch structure suggests architecture issues/cli-audit-tangleModule coupling analysis
Release flow involves shell scripts/cli-audit-shellAudit the release scripts
CONTRIBUTING.md references old branch protection/cli-audit-syncDoc-code coherence check
Stale PR waits on a silent human reviewer/cli-forge-plumeReviewer nudge message: relance ladder, calibrated humor

Rule: Recommend, don't auto-execute.

Integration with other cli-* skills

SkillRelationship
/cli-forge-pipelineOptimizes the CI YAML. cli-forge-github audits the GitHub layer above (rulesets, checks, PRs)
/cli-git-conventionalHandles commits/tags/branches. cli-forge-github handles the repo config and PR lifecycle
/cli-audit-syncChecks doc-code coherence. cli-forge-github checks GitHub config-code coherence (rulesets match CI)
/cli-cycleShould call cli-forge-github as part of the full project review
/cli-forge-chefMulti-agent sprints create many branches/PRs. cli-forge-github cleans up after

What this skill does NOT do

  • Does not modify CI YAML (that's /cli-forge-pipeline)
  • Does not write commit messages (that's /cli-git-conventional)
  • Does not manage GitHub Issues (out of scope — PRs only)
  • Does not configure GitHub Actions secrets (security boundary)
  • Does not force-push main or develop (ever)

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.