Skip to content

ci(pr-gate): sync slash-menu and runner fixes from EOS #21 - #7

Merged
autogame-17 merged 1 commit into
mainfrom
claude/pr-gate-menu-runner-sync-20260806
Aug 6, 2026
Merged

ci(pr-gate): sync slash-menu and runner fixes from EOS #21#7
autogame-17 merged 1 commit into
mainfrom
claude/pr-gate-menu-runner-sync-20260806

Conversation

@autogame-17

@autogame-17 autogame-17 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Touches hot-path: no
Phase: fix
Risk vector: forward

Summary

Syncs pr metadata policy from upstream EvoMap/engineering-operating-system (PR #21), which fixes two defects that block PRs for reasons unrelated to PR quality. Both have to land here before the check can be made required.

1. Slash-separated template menus are now recognised as menus. The gate derives its contract from this repo's own PR template, including which answers a Label: a | b | c line offers. The old parser only understood the pipe form, so a template writing the same menu with slashes offered nothing and a placeholder-looking word the template explicitly listed was rejected. EvoMap/evox writes Builds on: <#PR / #issue / docs/… path / none> and documents none for genuinely fresh work — the gate rejected that exact answer. Both separators now parse; the separator must be a spaced slash so a path like docs/… path is not shredded into bogus choices, and an et-cetera entry (..., , etc) is not treated as a selectable answer.

2. The gate no longer inherits the org's general CI runner label. runs-on read vars.CI_LABEL_LINUX_X64, which resolves to [self-hosted, Linux, X64] on this org. That queued a three-second check behind heavy builds on a shared autoscaled pool, and jobs came back cancelled with not acquired by Runner of type self-hosted even after multiple attempts. For a required check, a job that never reaches a conclusion blocks the PR exactly as hard as a failing one, and re-running does not converge reliably. The gate now defaults to ubuntu-latest; opting into self-hosted capacity is a dedicated PR_GATE_RUNNER variable, so no repo inherits a runner dependency merely by belonging to an org with a fleet.

Scope and cuts

PR authors in this repo now get a metadata verdict that reflects their PR body: the answer this repo's own template prescribes is accepted, and the check reaches a conclusion instead of dying unacquired.

Nothing cut. This is the complete upstream sync of both fixes.

Not in scope: adding pr metadata policy to this repo's branch protection. That is a separate, owner-visible step and is deliberately gated on this landing first.

Module boundary

CI configuration only, and only the files the pr-gate module owns:

  • .github/workflows/pr-metadata-policy.yml
  • scripts/validate_pr_metadata.py

No product code, no tests, no build config, no PR template change. The contract this gate enforces is unchanged — it is still derived from this repo's own .github/PULL_REQUEST_TEMPLATE.md on the default branch. No existing PR body needs editing because of this change.

Alternative considered

Wait for the next routine EOS sync instead of a targeted PR. Rejected: the gate is being promoted to a required check, and shipping that promotion on top of the known-bad validator is what would strand PRs whose Builds on: is the template-documented none.

Pinning the job to a narrower self-hosted label instead of moving to GitHub-hosted was also considered upstream and rejected — it still depends on the pool that demonstrably fails to acquire work. Using continue-on-error to paper over the starvation was rejected as strictly worse: it converts a starved gate into a silently-passing one.

Validation

  • Upstream EvoMap/engineering-operating-system#21: python3 -m unittest discover -s tests — 103 tests, 1 skipped, pass; python3 scripts/validate_scaffold.pyscaffold ok.
  • Differential proof across the live fleet: the pre-fix and post-fix validators were run against all 189 open PRs in the 19 adopting repos, each against its own default-branch template. Exactly one verdict change (EvoMap/evox#3809 FAIL → PASS, the bug) and zero PASS → FAIL regressions — so this sync cannot newly fail any currently-passing PR in this repo.
  • Files here are byte-identical to upstream canonical (pr-gate/validate_pr_metadata.py and pr-gate/pr-metadata-policy.yml), which upstream's validate_scaffold.py enforces.
  • This PR's own pr metadata policy check exercises the synced workflow against this repo's real template.

Rollback / recovery

Revert this PR to return to the previous workflow and validator. Before reverting, remove pr metadata policy from this repo's branch-protection required checks if it has been added — reverting restores both the Builds on: none rejection and the self-hosted starvation, either of which permanently blocks PRs once the check is required.

Builds on: none


Note

Medium Risk
Changes how required PR metadata is validated and where the gate runs; mis-parsing menus or runner misconfiguration could block or silently weaken enforcement, though upstream differential testing reported one targeted fix and no PASS→FAIL regressions.

Overview
Syncs the pr metadata policy gate from upstream EOS so two blocking defects are fixed before the check can be made required.

The workflow runs-on no longer uses the org-wide CI_LABEL_LINUX_X64 self-hosted label. It defaults to ubuntu-latest, with optional override via PR_GATE_RUNNER, so a short stdlib-Python job is less likely to stall or cancel with runner acquisition failures when the check must always reach a conclusion.

validate_pr_metadata.py extends _offered_choices so declaration menus written as a / b / c (not only pipe-separated lists) count as offered answers—e.g. Builds on: … / none—while stripping angle brackets, requiring a spaced slash separator, and ignoring continuation tokens like ... via CONTINUATION_RE so they are not valid selectable answers.

Reviewed by Cursor Bugbot for commit ee0d731. Bugbot is set up for automated code reviews on this repo. Configure here.

Two upstream fixes that block PRs for reasons unrelated to PR quality:

- Slash-separated template choice menus are now parsed, so an answer the
  repo's own template documents is no longer rejected as a placeholder.
- The gate no longer inherits the org's general self-hosted CI label,
  which was cancelling this three-second check with 'not acquired by
  Runner of type self-hosted even after multiple attempts'.

Verified by differential replay: pre-fix and post-fix validators run
against all 189 open PRs across the 19 adopting repos produced exactly
one verdict change (the bug being fixed) and zero regressions.
@autogame-17
autogame-17 merged commit 92dc8a0 into main Aug 6, 2026
1 of 7 checks passed
@autogame-17
autogame-17 deleted the claude/pr-gate-menu-runner-sync-20260806 branch August 6, 2026 18:18
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