Repository navigation
Conversation
Eight merges in 3m22s on 2026-10-04 started 220 push runs on main across 66 workflows, and jobs waited ~25 min for a runner (#869). 102 of the 104 workflows that run on push to main had no concurrency group, so nothing superseded anything. Each of them now has, at top level: concurrency: group: ${{ github.workflow_ref }}-${{ github.event_name == 'workflow_dispatch' && github.run_id || github.event_name }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} - push: one run active and one pending per file and branch; a newer commit replaces the pending run, and the active run is not cancelled. - pull_request: a new commit cancels the old commit's run. - workflow_dispatch: a group per run, so a push never cancels a manual run and two dispatches with different inputs never cancel each other. 85 of the 102 can be dispatched; #647's group (workflow + ref, cancel-in-progress always) would have done both. - The key is workflow_ref (the file), not github.workflow (the name): conformance-golden-selftests.yml and conformance-selftest.yml are both named "Conformance golden self-tests" and would have shared a group. Skipped: 2 workflows that already have a group, 18 with no push trigger, 0 reusable workflows. 102 files, 6 lines each, 0 deletions; every edited file re-parses with the block at top level and no job carrying one. Refs #869 #647 #851 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The first commit of this branch gave the 102 ungrouped push workflows a
concurrency group (2/104 -> 104/104). Nothing kept the next workflow from
arriving without one. This adds the gate.
tools/check_concurrency_groups.py reads every workflow with PyYAML's
composer, as the runner reads it, and fails on three things:
UNGROUPED runs on a push to main, no top-level group
BAD_REUSABLE workflow_call with a top-level group: a called workflow
reads its caller's github context, so the group is the
caller's own
SHARED_KEY two files whose groups are the same text once each file's
path and name are put in (two files here share a name:)
A dispatchable group without github.run_id is printed as a note, not a
failure: bench007-probe-ax7203 and trinity-identity-gate are built that
way. Push-to-main follows GitHub's filter rules (branches in order with
`!`, branches-ignore, tags-only, `?` and `+` as repeats). Exit 0 clean,
1 defect, 2 cannot tell (no PyYAML, unreadable YAML, duplicate or merge
key, no workflows).
Measured before committing:
- this branch: 123 read, 105 on push to main, 105 grouped, rc 0
- main (57de4a1): 102 UNGROUPED, rc 1 -- the negative control
- per-file agreement with an independent line-based reader of the
same rules: 122/122 on main and 122/122 on this branch
- tools/test_check_concurrency_groups.py: 57 of 57 planted cases
- mutation run on the checker: 29/29 mutants turn the test red; one
more (`*` crossing `/`) is equivalent, since only `main` is asked
about and it has no `/`
- research/audit_workflow_paths.py: 0 dead paths, 0 unwatched scripts
- the gates-can-fail case: clean rc 0, planted workflow rc 1
Registered in tools/check_gates_can_fail.py; MIN_TESTABLE 11 -> 12, as
that workflow's own comment asks of every gate added to the harness.
Refs #869
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
X Brain Health CheckScore: 100.0/100 X Brain is above merge threshold |
The six red checks on this PR are all pre-existing failures on mainThis PR changes concurrency groups only. The six failing checks, as of run time 2026-10-04 19:52Z, have these causes:
93 checks pass, 3 are pending, and 4 are skipped. Order: once #872 is on main, I will merge main into this branch and rerun, so the first three rows should turn green. The fourth will stay red until #874 is decided. 🤖 Generated with Claude Code |
bench007-probe-ax7203.yml and trinity-identity-gate.yml kept their own groups, <name>-<ref> with cancel-in-progress: true. A push to main shared that group with a dispatch on main and cancelled it. For the BENCH-007 probe that is a bitstream build of up to four hours (timeout-minutes: 240). Neither commit that set those groups (9947512, b71a144) gives a reason, and #798 does not mention one. Both now carry the block the other 103 push workflows have. With that, DISPATCH_CANCELS moves from a note to a failure in the gate, so the count stays at zero: before (066bfa2 tree): NOTE DISPATCH_CANCELS 2, rc 0 new gate on that tree: FAIL DISPATCH_CANCELS 2, rc 1 new gate on this tree: 105 of 105 grouped, rc 0 planted cases: 59 of 59 (two cases flipped to rc 1, two added) This commit stands alone. Reverting it restores both old groups and the note. Refs #869 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🚨 CRITICAL: Brain Health Below ThresholdThe brain health CI gate has failed. This PR cannot be merged until:
Please review the failed job logs and fix the issues. |
🧪 Brain Stress Test ResultsScore: not measured (no stress test prints a Score: line) X Stress test passed |
|
The "🚨 CRITICAL: Brain Health Below Threshold" comment above (21:10:18Z) is a false alarm, and this PR's concurrency change is what triggers it.
🤖 Generated with Claude Code |
3032785 to
a4d4508
Compare
Summary by t27-beesThis PR adds a standardized concurrency block to 102 workflow files that run on push to main but lacked concurrency control, preventing burst merges from queueing hundreds of runs. It also adds a gate workflow and checker script to enforce that future workflows include proper concurrency groups. Worth a look
Read: 108 files, +1250 -8, the whole diff up to 60000 characters (the rest was not read). Head |
Closes #869. Supersedes #647, regenerated on current main instead of rebased.
Edited 2026-10-04T19:33Z: a second commit (066bfa2) adds a gate that keeps every push workflow grouped, and this PR's own runs now show the push and pull_request behaviour. See "The gate" and "Seen on this PR". The first commit is unchanged.
Edited 2026-10-04T21:25Z: a third commit (3032785) gives
bench007-probe-ax7203andtrinity-identity-gatethe same block, and makes DISPATCH_CANCELS a failure. See "Third commit". It stands alone, so reverting it restores the two old groups and the note.What
Adds one top-level block to each of the 102 workflows that run on push to main and have no group:
Measured (#869)
How it differs from #647
#647's key was
${{ github.workflow }}-${{ github.ref }}withcancel-in-progress: true. On today's tree that key has three problems:workflow_dispatch. A push to main would have cancelled a manual run in progress on main, because both are in the group<name>-refs/heads/main.conformance-golden-selftests.ymlandconformance-selftest.ymlare both named "Conformance golden self-tests". Withgithub.workflowin the key they would share one group, and in a burst one file's pending run would replace the other's.github.workflow_refnames the file, so it cannot collide.#647 is also 766 commits behind and conflicts with main in two files. I have not closed it; that is the owner's call.
The gate (second commit)
Nothing in the first commit stops the next new workflow from arriving without a group.
tools/check_concurrency_groups.pydoes, in a newconcurrency-gate.yml(push to main and pull_request, on.github/workflows/**and its own two files). It reads each workflow with PyYAML's composer and fails on three things (four since the third commit):workflow_callwith a top-level group; a called workflow reads its caller'sgithubcontext, so the group is the caller's ownname:are put in; every file with a group is compared, not only push onesgithub.run_id, so a push replaces or cancels a manual run"Push to main" follows GitHub's filter rules:
branches:in order with!,branches-ignore:, tags-only filters, and?/+as repeats of the character before them. Exit 0 clean, 1 defect, 2 cannot tell (no PyYAML, unreadable YAML, a duplicate or merge key, no workflows).Checked before pushing:
tools/test_check_concurrency_groups.py, 57 of 57.*crossing/, cannot be caught: onlymainis asked about, and it has no/.research/audit_workflow_paths.py: 0 deadpaths:entries, 0 scripts run but not watched.tools/check_gates_can_fail.pywith a plantedon: pushworkflow and no group. Run locally, the clean tree gives rc 0, the planted workflow gives rc 1, and the file is removed afterwards.MIN_TESTABLEgoes from 11 to 12, as the comment ingates-can-fail.ymlasks for every gate added to the harness.Third commit: the last two dispatch-cancelling groups
When the first commit was made,
bench007-probe-ax7203andtrinity-identity-gatealready had groups,<name>-${{ github.ref }}withcancel-in-progress: true. A push to main shares that group with a dispatch on main, so the push cancels the dispatch. For the BENCH-007 probe, that dispatch is a bitstream build of up to four hours (timeout-minutes: 240). The second commit left both alone and called them the owner's call. Neither commit that set those groups (9947512, b71a144) gives a reason, and #798 does not mention one either, so I changed them. If one of them is deliberate, revert 3032785 alone.NOTE DISPATCH_CANCELS2, rc 0FAIL DISPATCH_CANCELS2, rc 1 (negative control)workflow_dispatchpassesThe 29-mutant run above was done on the second commit's checker. It was not repeated for this one.
Seen on this PR
lut-report.yml, one of the 102 edited files, ran to success (run 37227380125).pendingbehind the first commit's run, which is one active and one pending per group.Checked (first commit)
git diff --numstatshows 102 files, 6 lines added to each, 0 deletions.concurrencykey, andjobsis intact.bench007-probe-ax7203,trinity-identity-gate);workflow_call). A callee shares the caller's context, so it must not get its own group.fpga-docker.ymlpushes to GHCR only on push, never on pull_request. A push run is never cancelled in progress, so it needs no special case.git merge-treewith fix(ci): key the chipdb cache on the openXC7 image so it can hit #852, fix(ci): give fpga-hslm Yosys the embedding_weights.mem it reads #866, ci: run the nine document gates on push to main only #867 and ci(chipdb): cache two more workflows, state why five probes stay uncached #868 merges cleanly with each. ci: run the nine document gates on push to main only #867 edits theon:lines of nine gates, and the new block goes after the blank line that follows them.Not measured
concurrency-groupspassed (run 37228527581).gates-can-failfailed there because main fails doc-refs and orphan-artefacts after gft_mul: the product wire is 32 bits and GF-T32 needs 52 #510, which fix(gates): green doc-refs and orphan-artefacts on main after #510 #872 fixes; see the comment below. The third commit's numbers above come from local runs.tools/.Refs #851 #865
🤖 Generated with Claude Code