Skip to content

ci: merge-queue readiness audit; fix the stale "Verify (Node 24)" required-check comment - #557

Merged
ScriptedAlchemy merged 2 commits into
mainfrom
ci/merge-queue
Sep 5, 2026
Merged

ci: merge-queue readiness audit; fix the stale "Verify (Node 24)" required-check comment#557
ScriptedAlchemy merged 2 commits into
mainfrom
ci/merge-queue

Conversation

@ScriptedAlchemy

@ScriptedAlchemy ScriptedAlchemy commented Sep 4, 2026

Copy link
Copy Markdown
Owner

Summary

Merge-queue readiness audit of every workflow that provides a required check on main, plus the one defect it found: the Verify matrix comment in ci.yml still named Verify (Node 24) as the required context, which #549 replaced with the static Verify gate job.

The functional work — merge_group: triggers, SHA-keyed concurrency for queue entries, PR-only steps skipped while the required jobs still report — already landed in #536 (this morning) and #549. Nothing in the six required jobs needs to change for a queue; the audit table below records why, per workflow, so the next reader does not have to redo it.

Blocker (settings, not workflows): the repository is owned by the user account ScriptedAlchemy (GET /repos/…owner.type: User). GitHub offers merge queues only to organization-owned repositories ("Pull request merge queues are available in any public repository owned by an organization, or in private repositories owned by organizations using GitHub Enterprise Cloud"), and #536 already observed 422 Invalid rule 'merge_queue' when creating the ruleset here. The merge_group triggers therefore stay dormant until the repository is transferred to an organization. The settings section below gives the exact commands for both the immediate option (drop the up-to-date requirement) and the queue option (after a transfer).

Protection findings (as of this PR)

  • Rulesets: none. GET /repos/ScriptedAlchemy/agent-bundle/rulesets[]; GET …/rules/branches/main[].
  • Classic branch protection on main (GET …/branches/main/protection):
    • required_status_checks.strict: true ← the cascade: every merge to main invalidates every other open PR, which must gh pr update-branch and re-run all six checks.
    • Required contexts (all from GitHub Actions, app_id: 15368): Changeset present, Docs site (Node 22.19), Host install proofs (Node 22.19), Examples check (Node 22.19), Release gates (Node 22.19), Verify gate.
    • No required reviews, enforce_admins: false, required_linear_history: false, force pushes and deletions blocked, conversation resolution / lock / block-creations off.
  • Repository merge settings: squash, merge, and rebase allowed; auto-merge on; delete-branch-on-merge off.
Current classic protection JSON (GET repos/ScriptedAlchemy/agent-bundle/branches/main/protection)
{
  "required_status_checks": {
    "strict": true,
    "contexts": [
      "Changeset present",
      "Docs site (Node 22.19)",
      "Host install proofs (Node 22.19)",
      "Examples check (Node 22.19)",
      "Release gates (Node 22.19)",
      "Verify gate"
    ],
    "checks": [
      { "context": "Changeset present", "app_id": 15368 },
      { "context": "Docs site (Node 22.19)", "app_id": 15368 },
      { "context": "Host install proofs (Node 22.19)", "app_id": 15368 },
      { "context": "Examples check (Node 22.19)", "app_id": 15368 },
      { "context": "Release gates (Node 22.19)", "app_id": 15368 },
      { "context": "Verify gate", "app_id": 15368 }
    ]
  },
  "required_signatures": { "enabled": false },
  "enforce_admins": { "enabled": false },
  "required_linear_history": { "enabled": false },
  "allow_force_pushes": { "enabled": false },
  "allow_deletions": { "enabled": false },
  "block_creations": { "enabled": false },
  "required_conversation_resolution": { "enabled": false },
  "lock_branch": { "enabled": false },
  "allow_fork_syncing": { "enabled": false }
}

Per-workflow audit

Workflow Required contexts merge_group today Verdict
ci.yml Verify gate, Examples check (Node 22.19), Release gates (Node 22.19), Host install proofs (Node 22.19) merge_group: branches: [main] (#536). changes (docs-only classifier) is PR-only, so queue entries never skip heavy jobs; Verify runs the Node 24 leg for PRs and queue entries; verify-gate runs always(); dependency-review is PR-only and not required. Concurrency ci-${{ github.event.pull_request.number || github.sha }}, cancellation only for pull_request. Ready. This PR: the Verify comment now says the required context is Verify gate (was Verify (Node 24), stale since #549).
changeset.yml Changeset present merge_group: branches: [main] (#536). Every step is if: github.event_name != 'merge_group' except a notice step, so the job reports success without evaluating: a merge_group payload has no PR labels and the commit stacks earlier queue entries; the requirement is enforced on the PR, which must be green to enter the queue. Ready, unchanged.
docs.yml Docs site (Node 22.19) merge_group: branches: [main] (#536). Build/lint/site-build run; Pages upload and deploy stay gated on push/workflow_dispatch of refs/heads/main. Queue refs (gh-readonly-queue/main/…) get SHA-keyed concurrency. Ready, unchanged.
package-preview.yml pull_request + push: main only. Not required; pkg.pr.new previews are per-PR and per-main-commit. No trigger needed, unchanged.
release.yml push: main only (Version Packages / publish). Must not run on queue entries, unchanged.
mcp-conformance.yml, native-host-smoke.yml workflow_dispatch only. Unchanged.

branches: [main] under merge_group filters on the queue's base branch (confirmed by the Actions team in github/docs#32879), so the required workflows run for gh-readonly-queue/main/… refs. actionlint passes on the changed file (the only repo-wide finding is the pre-existing, intentional SC2016 in release.yml).

merge_group behaviours handled (all pre-existing, verified)

  • No github.event.pull_request object: every read of it sits behind an if: github.event_name == 'pull_request' job/step or an || fallback to github.sha.
  • github.ref is refs/heads/gh-readonly-queue/main/pr-<n>-<sha>: no workflow compares it to main except the deploy gates in docs.yml, which is the intended exclusion.
  • No PR labels / head repo: Changeset present reports success on queue entries instead of re-deriving skip-changeset and the release-branch exemption (already enforced on the PR).
  • No path skipping in the queue: the docs-only classifier is PR-only, so a queue entry always runs the full required set.
  • Nothing PR-only is a required check (Detect changed paths, Dependency review, Publish pkg.pr.new preview are not in the protection).

Settings change to apply after merge

There is no ruleset to PUT/PATCH, and a merge_queue rule is rejected on a user-owned repository, so the requested ruleset command cannot be applied as-is. Two options; neither is applied by this PR.

Option A — stop the cascade now (no queue): loose required checks

gh api --method PATCH \
  repos/ScriptedAlchemy/agent-bundle/branches/main/protection/required_status_checks \
  -F strict=false
# verify
gh api repos/ScriptedAlchemy/agent-bundle/branches/main/protection/required_status_checks --jq .strict
# revert
gh api --method PATCH \
  repos/ScriptedAlchemy/agent-bundle/branches/main/protection/required_status_checks \
  -F strict=true

Effect: a PR merges once its own six checks are green, even when behind main; gh pr merge --squash --auto merges immediately with no update-branch. Trade-off: this reintroduces the failure mode #536 closed (individually green PRs that break main when combined — #486×#490, #518×#509); the push: main CI run (full Node matrix) would catch it after the merge instead of before. AGENTS.md's "branch up to date with main (gh pr update-branch, …)" sentence would need a follow-up edit.

Option B — the real merge queue (requires an organization-owned repository)

  1. Transfer the repository to an organization (Settings → Danger Zone → Transfer, or gh api --method POST repos/ScriptedAlchemy/agent-bundle/transfer -f new_owner=<org>). GitHub redirects the repository URL, but the Pages site moves from scriptedalchemy.github.io/agent-bundle to <org>.github.io/agent-bundle (update website/ base/links and the AGENTS.md URL), and the Codex review app, Actions secrets/variables, and Pages source should be re-verified after the transfer.

  2. Create the ruleset (none exists, so this is a POST, not a PUT). It mirrors the current protection — deletion and force-push blocked, the same six contexts from integration_id 15368, admin bypass to match enforce_admins: false — with strict_required_status_checks_policy: false (the queue provides the up-to-date guarantee) and the merge_queue rule:

    gh api --method POST repos/<org>/agent-bundle/rulesets --input main-merge-queue-ruleset.json

    main-merge-queue-ruleset.json:

    {
      "name": "main",
      "target": "branch",
      "enforcement": "active",
      "bypass_actors": [
        { "actor_id": 5, "actor_type": "RepositoryRole", "bypass_mode": "always" }
      ],
      "conditions": { "ref_name": { "include": ["refs/heads/main"], "exclude": [] } },
      "rules": [
        { "type": "deletion" },
        { "type": "non_fast_forward" },
        {
          "type": "required_status_checks",
          "parameters": {
            "strict_required_status_checks_policy": false,
            "do_not_enforce_on_create": false,
            "required_status_checks": [
              { "context": "Changeset present", "integration_id": 15368 },
              { "context": "Docs site (Node 22.19)", "integration_id": 15368 },
              { "context": "Examples check (Node 22.19)", "integration_id": 15368 },
              { "context": "Host install proofs (Node 22.19)", "integration_id": 15368 },
              { "context": "Release gates (Node 22.19)", "integration_id": 15368 },
              { "context": "Verify gate", "integration_id": 15368 }
            ]
          }
        },
        {
          "type": "merge_queue",
          "parameters": {
            "merge_method": "SQUASH",
            "grouping_strategy": "ALLGREEN",
            "max_entries_to_build": 5,
            "min_entries_to_merge": 1,
            "max_entries_to_merge": 5,
            "min_entries_to_merge_wait_minutes": 5,
            "check_response_timeout_minutes": 60
          }
        }
      ]
    }

    Drop bypass_actors to make repository admins go through the queue too (AGENTS.md already forbids --admin bypass).

  3. Retire the classic protection so the ruleset is the single source of truth (otherwise its strict: true keeps demanding up-to-date branches). Run this only after step 2 succeeded, so main is never unprotected:

    gh api --method DELETE repos/<org>/agent-bundle/branches/main/protection

    Rollback: PUT repos/<org>/agent-bundle/branches/main/protection with the JSON in the details block above (required_pull_request_reviews: null, restrictions: null).

Once the queue is on, gh pr merge --squash --auto no longer merges directly: it enqueues the PR as soon as its own checks are green, the queue builds main + earlier entries + the PR on a gh-readonly-queue/main/pr-<n>-<sha> ref, the six required checks run there via merge_group, and GitHub squash-merges the group (merge_method: SQUASH) when they pass — no update-branch, no per-PR re-run of everyone else's CI.

Changeset

CI-only (.github/workflows/ci.yml comment); no publishable package changes, so Changeset present passes without a label, as on #553.

Self-review

Reviewer: gpt-5.6-sol-medium (change-risk-reviewer), against the diff vs origin/main at ee27c41.

  • No concrete merge risks found. The diff is three comment lines in .github/workflows/ci.yml; YAML unaffected; job names verified as Verify (Node …) plus the static Verify gate; ci.yml, changeset.yml, and docs.yml on origin/main all carry merge_group: branches: [main] (from ci: run required checks on merge_group for the merge queue #536).
  • Residual check the reviewer could not run itself — the classic protection's required contexts — was run by the author: strict: true; contexts: Changeset present, Docs site (Node 22.19), Host install proofs (Node 22.19), Examples check (Node 22.19), Release gates (Node 22.19), Verify gate — the same six contexts listed in the audit table and details block above, with Verify gate (not Verify (Node 24)) as the required name. Raw output of gh api repos/ScriptedAlchemy/agent-bundle/branches/main/protection/required_status_checks --jq '{strict, contexts}': {"contexts":["Changeset present","Docs site (Node 22.19)","Host install proofs (Node 22.19)","Examples check (Node 22.19)","Release gates (Node 22.19)","Verify gate"],"strict":true}.

…ue readiness audit

The Verify matrix comment in ci.yml still named "Verify (Node 24)" as the
required check on main; #549 replaced it with the static "Verify gate" job.
Audit of every required-check workflow for merge_group readiness (#536)
found no other gap; findings and the settings commands live in the PR body.
@changeset-bot

changeset-bot Bot commented Sep 4, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 74adf7b

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-04T21:13:57.336648Z ee27c41 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@pkg-pr-new

pkg-pr-new Bot commented Sep 4, 2026

Copy link
Copy Markdown
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle@557
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle/create-agent-bundle@557
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle/rsc-markdown-stream@557
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle/@agent-bundle/runtime@557

commit: 74adf7b

@ScriptedAlchemy
ScriptedAlchemy merged commit d1d855e into main Sep 5, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant