Skip to content

Commit f90bd3e

Browse files
committed
Add PR batch merge ledger
1 parent 809e306 commit f90bd3e

7 files changed

Lines changed: 1712 additions & 10 deletions

File tree

.agents/skills/pr-batch/SKILL.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,14 @@ next paragraph; an empty full check list is `UNKNOWN` / not ready. Treat untriag
161161
regression, compatibility, and missing-changelog findings as merge blockers
162162
unless a maintainer explicitly waives them.
163163
164+
At merge readiness and batch closeout, run the machine-checkable per-PR merge
165+
ledger with `script/pr-merge-ledger <PR> --strict`, supplying explicit changelog
166+
classification and any P0/P1/P2/Must-Fix disposition evidence. Do not report a
167+
target `complete` while the ledger has any `UNKNOWN` field, unresolved
168+
current-head review thread, `CHANGES_REQUESTED` review object, or
169+
`complete_allowed: false`. Include the ledger JSON artifact path or table in the
170+
final handoff.
171+
164172
If `gh pr checks <PR> --required` reports no required checks, do NOT treat that
165173
as CI-ready. Instead treat the full `gh pr checks <PR>` list as the readiness
166174
gate and require each current-head check to pass or be skipped with CI selector
@@ -216,7 +224,9 @@ Use the canonical Batch Handoff Format in
216224
`.agents/workflows/pr-processing.md`. In short, split final batch handoffs into
217225
**Immediate maintainer attention** for true blockers and questions only, and
218226
**FYI / decisions made** for decisions, validations, review state, full-CI
219-
requests already handled, and no-PR rationales.
227+
requests already handled, no-PR rationales, and per-PR merge-ledger summaries.
228+
Do not call a target `complete` while its ledger has `UNKNOWN` fields or
229+
`complete_allowed: false`.
220230

221231
## Coordination State
222232

@@ -243,7 +253,7 @@ reporting, full-CI decisions, and merge sequencing.
243253
For the complete numbered sequence, follow the canonical closeout lane in
244254
`.agents/workflows/pr-processing.md` instead of stopping at PR creation. The
245255
coordinator owns the live re-fetch, current-head checks and review-thread triage,
246-
stale release-mode classification updates and the finalized PR-body
256+
per-PR merge-ledger run, stale release-mode classification updates and the finalized PR-body
247257
`Agent Merge Confidence` block refresh required for accelerated-RC readiness (kept
248258
distinct), full-CI request and waitback when uncertainty remains, and any
249259
authorized ready/merge action, and the late post-merge bot-finding sweep before

.agents/workflows/pr-processing.md

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,22 @@ gh api graphql --paginate -f owner="${OWNER}" -f name="${NAME}" -F pr="${PR_NUMB
9292

9393
Use `-F pr=...` intentionally here: `gh api graphql` needs a JSON integer for `$pr:Int!`, and raw `-f pr=...` sends a string.
9494

95+
At merge readiness or batch closeout, build the machine-checkable per-PR merge
96+
ledger. The command uses GitHub GraphQL/API reviewThreads, reviews, and PR
97+
comments, then emits JSON against `script/pr-merge-ledger.schema.json`:
98+
99+
```bash
100+
script/pr-merge-ledger <PR> --repo "${REPO}" \
101+
--changelog-classification <changelog_present|changelog_missing|deferred_to_update_changelog|not_user_visible> \
102+
--finding-dispositions <optional-dispositions.json> \
103+
--strict --pretty > "/tmp/pr-<PR>-merge-ledger.json"
104+
script/pr-merge-ledger --schema
105+
```
106+
107+
If changelog classification or P0/P1/P2/Must-Fix dispositions are not supplied,
108+
the ledger records those fields as `UNKNOWN`. `--strict` exits non-zero when any
109+
ledger violation exists or any field is `UNKNOWN`.
110+
95111
For an issue, gather enough context to avoid duplicate work:
96112

97113
```bash
@@ -387,11 +403,11 @@ it as an immediate maintainer question. Also apply the merge-endgame debounce
387403
and waiver-soak rule under **Merge Endgame Debounce And Waiver Soak** before
388404
the final merge/readiness decision.
389405
390-
After workers finish, the coordinator must keep working through the Coordinator Closeout Lane instead of stopping at PR creation: re-fetch live PR status, wait for current-head checks and reviews, triage/resolve or explicitly waive current unresolved review threads, update stale release-mode classification, refresh the finalized PR-body `Agent Merge Confidence` block when accelerated-RC readiness requires it, request full CI when uncertainty remains, re-fetch and wait for the newly requested current-head checks, and merge eligible ready PRs when authorized under the current release mode.
406+
After workers finish, the coordinator must keep working through the Coordinator Closeout Lane instead of stopping at PR creation: re-fetch live PR status, wait for current-head checks and reviews, triage/resolve or explicitly waive current unresolved review threads, run `script/pr-merge-ledger <PR> --strict` with explicit changelog classification and P0/P1/P2/Must-Fix dispositions, update stale release-mode classification, refresh the finalized PR-body `Agent Merge Confidence` block when accelerated-RC readiness requires it, request full CI when uncertainty remains, re-fetch and wait for the newly requested current-head checks, and merge eligible ready PRs when authorized under the current release mode.
391407
392408
For blocking questions, stop work on that target, surface a structured question to the coordinator or maintainer, and mark the issue/PR with the agreed pending-question state. Report the question/comment URL as `blocked needing user input`; do not open a speculative PR. For non-blocking questions where you make a decision and continue, record the decision in the PR description before review or merge.
393409
394-
Before final handoff, kill or confirm no stray GitHub polling processes are still running. Final state for every target must be one of: merged PR; open PR waiting on checks/review; blocked needing user input with the surfaced question/comment URL; or no-PR with an evidence-backed issue/PR comment URL. Split the handoff into `Immediate maintainer attention` and `FYI / decisions made`. Put only true blockers or questions in Immediate. Put non-blocking decisions, no-PR rationales, and full-CI uncertainty that was already handled by requesting full CI in FYI. Final handoff must list branches, PR URLs, issue outcomes, validations, last-known CI state, blockers, no-PR comments, and next actions.
410+
Before final handoff, kill or confirm no stray GitHub polling processes are still running. Final state for every target must be one of: merged PR; open PR waiting on checks/review; blocked needing user input with the surfaced question/comment URL; or no-PR with an evidence-backed issue/PR comment URL. Do not report a target `complete` while its merge ledger has any `UNKNOWN` field or `complete_allowed: false`. Split the handoff into `Immediate maintainer attention` and `FYI / decisions made`. Put only true blockers or questions in Immediate. Put non-blocking decisions, no-PR rationales, full-CI uncertainty that was already handled by requesting full CI, and the per-PR merge-ledger summary in FYI. Final handoff must list branches, PR URLs, issue outcomes, validations, last-known CI state, merge-ledger path or JSON artifact, blockers, no-PR comments, and next actions.
395411
```
396412

397413
### Question And Decision Handling
@@ -433,10 +449,14 @@ Split batch handoffs into two sections:
433449
unresolved `DISCUSS` feedback, or a merge/release-mode conflict.
434450
- **FYI / decisions made**: no-PR rationales, non-blocking decisions, full CI
435451
requested because the coordinator was unsure at readiness time, validation
436-
evidence, review churn notes, and already-answered questions.
452+
evidence, review churn notes, already-answered questions, and a per-PR
453+
merge-ledger table or JSON artifact path.
437454

438455
Do not put full-CI uncertainty in Immediate at final readiness after local
439456
validation and the final push. Request full CI and log it in FYI.
457+
Do not report a PR/target as `complete` while `script/pr-merge-ledger <PR>
458+
--strict` reports `UNKNOWN` fields, review-thread/review-object violations, or
459+
`complete_allowed: false`.
440460

441461
### Coordination State
442462

@@ -542,19 +562,25 @@ The closeout lane is:
542562
polling.
543563
4. Fetch current unresolved review threads and triage them as fixed, waived, or
544564
still blocking.
545-
5. Refresh stale release-mode classification from the release tracker when
565+
5. Run `script/pr-merge-ledger <PR> --strict` for every worker PR, supplying
566+
explicit changelog classification and any P0/P1/P2/Must-Fix disposition
567+
evidence. Store the JSON artifact or table for the final handoff. Do not
568+
mark a target complete while the ledger has `UNKNOWN` fields, unresolved
569+
current-head review threads, `CHANGES_REQUESTED` review objects, or
570+
`complete_allowed: false`.
571+
6. Refresh stale release-mode classification from the release tracker when
546572
needed. For accelerated-RC merge readiness, refresh the latest finalized
547573
PR-body `Agent Merge Confidence` block required by `AGENTS.md`; keep this
548574
distinct from tracker mode/classification updates.
549-
6. After the final push, if local validation passed and the only uncertainty is
575+
7. After the final push, if local validation passed and the only uncertainty is
550576
whether full CI is needed, request full CI with `+ci-run-full` and record the
551577
reason as FYI, then loop back to re-fetch and wait for the newly requested
552578
current-head checks before readiness or merge.
553-
7. Under the current release mode, mark ready or merge PRs that satisfy the
579+
8. Under the current release mode, mark ready or merge PRs that satisfy the
554580
merge qualification rules, including the merge-endgame debounce and
555581
waiver-soak rules before merge; report only remaining blockers, questions,
556582
or `UNKNOWN` live state.
557-
8. After any closeout-lane merge action, run a lightweight sweep for late
583+
9. After any closeout-lane merge action, run a lightweight sweep for late
558584
post-merge bot findings before the final batch handoff: confirm the PR landed,
559585
check `main` status, and inspect late review/check comments that arrived
560586
around or after merge. Route release-relevant findings into the next
@@ -841,6 +867,9 @@ Before saying a PR is ready to merge:
841867
gh pr view <PR> --json headRefOid,mergeStateStatus,reviewDecision,isDraft,labels,latestReviews,reviews,comments,mergedAt
842868
gh pr checks <PR> --required
843869
gh pr checks <PR>
870+
script/pr-merge-ledger <PR> \
871+
--changelog-classification <changelog_present|changelog_missing|deferred_to_update_changelog|not_user_visible> \
872+
--strict
844873
```
845874

846875
Before evaluating review feedback at this gate, also fetch inline PR review
@@ -859,6 +888,7 @@ Also verify:
859888
- No requested adversarial review has unresolved `BLOCKING` or `DISCUSS` findings.
860889
- Required checks are green, or the user has explicitly accepted an auditable waiver for full CI.
861890
- The PR body or latest agent comment includes exact local validation commands and results.
891+
- The merge ledger has no `UNKNOWN` fields and reports `complete_allowed: true`.
862892

863893
Merge qualification follows the canonical rule in `AGENTS.md` -> Review Workflow -> For All PRs: CI is passing, all current review comments and threads are addressed or explicitly triaged by tier, no major question or discussion item needs maintainer attention, and advisory AI systems such as CodeRabbit.ai are not special approval gates.
864894

Rakefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ end
7070

7171
def root_rubocop_paths
7272
# Root lint covers repo-root tooling only; package-owned rakelib files stay under package RuboCop.
73-
%w[Gemfile Rakefile rakelib]
73+
%w[Gemfile Rakefile rakelib script/pr-merge-ledger]
7474
end
7575

7676
def define_package_task(task_name, *arg_names)
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
{
2+
"repository": "shakacode/react_on_rails",
3+
"pull_request": {
4+
"number": 3613,
5+
"title": "ci(rspack): decouple per-bundler build + integration jobs so one bundler's build failure doesn't skip the other (#3593)",
6+
"url": "https://github.com/shakacode/react_on_rails/pull/3613",
7+
"state": "MERGED",
8+
"isDraft": false,
9+
"baseRefName": "main",
10+
"headRefName": "jg-conductor/3593-fix",
11+
"headRefOid": "62ecd5760e3466726a3be1ed77b0071665c5cf2d",
12+
"mergedAt": "2026-06-05T01:32:12Z",
13+
"reviewDecision": "CHANGES_REQUESTED"
14+
},
15+
"files": [
16+
".github/workflows/dummy-app-bundler-tests.yml",
17+
".github/workflows/integration-tests.yml"
18+
],
19+
"review_threads": [
20+
{
21+
"id": "PRRT_kwDOAnNnU86HM4iZ",
22+
"isResolved": false,
23+
"isOutdated": false,
24+
"path": ".github/workflows/integration-tests.yml",
25+
"line": 131,
26+
"comments": [
27+
{
28+
"id": "PRRC_kwDOAnNnU87INkFj",
29+
"databaseId": 3358998883,
30+
"body": "**P2** Keep CI rerun helper aligned with new check names.",
31+
"author": {
32+
"login": "chatgpt-codex-connector"
33+
},
34+
"url": "https://github.com/shakacode/react_on_rails/pull/3613#discussion_r3358998883",
35+
"path": ".github/workflows/integration-tests.yml",
36+
"line": 131,
37+
"createdAt": "2026-06-04T21:26:41Z",
38+
"outdated": false,
39+
"commit": {
40+
"oid": "62ecd5760e3466726a3be1ed77b0071665c5cf2d"
41+
},
42+
"originalCommit": {
43+
"oid": "d4d94358873321664b1e3a8c2a297f793a8ae3ed"
44+
},
45+
"pullRequestReview": {
46+
"id": "PRR_kwDOAnNnU88AAAABCCSc3Q",
47+
"state": "COMMENTED",
48+
"submittedAt": "2026-06-04T21:26:41Z",
49+
"commit": {
50+
"oid": "d4d94358873321664b1e3a8c2a297f793a8ae3ed"
51+
},
52+
"author": {
53+
"login": "chatgpt-codex-connector"
54+
}
55+
}
56+
}
57+
]
58+
}
59+
],
60+
"reviews": [
61+
{
62+
"id": "PRR_kwDOAnNnU88AAAABCCTgOg",
63+
"state": "CHANGES_REQUESTED",
64+
"submittedAt": "2026-06-04T21:29:57Z",
65+
"author": {
66+
"login": "coderabbitai"
67+
},
68+
"commit": {
69+
"oid": "d4d94358873321664b1e3a8c2a297f793a8ae3ed"
70+
},
71+
"url": "https://github.com/shakacode/react_on_rails/pull/3613#pullrequestreview-4431601722",
72+
"body": "**P2** Run this PR under full-ci before merge."
73+
},
74+
{
75+
"id": "PRR_kwDOAnNnU88AAAABCC6cRg",
76+
"state": "COMMENTED",
77+
"submittedAt": "2026-06-04T23:36:33Z",
78+
"author": {
79+
"login": "coderabbitai"
80+
},
81+
"commit": {
82+
"oid": "62ecd5760e3466726a3be1ed77b0071665c5cf2d"
83+
},
84+
"url": "https://github.com/shakacode/react_on_rails/pull/3613#pullrequestreview-4432239686",
85+
"body": "Nitpick comments only."
86+
}
87+
]
88+
}

0 commit comments

Comments
 (0)