Repository navigation
policy: derive the gate list from docs/testing-layers.json - #2304
Conversation
`policy/gates.json` was handwritten while `docs/testing-layers.json` already says which workflows a merge cannot land without, and the two drifted: the merge gate and the enqueue guard were gates by the manifest and not gate files, so a pull request could rewrite either one with nobody else's signature. `gate-check.mjs`, which writes the `enqueue-guard` check run the fork's ruleset requires, was outside the list for the same reason. `policy/gates.test.mjs` is the derivation now: every `gate: true` workflow is a gate file, and each gate workflow is pinned to the scripts it runs in both directions. The manifest calls the container-image build a gate, so `docker.yml` joins the list; the test says so in one explicit line so a manifest that stops calling it a gate has to move that line. The new file lives at `policy/gates.test.mjs` as the issue asks, which no suite row globbed: the `scripts` suite, the L1 command, `npm run verify` and the `package` job name `policy/*.test.mjs` too, and the tables in docs/testing-layers.md are regenerated.
|
@Birfy — one review request at tip 5ed8d0d (7 files, +156/-6, base 551375d).
Two checks are red on purpose and will stay red until your verdict lands: Node 24 refuses the gate-file change for lack of a |
|
Verdict: PASS at 5ed8d0d Ran at this tip: Red-first, one file only: with Review at this tip:
Not run: the smoke test (no Policy-sign: this comment, at this tip. |
|
Written-by: Dev1 Please re-run |
Fixes #2303
Written-by: Dev1
Owner: Dev1
Reviewer: Birfy
Tier: T3
Claim-Id: 80b61fa455944d17a7fa5ccb0f8ca39c
Branch: dev/1-p498-gate-switch-coverage
Base: 551375d
Tree: 2116dcba68f52dcf4aeaf5d7e72724f533e88d35
Verified commit: 3f2aeb005271c7b935902d022b94edd596369f5c
Pushed head: 5ed8d0d
Policy-sign: 6604947145
Scope
policy/gates.jsonwas handwritten whiledocs/testing-layers.jsonalready says which workflows a merge cannot land without, and the two had drifted. Read on the base with the repository's own rule: a change tomerge-gate.mjsneeded another person's signature while a change tomerge-gate.yml— the workflow that runs it — needed none; the same forenqueue-guard.mjsagainstenqueue-guard.yml, andgate-check.mjs, which writes theenqueue-guardcheck run the fork's ruleset requires, was outside the list entirely. A rule that does not cover its own switch is advice, not a gate, asgates.json's own$commentsays.policy/gates.test.mjsis the derivation now: every workflow the manifest marksgate: trueis a gate file by construction, and each gate workflow is pinned to the scripts it runs in both directions — the workflow starts the script or reaches it through its imports, and no other workflow starts it. Pins:merge-gate.yml→merge-gate.mjs;enqueue-guard.yml→gate-check.mjs, and through itenqueue-guard.mjsandenqueue-rules.mjs;test.yml→policy-sign.mjs.Changing
docker.yml,.github/scripts/gate-check.mjs,.github/workflows/merge-gate.ymlor.github/workflows/enqueue-guard.ymlnow needs aPolicy-sign:comment from a non-author, because those names are on the list.What this does not buy: a packaging change can still merge today with a red Docker check. The required contexts are only
tests-okandenqueue-guard(gate-ruleset.mjs:30);docker.ymlis path-filtered and is not aggregated intotests-ok. Listingdocker.ymlis still right on its own terms — the manifest calls it a gate, and being on the list means edits to it need a signature. Promoting the Docker check itself to a required context is a ruleset change and stays out of scope of #2303.The entry is one explicit line in the test rather than an inference: a manifest that stops calling the image build a gate has to move that line in the same pull request.
One wiring note, because the issue asks for the test at
policy/gates.test.mjs: nothing globbed that path, so the test would have run nowhere and the manifest check would have refused the file as unclassified. Thescriptssuite row, the L1 command,npm run verifyand thepackagejob now namepolicy/*.test.mjsas well, anddocs/testing-layers.mdis regenerated from the manifest. Nocore/file changes, so nothing here is generated by the client build or the patch set.Changed files (7, +156/−6):
policy/gates.test.mjs(new, +144) — the three cases: every gate workflow is a gate file (and no workflow in the list is stale), the pin table in both directions, and the image build's explicit entrypolicy/gates.json(+4) —gate-check.mjs,merge-gate.yml,enqueue-guard.yml,docker.ymldocs/testing-layers.json(+4/−3) — thescriptssuite row, its command and the L1 command includepolicy/*.test.mjsdocs/testing-layers.md(+1/−1) — regenerated bynode .github/scripts/testing-layers.mjs --writepackage.json(+1/−1),.github/workflows/test.yml(+1/−1) —npm run verifyand thepackagejob run the new glob toochangelog.d/2303-gate-list-derived.changed.md(new, +1)Red first, on live main
551375ddWith only
policy/gates.test.mjsadded to the clean base tree: 3 tests / 0 pass / 3 fail, exit 1.policy/gates.test.mjs:74— everygate: trueworkflow is a gate file: actual['.github/workflows/merge-gate.yml', '.github/workflows/enqueue-guard.yml', '.github/workflows/docker.yml'], expected[]policy/gates.test.mjs:88— the pin table:'.github/scripts/gate-check.mjs decides a gate workflow, so it is a gate file too; add it to policy/gates.json'policy/gates.test.mjs:132— the image build:'docker.yml builds the image a packaging change must start before it merges, so it is a gate file'After the fix the same file is 3/3/0.
Gates at this tip
node .github/scripts/testing-layers.mjs --check— 634 test files in 16 workflows, every one classified; thepolicy/gates.test.mjsfile is covered by thescriptsrownode .github/scripts/changelog.mjs check— 36 fragments well formednode core/scripts/build-client.mjs --check— silent, exit 0 (no client source touched)node scripts/ds-bot-patches.mjs check— fouroklines (ds-bot/= the pin; 10 patches apply cleanly in order;core/equalsds-bot/+patches/ds-bot/);canonical—ok patches/ds-bot/ is what generate writes (generate is a no-op)TZ=UTC ARCH_DOCS_BASE=551375dda317e9686351441aad431fce400fddc7 npm run verify— exit 0, 8 suites, 4693 tests / 4693 pass / 0 fail: core 2719, social 570, tree 132, timeline 140, workflow 411,.github/scripts+policy658 (the base's 655 plus the three new cases), interop 37, live-e2e 26; lint 74/36/9/2/16/1/0 warnings, 0 errors in every package;arch-docs: OK (7 changed file(s))This pull request changes files under
policy/, so it needs onePolicy-sign:naming a comment by someone other than its author on this tip; the line is added once that comment exists.Not run: the smoke test (no
core/index.jsorcore/src/host/file changes) and the CIpackagejob's own extras thatverifydoes not include (pack check, strict typecheck, actionlint).Checkpoint
{ "pr": 2304, "claim": "Dev1", "issue": 2303, "summary": "`policy/gates.json` now names every `gate: true` workflow: `merge-gate.yml`, `enqueue-guard.yml`, `docker.yml`, plus `gate-check.mjs`, which writes the `enqueue-guard` check run. `policy/gates.test.mjs` derives that list from the manifest and pins each workflow to the scripts it starts or reaches through imports, refusing a second workflow that starts one. `docker.yml` is one explicit assertion, not an inference. The `scripts` row, the L1 command, `npm run verify` and the `package` job now run `policy/*.test.mjs`; `docs/testing-layers.md` is regenerated.", "files": ["policy/gates.test.mjs", "policy/gates.json", ".github/workflows/test.yml", "package.json", "docs/testing-layers.json", "docs/testing-layers.md", "changelog.d/2303-gate-list-derived.changed.md"], "checks": { "ran": "TZ=UTC ARCH_DOCS_BASE=551375dd npm run verify (8 suites 4693/4693/0, lint 0 errors, arch-docs 7 files), testing-layers --check, changelog check, build-client --check, ds-bot-patches check/canonical; tree 2116dcba == 3f2aeb00", "result": "green", "at": "5ed8d0df7c78f1ab0a7a80569635ef6a41153245" }, "next": "Ready for review at this tip; then `Policy-sign:` takes Birfy's comment id and the owner reruns `policy-sign.mjs` on live main." }