From 929dceba649329c4f4d17a8f9f63970db97c9cf2 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 4 Aug 2026 03:52:57 +0000 Subject: [PATCH 1/9] CI: supersede stacked check runs instead of letting them pile up MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Measured, not assumed. The GraphQL quota for the repo owner keeps hitting zero (`sweep-review-threads` died on it again today), so I inventoried where the calls come from rather than guessing: - Scheduled workflows are NOT the driver: 11 crons totalling ~3 runs/day. - 24 workflows fire on push / pull_request / issue_comment. Of those, 19 had no concurrency guard at all, so every push to an open PR started a fresh full set while the previous set kept running to completion. Nobody is waiting on the older run's verdict; it burns runners and API calls to report on a commit that has already been replaced. This adds a guard to the nine read-only check workflows — the ones that verified as zero write operations, no commits, no deploys, no PR/issue mutations, so a cancelled run cannot leave partial state behind: check-dotfolder-anchors check-notebooks-paired check-portable-paths cross-platform-smoke laf-usb-manifest-policy large-file-policy validate-daily-notes validate-agent-content secret-pattern-policy Two deliberate choices in the group key: - `github.event_name` is included so the push-event run and the pull_request-event run of one branch land in SEPARATE groups. Collapsing them would dedupe the double-fire, but at the cost of letting a push run cancel a required PR check — and a cancelled required check reads as a blocked PR. Not worth it. - merge_group is exempted from cancellation. Cancelling a merge-queue check breaks the queue. No coverage is lost: the final state of a branch is still checked in full. Only verdicts on superseded commits are dropped. Verified: all 49 workflow files still parse as YAML; the nine resolve the expected cancel-in-progress expression; and PR #913's diff still applies cleanly on top of this branch, so the two are independent. Left alone, deliberately, because they change behavior rather than just scheduling — Logan's call, not mine: - secret-pattern-policy still carries `push: branches: ['**']` where the other seven use ['main']. That is the duplicate run AND the whole-tree scan that false-reds every new branch. Narrowing it narrows a security control, so it is not something to do unasked. - review-feedback-loop fires on every issue_comment, including each bot's (CodeRabbit, Sourcery, Codacy), and its sweep queries reviewThreads(first:100){comments(first:100)} — up to 10,000 nodes per call. Gating on non-bot commenters would cut most firings, but I have not verified what verify-agent-claims expects to react to. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01EBV6TkrwsZhcwkh1b6NUHs --- .github/workflows/check-dotfolder-anchors.yml | 14 ++++++++++++++ .github/workflows/check-notebooks-paired.yml | 14 ++++++++++++++ .github/workflows/check-portable-paths.yml | 14 ++++++++++++++ .github/workflows/cross-platform-smoke.yml | 14 ++++++++++++++ .github/workflows/laf-usb-manifest-policy.yml | 14 ++++++++++++++ .github/workflows/large-file-policy.yml | 14 ++++++++++++++ .github/workflows/secret-pattern-policy.yml | 14 ++++++++++++++ .github/workflows/validate-agent-content.yml | 14 ++++++++++++++ .github/workflows/validate-daily-notes.yml | 14 ++++++++++++++ 9 files changed, 126 insertions(+) diff --git a/.github/workflows/check-dotfolder-anchors.yml b/.github/workflows/check-dotfolder-anchors.yml index 390f413aed..e88794b8f5 100644 --- a/.github/workflows/check-dotfolder-anchors.yml +++ b/.github/workflows/check-dotfolder-anchors.yml @@ -6,6 +6,20 @@ on: pull_request: merge_group: +# Supersede, don't stack: a second push to the same branch cancels the still-running +# check for the previous commit, which nobody is waiting on. The final state of the +# branch is still checked in full, so no coverage is lost. +# +# `github.event_name` is in the group key on purpose: it keeps the push-event run and +# the pull_request-event run of the same branch in SEPARATE groups. Collapsing them +# would let a push run cancel a required PR check, and a cancelled required check +# blocks the PR. +# +# merge_group is never cancelled — cancelling a merge-queue check breaks the queue. +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }} + cancel-in-progress: ${{ github.event_name != 'merge_group' }} + jobs: check-dotfolder-anchors: runs-on: ubuntu-latest diff --git a/.github/workflows/check-notebooks-paired.yml b/.github/workflows/check-notebooks-paired.yml index 3fe98dacc5..e2a8e395db 100644 --- a/.github/workflows/check-notebooks-paired.yml +++ b/.github/workflows/check-notebooks-paired.yml @@ -21,6 +21,20 @@ on: permissions: contents: read +# Supersede, don't stack: a second push to the same branch cancels the still-running +# check for the previous commit, which nobody is waiting on. The final state of the +# branch is still checked in full, so no coverage is lost. +# +# `github.event_name` is in the group key on purpose: it keeps the push-event run and +# the pull_request-event run of the same branch in SEPARATE groups. Collapsing them +# would let a push run cancel a required PR check, and a cancelled required check +# blocks the PR. +# +# merge_group is never cancelled — cancelling a merge-queue check breaks the queue. +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }} + cancel-in-progress: ${{ github.event_name != 'merge_group' }} + jobs: paired: runs-on: ubuntu-latest diff --git a/.github/workflows/check-portable-paths.yml b/.github/workflows/check-portable-paths.yml index b5d1541d40..a1e3d2532c 100644 --- a/.github/workflows/check-portable-paths.yml +++ b/.github/workflows/check-portable-paths.yml @@ -6,6 +6,20 @@ on: branches: [main] merge_group: +# Supersede, don't stack: a second push to the same branch cancels the still-running +# check for the previous commit, which nobody is waiting on. The final state of the +# branch is still checked in full, so no coverage is lost. +# +# `github.event_name` is in the group key on purpose: it keeps the push-event run and +# the pull_request-event run of the same branch in SEPARATE groups. Collapsing them +# would let a push run cancel a required PR check, and a cancelled required check +# blocks the PR. +# +# merge_group is never cancelled — cancelling a merge-queue check breaks the queue. +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }} + cancel-in-progress: ${{ github.event_name != 'merge_group' }} + jobs: check-paths: runs-on: ubuntu-latest diff --git a/.github/workflows/cross-platform-smoke.yml b/.github/workflows/cross-platform-smoke.yml index 97a1dfb2b5..bdd71dfae8 100644 --- a/.github/workflows/cross-platform-smoke.yml +++ b/.github/workflows/cross-platform-smoke.yml @@ -20,6 +20,20 @@ on: permissions: contents: read +# Supersede, don't stack: a second push to the same branch cancels the still-running +# check for the previous commit, which nobody is waiting on. The final state of the +# branch is still checked in full, so no coverage is lost. +# +# `github.event_name` is in the group key on purpose: it keeps the push-event run and +# the pull_request-event run of the same branch in SEPARATE groups. Collapsing them +# would let a push run cancel a required PR check, and a cancelled required check +# blocks the PR. +# +# merge_group is never cancelled — cancelling a merge-queue check breaks the queue. +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }} + cancel-in-progress: ${{ github.event_name != 'merge_group' }} + jobs: smoke: strategy: diff --git a/.github/workflows/laf-usb-manifest-policy.yml b/.github/workflows/laf-usb-manifest-policy.yml index 7d17f9a971..5fc242e276 100644 --- a/.github/workflows/laf-usb-manifest-policy.yml +++ b/.github/workflows/laf-usb-manifest-policy.yml @@ -14,6 +14,20 @@ on: - ".github/scripts/laf_usb_manifest.py" - ".github/workflows/laf-usb-manifest-policy.yml" +# Supersede, don't stack: a second push to the same branch cancels the still-running +# check for the previous commit, which nobody is waiting on. The final state of the +# branch is still checked in full, so no coverage is lost. +# +# `github.event_name` is in the group key on purpose: it keeps the push-event run and +# the pull_request-event run of the same branch in SEPARATE groups. Collapsing them +# would let a push run cancel a required PR check, and a cancelled required check +# blocks the PR. +# +# merge_group is never cancelled — cancelling a merge-queue check breaks the queue. +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }} + cancel-in-progress: ${{ github.event_name != 'merge_group' }} + jobs: validate: runs-on: ubuntu-latest diff --git a/.github/workflows/large-file-policy.yml b/.github/workflows/large-file-policy.yml index 3061e286bd..23b8977f12 100644 --- a/.github/workflows/large-file-policy.yml +++ b/.github/workflows/large-file-policy.yml @@ -7,6 +7,20 @@ on: merge_group: workflow_dispatch: +# Supersede, don't stack: a second push to the same branch cancels the still-running +# check for the previous commit, which nobody is waiting on. The final state of the +# branch is still checked in full, so no coverage is lost. +# +# `github.event_name` is in the group key on purpose: it keeps the push-event run and +# the pull_request-event run of the same branch in SEPARATE groups. Collapsing them +# would let a push run cancel a required PR check, and a cancelled required check +# blocks the PR. +# +# merge_group is never cancelled — cancelling a merge-queue check breaks the queue. +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }} + cancel-in-progress: ${{ github.event_name != 'merge_group' }} + jobs: check-large-files: runs-on: ubuntu-latest diff --git a/.github/workflows/secret-pattern-policy.yml b/.github/workflows/secret-pattern-policy.yml index 85c6869244..8e66ed348a 100644 --- a/.github/workflows/secret-pattern-policy.yml +++ b/.github/workflows/secret-pattern-policy.yml @@ -7,6 +7,20 @@ on: merge_group: workflow_dispatch: +# Supersede, don't stack: a second push to the same branch cancels the still-running +# check for the previous commit, which nobody is waiting on. The final state of the +# branch is still checked in full, so no coverage is lost. +# +# `github.event_name` is in the group key on purpose: it keeps the push-event run and +# the pull_request-event run of the same branch in SEPARATE groups. Collapsing them +# would let a push run cancel a required PR check, and a cancelled required check +# blocks the PR. +# +# merge_group is never cancelled — cancelling a merge-queue check breaks the queue. +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }} + cancel-in-progress: ${{ github.event_name != 'merge_group' }} + jobs: check-secret-patterns: runs-on: ubuntu-latest diff --git a/.github/workflows/validate-agent-content.yml b/.github/workflows/validate-agent-content.yml index 8077d2c1f2..14314419fd 100644 --- a/.github/workflows/validate-agent-content.yml +++ b/.github/workflows/validate-agent-content.yml @@ -5,6 +5,20 @@ on: branches: - "agent/**" +# Supersede, don't stack: a second push to the same branch cancels the still-running +# check for the previous commit, which nobody is waiting on. The final state of the +# branch is still checked in full, so no coverage is lost. +# +# `github.event_name` is in the group key on purpose: it keeps the push-event run and +# the pull_request-event run of the same branch in SEPARATE groups. Collapsing them +# would let a push run cancel a required PR check, and a cancelled required check +# blocks the PR. +# +# merge_group is never cancelled — cancelling a merge-queue check breaks the queue. +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }} + cancel-in-progress: ${{ github.event_name != 'merge_group' }} + jobs: validate: name: Validate markdown content on agent branches diff --git a/.github/workflows/validate-daily-notes.yml b/.github/workflows/validate-daily-notes.yml index c3a9ca58a1..440d44d48f 100644 --- a/.github/workflows/validate-daily-notes.yml +++ b/.github/workflows/validate-daily-notes.yml @@ -8,6 +8,20 @@ on: permissions: contents: read +# Supersede, don't stack: a second push to the same branch cancels the still-running +# check for the previous commit, which nobody is waiting on. The final state of the +# branch is still checked in full, so no coverage is lost. +# +# `github.event_name` is in the group key on purpose: it keeps the push-event run and +# the pull_request-event run of the same branch in SEPARATE groups. Collapsing them +# would let a push run cancel a required PR check, and a cancelled required check +# blocks the PR. +# +# merge_group is never cancelled — cancelling a merge-queue check breaks the queue. +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }} + cancel-in-progress: ${{ github.event_name != 'merge_group' }} + jobs: check-date-placeholders: runs-on: ubuntu-latest From 0a5d3829ca7af1ca9148c6f62f58185041cd8807 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 4 Aug 2026 05:10:26 +0000 Subject: [PATCH 2/9] CI: scope the new-branch secret scan, and stop stacking review sweeps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two changes to the machinery that has been failing all day, both measured. 1. secret-pattern-policy: the new-branch fallback scanned the whole repo. The `push: branches: ['**']` trigger STAYS. Its own comment records that it was broadened on 2026-07-02 because a real leak arrived by direct push to a working branch, which a main-only trigger never sees. Narrowing it would reopen the hole a documented incident closed. (An earlier version of this branch's PR description recommended exactly that; it was wrong and has been withdrawn.) The defect is one level down. On a new branch (`before == 000…0`) the job ran `git ls-tree -r` over everything: whole tree 75,420 files files the branch introduces 16 files It re-reported the same ~55 pre-existing findings (minified plugin bundles, clipped articles with embedded map keys) on #910, #913 and #918 in one day, which is how a gate that caught a genuine leak gets trained into noise. Now it diffs from the parent of the oldest commit reachable from this branch and from no other ref — every file the branch's own commits touch. A secret pushed straight to a working branch is by definition in such a file, so the leak this trigger exists for is still caught. If that base cannot be determined (root commit, orphan branch, refs not fetched) it FAILS CLOSED to the whole-tree scan, so the worst case is exactly today's behaviour. 2. review-feedback-loop: `sweep-review-threads` had no concurrency guard. This is the repository's largest GraphQL consumer. It fires on `synchronize` — every push to every open PR — and each run issues `reviewThreads(first: 100) { comments(first: 100) }`, which GitHub prices at roughly 100 points against a 5,000/hour budget. That is ~50 sweeps an hour. A few pushes across a few branches exhaust it, and then every PR in the repo reports "API rate limit already exceeded for user ID 136375980" — which is what has been happening. Cancelling a superseded sweep is safe because sync-pr is a *sync*: it drives labels and thread state toward what the PR currently looks like, so a run cut short is corrected by the next one, which reads current state rather than resuming. Only the last run's verdict matters. Guard is job-level, so the two issue_comment jobs are untouched. Not done, deliberately: shrinking the query's page sizes would cut the cost further, but consumers read comment bodies out of those threads and I could not establish a smaller page that never drops one. Silently missing a comment is the failure class this commit is cleaning up, not one to introduce. Corrected from my own earlier claim on #918: bot comments are NOT the main drain. `acknowledge-apply` and `verify-claim` filter on the comment body before the expensive fetch, so a CodeRabbit or Sourcery comment costs `ensure_labels()` and exits. The pushes are the cost, and today most of them were mine. Verified: the scoping logic run verbatim against this branch yields base a83c1d6f and 16 files; the empty-base path falls through to the whole-tree scan; the scoped file set passes check_secret_patterns.py; all 49 workflows parse; the rewritten shell block passes `bash -n`. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01EBV6TkrwsZhcwkh1b6NUHs --- .github/workflows/review-feedback-loop.yml | 17 +++++++++ .github/workflows/secret-pattern-policy.yml | 38 +++++++++++++++++++-- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/.github/workflows/review-feedback-loop.yml b/.github/workflows/review-feedback-loop.yml index e3d27df414..293cede025 100644 --- a/.github/workflows/review-feedback-loop.yml +++ b/.github/workflows/review-feedback-loop.yml @@ -58,6 +58,23 @@ jobs: group: sweep-review-threads-${{ github.event_name }}-${{ github.event.pull_request.number }} cancel-in-progress: true runs-on: ubuntu-latest + # This job is the repository's single largest consumer of the GraphQL rate + # limit. It fires on `synchronize` — every push to every open PR — and each + # run issues `reviewThreads(first: 100) { comments(first: 100) }`, which GitHub + # prices at roughly 100 points. The 5,000 points/hour budget is therefore about + # 50 sweeps, and an agent pushing a few times across a few branches exhausts it; + # `sweep-review-threads` then fails on every PR in the repo with + # "API rate limit already exceeded". + # + # Cancelling a superseded sweep is safe *because sync-pr is a sync*: it drives + # labels and thread state toward whatever the PR currently looks like. A run + # interrupted halfway is corrected by the next run, which reads current state + # rather than resuming. The only run whose verdict matters is the last one. + # + # Job-level, not workflow-level, so the issue_comment jobs are untouched. + concurrency: + group: review-feedback-loop-sweep-${{ github.event.pull_request.number }} + cancel-in-progress: true permissions: # contents: write is required to enable merge-queue auto-merge # (enablePullRequestAutoMerge is gated like resolveReviewThread, #546). sync-pr diff --git a/.github/workflows/secret-pattern-policy.yml b/.github/workflows/secret-pattern-policy.yml index 8e66ed348a..44d98c6f02 100644 --- a/.github/workflows/secret-pattern-policy.yml +++ b/.github/workflows/secret-pattern-policy.yml @@ -55,8 +55,42 @@ jobs: before="${{ github.event.before }}" after="${{ github.sha }}" if [[ "$before" == "0000000000000000000000000000000000000000" ]]; then - git ls-tree -r -z --name-only "$after" | - python trusted-main/.github/scripts/check_secret_patterns.py --paths-from-stdin + # New branch: there is no `before` to diff against, but "everything in + # the repo" is the wrong answer. It re-reports ~55 findings that were + # already here (minified plugin bundles, clipped articles with embedded + # map keys) on every branch anyone creates, which is how a gate that + # caught a real leak gets trained into noise people click past. + # + # Scan what the BRANCH introduces: the commits reachable from it and + # from nothing else, diffed from the parent of the oldest one. A secret + # pushed straight to a working branch — the leak this trigger was + # broadened for on 2026-07-02 — is by definition in a file that branch + # touched, so it is still caught. + self_local="refs/heads/${GITHUB_REF#refs/heads/}" + self_remote="refs/remotes/origin/${GITHUB_REF#refs/heads/}" + others=$(git for-each-ref --format='%(refname)' refs/heads refs/remotes/origin \ + | grep -vFx "$self_local" | grep -vFx "$self_remote" || true) + + base="" + if [ -n "$others" ]; then + first=$(git rev-list "$after" --not $others 2>/dev/null | tail -1) + if [ -n "$first" ] && git rev-parse -q --verify "${first}^" >/dev/null 2>&1; then + base=$(git rev-parse "${first}^") + fi + fi + + if [ -n "$base" ]; then + echo "New branch: scanning $base..$after (files this branch introduces)" + git diff --name-only -z --diff-filter=ACMR "$base" "$after" | + python trusted-main/.github/scripts/check_secret_patterns.py --paths-from-stdin + else + # Fail closed. If the branch's own commits cannot be isolated (root + # commit, orphan branch, no other refs fetched), scan everything + # rather than scan nothing. Worst case is the previous behaviour. + echo "New branch: cannot isolate branch commits; scanning whole tree." + git ls-tree -r -z --name-only "$after" | + python trusted-main/.github/scripts/check_secret_patterns.py --paths-from-stdin + fi else git diff --name-only -z --diff-filter=ACMR "$before" "$after" | python trusted-main/.github/scripts/check_secret_patterns.py --paths-from-stdin From 32dde25107af2603c95f125dbb39bae0e257e00f Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 8 Aug 2026 07:14:25 +0000 Subject: [PATCH 3/9] Note the provenance of this restore The two commits below were merged into logan/obsidian as #918 on 2026-08-04T05:27:58Z (merge commit 913a84c76) and discarded ten minutes later when 3591a4bb was committed on main's tip and pushed to logan/obsidian, resetting that branch. Neither commit is an ancestor of main or of logan/obsidian today; both survive on origin/claude/ci-concurrency-qzt7le. Cherry-picked, not rewritten, so authorship and content are unchanged. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01EBV6TkrwsZhcwkh1b6NUHs From e51e87fa06d2bede85b0a934d6cd2a4155bf2f70 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 9 Aug 2026 20:05:27 +0000 Subject: [PATCH 4/9] Drop #918's sweep guard: main already has a better one MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cherry-picking #918 added a second `concurrency:` key to the sweep-review-threads job. That job already had one on main. Two problems, both real: - Duplicate mapping keys in a job are invalid for GitHub Actions. - Under last-key-wins parsing, #918's block silently REPLACED main's. Main's key namespaces by `github.event_name`; #918's does not. This workflow also fires on `issue_comment`, where `issue.number` is the same number as `pull_request.number` — so without the namespace a comment event can contend with, and cancel, a live sweep for that PR. The duplicate reintroduced exactly the collision main's comment warns about. Main's guard is kept unchanged. #918's is dropped: that part of #918 was independently re-implemented on main, and better. Found by Sourcery on #937. It got past my own check because yaml.safe_load accepts duplicate keys silently and keeps the last. Replaced with a loader that raises on duplicates; all 52 workflows scanned, 0 failures. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01EBV6TkrwsZhcwkh1b6NUHs --- .github/workflows/review-feedback-loop.yml | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/.github/workflows/review-feedback-loop.yml b/.github/workflows/review-feedback-loop.yml index 293cede025..e3d27df414 100644 --- a/.github/workflows/review-feedback-loop.yml +++ b/.github/workflows/review-feedback-loop.yml @@ -58,23 +58,6 @@ jobs: group: sweep-review-threads-${{ github.event_name }}-${{ github.event.pull_request.number }} cancel-in-progress: true runs-on: ubuntu-latest - # This job is the repository's single largest consumer of the GraphQL rate - # limit. It fires on `synchronize` — every push to every open PR — and each - # run issues `reviewThreads(first: 100) { comments(first: 100) }`, which GitHub - # prices at roughly 100 points. The 5,000 points/hour budget is therefore about - # 50 sweeps, and an agent pushing a few times across a few branches exhausts it; - # `sweep-review-threads` then fails on every PR in the repo with - # "API rate limit already exceeded". - # - # Cancelling a superseded sweep is safe *because sync-pr is a sync*: it drives - # labels and thread state toward whatever the PR currently looks like. A run - # interrupted halfway is corrected by the next run, which reads current state - # rather than resuming. The only run whose verdict matters is the last one. - # - # Job-level, not workflow-level, so the issue_comment jobs are untouched. - concurrency: - group: review-feedback-loop-sweep-${{ github.event.pull_request.number }} - cancel-in-progress: true permissions: # contents: write is required to enable merge-queue auto-merge # (enablePullRequestAutoMerge is gated like resolveReviewThread, #546). sync-pr From 088a676c913fb528b0b0fc1976f9f6021f7389f5 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 9 Aug 2026 20:07:03 +0000 Subject: [PATCH 5/9] Restore the all-branches secret-scan trigger, and count tags as existing history MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two fixes to the same file, both from review on #937. 1. push.branches back to ['**']. Restoring #918's scoping without this was restoring a fix for a code path that cannot run. `main` has push.branches: [main], so a push to a working branch never starts this workflow at all — the new-branch case the scoping handles is unreachable. The broadening is a third casualty of the same 05:37 rewind: `git log -S` finds ['**'] nowhere in main's history for this file. It was broadened on logan/obsidian on 2026-07-02 because a real leak arrived by direct push to a working branch, which a main-only trigger never scans. The trigger and the scoping are one design — the trigger is what provides the coverage, the scoping is what keeps that coverage from drowning in ~55 pre-existing findings on every new branch. The PR body claimed this trigger was already intact. It was not. That claim was copied from #918's description instead of read off the file. 2. refs/tags added to the `others` set. If a branch starts from a commit reachable only through a tag, omitting tags makes `rev-list --not others` treat that pre-existing history as branch-unique and widen the scan to unrelated files — the exact noise the scoping exists to prevent. Over-scan, not under-scan, so no leak was missable; it just defeats the purpose. Verified: 52 workflows scanned for duplicate keys, 0 failures; bash -n clean; scoping logic re-run verbatim with tags -> base 02b3af173, 9 files against a 38,480-file tree, check_secret_patterns.py OK. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01EBV6TkrwsZhcwkh1b6NUHs --- .github/workflows/secret-pattern-policy.yml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/secret-pattern-policy.yml b/.github/workflows/secret-pattern-policy.yml index 44d98c6f02..cb885035fd 100644 --- a/.github/workflows/secret-pattern-policy.yml +++ b/.github/workflows/secret-pattern-policy.yml @@ -3,7 +3,12 @@ name: Secret Pattern Policy on: pull_request: push: - branches: [main] + # Broadened 2026-07-02 from [main] only: the leak was a direct push to a + # working branch (logan/obsidian), which the main-only trigger never scanned. + # Runs on every branch push now; the job scopes the new-branch case + # (before==0000…) to the files that branch introduces, and falls back to the + # whole tree if it cannot isolate them. + branches: ['**'] merge_group: workflow_dispatch: @@ -68,7 +73,11 @@ jobs: # touched, so it is still caught. self_local="refs/heads/${GITHUB_REF#refs/heads/}" self_remote="refs/remotes/origin/${GITHUB_REF#refs/heads/}" - others=$(git for-each-ref --format='%(refname)' refs/heads refs/remotes/origin \ + # refs/tags included: if the branch starts from a commit reachable + # only through a tag, omitting tags makes `rev-list --not others` + # treat that pre-existing history as branch-unique, and the scan + # widens to unrelated files — the noise this scoping exists to stop. + others=$(git for-each-ref --format='%(refname)' refs/heads refs/remotes/origin refs/tags \ | grep -vFx "$self_local" | grep -vFx "$self_remote" || true) base="" From e20c96010c062286e8f56c43f113a99c21a885e1 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 9 Aug 2026 20:13:56 +0000 Subject: [PATCH 6/9] Never cancel a push run on the five delta-scanning checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #918 justified branch-level cancellation on the grounds that these checks are read-only, so a cancelled run cannot leave partial state. That is true and it is not the relevant property. Read-only is not the same as cumulative. Five of the nine guarded workflows scan only the current push's before..after delta: check-portable-paths large-file-policy secret-pattern-policy validate-agent-content validate-daily-notes For those, cancelling a push run loses that delta's coverage permanently. Push A adds a violation; push B touches an unrelated file and cancels A; B scans only its own files, and A's remain on the branch never having been examined. Nothing rescans them, because the next push's `before` is A's `after`. On secret-pattern-policy that is a hole in the check whose entire purpose is catching a secret pushed straight to a working branch — the same leak the ['**'] trigger was broadened for. Restoring that trigger while adding branch-level cancellation would have handed back the coverage with one hand and removed it with the other. Push groups on those five are now SHA-specific, so every push run is alone in its group and always completes. pull_request runs scan base..head, which is cumulative, so superseding one loses nothing — they still dedupe. The other four (check-dotfolder-anchors, check-notebooks-paired, cross-platform-smoke, laf-usb-manifest-policy) do not read github.event.before and are left exactly as #918 had them. Found by Copilot on #937. Measured before applying: grep for github.event.before across all nine, 5 hits / 4 clean. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01EBV6TkrwsZhcwkh1b6NUHs --- .github/workflows/check-portable-paths.yml | 8 +++++++- .github/workflows/large-file-policy.yml | 8 +++++++- .github/workflows/secret-pattern-policy.yml | 8 +++++++- .github/workflows/validate-agent-content.yml | 8 +++++++- .github/workflows/validate-daily-notes.yml | 8 +++++++- 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/.github/workflows/check-portable-paths.yml b/.github/workflows/check-portable-paths.yml index a1e3d2532c..5ccac56156 100644 --- a/.github/workflows/check-portable-paths.yml +++ b/.github/workflows/check-portable-paths.yml @@ -17,7 +17,13 @@ on: # # merge_group is never cancelled — cancelling a merge-queue check breaks the queue. concurrency: - group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }} + # Push groups are SHA-specific, so push runs never cancel each other. + # These checks scan only the push's own before..after delta, so a cancelled + # push run loses that delta's coverage for good: push A adds a violation, + # push B touches an unrelated file and cancels A, and B then scans only its + # own files while A's remain on the branch, unexamined. pull_request runs + # scan base..head, which is cumulative, so superseding one loses nothing. + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }}-${{ github.event_name == 'push' && github.sha || 'shared' }} cancel-in-progress: ${{ github.event_name != 'merge_group' }} jobs: diff --git a/.github/workflows/large-file-policy.yml b/.github/workflows/large-file-policy.yml index 23b8977f12..0cd7344e07 100644 --- a/.github/workflows/large-file-policy.yml +++ b/.github/workflows/large-file-policy.yml @@ -18,7 +18,13 @@ on: # # merge_group is never cancelled — cancelling a merge-queue check breaks the queue. concurrency: - group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }} + # Push groups are SHA-specific, so push runs never cancel each other. + # These checks scan only the push's own before..after delta, so a cancelled + # push run loses that delta's coverage for good: push A adds a violation, + # push B touches an unrelated file and cancels A, and B then scans only its + # own files while A's remain on the branch, unexamined. pull_request runs + # scan base..head, which is cumulative, so superseding one loses nothing. + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }}-${{ github.event_name == 'push' && github.sha || 'shared' }} cancel-in-progress: ${{ github.event_name != 'merge_group' }} jobs: diff --git a/.github/workflows/secret-pattern-policy.yml b/.github/workflows/secret-pattern-policy.yml index cb885035fd..6da39e1a1b 100644 --- a/.github/workflows/secret-pattern-policy.yml +++ b/.github/workflows/secret-pattern-policy.yml @@ -23,7 +23,13 @@ on: # # merge_group is never cancelled — cancelling a merge-queue check breaks the queue. concurrency: - group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }} + # Push groups are SHA-specific, so push runs never cancel each other. + # These checks scan only the push's own before..after delta, so a cancelled + # push run loses that delta's coverage for good: push A adds a violation, + # push B touches an unrelated file and cancels A, and B then scans only its + # own files while A's remain on the branch, unexamined. pull_request runs + # scan base..head, which is cumulative, so superseding one loses nothing. + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }}-${{ github.event_name == 'push' && github.sha || 'shared' }} cancel-in-progress: ${{ github.event_name != 'merge_group' }} jobs: diff --git a/.github/workflows/validate-agent-content.yml b/.github/workflows/validate-agent-content.yml index 14314419fd..de35c7ad33 100644 --- a/.github/workflows/validate-agent-content.yml +++ b/.github/workflows/validate-agent-content.yml @@ -16,7 +16,13 @@ on: # # merge_group is never cancelled — cancelling a merge-queue check breaks the queue. concurrency: - group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }} + # Push groups are SHA-specific, so push runs never cancel each other. + # These checks scan only the push's own before..after delta, so a cancelled + # push run loses that delta's coverage for good: push A adds a violation, + # push B touches an unrelated file and cancels A, and B then scans only its + # own files while A's remain on the branch, unexamined. pull_request runs + # scan base..head, which is cumulative, so superseding one loses nothing. + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }}-${{ github.event_name == 'push' && github.sha || 'shared' }} cancel-in-progress: ${{ github.event_name != 'merge_group' }} jobs: diff --git a/.github/workflows/validate-daily-notes.yml b/.github/workflows/validate-daily-notes.yml index 440d44d48f..532488f3ad 100644 --- a/.github/workflows/validate-daily-notes.yml +++ b/.github/workflows/validate-daily-notes.yml @@ -19,7 +19,13 @@ permissions: # # merge_group is never cancelled — cancelling a merge-queue check breaks the queue. concurrency: - group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }} + # Push groups are SHA-specific, so push runs never cancel each other. + # These checks scan only the push's own before..after delta, so a cancelled + # push run loses that delta's coverage for good: push A adds a violation, + # push B touches an unrelated file and cancels A, and B then scans only its + # own files while A's remain on the branch, unexamined. pull_request runs + # scan base..head, which is cumulative, so superseding one loses nothing. + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }}-${{ github.event_name == 'push' && github.sha || 'shared' }} cancel-in-progress: ${{ github.event_name != 'merge_group' }} jobs: From 249360c730c119dc0fec7fd5e4bebecf07a0ac54 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 9 Aug 2026 20:24:58 +0000 Subject: [PATCH 7/9] Order rev-list topologically; drop the inert guard on validate-agent-content MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two findings from Copilot on #937. 1. `git rev-list ... | tail -1` now uses --topo-order. Default ordering is by date, which carries no topological guarantee. With skewed timestamps — rebases, or cherry-picks that preserve original author dates, which is exactly what this branch did — `tail -1` is not certain to be the root of the branch-unique history. Selecting a descendant would set `base` too late and silently omit an earlier commit's files from the scan, which is a miss rather than noise. Honest scope: I could not construct a case where the two orderings actually diverge. Along a linear chain git emits children before parents regardless of dates, and every case I built stayed linear. --topo-order is applied because it makes the guarantee explicit at no cost, not because a reproduction is attached. 2. validate-agent-content has no concurrency guard at all now. It fires on `push` and nothing else, and scans only that push's before..after delta. Branch grouping would let a later push cancel an earlier one whose files nothing would ever rescan. SHA grouping — what the previous commit gave it — makes every run unique, so nothing is ever superseded and the block does nothing. Inert config that reads as a guard is worse than none, because it gets counted as one; I counted it as one. The check is unguardable until a replacement run validates cumulative branch state instead of one delta. Removed, with a comment saying why, so the gap is visible rather than papered over. That leaves 8 guarded workflows, not 9: 4 branch-grouped (cumulative scans), 4 push-SHA-grouped (delta scans). Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01EBV6TkrwsZhcwkh1b6NUHs --- .github/workflows/secret-pattern-policy.yml | 9 +++++- .github/workflows/validate-agent-content.yml | 31 +++++++++----------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/.github/workflows/secret-pattern-policy.yml b/.github/workflows/secret-pattern-policy.yml index 6da39e1a1b..f0301aab7e 100644 --- a/.github/workflows/secret-pattern-policy.yml +++ b/.github/workflows/secret-pattern-policy.yml @@ -88,7 +88,14 @@ jobs: base="" if [ -n "$others" ]; then - first=$(git rev-list "$after" --not $others 2>/dev/null | tail -1) + # --topo-order, not the default date order: date order carries no + # topological guarantee, so with skewed timestamps (rebases, + # cherry-picks preserving original dates) `tail -1` is not certain to + # be the true root of the branch-unique history. Picking a descendant + # would set `base` too late and silently omit an earlier commit's + # files. --topo-order never emits a parent before its children, so the + # last entry is a real boundary. + first=$(git rev-list --topo-order "$after" --not $others 2>/dev/null | tail -1) if [ -n "$first" ] && git rev-parse -q --verify "${first}^" >/dev/null 2>&1; then base=$(git rev-parse "${first}^") fi diff --git a/.github/workflows/validate-agent-content.yml b/.github/workflows/validate-agent-content.yml index de35c7ad33..e663986532 100644 --- a/.github/workflows/validate-agent-content.yml +++ b/.github/workflows/validate-agent-content.yml @@ -5,25 +5,22 @@ on: branches: - "agent/**" -# Supersede, don't stack: a second push to the same branch cancels the still-running -# check for the previous commit, which nobody is waiting on. The final state of the -# branch is still checked in full, so no coverage is lost. +# No concurrency guard here, deliberately. # -# `github.event_name` is in the group key on purpose: it keeps the push-event run and -# the pull_request-event run of the same branch in SEPARATE groups. Collapsing them -# would let a push run cancel a required PR check, and a cancelled required check -# blocks the PR. +# This workflow fires on `push` and nothing else, and it scans only that push's +# own before..after delta. Those two facts together rule out every option: # -# merge_group is never cancelled — cancelling a merge-queue check breaks the queue. -concurrency: - # Push groups are SHA-specific, so push runs never cancel each other. - # These checks scan only the push's own before..after delta, so a cancelled - # push run loses that delta's coverage for good: push A adds a violation, - # push B touches an unrelated file and cancels A, and B then scans only its - # own files while A's remain on the branch, unexamined. pull_request runs - # scan base..head, which is cumulative, so superseding one loses nothing. - group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }}-${{ github.event_name == 'push' && github.sha || 'shared' }} - cancel-in-progress: ${{ github.event_name != 'merge_group' }} +# - Grouping by branch would let a later push cancel an earlier one, and the +# earlier push's files would then never be scanned by anything — the next +# push's `before` is the cancelled run's `after`. Coverage lost for good. +# - Grouping by SHA makes every run unique, so nothing is ever superseded and +# the block does nothing at all. Config that reads as a guard but is inert +# is worse than no config, because it invites being counted as one. +# +# So this check is genuinely unguardable as written. Making it safely +# cancellable means making a replacement run validate cumulative branch state +# rather than one push's delta; until someone does that, the honest thing is +# an empty space and this note. jobs: validate: From a9894c155a711a9ed1b35f7e0ca73ebae6124e86 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 9 Aug 2026 20:30:22 +0000 Subject: [PATCH 8/9] Stop subtracting refs/tags: tags are not a scanned baseline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reverts the refs/tags addition from 088a676c. Two reviewers disagreed and the security-relevant one is right. Everything in the `others` set is asserted to be already-scanned history. This workflow triggers on push.branches with no `tags:` filter, so a tag push never runs it — tagged commits have never been scanned by anything. Subtracting them asserts a baseline that does not exist. If a tag points at secret-bearing commit S and a branch adds harmless commit U on top, `rev-list --not ` returns only U, `base` becomes S, and the S..U scan steps over the secret. CodeRabbit asked for tags to be included to avoid an over-scan when a branch starts from a tag-only-reachable commit. That cost is real but it is noise. Copilot's cost is a miss. For a secret scanner those are not comparable, so this fails toward noise. I applied the first suggestion without asking what the subtraction was asserting. The reasoning is now in the file so the next person does not re-add it for the same plausible reason. Zero tags exist in this repo today, so nothing changes in practice — the code is wrong regardless of whether it is currently reachable. Verified: 52 workflows 0 duplicate-key/parse failures; bash -n clean; scoping run verbatim -> base 02b3af173, 20 files of 38,480, guard OK. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01EBV6TkrwsZhcwkh1b6NUHs --- .github/workflows/secret-pattern-policy.yml | 24 ++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/.github/workflows/secret-pattern-policy.yml b/.github/workflows/secret-pattern-policy.yml index f0301aab7e..44bcc19fe8 100644 --- a/.github/workflows/secret-pattern-policy.yml +++ b/.github/workflows/secret-pattern-policy.yml @@ -79,11 +79,25 @@ jobs: # touched, so it is still caught. self_local="refs/heads/${GITHUB_REF#refs/heads/}" self_remote="refs/remotes/origin/${GITHUB_REF#refs/heads/}" - # refs/tags included: if the branch starts from a commit reachable - # only through a tag, omitting tags makes `rev-list --not others` - # treat that pre-existing history as branch-unique, and the scan - # widens to unrelated files — the noise this scoping exists to stop. - others=$(git for-each-ref --format='%(refname)' refs/heads refs/remotes/origin refs/tags \ + # refs/tags is deliberately NOT in this list, and the reason is worth + # keeping because it looks like an oversight. + # + # Everything subtracted here is asserted to be already-scanned history. + # This workflow triggers on `push.branches`, with no `tags:` filter, so + # a tag push never runs it — tagged commits have never been scanned by + # anything. Subtracting them would assert a baseline that does not exist: + # if a tag points at secret-bearing commit S and a branch adds harmless + # commit U on top, `rev-list --not ` returns only U, `base` becomes + # S, and the S..U scan steps right over the secret. + # + # Omitting tags costs an over-scan when a branch starts from a tag-only + # commit: pre-existing history is treated as branch-unique and more files + # are scanned than necessary. That is noise. Including them costs a miss. + # For a secret scanner those are not comparable, so this fails toward noise. + # + # If tag pushes ever get scanned too, tags become a real baseline and + # refs/tags can be added back. + others=$(git for-each-ref --format='%(refname)' refs/heads refs/remotes/origin \ | grep -vFx "$self_local" | grep -vFx "$self_remote" || true) base="" From 0ed69895eaf4205ed15c3894f0fd4c420a88ef0d Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 9 Aug 2026 20:37:46 +0000 Subject: [PATCH 9/9] Baseline the new-branch scan on merge-base; stop comments contradicting code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two problems, both from Copilot on #937. 1. Subtracting every ref asserted a baseline that does not exist. The old logic found "commits unique to this branch" with `rev-list --not `. Everything subtracted is an assertion that the history has already been scanned. It has not: until this PR broadens the trigger, only the default branch was scanned on push, so a sibling branch ref may never have been scanned at all — and a ref survives a scan that FAILED. If such a ref points at secret-bearing commit S and this branch adds U on top, subtracting it sets base to S and the S..U scan steps over the secret. The leak that broadened this trigger on 2026-07-02 was a direct push to a working branch, which is exactly that shape. This is the same argument I accepted one commit ago for refs/tags. It applies to branch refs for the same reason, and I did not carry it through. Now: merge-base against the default branch — the only baseline here that is genuinely scanned (on every push to it and on every pull_request). Falls back to the whole tree when the default branch cannot be resolved. Cost: a branch cut from another unmerged branch rescans that branch's files. Over-scan, not a miss. That is the correct direction to fail, and it drops the ref enumeration, self/tag exclusions and --topo-order reasoning entirely — about 25 lines of logic replaced by 6. 2. Headers claiming behaviour the code no longer has. The #918 header says "a second push to the same branch cancels the still-running check ... no coverage is lost". On the four SHA-keyed workflows that is now the opposite of true, and the comment beneath `concurrency:` already states the real rule — so the outer header is deleted rather than reworded. check-notebooks-paired carried a header about push separation and merge-queue cancellation while triggering only on pull_request and workflow_dispatch. laf-usb-manifest-policy promised merge_group handling it has no trigger for. Both rewritten to their actual triggers. Verified: 52 workflows, 0 parse/duplicate-key failures, 131 run blocks bash -n clean; merge-base logic simulated on this branch -> base 2de9687dd, 9 files of 38,480, guard OK; unresolvable default branch -> whole-tree fallback; automated check that no header claims an event its workflow does not declare, 8/8 OK. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01EBV6TkrwsZhcwkh1b6NUHs --- .github/workflows/check-notebooks-paired.yml | 14 ++-- .github/workflows/check-portable-paths.yml | 10 --- .github/workflows/laf-usb-manifest-policy.yml | 15 ++-- .github/workflows/large-file-policy.yml | 10 --- .github/workflows/secret-pattern-policy.yml | 71 ++++++------------- .github/workflows/validate-daily-notes.yml | 10 --- 6 files changed, 33 insertions(+), 97 deletions(-) diff --git a/.github/workflows/check-notebooks-paired.yml b/.github/workflows/check-notebooks-paired.yml index e2a8e395db..c681d1a06a 100644 --- a/.github/workflows/check-notebooks-paired.yml +++ b/.github/workflows/check-notebooks-paired.yml @@ -21,16 +21,10 @@ on: permissions: contents: read -# Supersede, don't stack: a second push to the same branch cancels the still-running -# check for the previous commit, which nobody is waiting on. The final state of the -# branch is still checked in full, so no coverage is lost. -# -# `github.event_name` is in the group key on purpose: it keeps the push-event run and -# the pull_request-event run of the same branch in SEPARATE groups. Collapsing them -# would let a push run cancel a required PR check, and a cancelled required check -# blocks the PR. -# -# merge_group is never cancelled — cancelling a merge-queue check breaks the queue. +# Supersede, don't stack. This workflow runs on pull_request and workflow_dispatch +# only — no push, no merge_group — so the group key is just the ref, and a newer run +# for the same PR replaces an older one. A PR run scans the notebook set as it stands, +# not a delta, so nothing is lost by superseding. concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }} cancel-in-progress: ${{ github.event_name != 'merge_group' }} diff --git a/.github/workflows/check-portable-paths.yml b/.github/workflows/check-portable-paths.yml index 5ccac56156..1c737b5ffe 100644 --- a/.github/workflows/check-portable-paths.yml +++ b/.github/workflows/check-portable-paths.yml @@ -6,16 +6,6 @@ on: branches: [main] merge_group: -# Supersede, don't stack: a second push to the same branch cancels the still-running -# check for the previous commit, which nobody is waiting on. The final state of the -# branch is still checked in full, so no coverage is lost. -# -# `github.event_name` is in the group key on purpose: it keeps the push-event run and -# the pull_request-event run of the same branch in SEPARATE groups. Collapsing them -# would let a push run cancel a required PR check, and a cancelled required check -# blocks the PR. -# -# merge_group is never cancelled — cancelling a merge-queue check breaks the queue. concurrency: # Push groups are SHA-specific, so push runs never cancel each other. # These checks scan only the push's own before..after delta, so a cancelled diff --git a/.github/workflows/laf-usb-manifest-policy.yml b/.github/workflows/laf-usb-manifest-policy.yml index 5fc242e276..36596c6e83 100644 --- a/.github/workflows/laf-usb-manifest-policy.yml +++ b/.github/workflows/laf-usb-manifest-policy.yml @@ -14,16 +14,13 @@ on: - ".github/scripts/laf_usb_manifest.py" - ".github/workflows/laf-usb-manifest-policy.yml" -# Supersede, don't stack: a second push to the same branch cancels the still-running -# check for the previous commit, which nobody is waiting on. The final state of the -# branch is still checked in full, so no coverage is lost. +# Supersede, don't stack: a newer run for the same branch replaces the still-running +# one, which nobody is waiting on. This check reads the manifest as it stands rather +# than a per-push delta, so the replacement run sees everything the cancelled one would. # -# `github.event_name` is in the group key on purpose: it keeps the push-event run and -# the pull_request-event run of the same branch in SEPARATE groups. Collapsing them -# would let a push run cancel a required PR check, and a cancelled required check -# blocks the PR. -# -# merge_group is never cancelled — cancelling a merge-queue check breaks the queue. +# `github.event_name` is in the group key on purpose: it keeps push-event and +# pull_request-event runs of one branch in SEPARATE groups, so a push run cannot +# cancel a required PR check. This workflow has no merge_group trigger. concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }} cancel-in-progress: ${{ github.event_name != 'merge_group' }} diff --git a/.github/workflows/large-file-policy.yml b/.github/workflows/large-file-policy.yml index 0cd7344e07..18a980ffac 100644 --- a/.github/workflows/large-file-policy.yml +++ b/.github/workflows/large-file-policy.yml @@ -7,16 +7,6 @@ on: merge_group: workflow_dispatch: -# Supersede, don't stack: a second push to the same branch cancels the still-running -# check for the previous commit, which nobody is waiting on. The final state of the -# branch is still checked in full, so no coverage is lost. -# -# `github.event_name` is in the group key on purpose: it keeps the push-event run and -# the pull_request-event run of the same branch in SEPARATE groups. Collapsing them -# would let a push run cancel a required PR check, and a cancelled required check -# blocks the PR. -# -# merge_group is never cancelled — cancelling a merge-queue check breaks the queue. concurrency: # Push groups are SHA-specific, so push runs never cancel each other. # These checks scan only the push's own before..after delta, so a cancelled diff --git a/.github/workflows/secret-pattern-policy.yml b/.github/workflows/secret-pattern-policy.yml index 44bcc19fe8..dffdbac186 100644 --- a/.github/workflows/secret-pattern-policy.yml +++ b/.github/workflows/secret-pattern-policy.yml @@ -12,16 +12,6 @@ on: merge_group: workflow_dispatch: -# Supersede, don't stack: a second push to the same branch cancels the still-running -# check for the previous commit, which nobody is waiting on. The final state of the -# branch is still checked in full, so no coverage is lost. -# -# `github.event_name` is in the group key on purpose: it keeps the push-event run and -# the pull_request-event run of the same branch in SEPARATE groups. Collapsing them -# would let a push run cancel a required PR check, and a cancelled required check -# blocks the PR. -# -# merge_group is never cancelled — cancelling a merge-queue check breaks the queue. concurrency: # Push groups are SHA-specific, so push runs never cancel each other. # These checks scan only the push's own before..after delta, so a cancelled @@ -50,6 +40,8 @@ jobs: python-version: "3.13" - name: Check changed files for secret patterns shell: bash + env: + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} run: | set -eo pipefail # a failed git diff must fail the step, not feed the checker empty stdin if [[ "${{ github.event_name }}" == "pull_request" ]]; then @@ -72,48 +64,31 @@ jobs: # map keys) on every branch anyone creates, which is how a gate that # caught a real leak gets trained into noise people click past. # - # Scan what the BRANCH introduces: the commits reachable from it and - # from nothing else, diffed from the parent of the oldest one. A secret - # pushed straight to a working branch — the leak this trigger was - # broadened for on 2026-07-02 — is by definition in a file that branch - # touched, so it is still caught. - self_local="refs/heads/${GITHUB_REF#refs/heads/}" - self_remote="refs/remotes/origin/${GITHUB_REF#refs/heads/}" - # refs/tags is deliberately NOT in this list, and the reason is worth - # keeping because it looks like an oversight. + # Diff from the merge-base with the default branch. That is the ONLY + # baseline in this repo that has actually been scanned: the default + # branch is scanned on every push to it and on every pull_request. # - # Everything subtracted here is asserted to be already-scanned history. - # This workflow triggers on `push.branches`, with no `tags:` filter, so - # a tag push never runs it — tagged commits have never been scanned by - # anything. Subtracting them would assert a baseline that does not exist: - # if a tag points at secret-bearing commit S and a branch adds harmless - # commit U on top, `rev-list --not ` returns only U, `base` becomes - # S, and the S..U scan steps right over the secret. + # An earlier version of this subtracted every other ref instead + # (`rev-list --not `) to find "commits unique to + # this branch". That asserts those refs are clean history, and they are + # not: until this workflow's trigger was broadened, only the default + # branch was scanned on push, so a sibling branch ref may never have + # been scanned at all — and a ref survives a scan that FAILED. If such a + # ref points at secret-bearing commit S and this branch adds U on top, + # subtracting it sets base to S and the S..U scan steps over the secret. + # The leak that broadened this trigger on 2026-07-02 was a direct push to + # a working branch, which is exactly that shape. # - # Omitting tags costs an over-scan when a branch starts from a tag-only - # commit: pre-existing history is treated as branch-unique and more files - # are scanned than necessary. That is noise. Including them costs a miss. - # For a secret scanner those are not comparable, so this fails toward noise. - # - # If tag pushes ever get scanned too, tags become a real baseline and - # refs/tags can be added back. - others=$(git for-each-ref --format='%(refname)' refs/heads refs/remotes/origin \ - | grep -vFx "$self_local" | grep -vFx "$self_remote" || true) - + # Cost of using merge-base instead: a branch cut from another unmerged + # branch rescans that branch's files too. That is an over-scan — noise — + # and noise is the correct direction for a secret gate to fail. base="" - if [ -n "$others" ]; then - # --topo-order, not the default date order: date order carries no - # topological guarantee, so with skewed timestamps (rebases, - # cherry-picks preserving original dates) `tail -1` is not certain to - # be the true root of the branch-unique history. Picking a descendant - # would set `base` too late and silently omit an earlier commit's - # files. --topo-order never emits a parent before its children, so the - # last entry is a real boundary. - first=$(git rev-list --topo-order "$after" --not $others 2>/dev/null | tail -1) - if [ -n "$first" ] && git rev-parse -q --verify "${first}^" >/dev/null 2>&1; then - base=$(git rev-parse "${first}^") + for ref in "origin/${DEFAULT_BRANCH}" "${DEFAULT_BRANCH}"; do + if git rev-parse -q --verify "$ref" >/dev/null 2>&1; then + base=$(git merge-base "$ref" "$after" 2>/dev/null) && break + base="" fi - fi + done if [ -n "$base" ]; then echo "New branch: scanning $base..$after (files this branch introduces)" diff --git a/.github/workflows/validate-daily-notes.yml b/.github/workflows/validate-daily-notes.yml index 532488f3ad..ca6dd2be45 100644 --- a/.github/workflows/validate-daily-notes.yml +++ b/.github/workflows/validate-daily-notes.yml @@ -8,16 +8,6 @@ on: permissions: contents: read -# Supersede, don't stack: a second push to the same branch cancels the still-running -# check for the previous commit, which nobody is waiting on. The final state of the -# branch is still checked in full, so no coverage is lost. -# -# `github.event_name` is in the group key on purpose: it keeps the push-event run and -# the pull_request-event run of the same branch in SEPARATE groups. Collapsing them -# would let a push run cancel a required PR check, and a cancelled required check -# blocks the PR. -# -# merge_group is never cancelled — cancelling a merge-queue check breaks the queue. concurrency: # Push groups are SHA-specific, so push runs never cancel each other. # These checks scan only the push's own before..after delta, so a cancelled