process_prs
Skill38 starsChanged 2 months agoMITView on GitHub
Process PRs
In this repository101 other files it gives its agents.
- AGENTS.mdAGENTS.md
- .claude/CLAUDE.mdCLAUDE.md
- .cursor/rules/autonomous_execution.mdcCursor rule
- .cursor/rules/cursor_rules_editing.mdcCursor rule
- .cursor/rules/cursor_rules_sync.mdcCursor rule
- .cursor/rules/cursor_rules_sync_requirement.mdcCursor rule
- site_pages/llms.txtllms.txt
- advisorySkill
- analyzeSkill
- auditSkill
- commitSkill
- create-planSkill
- create_planSkill
- create-prototypeSkill
- create_prototypeSkill
- create_prSkill
- create-releaseSkill
- create_releaseSkill
- create-ruleSkill
- create_ruleSkill
- debugSkill
- draft-illustrationSkill
- draft_illustrationSkill
- endSkill
- evaluate_positioningSkill
- final-reviewSkill
- final_reviewSkill
- fix-feature-bugSkill
- fix_feature_bugSkill
- learnSkill
- manage-error-debuggingSkill
- manage_error_debuggingSkill
- neversight_learn_skills.dev_obviously_awesomeSkill
- process_issuesSkill
- publish-planSkill
- publish_planSkill
- publishSkill
- pullSkill
- pushSkill
- recover_sqlite_databaseSkill
- releaseSkill
- report-errorSkill
- report_errorSkill
- reportSkill
- reviewSkill
- run-feature-workflowSkill
- run_feature_workflowSkill
- setup-commandsSkill
- setup_commandsSkill
- setup-cursor-copiesSkill
- setup_cursor_copiesSkill
- store-neotomaSkill
- store_neotomaSkill
- sync-env-from-1passwordSkill
- sync_env_from_1passwordSkill
- analyzeSkill
- auditSkill
- commitSkill
- create-planSkill
- create-prototypeSkill
- The first 60 shown.
The file
Show its rules and text
We split this skill into the rules it gives an agent
44 rules. About 0 are common, 20 are distinctive, and 24 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈20
Distinctive · estimate
This author's own choices. Worth a look.
24
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Very specific: line 11
Use this skill to work the open PR queue end-to-end: assess merge readiness, run security gates, selectively request Claude Opus review on …
- Distinctive: line 15
When you want to triage and advance open PRs on the repository — checking CI status, running security checks, merging what is ready, and …
- Distinctive: line 39
When to fan out vs. inline: if the MERGEABLE candidate set is > 6 PRs, fan out.
- Very specific: line 52
Treat the subagent report as a prioritized worklist with evidence, not a decision.
- Distinctive: line 95
If a prior review comment exists, count commits that landed after that timestamp:
- Very specific: line 121
If the most recent review is a placeholder, treat the PR as "review requested but not delivered" and re-post @claude review (subject to the …
- Distinctive: line 129
If the review has any Blocking items, the PR is review-blocked until either:
- Very specific: line 148
Use this check to compute pending_review_blockers for each PR:
- Distinctive: line 161
If the review had Blocking items and zero substantive (non-housekeeping) commits landed after it, the PR is review-blocked.
- Distinctive: line 182
If the command produces any output, the PR is agentic-behavior-adjacent.
- Very specific: line 239
If the diff contains files under src/cli/ (new CLI surface), src/services/ (new tool behavior), or openapi.yaml — cross-check that the PR …
- Distinctive: line 241
If a documented surface was added or modified but the corresponding doc file was not changed:
- Very specific: line 245
Do not merge until the doc gap is filled or the author posts Waiver: <reason> explaining why no doc update is needed
- Very specific: line 267
If the diff adds files in src/cli/ (new CLI command), src/services/ (new service behavior), or touches migration scripts — cross-check that …
- Distinctive: line 271
If a testable surface was added but no test covers it:
- Very specific: line 275
Do not merge until tests are added or the author posts Test-waiver: <reason> explaining why coverage is not feasible
- Very specific: line 284
If yes: do not merge. Report it and instruct the user to run /release to handle it.
- Very specific: line 292
What is the CI status?: Read statusCheckRollup from the PR JSON.
- Distinctive: line 296
Not a release PR
- Very specific: line 332
Run npm run security:lint and report results.
- Distinctive: line 392
Verify that every original ask appears in the "How it was addressed" or "Deferred" section.
- Very specific: line 399
If the issue is in the "auto-close gap" list from the detection step (closure verb in body/commit but not in closingIssuesReferences), …
- Very specific: line 418
Use --merge (no-ff merge) to preserve PR history.
- Distinctive: line 420
After merging, confirm the merge succeeded and manually close any auto-close-gap issues identified in Step 4:
- Very specific: line 478
Never push to main directly.
- Very specific: line 479
Never merge a release PR (dev→main with version bump).
- Distinctive: line 481
Never amend a pushed commit.
- Distinctive: line 482
Never merge if CI is failing or pending unless the user explicitly instructs.
- Distinctive: line 483
Never merge if G2 or G3 produce errors on a security-adjacent PR.
- Distinctive: line 488
Always run G2 and G3 before merging a security-adjacent PR.
- Distinctive: line 489
Always report security gate results in the summary, even when advisory.
- Distinctive: line 490
Always run Step 1c (Audit Existing Review Findings) for every non-draft PR before classification in Step 2.
- Distinctive: line 491
Always run Step 1d (Check Agentic Behavior Eval Coverage) for every non-draft PR before classification in Step 2.
- Distinctive: line 492
Always run Step 1e (Docs-Coverage Gate) for every non-draft PR before classification in Step 2.
- Distinctive: line 493
Always run Step 1f (Test-Coverage Gate) for every non-draft PR before classification in Step 2.
- Very specific: line 494
Always run Step 4 (Post issue-closure comments) before gh pr merge for every PR that closes a linked issue.
- Very specific: line 495
After merge, manually close any issue that the PR resolved but GitHub did not auto-close (the auto-close-gap case: closure verb in …
- Very specific: line 496
Never post @claude review on a claude/* branch PR — the workflow already runs on opened for those.
- Very specific: line 497
Never post @claude review more than once per batch run on the same PR.
- Very specific: line 498
Do not post @claude review on trivially small PRs (≤5 files, ≤150 lines, no contract surface changes, not security-adjacent).
- Very specific: line 499
Treat placeholder review bodies (I'll analyze this and get back to you.
- Very specific: line 501
Use Explore (read-only) for audit-batch subagents so they structurally cannot merge, comment, or push.
- Very specific: line 502
Always re-confirm CI freshness against the current head SHA, the actual diff surface, and mergeStateStatus on the main thread before …
- Very specific: line 518
Leaving issues open that the merged PR resolved: When detection in Step 4 surfaces an auto-close gap (closure verb in body/commit but issue …
≈ “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
<!-- Source: .cursor/skills/process-prs/SKILL.md -->Process PRs
Use this skill to work the open PR queue end-to-end: assess merge readiness, run security gates, selectively request Claude Opus review on substantial PRs, merge eligible PRs, and hand off release PRs to /release.
When to Use
When you want to triage and advance open PRs on the repository — checking CI status, running security checks, merging what is ready, and surfacing what is blocked.
Trigger with /process_prs, or naturally ("work the PR queue", "triage open PRs").
Workflow
Step 1: Discover Open PRs
gh pr list --state open --json number,title,headRefName,baseRefName,isDraft,reviewDecision,statusCheckRollup,labels,mergeable,authorExclude draft PRs from automated merge actions. Include them in the summary report.
Step 1a: Partition the queue and fan out the audit to subagents
The per-PR audit (Steps 1b, 1c, 2, 3-discovery) is read-only gh/git work with no cross-PR dependencies. It is the right shape for parallel subagent delegation: each subagent audits a disjoint batch, returns a structured verdict, and the main thread synthesizes and takes all merge/comment/review actions itself. This keeps mutation single-threaded (no two agents racing to merge) while collapsing the wall-clock cost of a large queue.
Partition first — do not audit every PR at full depth. From the Step 1 JSON, bucket PRs before spending audit budget:
mergeable: CONFLICTING→ blocked-needs-rebase. These cannot merge regardless of any other signal. Do not deep-audit; list them in the report's rebase bucket. (Verify the bucket isn't masking a base-branch issue, but a conflicting PR is never merge-eligible this run.)- Stacked PRs (
baseRefNameis notmain/devbut another open PR's head) → blocked on parent. Note the parent; do not deep-audit until the parent lands. mergeable: MERGEABLE→ the real audit candidates. These get the full Step 1b/1c/2/3 fan-out.
When to fan out vs. inline: if the MERGEABLE candidate set is > 6 PRs, fan out. At or below that, audit inline on the main thread (subagent spin-up overhead isn't worth it). Scale the subagent count so each handles 3–5 PRs: ceil(candidates / 4) subagents, capped at 8.
Dispatch (single message, multiple Agent calls so they run concurrently):
subagent_type: "Explore"for the audit batches — it is read-only by construction (cannot merge, comment, or push), which is exactly the guarantee you want for a discovery agent. Give each one a disjoint list of PR numbers and the full per-PR audit checklist (CI status + mechanical-vs-substantive failure classification, base-branch/stacked detection, security-adjacency with triggering files, diff size + contract-surface flag, Step 1c review-blocker verdict with quoted blocking findings, linked-issue detection including the auto-close gap, andreviewDecision/mergeable). Require a terminal one-line verdict per PR:MERGE-ELIGIBLE | BLOCKED(<reason>) | STACKED(base=<branch>) | REVIEW-BLOCKED | SECURITY-GATE-NEEDED.- For a deep correctness read of a specific high-risk PR (security-adjacent + large contract diff), additionally spawn the
code-reviewersubagent on that single PR. Use this sparingly — it is for the PRs where a holistic human-grade review matters, not routine triage.
Synthesis is mandatory and adversarial — never act on a subagent verdict alone. Subagents read excerpts, not whole files, and will miss things. Before any merge, the main thread MUST independently re-confirm the load-bearing facts for that specific PR:
- CI freshness — re-run
gh pr checks <n>and confirm the green run is against the current head SHA, not a months-old run. A subagent reporting "CI passed" may be quoting a stale run; main moving (or the baseline gate's openapi-drift check) can invalidate it. This is the single most common synthesis correction. - Actual diff surface — re-run
gh pr diff <n> --name-only. Subagents have under-counted security-adjacency and contract-surface by trusting a PR's self-description or a stale rebase view. Verifysrc/actions.ts,openapi.yaml, and the security-adjacency file set directly. mergeStateStatus—CLEANis required to merge;UNKNOWNmeans GitHub is still computing mergeability (wait/re-poll),BEHIND/DIRTYmeans rebase needed.
Treat the subagent report as a prioritized worklist with evidence, not a decision. The main thread owns every gh pr merge, gh pr comment, gh issue comment/close, and @claude review call.
Step 1b: Gate Substantial PRs for Opus Review
Before classifying for merge, check whether each PR needs (or needs another) automated Opus review. The claude_pr_review.yml workflow runs on synchronize events but deliberately skips claude/* branches to avoid runaway agent loops. This step compensates by explicitly posting @claude review on PRs that are worth a holistic look.
Skip review-requesting for:
- Draft PRs
- Release PRs (dev→main with version bump)
- PRs whose head branch starts with
claude/— the workflow already runs onopenedfor these
For newly opened PRs (state was just opened, no review comment yet):
gh pr diff <number> --statParse the stat output to get: files changed, insertions, deletions. Also check whether the diff touches both src/ and openapi.yaml simultaneously:
gh pr diff <number> --name-onlyPost @claude review if any of the following are true:
- Files changed > 5
- Total lines changed (insertions + deletions) > 150
- Diff touches both
src/andopenapi.yaml(contract surface change) - PR is security-adjacent (per the criteria in Step 2)
gh pr comment <number> --body "@claude review"For PRs with new commits since last review was requested:
Find the most recent @claude review comment:
gh pr view <number> --json comments --jq '[.comments[] | select(.body | contains("@claude review"))] | last | .createdAt // empty'If a prior review comment exists, count commits that landed after that timestamp:
gh api repos/{owner}/{repo}/pulls/<number>/commits --jq '[.[] | select(.commit.committer.date > "<last_review_iso_timestamp>")] | length'Post another @claude review if new commits since last review ≥ 3.
Never post @claude review more than once per batch run on the same PR. If you already posted in this run, do not post again.
Step 1c: Audit Existing Review Findings (Merge Blocker)
Reviews posted asynchronously by the Opus review job can land after the author pushed the final commit. The agent that merges later must not assume "review happened, so review was addressed." This step blocks merge on unaddressed substantive findings.
For each PR, fetch the most recent review comment from github-actions[bot]:
gh api repos/{owner}/{repo}/issues/<number>/comments \
--jq '[.[] | select(.user.login == "github-actions[bot]" and (.body | test("PR Review|Recommended|Blocker|Blocking|MUST|Findings"; "i")) and (.body | length > 300))] | last | {created_at, body}'Detect and skip placeholder reviews that never completed:
- Body contains only the line
I'll analyze this and get back to you.(no substantive content) usage.output_tokenswas 0 (the action timed out or errored)
If the most recent review is a placeholder, treat the PR as "review requested but not delivered" and re-post @claude review (subject to the once-per-batch cap in Step 1b).
For substantive reviews, classify findings by scanning the body for:
- Blocking: lines containing
Blocker,Blocking,MUST,must fix,Required:,request changes,Verdict: request changes - Substantive non-blocking: numbered findings (
**1.**,### 1.,1. **) that are not in a "Resolved" or "Verified" section - Informational: lines in an
## Approve,Verdict: approve,Resolved, orNon-blockingsection
If the review has any Blocking items, the PR is review-blocked until either:
- A commit lands after the review timestamp whose commit message explicitly references the finding (by quoting the reviewer's text, the finding number, or a referenced filename and line number), or
- The author posts a comment containing the literal phrase
Waiver: <reason>on a per-finding basis acknowledging the deferral, or - A fresh
@claude reviewis requested and the new review's verdict isapprove/approve in substance.
Detecting "housekeeping commits" that do not count as addressing findings:
A commit is housekeeping (and does not clear a Blocking finding) if its message matches any of:
^chore: regenerate test catalog^chore: regenerate openapi types^chore: apply prettier formatting^chore: fix prettier formatting^Merge branch 'main'/^Merge pull request^chore: rebase onto main
Counting these as "post-review work" is the exact pattern that caused PRs #152, #222, #223, #224, #178, #233, #232, #151 to merge with unaddressed findings on 2026-05-18.
Use this check to compute pending_review_blockers for each PR:
# Count substantive (non-housekeeping) commits after the latest substantive review
last_review_iso=$(gh api repos/{owner}/{repo}/issues/<number>/comments \
--jq '[.[] | select(.user.login == "github-actions[bot]" and (.body | length > 300) and (.body | test("PR Review|Recommended|Blocker|MUST|Findings"; "i")))] | last | .created_at // empty')
if [ -n "$last_review_iso" ]; then
gh api repos/{owner}/{repo}/pulls/<number>/commits \
--jq "[.[] | select(.commit.committer.date > \"$last_review_iso\") | select(.commit.message | test(\"^chore: (regenerate|apply|fix) prettier|^chore: regenerate test catalog|^chore: regenerate openapi types|^Merge branch|^Merge pull request|^chore: rebase\"; \"\") | not) | .sha[:8]]"
fiIf the review had Blocking items and zero substantive (non-housekeeping) commits landed after it, the PR is review-blocked. Post a summary comment listing the unaddressed findings and request fixes; do not merge.
Step 1d: Check Agentic Behavior Eval Coverage (Merge Blocker)
A PR that changes agentic behavior — the instructions agents receive, the tools they can call, or the flows they execute — must demonstrate eval coverage before it can be merged.
Detect agentic behavior changes. A PR is agentic-behavior-adjacent if its diff touches any of:
docs/developer/mcp/instructions.mdsrc/tool_definitions.tssrc/server.ts.cursor/skills/*/SKILL.md.claude/skills/*/SKILL.md- Any file whose path contains
agent_instructions - Any file under
src/services/whose name containsagentorinstruction
Detection command:
gh pr diff <number> --name-only | grep -E \
'docs/developer/mcp/instructions\.md|src/tool_definitions\.ts|src/server\.ts|\.cursor/skills/.*/SKILL\.md|\.claude/skills/.*/SKILL\.md|agent_instructions'If the command produces any output, the PR is agentic-behavior-adjacent.
Check for eval evidence. A PR satisfies the eval requirement if at least one of the following is true:
- PR body references evals. The PR description body (not just title) contains at least one of:
eval,agentic eval,agentic_eval,scenario,tier 1,tier 2.gh pr view <number> --json body --jq '.body' | grep -iE 'eval|agentic_eval|scenario|tier 1|tier 2' - Linked issue references evals. Any issue closed by the PR (from
gh pr view <number> --json closingIssuesReferences) has a body or comment referencing eval coverage. - New or modified eval fixture. The diff includes a file under
tests/fixtures/agentic_eval/.gh pr diff <number> --name-only | grep 'tests/fixtures/agentic_eval/' - Human reviewer confirmed evals pass. A human reviewer (non-bot) posted a comment containing
eval coverage confirmed,evals pass, orevals verified(case-insensitive).gh pr view <number> --json comments --jq '.comments[] | select(.author.login != "github-actions[bot]") | select(.body | test("eval coverage confirmed|evals pass|evals verified"; "i")) | .body'
If no eval evidence is found, the PR is eval-blocked. Post a comment on the PR:
This PR modifies agentic behavior (agent instructions, MCP tool definitions, skill files, or related paths) and does not yet have eval coverage.
**Before this PR can be merged, please provide at least one of:**
1. Update the PR description to reference passing evals (mention `eval`, `agentic eval`, `scenario`, or `tier 1`/`tier 2`).
2. Add or update an eval fixture in `tests/fixtures/agentic_eval/` that covers the changed behavior.
3. Post a comment confirming evals pass: `eval coverage confirmed` or `evals pass`.
See [docs/developer/eval_requirements.md](../docs/developer/eval_requirements.md) for how to write an eval fixture and what counts as eval evidence.If eval evidence is found, continue to Step 2. Note this in the per-PR summary as "Eval coverage: ✓".
Note: a commit message referencing evals (e.g. test: add eval fixture for …) is not by itself eval evidence unless the commit also adds/modifies a fixture file under tests/fixtures/agentic_eval/.
Step 1e: Docs-Coverage Gate
For each PR that adds or modifies user-facing surfaces (CLI commands, flags, API endpoints, MCP tools, config knobs), verify that documentation was updated in the same PR.
Surfaces that require documentation updates:
- New or modified CLI commands/flags →
docs/developer/cli_reference.mdanddocs/developer/cli_agent_instructions.md - New or modified MCP tools →
docs/developer/mcp/tool_descriptions.yamlanddocs/developer/mcp/instructions.md - New or modified API endpoints or request/response fields →
openapi.yaml - New config options or environment variables →
docs/developer/cli_reference.mdRuntime overrides table - New behavioral rules affecting agents → mirrored in both MCP and CLI instruction files
Check for missing docs coverage:
gh pr diff <number> --name-onlyIf the diff contains files under src/cli/ (new CLI surface), src/services/ (new tool behavior), or openapi.yaml — cross-check that the PR also modifies the corresponding doc files listed above.
If a documented surface was added or modified but the corresponding doc file was not changed:
- Flag the PR as docs-blocked
- Post a comment naming the missing doc update(s)
- Do not merge until the doc gap is filled or the author posts
Waiver: <reason>explaining why no doc update is needed
A Waiver: comment on the PR is sufficient to clear a docs-blocked status.
Step 1f: Test-Coverage Gate
For each PR that adds or modifies user-facing surfaces, verify that tests covering the new behavior were added or updated in the same PR.
Surfaces that require test coverage per change_guardrails_rules.md rules 19–21:
- New CLI commands → integration test in
tests/cli/exercising the command end-to-end - New destructive or data-mutating operations (migrations, repair commands, bulk rewrites) → round-trip integration test covering identity, dry-run non-mutation, idempotency, and NULL preservation
- New external-file-shape parsers (harness transcripts, SQLite imports, third-party configs) → fixture-based test exercising the actual parser path (not just
detectSource) - New HTTP runtime-config knobs (timeouts, headers, keep-alive) → runtime behavior test asserting observable output, not just source constants
- New store/ingestion paths → test asserting the POST body fields sent to the store API
Check for missing test coverage:
gh pr diff <number> --name-onlyIf the diff adds files in src/cli/ (new CLI command), src/services/ (new service behavior), or touches migration scripts — cross-check that the PR also adds or modifies test files in tests/ or co-located *.test.ts files.
For transcript/file-import surfaces specifically: verify that tests assert POST body structure (field names and values), not just the count of POST calls. A test that only counts calls will not catch a broken parser that sends {} instead of { file_path, observation_source }.
If a testable surface was added but no test covers it:
- Flag the PR as test-blocked
- Post a comment naming the missing test coverage
- Do not merge until tests are added or the author posts
Test-waiver: <reason>explaining why coverage is not feasible
A Test-waiver: comment (distinct from Waiver: used for docs and review findings) is sufficient to clear a test-blocked status.
Step 2: Classify Each PR
For each open PR, determine:
- Is it a release PR? Criteria: base branch is
main, head branch isdev(or configured integration branch), andpackage.jsonversion bump is present in the diff.- If yes: do not merge. Report it and instruct the user to run
/releaseto handle it. Do not inline release steps.
- If yes: do not merge. Report it and instruct the user to run
- Is it security-adjacent? A PR is security-adjacent if its diff touches any of:
src/actions.ts,src/services/local_auth.ts,src/middleware/, any route handler- Auth, middleware, proxy trust, forwarded-for handling, session, credential, or token logic
protected_routes_manifest.json,scripts/security/,docs/security/- Any file matching
*auth*,*token*,*session*,*credential*,*permission*
- What is the CI status? Read
statusCheckRollupfrom the PR JSON. Classify as:passed,failed,pending, ormissing. - Is it mergeable? A PR is merge-eligible when:
- Not a draft
- Not a release PR
- CI status is
passed(all checks green) reviewDecisionisAPPROVEDor review is not required by branch protectionmergeableisMERGEABLE- Security gates pass (see Step 3)
- No unaddressed review blockers from Step 1c. A PR with Blocking findings from the most recent substantive
github-actions[bot]review and no substantive (non-housekeeping) commits orWaiver:comments since is review-blocked and must not be merged. - Eval coverage present for agentic-behavior-adjacent PRs (Step 1d). A PR that touches agent instructions, MCP tool definitions, skill files, or related agentic flows is eval-blocked until eval evidence is provided.
- No docs-coverage gaps from Step 1e. A PR that adds a user-facing surface without updating the corresponding doc files is docs-blocked until the gap is filled or a
Waiver:comment explains the omission. - No test-coverage gaps from Step 1f. A PR that adds a testable surface without adding tests is test-blocked until tests are added or a
Test-waiver:comment explains why coverage is not feasible. - Closure comments drafted for every linked issue (Step 4). A merge that closes issues without a closure narrative loses the resolution trail. The closure comment must be posted before
gh pr merge.
Step 3: Run Security Gates
For security-adjacent PRs — mandatory before merge:
npm run security:lintErrors are blocking. Warnings are noted but do not block. If errors are found, report them on the PR and do not merge until resolved.
npm run security:manifest:check
npm run test:security:auth-matrixBoth must pass. If security:manifest:check fails due to an out-of-date manifest (not a code error), run:
npm run security:manifest:writeand confirm the manifest change is staged in the PR branch before re-running the check.
For all other PRs — advisory:
Run npm run security:lint and report results. Do not block merge on warnings, but surface any errors for the PR author.
Do not run security:classify-diff, security:ai-review, or the deployed probes (deployed_probes.sh) — those are release-scoped gates that run in /release Step 3.5 and Step 5.
Step 4: Post issue-closure comments on linked issues (before merge)
For each PR that passes all merge-eligibility criteria, before running gh pr merge, walk every issue the PR claims to close and post a closure-narrative comment on it. This memorializes the work and forces a final verification that every original ask was addressed.
The auto-close behavior of GitHub (Closes #N in PR body) only posts a generic merge-link comment. That is not sufficient: it does not verify that each bullet of the issue body was addressed, does not reconcile review-thread follow-ups, and does not call out explicit deferrals.
Detect the linked issues:
# Issues GitHub auto-tracks (must be in body via "Closes/Fixes/Resolves #N")
gh pr view <number> --json closingIssuesReferences --jq '[.closingIssuesReferences[].number]'
# Also scan the PR body and commit messages for bare references that GitHub did
# not parse (e.g. "fix bugs #168 #170 #171 #172" — only #168 auto-closes).
gh pr view <number> --json body,commits --jq '.body, (.commits[].messageHeadline), (.commits[].messageBody // "")' \
| grep -oE '(closes|close|fixes|fix|resolves|resolve)\s+#[0-9]+' -i | sort -u
# Any issue listed here that is NOT in closingIssuesReferences will not be
# auto-closed at merge time — flag it for manual `gh issue close` after merge.Closure comment shape (uniform across PRs):
Resolved by PR #<pr> (merged <yyyy-mm-dd>). Shipping in **v<version>**.
## What the issue asked for
<bullets quoted from the issue's Expected / Proposed fix / Acceptance / Problem section>
## How it was addressed
<concrete description of the fix: bullets from the PR's Summary section,
ideally referencing file:line or commit SHA for each ask. If the PR closes
multiple issues, include only the bullet that pertains to *this* issue.>
<If review-thread follow-ups for this PR landed in a separate cleanup PR,
note that explicitly: "Review-thread follow-ups for PR #X were addressed in
cleanup batch PR #Y.">
## Verification
<bullets from the PR's Verification / Test plan section, with checkboxes
ticked since the PR has merged.>
## Deferred / out of scope (if applicable)
<bullets describing any original-issue ask or review-comment ask that was
NOT addressed by this PR, with a link to the follow-up issue or a written
reason for the deferral.>Operationally:
- For each linked issue, read the issue body (
gh issue view <iss>) and the PR body (gh pr view <pr>). - Build the comment per the shape above. Quote the issue's original asks verbatim where possible.
- Verify that every original ask appears in the "How it was addressed" or "Deferred" section. If any ask is unaccounted for, do not merge — push back on the PR author or file a follow-up issue.
Post the comment:
gh issue comment <iss> --body-file <draft.md>If the issue is in the "auto-close gap" list from the detection step (closure verb in body/commit but not in
closingIssuesReferences), close it manually after merge:gh issue close <iss> --reason completed
Skip the closure comment for:
- Issues that are purely process/governance (e.g. "we should be more rigorous about commit-message scopes") — leave open with a comment explaining why.
- Trivial single-line fixes where the PR title + auto-close comment are obviously sufficient. The judgment call: would a reader landing on this issue six months from now want a narrative, or is the linked PR self-evidently dispositive? Default to writing the comment — narratives age better than diffs.
Step 4c: Merge Eligible PRs
For each PR that passes all merge-eligibility criteria AND has closure comments posted on every linked issue:
gh pr merge <number> --merge --delete-branchUse --merge (no-ff merge) to preserve PR history. Use --squash only if the PR branch has a single logical commit and the repo convention allows it. Do not rebase-merge.
After merging, confirm the merge succeeded and manually close any auto-close-gap issues identified in Step 4:
gh pr view <number> --json state,mergedAt
# For each issue in the auto-close gap list:
gh issue close <iss> --reason completedStep 5: Handle Blocked PRs
For each PR that cannot be merged, take the appropriate action:
- CI failing: Post a comment summarizing which checks failed. Do not merge.
- Security gate errors (G2/G3): Post a comment with the specific
security:linterrors or manifest/auth-matrix failures. Do not merge. - Review-blocked (Step 1c): Post a comment listing the unaddressed Blocking findings from the most recent review, quoting the relevant lines and naming the file paths. Request that the author either land substantive fix commits, post
Waiver: <reason>comments per finding, or re-request@claude reviewafter the fixes. Do not merge. - Eval-blocked (Step 1d): Post the standard eval-coverage-required comment (see Step 1d comment template). Do not merge until at least one of the four eval-evidence criteria is satisfied.
- Docs-blocked (Step 1e): Post a comment naming the missing documentation files. Request the author add the doc updates or post
Waiver: <reason>explaining why no doc change is needed. Do not merge. - Test-blocked (Step 1f): Post a comment naming the missing test coverage and the specific surface (CLI command, parser, migration, etc.) that lacks tests. Request the author add tests or post
Test-waiver: <reason>explaining why coverage is not feasible. Do not merge. - Awaiting review: Note in the summary report. Do not post a comment unless explicitly requested.
- Merge conflicts: Post a comment asking the author to rebase.
- Draft: Skip. Report in summary.
- Release PR: Report in summary, instruct user to run
/release.
Step 6: Report
Produce a comprehensive summary covering:
- Total PRs reviewed
- For each PR: title, number, classification (release / security-adjacent / standard), CI status, security gate results, and action taken (merged / blocked / handed off / skipped / review requested)
- PRs where
@claude reviewwas posted and why (new substantial PR, or N new commits since last review) - Any security gate errors found, with PR numbers
- Any docs-blocked PRs (Step 1d), with the specific missing doc files named
- Any test-blocked PRs (Step 1e), with the specific missing test coverage named
- Release PRs identified, with a clear "run
/releaseto ship these" callout - Outstanding blockers that require author or user action
- A "What I need from you" section if any PR requires a decision
- When the queue was fanned out (Step 1a): how many subagents ran, the batch partition, and any verdict the main-thread synthesis overrode (e.g. a "CI passed" that was a stale run, an under-counted security surface). Surfacing overrides keeps the fan-out honest and flags subagent blind spots for the next run.
Security Gate Reference
| Gate | Command | When to run | Blocks merge? |
| G2 static lint | npm run security:lint | All PRs | Yes, on errors |
| G3a manifest check | npm run security:manifest:check | All PRs | Yes, on failure |
| G3b auth matrix | npm run test:security:auth-matrix | All PRs | Yes, on failure |
Gates not run here (release-only):
| Gate | Reason |
G1 security:classify-diff | Requires --base <last-tag>; release-scoped semantic |
G4 security:ai-review | Requires tag, writes to release supplement path |
| G5 deployed probes | Requires live deployed environment |
The /release Step 3.5 re-runs G2 and G3 against the exact release commit as a hard gate. The duplication is intentional: PRs merged to dev weeks before release may be followed by commits that break the gates.
Constraints
- Never push to
maindirectly. Merges tomainonly happen via/release. - Never merge a release PR (dev→main with version bump). Hand off to
/release. - Never use
--no-verify. - Never amend a pushed commit.
- Never merge if CI is failing or pending unless the user explicitly instructs.
- Never merge if G2 or G3 produce errors on a security-adjacent PR.
- Never merge a PR that is review-blocked per Step 1c. A substantive
github-actions[bot]review with Blocking findings followed only by housekeeping commits is not a green light. The author must either (a) land non-housekeeping fix commits, (b) postWaiver: <reason>comments per deferred finding, or (c) trigger a re-review whose verdict isapprove. - Never merge a PR that is eval-blocked per Step 1d. A PR touching agentic behavior (agent instructions, MCP tool definitions, skill files, or store/correction flows) without eval evidence is not merge-eligible. The author must satisfy at least one eval-evidence criterion before merge.
- Never merge a PR that is docs-blocked per Step 1e until the missing doc files are added or a
Waiver:comment explains the omission. - Never merge a PR that is test-blocked per Step 1f until tests are added or a
Test-waiver:comment explains why coverage is not feasible. - Always run G2 and G3 before merging a security-adjacent PR.
- Always report security gate results in the summary, even when advisory.
- Always run Step 1c (Audit Existing Review Findings) for every non-draft PR before classification in Step 2.
- Always run Step 1d (Check Agentic Behavior Eval Coverage) for every non-draft PR before classification in Step 2.
- Always run Step 1e (Docs-Coverage Gate) for every non-draft PR before classification in Step 2.
- Always run Step 1f (Test-Coverage Gate) for every non-draft PR before classification in Step 2.
- Always run Step 4 (Post issue-closure comments) before
gh pr mergefor every PR that closes a linked issue. Auto-close alone does not produce a resolution trail. - After merge, manually close any issue that the PR resolved but GitHub did not auto-close (the auto-close-gap case: closure verb in body/commit but issue not in
closingIssuesReferences). - Never post
@claude reviewon aclaude/*branch PR — the workflow already runs onopenedfor those. - Never post
@claude reviewmore than once per batch run on the same PR. - Do not post
@claude reviewon trivially small PRs (≤5 files, ≤150 lines, no contract surface changes, not security-adjacent). - Treat placeholder review bodies (
I'll analyze this and get back to you.with 0 tokens) as "review not delivered," not "review approved." Re-trigger once per batch. - Fan out the audit to read-only subagents (Step 1a) when the MERGEABLE candidate set exceeds 6 PRs; keep it inline below that threshold.
- Use
Explore(read-only) for audit-batch subagents so they structurally cannot merge, comment, or push. Keep every mutating action (gh pr merge,gh pr comment,gh issue comment/close,@claude review) on the main thread. - Always re-confirm CI freshness against the current head SHA, the actual diff surface, and
mergeStateStatuson the main thread before merging — never merge on a subagent's verdict alone.
Forbidden Patterns
- Merging a release PR instead of handing off to
/release - Skipping security gates on security-adjacent PRs
- Treating CI warnings as failures (only errors block)
- Treating G2/G3 warnings as blocking (only errors block)
- Posting noisy comments on PRs that merely need a reviewer
- Force-pushing or rebasing shared branches
- Spamming
@claude reviewon every push — only request when the diff genuinely warrants a holistic re-review (≥3 new commits since last request) - Merging on the strength of a review timestamp alone. A review was posted does not mean its findings were addressed. Verify via Step 1c.
- Merging an eval-blocked PR. A PR touching agentic behavior without eval evidence is not merge-eligible regardless of CI status or human approvals.
- Counting
chore: regenerate test catalog/prettier/ rebase-merge commits as "post-review fixes." They are housekeeping and do not clear review blockers. - Treating placeholder review comments (
I'll analyze this and get back to you.with 0 output tokens) as completed reviews. Re-trigger and wait for a substantive review. - Merging a PR that closes issues without first posting a closure-narrative comment on each linked issue (Step 4). The GitHub auto-close link is not a resolution trail.
- Leaving issues open that the merged PR resolved. When detection in Step 4 surfaces an auto-close gap (closure verb in body/commit but issue not in
closingIssuesReferences), close the issue manually after merge withgh issue close <iss> --reason completedand a comment linking the resolving PR. - Acting on a subagent verdict without main-thread re-verification. A subagent reporting "MERGE-ELIGIBLE / CI passed" is a worklist entry with evidence, not a merge authorization. Stale CI runs and under-counted security/contract surfaces are the recurring failure modes; re-confirm before merging.
- Letting a subagent perform a mutating action. Audit subagents are read-only by design. If an audit needs a follow-up that mutates state, the main thread does it.
- Merging a PR that added a user-facing CLI command, parser, migration, or store path without test coverage. Counting POST calls is not coverage of POST body structure; tests must assert the fields sent.
- Treating a
Waiver:comment as clearing a test-blocked status. Docs waivers and test waivers are distinct; onlyTest-waiver:clears a test-blocked status.
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.

