ワンクリックで
batch-closing-issues-after-multi-fix-commit
Post-push verification + batch close-out for commits with multiple `Closes
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Post-push verification + batch close-out for commits with multiple `Closes
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Pre-push grep audit for cross-cutting changes (auth-status code flips, response-envelope reshapes, DELETE-success status flips, /api/health body reshapes). The per-push gate's spec list is a strict subset of e2e-full's; cross-cutting changes that pass per-push can red e2e-full because the bare *.spec.js smoke tests aren't in the per-push gate list. Without this audit, every cross-cutting change pays a release-validation round-trip (~15 min) to discover its missed specs. With it, both layers go green on the first try. Today's v3.4.14 cycle hit this twice (#537 401-vs-403 missed 7 specs;
Closes a multi-piece GitHub issue (e.g. `[Bug] Patients page: missing pagination, no bulk/individual tag add, no CSV/XLSX export & template`) by enumerating its sub-items, shipping one slice per cron tick as a file-disjoint pair (backend + frontend; or two backends; or backend + PRD), and only closing the issue after the final slice. Use when an open issue's body lists ≥3 sub-features. Encodes the discipline established across the #820 arc (14 commits across 10 ticks #181 → #197): pagination → bulk-tags → tag-chip → CSV → XLSX backend → XLSX button → template backend → template button → backend filters → frontend filters → import backend → import button → tag-remove backend → tag-remove UI. Each tick shipped 1 small slice; the issue closed naturally once 7/8 items were green.
Authors a NEW `docs/PRD_<FEATURE>.md` for a multi-day or product-call-blocked feature. Use when an open issue (`[Gap]` / `[Zylu-Gap]` / `[Travel Gap]` / `[Bug]` with multi-piece scope) needs a design call before implementation can start, and writing the PRD makes the open questions explicit so the call can actually happen. Encodes the §1-§10 template + 4-7 DD + 5-7 OQ + MANUAL_CODING_BACKLOG D-cluster cross-ref shape that 12+ bonus PRDs followed across the 2026-05-24 → 2026-05-25 cron arc (Purchase Orders, Payment Gateway Config, IE Jobs, Integrations Hub, Tag Master, AI Chat History, Customer Segments, Staff Detail, Wallet Top-up, POS New Sale, POS Polymorphic Invoice, Mini Website). Saves ~15 min of structural decisions per PRD; ships a usable design-call surface.
Authors a new `backend/services/<vendor>Client.js` stub for a cred-blocked third-party integration. Use when a vendor API (RFU Zikr Cabs, Haramain Rail, Booking.com, AdsGPT, RateHawk, Callified, etc.) is on the roadmap but the credentials haven't landed yet — ship the API surface inert so downstream consumers (routes, frontend admin pages, cron engines) can be built end-to-end. Encodes the 8-instance recipe established across adsGptClient / ratehawkClient / callifiedClient / bookingExpediaClient / bookingCom / haramainRailClient / zikrCabsClient: INTEGRATION constant + BUDGET_CAP_KEY + DEFAULT_CAP_CENTS + checkBudgetCap with CJS self-mocking seam + provider-specific search/details/book methods + bookX() throws `XXX_NOT_YET_ENABLED` + 12+ vitest cases including one regression-pin for the seam. Future stubs clone this in ~30 min vs ~90 min from scratch.
Pattern for one-shot paramiko SSH scripts that clean demo's MySQL database of E2E test pollution (E2E_*, _teardown_*, IsoTest *), polluted seed entries, or schema-migration orphans. Use when a pen-test or QA report flags "ledger contains ~N duplicate rows" / "list shows N rows of test data" / "seed-X polluted with Y prefix" — these are operator-side cleanups, NOT code fixes. Encodes the dotenv + paramiko + tenant-scope-by-default + BEFORE/AFTER counts + idempotency + JSON-summary pattern that 3 successful scripts have used (cleanup-orphan-touchpoints.py, seed-drugs-on-demo.py, cleanup-demo-pollution.py). Pairs with applying-demo-ssh-config for non-DB ops.
Orchestrates a wave of parallel closer agents to ship multiple independent gate specs / unit tests / fixes in one round. Use when the user asks to "fire up parallel agents" or when there's a batch of disjoint pickups (R-1/R-4 small-route specs, R-5 cron-engine vitests, G-x engine specs) and waiting for them sequentially would be slow. Encodes the patterns that worked in v3.4.x — disjoint-files invariant (no two agents touching the same route or workflow YAML), max 4-5 concurrent agents (5 worked; 8 had merge collisions), when to spawn a discovery agent first vs jump straight to closers, the standing-rule preamble that points agents at the existing skills, and the rebase-on-collision recovery pattern.
| name | batch-closing-issues-after-multi-fix-commit |
| description | Post-push verification + batch close-out for commits with multiple `Closes |
You just pushed a commit that has multiple Closes #N trailers (typically because a wave-agent bundled N fixes into one commit per the dispatching-parallel-agent-wave skill's "1 commit covering all N fixes" rule).
Check whether GitHub actually auto-closed every issue. Spoiler: it usually didn't.
Closes #A #B #C only auto-closes the FIRSTPer GitHub's grammar, the closing keyword must immediately precede each #N. The commit body:
Closes #685 #686 #687 #688
Only auto-closes #685. The keyword "Closes" doesn't carry over.
Mitigation in the commit: use one Closes #N per line. The body should look like:
Closes #685.
Closes #686.
Closes #687.
Closes #688.
Or use the Refs: pattern + manual close:
Refs #685 #686 #687 #688 — see per-issue rationale below.
Even when every trailer is correctly formatted (one Closes #N per line), commits with 5+ trailers silently cap. Multiple confirmed instances:
ecb4ae0 had 7 Closes #N lines; only 6 fired (#476 stayed OPEN).fc9898e had #465 + #473 stay OPEN despite explicit trailers.Closes #N lines; the trailer cap left 14 issues open across the three commits. Required a batch manual close-out.There's no documented limit and the behavior may be intermittent (rate-limit on the close-on-commit hook). Treat the cap as load-bearing — always verify after multi-issue commits.
Run immediately after git push:
# Extract all issue numbers from the commit message body
COMMIT_SHA="$(git rev-parse HEAD)"
ISSUES=$(git log -1 --format=%B "$COMMIT_SHA" | grep -oE '#[0-9]+' | tr -d '#' | sort -u)
# Verify each
for n in $ISSUES; do
state=$(gh issue view "$n" --json state --jq '.state')
echo "#$n: $state"
done
For each issue still showing OPEN, run the manual close with a citation comment:
gh issue close <N> --reason completed --comment "$(cat <<'EOF'
Shipped in commit <SHA> — <one-line summary of what landed>.
<file:line citation OR which test pins the contract>
Auto-close trailer didn't fire (multi-issue commit hit GitHub's cap — see CLAUDE.md standing rule on the trailer behaviour). Closing manually.
EOF
)"
The comment is load-bearing for the post-mortem audit trail. It serves THREE purposes:
Minimum content:
Shipped in commit `<SHA>` — <one-line description>.
**Evidence:** `<file>:<line>` (or `<file>` if the change is structural).
**Pinned by:** `e2e/tests/<spec>.spec.js` / `backend/test/<test>.test.js` (the test that catches a regression).
[Auto-close trailer didn't fire — multi-issue commit hit GitHub's cap. Closing manually as part of the post-push wrap-up.]
If the close is a phantom-carry-over (issue was reporting a symptom of already-shipped code, not a missing feature), expand the comment to include the phantom rationale:
Verified-shipped per the YYYY-MM-DD phantom audit.
**Evidence:** <file:line> + commit <SHA> citation.
<2-3 sentence context: what code is live, what the symptom likely reflects, what to verify if the symptom recurs against current demo>
If the symptom genuinely recurs against demo (running vX.Y.Z), please re-file with a fresh screenshot + the URL where it appears + the role you were logged in as.
After verifying which issues didn't auto-close, you have two paths:
| Situation | Path |
|---|---|
| Commit not yet pushed (still local) | Amend the commit message — restructure Closes #N trailers to one-per-line, keep total ≤ 4 |
| Already pushed; ≤ 2 issues missed | Manual close with citation comment per issue |
| Already pushed; > 2 issues missed | Manual close in a batched loop (see below) |
| Mix of phantoms and real fixes | Use separate comment templates per category |
Don't --force-push an amend just to fix trailer formatting. The history-rewrite cost (broken hash references in PR comments, broken links in CHANGELOG) outweighs the convenience of auto-close.
For the common case of 4+ issues to close from one commit, write a small bash loop with per-issue customised comments:
declare -A COMMENTS=(
[685]="<citation A>"
[686]="<citation B>"
[687]="<citation C>"
[688]="<citation D>"
)
for n in "${!COMMENTS[@]}"; do
gh issue close "$n" --reason completed --comment "Shipped in commit \`<SHA>\` — ${COMMENTS[$n]}
Auto-close trailer didn't fire (multi-issue commit hit GitHub's cap). Closing manually as part of the post-push wrap-up." 2>&1 | head -1
done
The 2>&1 | head -1 keeps the output tight so you can see at-a-glance which closures landed.
GitHub recognises the keywords: close / closes / closed / fix / fixes / fixed / resolve / resolves / resolved. Plus a few legacy variants. But there's no guarantee these all behave identically under the cap — Closes is the most-reliable; the others may degrade earlier.
#N referenceIf your commit body says Closes #689 (relates to #555), GitHub may try to close #555 as well. Usually it's smart enough to ignore non-keyword-preceded numbers, but cross-repo references (org/repo#N) are particularly flaky.
Closes Globussoft-Technologies/globussoft-crm#689 works for cross-repo but takes a different code path on GitHub's side and is more prone to silent cap behaviour. Always use the bare #N form for same-repo issues.
If the issue was already closed (e.g. by an earlier commit or a manual close), gh issue close returns a warning but doesn't error. Don't trust the warning to surface — re-verify state after the batch loop:
for n in 685 686 687 688; do
echo -n "#$n: "; gh issue view "$n" --json state --jq '.state'
done
# All should report CLOSED.
dispatching-parallel-agent-wave/SKILL.md — the "Verify each issue's auto-close after multi-issue commits" section that motivated this skill. This skill extracts + extends that material so it's discoverable for non-wave commits too (a single-agent commit with multiple Closes #N can hit the cap too).auditing-cross-cutting-spec-impact/SKILL.md — when the commit changes a public shape, the cross-cutting audit must run BEFORE the multi-fix bundle. If the audit catches missed test pins, the commit grows and the trailer count grows — pay even more attention to the verify-loop afterwards.