From 3016a4e322de7244711cd416c144d325da03643c Mon Sep 17 00:00:00 2001 From: mintaka Date: Wed, 9 Sep 2026 22:48:00 -0400 Subject: [PATCH 1/2] fix(ci): stop body edits cancelling the base-re-point guard (RIG-3372) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `pr-base-repoint.yml` keyed its concurrency group on the PR number alone, so the two `pull_request.edited` classes shared one cancel group. jj-vine edits every PR body ~2s after a base re-point, so the body-edit run cancelled the re-point run and then skipped itself (`changes.base == null`) — the PR kept its stale green checks and nothing went red. On PR #916 the cancelled run executed zero steps, dying before `dispatch`, so the verify step built to catch exactly this never ran to fail. Partition the group by event class, matching the job's own guard predicate: pr-base-repoint-- `cancel-in-progress: true` is kept: a genuine second base re-point still supersedes the first, since both land in the `-repoint` group. Only the body-edit arm moves out of the way. The condition is `changes.base != null`, not a bare `changes.base`. GitHub's `&&`/`||` return the operand rather than a boolean, and objects are never converted to a string, so a bare truthiness test would put the `changes.base` OBJECT into the group name. Comparing to null yields a boolean, so both arms return strings. actionlint accepts either form — it does not catch this. Ledger-impact: none — a CI workflow concurrency-key fix; no design record touched. --- .github/workflows/pr-base-repoint.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr-base-repoint.yml b/.github/workflows/pr-base-repoint.yml index 5e882c3d4..104d5338c 100644 --- a/.github/workflows/pr-base-repoint.yml +++ b/.github/workflows/pr-base-repoint.yml @@ -35,8 +35,13 @@ permissions: # One re-trigger in flight per PR. A second base re-point supersedes the first; # the older dispatch is answering a question about a base that no longer holds. +# +# The group is partitioned by event class because a body edit arrives ~2s after +# a base re-point on the same PR: sharing one group, it cancelled the re-point +# run before its dispatch step and then skipped itself, leaving the PR on stale +# checks with nothing red to show for it. concurrency: - group: pr-base-repoint-${{ github.event.pull_request.number }} + group: pr-base-repoint-${{ github.event.pull_request.number }}-${{ github.event.changes.base != null && 'repoint' || 'edit' }} cancel-in-progress: true jobs: From 2a5f064b931661668d28a34d499d87c74d44e81f Mon Sep 17 00:00:00 2001 From: mintaka Date: Wed, 9 Sep 2026 23:23:54 -0400 Subject: [PATCH 2/2] docs(ci): correct the base-re-point guard's rationale (RIG-3372) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Review of #1060 found the justification in the previous commit's message is wrong, and narrowed what the fix delivers. The expression itself is correct and unchanged; this commit fixes the prose around it. **Correction.** The previous message claimed a bare `changes.base && 'repoint'` would put the `changes.base` OBJECT into the group name. It would not. GitHub's `&&` returns its RIGHT operand when the left is truthy, so the bare form also yields 'repoint'. The object could only reach the name by being the operand actually returned, which never happens here. Verified against GitHub's own reference evaluator (`@actions/expressions`) across six payload shapes: base re-point, body edit, title edit, `changes` absent, `changes` empty, and `changes.base` explicitly null. `!= null` remains the right form, for the real reason: it types the predicate as a boolean and mirrors the job's own `if:` conjunct verbatim, so the group and the guard are visibly the same test. **Scope of the fix.** The comment said the race left "nothing red to show for it", implying the fix restores a gate. It restores a *signal*: `rollup` is the only required context on `main`, so a red guard does not block the merge queue. The comment now says so. Also records why the key mirrors only the `changes.base` conjunct and not the same-repo one: a PR's head repo is fixed at creation, so a fork PR's runs only ever share a group with other fork runs of the same PR, all of which skip. Ledger-impact: none — comment and rationale only; no design record touched. --- .github/workflows/pr-base-repoint.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr-base-repoint.yml b/.github/workflows/pr-base-repoint.yml index 104d5338c..7bb67ac7b 100644 --- a/.github/workflows/pr-base-repoint.yml +++ b/.github/workflows/pr-base-repoint.yml @@ -38,8 +38,14 @@ permissions: # # The group is partitioned by event class because a body edit arrives ~2s after # a base re-point on the same PR: sharing one group, it cancelled the re-point -# run before its dispatch step and then skipped itself, leaving the PR on stale -# checks with nothing red to show for it. +# run before its dispatch step and then skipped itself, so no guard run ever +# reached a verdict. The guard is advisory — `rollup` is the only required +# context — so its red is an operator signal, not a merge gate. +# +# The key mirrors only the `changes.base` half of the job's `if:`, not the +# same-repo conjunct. Safe because a PR's head repo is fixed at creation: a +# fork PR's runs only ever share a group with other fork runs of the same PR, +# and every one of those skips. concurrency: group: pr-base-repoint-${{ github.event.pull_request.number }}-${{ github.event.changes.base != null && 'repoint' || 'edit' }} cancel-in-progress: true