fix(sdlc): native merge queue core drain — arm-only autoqueue + all-green + governance-gate#3849
Conversation
…zes shared-file contention The native GitHub merge queue serializes shared-file contention through its speculative gh-readonly-queue branches (auto-rebase + bisect-on-failure), so the pre-admission affinity hold for the CLOG decompose epic is redundant. Empty the registry; the hold mechanism remains available via the explicit `epic_serialize` frontmatter field. The four affinity mechanism tests are rewired to that field, and a regression test asserts a CLOG `parent_spec` alone no longer holds. Part of the reform-native-merge-queue core drain (demote the local autoqueue to arm-only; let GitHub own batching/dequeue/bisect). Task: reform-native-merge-queue-20260601 AuthorityCase: CASE-SDLC-REFORM-001 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughThis PR refactors PR queuing and CI validation by introducing CI result aggregation, server-side governance validation, and shifting auto-queue merging from direct command management to GitHub's native merge-queue arm-only flow with updated shared-file epic serialization. ChangesCI Infrastructure and Governance
Auto-queue Merge Strategy and Shared-file Epic
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
…quash) The native GitHub merge queue already drains armed PRs; the loss was the local autoqueue reimplementing a queue with direct `--merge` adds and dequeue mutations that raced GitHub's own batching and stranded PRs. Demote the reconciler's sole positive mutation to one idempotent `gh pr merge --auto --squash` (arm-only), for both the `queue` and `enable_auto_merge` decisions. GitHub then owns batching, speculative gh-readonly-queue branches, auto-rebase, and bisect-on-failure. `--squash` matches the queue's configured merge method. Corrective `disable-auto` / `dequeue` paths for now-blocked PRs are unchanged. Tests: command assertions updated to `--auto --squash`; 47 pass. Task: reform-native-merge-queue-20260601 AuthorityCase: CASE-SDLC-REFORM-001 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Collapses the five literal required checks (lint/test/typecheck/web-build/ vscode-build) into one aggregate job so the native merge queue can't be permanently stalled by a required-context-name mismatch. if: always() plus treating skipped as OK preserves the fast/slow split — test-full-shard is merge_group-only and is skipped on pull_request events, so all-green still passes there. Results read from an env var (injection-safe pattern). hooks/gate-manifest.yaml: register the new job so the gate-manifest wiring check stays green (the manifest pins the canonical ci.yml job set). Post-merge admin step: swap branch-protection required contexts -> all-green. Task: reform-native-merge-queue-20260601 AuthorityCase: CASE-SDLC-REFORM-001 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…sion proof) Part 3 of the native-merge-queue reform. Makes governance a server-side gate so enqueueing itself is governed: a PR enters the merge queue only when its linked cc-task is governance-releasable (stage >= S7_RELEASE, release_authorized, authority_case). GitHub-hosted runners cannot read the local cc-task vault, so the gate verifies the PROOF the vault-reading local autoqueue posts — the hapax/autoqueue-admission commit status — via the existing queue-admission-proof-check.py. Enforced only for enqueued/auto-merge PRs and merge_group, so ordinary PR CI is never wedged. Distinct, clearly-named context (vs pr-admission.yml's freeze governor) so it can be made a required status check in the main-merge-queue ruleset. Post-merge admin step: add governance-gate to the ruleset required contexts after verifying it goes green on a live armed PR. Task: reform-native-merge-queue-20260601 AuthorityCase: CASE-SDLC-REFORM-001 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 588a25c459
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| case "$r" in | ||
| success | skipped) ;; |
There was a problem hiding this comment.
Fail all-green when required jobs are skipped unexpectedly
Because all-green does not depend on docs_only_filter or post_merge_duplicate_filter, a failure in either setup job causes downstream jobs like lint, typecheck, web-build, and vscode-build to be skipped; this loop then treats every skipped result as acceptable and reports the aggregate check green. Once branch protection is switched to require only all-green, a broken filter/duplicate-detection step can therefore let a PR or merge-group pass without running the required CI jobs. Please either include the setup jobs in the aggregate or only allow skipped for the explicitly expected cases.
Useful? React with 👍 / 👎.
| SHARED_FILE_EPIC_PARENT_SPECS: dict[str, str] = { | ||
| # parent_spec basename -> serialized-epic id (the shared file it contends on). | ||
| # | ||
| # Emptied 2026-06-01 (task reform-native-merge-queue): the native GitHub merge | ||
| # queue serializes shared-file contention through its speculative |
There was a problem hiding this comment.
Keep parent-spec hold for unqueued epic work
This registry is now empty, so existing CLOG tasks that only carry the documented parent_spec no longer participate in shared_file_epic_affinity_blockers unless every note has already been migrated to epic_serialize. The native merge queue can serialize PRs that have reached the queue, but it cannot see an in-progress sibling with no PR yet; in that common case a ready CLOG PR can be admitted while another lane is still editing the same shared file, reintroducing the conflict this hold was designed to prevent.
Useful? React with 👍 / 👎.
| python3 scripts/queue-admission-proof-check.py \ | ||
| --repo "$REPO" \ | ||
| --event-path "$GITHUB_EVENT_PATH" |
There was a problem hiding this comment.
Run the proof verifier from a protected revision
This required gate checks out the candidate ref and then executes scripts/queue-admission-proof-check.py from that same checkout, so any PR that changes the verifier can make governance-gate pass without a valid hapax/autoqueue-admission status. For a server-side admission gate that is meant to constrain queued and merge-group PRs, the verifier needs to come from a protected base revision or pinned action rather than from the code being admitted.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
.github/workflows/governance-gate.yml (1)
44-44: 💤 Low valueConsider upgrading to actions/checkout@v6 for consistency.
The CI workflow uses
actions/checkout@v6, but this workflow uses@v4. While both versions work, using consistent versions across workflows reduces maintenance burden and potential behavioral differences.📦 Proposed version alignment
- uses: actions/checkout@v4 + uses: actions/checkout@b5297f6833c67f732b6632c5c4dbfc4e592b0cb2 # v6.2.0🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/governance-gate.yml at line 44, Update the checkout action to the consistent version by replacing the occurrence of "uses: actions/checkout@v4" in the governance-gate.yml workflow with "uses: actions/checkout@v6" so the workflow matches the other CI workflows and avoids version drift.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/governance-gate.yml:
- Around line 43-46: The Checkout step currently uses the floating tag
actions/checkout@v4 and leaves credential persistence defaulted; update the
Checkout step (the use: actions/checkout@v4 entry) to pin the action to a
repository-specific commit SHA (replace the v4 tag with the approved commit SHA
for actions/checkout) and add the with: persist-credentials: false setting (you
can keep fetch-depth: 1) so credentials are not persisted to the workspace or
artifacts.
In `@scripts/cc-pr-autoqueue.py`:
- Around line 910-918: The arming command for auto-merge in the block where
decision.action is ("enable_auto_merge","queue") currently extends cmd with
["--auto","--squash"] without binding to the proven head SHA; update the call
site that builds cmd (where cmd.extend is used) to also append
"--match-head-commit" followed by the admission proof SHA from
decision.pr.head_sha (the same SHA used by set_autoqueue_admission_status()) so
GitHub will require the PR head to match the proof before arming.
---
Nitpick comments:
In @.github/workflows/governance-gate.yml:
- Line 44: Update the checkout action to the consistent version by replacing the
occurrence of "uses: actions/checkout@v4" in the governance-gate.yml workflow
with "uses: actions/checkout@v6" so the workflow matches the other CI workflows
and avoids version drift.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: f60e62f9-4b59-4024-bab5-99ccad3f8746
📒 Files selected for processing (5)
.github/workflows/ci.yml.github/workflows/governance-gate.ymlhooks/gate-manifest.yamlscripts/cc-pr-autoqueue.pytests/test_cc_pr_autoqueue.py
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 1 |
There was a problem hiding this comment.
Pin action to commit SHA and disable credential persistence.
The checkout action should be pinned to a specific commit SHA per repository policy and should set persist-credentials: false to prevent credential leakage through artifacts.
🔒 Proposed security fix
- name: Checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 1
+ persist-credentials: falseAs per coding guidelines and static analysis (zizmor): actions must be pinned to commit hashes per blanket policy, and credentials should not persist to prevent exposure through artifacts.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 1 | |
| - name: Checkout | |
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| with: | |
| fetch-depth: 1 | |
| persist-credentials: false |
🧰 Tools
🪛 zizmor (1.25.2)
[warning] 43-46: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 44-44: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/governance-gate.yml around lines 43 - 46, The Checkout
step currently uses the floating tag actions/checkout@v4 and leaves credential
persistence defaulted; update the Checkout step (the use: actions/checkout@v4
entry) to pin the action to a repository-specific commit SHA (replace the v4 tag
with the approved commit SHA for actions/checkout) and add the with:
persist-credentials: false setting (you can keep fetch-depth: 1) so credentials
are not persisted to the workspace or artifacts.
| if decision.action in ("enable_auto_merge", "queue"): | ||
| # Arm-only (task reform-native-merge-queue): the local autoqueue's sole | ||
| # positive mutation is to ARM auto-merge with one idempotent command. | ||
| # GitHub's native merge queue then owns batching, speculative | ||
| # gh-readonly-queue branches, auto-rebase, and bisect-on-failure — we no | ||
| # longer issue a direct `--merge` (which raced the queue's own management). | ||
| # Re-arming an already-armed PR is a no-op; `--squash` matches the queue's | ||
| # configured merge method. | ||
| cmd.extend(["--auto", "--squash"]) |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
In the official GitHub CLI documentation for gh pr merge, is the --match-head-commit flag supported, and does it prevent merging or enabling auto-merge when the PR head SHA has changed?
💡 Result:
Yes, the --match-head-commit flag is supported in the official GitHub CLI documentation for the gh pr merge command [1][2][3]. This flag requires a commit SHA as an argument, which serves as a safety check: the pull request's head must match the provided SHA to allow the merge to proceed [1][4][2]. If the pull request head SHA has changed (i.e., it does not match the SHA provided), the command will prevent the merge [4][5]. While the documentation notes that the flag ensures the branch has not changed out from under the user [4], its primary function is to block the operation if the specified HEAD condition is not met. It is not explicitly stated in the manual that this flag disables the enabling of auto-merge, but rather that it serves as a constraint to allow or block the merge process based on the current state of the pull request head [1][2][3].
Citations:
- 1: https://cli.github.com/manual/gh_pr_merge
- 2: https://man.archlinux.org/man/gh-pr-merge.1.en
- 3: https://cli.github.com/manual/gh_help_reference
- 4: Add support for --with-lease like behavior to `pr merge` cli/cli#7464
- 5: Add
--match-head-commitfield togh pr mergecli/cli#5692
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Show context around the cited lines
sed -n '860,960p' scripts/cc-pr-autoqueue.py | nl -ba | sed -n '1,140p'
# Find and inspect set_autoqueue_admission_status()
rg -n "def set_autoqueue_admission_status|set_autoqueue_admission_status\(" -S scripts/cc-pr-autoqueue.py
python3 - <<'PY'
import re, itertools, pathlib
path = pathlib.Path("scripts/cc-pr-autoqueue.py")
txt = path.read_text(encoding="utf-8", errors="replace").splitlines()
# locate function start
start = None
for i,line in enumerate(txt):
if re.match(r"def set_autoqueue_admission_status\s*\(", line):
start = i
break
if start is None:
raise SystemExit("set_autoqueue_admission_status not found")
# print ~200 lines from start
for j in range(start, min(len(txt), start+220)):
print(f"{j+1:5d}:{txt[j]}")
PY
# Search for gh pr merge invocation / cmd construction near that block
rg -n "gh pr merge|pr merge|--auto|--squash|merge queue" scripts/cc-pr-autoqueue.pyRepository: hapax-systems/hapax-council
Length of output: 114
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Show context around the cited region without relying on `nl`
echo "=== scripts/cc-pr-autoqueue.py lines 880-960 (approx) ==="
sed -n '880,960p' scripts/cc-pr-autoqueue.py | sed -n '1,120p'
echo
echo "=== Locate set_autoqueue_admission_status definition ==="
rg -n "def set_autoqueue_admission_status\s*\(" scripts/cc-pr-autoqueue.py
echo
echo "=== Print set_autoqueue_admission_status body (first ~240 lines) ==="
python3 - <<'PY'
import re, pathlib
p = pathlib.Path("scripts/cc-pr-autoqueue.py")
lines = p.read_text(encoding="utf-8", errors="replace").splitlines()
start = None
for i,l in enumerate(lines):
if re.match(r"def set_autoqueue_admission_status\s*\(", l):
start = i
break
assert start is not None
end = min(len(lines), start+240)
for idx in range(start, end):
print(f"{idx+1:5d}:{lines[idx]}")
PY
echo
echo "=== Search for gh pr merge command construction/execution ==="
rg -n "gh pr merge|--auto|--squash|--match-head-commit|subprocess\.run|check_call|Popen" scripts/cc-pr-autoqueue.py
echo
echo "=== Extract the specific if block around cmd.extend([\"--auto\", \"--squash\"]) ==="
rg -n "cmd\.extend\(\[\s*\"--auto\"\s*,\s*\"--squash\"\s*\]\)" -n scripts/cc-pr-autoqueue.py || true
python3 - <<'PY'
import pathlib, re
p = pathlib.Path("scripts/cc-pr-autoqueue.py")
lines = p.read_text(encoding="utf-8", errors="replace").splitlines()
for i,l in enumerate(lines):
if 'cmd.extend(["--auto", "--squash"])' in l.replace(" ", "") or 'cmd.extend(["--auto", "--squash"])' in l:
# print ~25 lines around
s=max(0,i-20); e=min(len(lines), i+25)
print(f"Match near line {i+1}")
for j in range(s,e):
print(f"{j+1:5d}:{lines[j]}")
PYRepository: hapax-systems/hapax-council
Length of output: 16441
🌐 Web query:
gh pr merge --match-head-commit --auto behavior when PR head changes
💡 Result:
Behavior summary for gh pr merge --match-head-commit <SHA> --auto when the PR head changes: 1) --auto does not “track” the PR head for you. When you run gh pr merge --auto, the CLI only enables auto-merge (or queues it) based on the PR state it reads and on the merge payload it sends at that moment; it doesn’t re-issue the merge request automatically if the PR head commit changes later. This is evidenced by gh pr merge’s documented intent for --auto (“Automatically merge only after necessary requirements are met”) and the implementation discussion where the CLI sets auto-merge based on fetched PR state and then sends that directly through the merge payload without continuing to re-evaluate on later PR updates.[1][2] 2) --match-head-commit is a hard precondition: the head must still match the specified commit SHA. The --match-head-commit SHA flag is explicitly defined as “Commit SHA that the pull request head must match to allow merge”.[1] Therefore, if you specify a head SHA and then the PR head changes (new commits are pushed), GitHub will no longer satisfy that precondition, so the already-configured auto-merge/merge attempt will not proceed for that earlier head SHA. 3) Practical effect: you should expect auto-merge to stall/fail for the prior head SHA, and you must re-run the command (or otherwise update the auto-merge configuration) for the new head. Because the head-matching is required “to allow merge”[1], the common outcome when the PR head diverges is that merge will not be permitted until the configuration matches the latest head again (e.g., by reissuing gh pr merge with --match-head-commit set to the new head SHA). 4) Related nuance: --auto can be backed by merge queue behavior. If the target base branch uses a merge queue, gh pr merge will “enable auto-merge” when required checks have not passed yet, or “add the pull request to the merge queue” when required checks have passed.[1] In either case, --match-head-commit still represents the required head SHA for the merge to be allowed.[1] Bottom line If the PR head changes after you run gh pr merge --match-head-commit <oldSHA> --auto, GitHub will not merge that PR for <oldSHA> because the head no longer matches the required SHA.[1] Re-run gh pr merge --auto --match-head-commit <newSHA> (or omit --match-head-commit if you don’t need this safety gate) so the precondition matches the updated head commit.
Citations:
- 1: https://cli.github.com/manual/gh_pr_merge
- 2: gh pr merge $pr_number --auto --merge fails if a required status check has failed. cli/cli#8206
🌐 Web query:
cli.github.com manual gh pr merge --match-head-commit requires head match fail if head changed
💡 Result:
If the PR head commit changes after you captured the SHA and you run gh pr merge with --match-head-commit , the merge will not proceed because that flag specifies “Commit SHA that the pull request head must match to allow merge” (i.e., it acts as a precondition). The official gh pr merge manual documents the flag semantics but does not describe the exact wording of the error message you’ll see, only that the merge is allowed only when the head matches the provided SHA [1]. References: [1] https://cli.github.com/manual/gh_pr_merge
Citations:
Bind the auto-merge/merge-queue arming command to the classified head SHA.
scripts/cc-pr-autoqueue.py currently enables auto-merge/queue via gh pr merge <pr-number> --auto --squash (keyed only by PR number), while set_autoqueue_admission_status() posts the admission proof to decision.pr.head_sha. If the PR head changes between those steps, the arming request can target a different head; add --match-head-commit <head_sha> so GitHub requires the PR head to still match the proof SHA to allow the operation.
Suggested change
if decision.action in ("enable_auto_merge", "queue"):
# Arm-only (task reform-native-merge-queue): the local autoqueue's sole
# positive mutation is to ARM auto-merge with one idempotent command.
# GitHub's native merge queue then owns batching, speculative
# gh-readonly-queue branches, auto-rebase, and bisect-on-failure — we no
# longer issue a direct `--merge` (which raced the queue's own management).
# Re-arming an already-armed PR is a no-op; `--squash` matches the queue's
# configured merge method.
cmd.extend(["--auto", "--squash"])
+ if decision.pr.head_sha:
+ cmd.extend(["--match-head-commit", decision.pr.head_sha])
elif decision.action == "disable_auto_merge":
cmd.append("--disable-auto")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if decision.action in ("enable_auto_merge", "queue"): | |
| # Arm-only (task reform-native-merge-queue): the local autoqueue's sole | |
| # positive mutation is to ARM auto-merge with one idempotent command. | |
| # GitHub's native merge queue then owns batching, speculative | |
| # gh-readonly-queue branches, auto-rebase, and bisect-on-failure — we no | |
| # longer issue a direct `--merge` (which raced the queue's own management). | |
| # Re-arming an already-armed PR is a no-op; `--squash` matches the queue's | |
| # configured merge method. | |
| cmd.extend(["--auto", "--squash"]) | |
| if decision.action in ("enable_auto_merge", "queue"): | |
| # Arm-only (task reform-native-merge-queue): the local autoqueue's sole | |
| # positive mutation is to ARM auto-merge with one idempotent command. | |
| # GitHub's native merge queue then owns batching, speculative | |
| # gh-readonly-queue branches, auto-rebase, and bisect-on-failure — we no | |
| # longer issue a direct `--merge` (which raced the queue's own management). | |
| # Re-arming an already-armed PR is a no-op; `--squash` matches the queue's | |
| # configured merge method. | |
| cmd.extend(["--auto", "--squash"]) | |
| if decision.pr.head_sha: | |
| cmd.extend(["--match-head-commit", decision.pr.head_sha]) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/cc-pr-autoqueue.py` around lines 910 - 918, The arming command for
auto-merge in the block where decision.action is ("enable_auto_merge","queue")
currently extends cmd with ["--auto","--squash"] without binding to the proven
head SHA; update the call site that builds cmd (where cmd.extend is used) to
also append "--match-head-commit" followed by the admission proof SHA from
decision.pr.head_sha (the same SHA used by set_autoqueue_admission_status()) so
GitHub will require the PR head to match the proof before arming.
Reform native merge queue — the core drain (sub-PR 2 of the migration)
cc-task:
reform-native-merge-queue-20260601AuthorityCase: CASE-SDLC-REFORM-001
Parent spec:
coordination-reform-master-design-2026-05-30.mdActivates the GitHub-native merge queue as the sole drain and demotes the local
cc-pr-autoqueueto arm-only, so armed+green PRs stop stranding. The nativequeue already drains armed PRs (verified live: #3840/#3845/#3847/#3848 merged
through
gh-readonly-queue); the loss was the local autoqueue reimplementing aqueue with direct
--merge/dequeue mutations that fight GitHub's batching. ThisPR makes the autoqueue issue exactly one idempotent
gh pr merge --auto --squashto arm, and lets GitHub own batching, speculative branches, auto-rebase, and
bisect-on-failure.
Changes
scripts/cc-pr-autoqueue.py—merge_prarms with--auto --squashforboth the
queueandenable_auto_mergedecisions (was direct--merge/--auto --merge). Arm-only; idempotent; GitHub owns the rest.scripts/cc-pr-autoqueue.py—SHARED_FILE_EPIC_PARENT_SPECSemptied: thenative queue's speculative branches serialize shared-file contention, so the
CLOG pre-admission affinity hold is redundant. Mechanism preserved via the
explicit
epic_serializefield..github/workflows/ci.yml— newall-greenaggregate job (needs:therequired jobs +
test-full-shard,if: always(), passes on success/skipped).Collapses the five literal required contexts into one, killing the
required-context-name-mismatch that can stall the queue. Fast/slow split
preserved (
test-full-shardstays merge_group-only ⇒all-greenstill passeson PR events).
.github/workflows/governance-gate.yml— new dedicated governance checkthat verifies the server-side
hapax/autoqueue-admissionproof (viaqueue-admission-proof-check.py) onpull_request+merge_group. Runner-sidevault reads are infeasible (vault is local-only), so this reuses the proof the
vault-reading local autoqueue already posts. Enforces only for enqueued/armed
PRs ⇒ it never wedges normal PR CI.
Follow-up (ruleset, requires admin verification — done post-merge)
lint/test/typecheck/web-build/vscode-build→all-green.governance-gate(and the existingpr-admissionproof) to required contexts.Built off
mainin an isolated worktree; the canonical theta worktree isoccupied by a different in-flight task.
Summary by CodeRabbit
New Features
Improvements