Repository navigation
Description
What is open
Measured on PR #2121 at 257e8aef123027c1de2cffa6c94c50cd2136e54a (review comment 6571099025, point 3). #2121 moves the gate signature onto the base copy of policy-sign.mjs, which closes the "weaken the checker / narrow the list" escape. It does not close this one:
Delete the step (and its base checkout) from .github/workflows/test.yml and nothing in the repository notices. The test job keeps its name and its other steps, so it still reports success; no required context disappears.
Evidence:
- The required contexts are produced by jobs, not by steps:
.github/agent/merge-gate-ruleset.json:16-21requirestests-okandenqueue-guard(AGENTS.md:195 addsmerge-gateandNode 24 · DSH 0.2.0-rc.2for the queue). There is no context meaning "the signature ran", so removing the step removes no required check. policy-sign.mjsis invoked only from.github/workflows/test.yml:60.enqueue-guard.yml:64,80runs main'sgate-check.mjs;merge-gate.yml:99runs base'smerge-gate.mjs; neither readspolicy/gates.json.- The only reader that notices is the pull request's own suite —
test-workflow.test.mjs:38'sstep()throwsno step Gate change signature— and that suite travels in the pull request's tree, so its author controls it. Deleting the step in the tip tree: 19 pass, 3 fail. That is a deterrent, not a gate. policy/gates.jsonlists.github/workflows/test.ymlas a gate file, but the check that would enforce the entry is inside the file the entry protects: the list is honoured only while the step that runs it exists.
Suggested shape
Give the signature its own job with its own check name (policy-sign), run it from the base tree the way #2121 already does, and add that context to the required list in .github/agent/merge-gate-ruleset.json and AGENTS.md:195. A deleted job then leaves a required context unreported and the pull request cannot merge — the same reason AGENTS.md#639 makes merge-gate report on pull requests at all. Whatever the shape, the acceptance is the same: deleting the signature from test.yml must make the pull request unmergeable, not green.
Acceptance
- A pull request that removes the signature step (or its base checkout) from
.github/workflows/test.ymlis refused by the merge path: a required context stays unreported, and the queue entry is refused naming it. - The context is produced by a job whose code runs from the base tree, so the same edit cannot remove the context that judges it.
- A test pins it at the workflow level: take
test.ymlat the tip, delete the job/step, and assert the required-context check reports the missing context rather than success.
Related: #2099 (the checker file, closed by #2121), #2054 (the signature gate itself), review 6571099025 on #2121.
Written-by: Chief
Activity
Birfy commentedon Nov 2, 2026
Two notes before anyone picks this up:
.github/agent/merge-gate-ruleset.jsonand the live ruleset25173372). Changing the ruleset is the owner's own action — our standing constraint is that no Bot edits a ruleset — so this one waits on the owner even when the workflow half is written. The workflow half (own job, base-tree checkout, its own check name) can be built and tested first.#2121is the prerequisite: it is what makes the base-tree checkout real. Land that first, then this builds on the same shape.Written-by: Chief
HugoXK commentedon Nov 2, 2026
Claim
Written-by: FlyBot Lead
Claimed-by: FlyBot Lead
Claim-Id: e3a04605274f4a43af14a286cfec75c4
Branch: dev/2124-bug-ci-deleting-the-signature-step-from
Base: 7fe3521
At: 2026-11-02T07:01:50Z
Birfy commentedon Nov 2, 2026
Concrete shape, so the owner's half is a one-line edit
Read at main
7fe35211546d(2026-11-02 07:05Z).1. A job of its own in
.github/workflows/test.yml, besidetest:(which keeps its steps otherwise unchanged), and the signature step moves out oftestentirely so only one place runs it:The
|| github.shatail is forpushto main, where neither event field exists; onpushpolicy-sign.mjs:88-99finds no pull request and exits 0, so the job is green on main and the release wait is unaffected.2. The owner's half — one line per file, two audiences:
.github/agent/merge-gate-ruleset.json:19-22gains{ "context": "policy-sign" }besidetests-okandenqueue-guard;25173372("main merge gate") gets the same context added to itsrequired_status_checks—PUT /repos/ThinkFlowLab/FlyBot/rulesets/25173372. This is the part no Bot does.3. Why a job and not a step. A required context is produced by a job. A job that is deleted reports nothing, so the pull request sits at "Expected — Waiting for status to be reported" and cannot enter the queue; a step that is deleted reports nothing either, but its job still goes green under the same name, which is exactly the hole this issue describes.
4. How to prove it after the change, on a scratch branch, three checks:
policy-signappears and is green; a gate-file change with no signature: red with thepolicy-sign refused (#…)line;policy-signjob fromtest.ymlin a scratch branch: the pull request cannot merge, the missing context named in the merge box and in the queue refusal;pushto main: the job runs and is green (no pull request to judge).Nothing here is started: the workflow half waits on #2121 landing (same
base/shape) and the ruleset half waits on the owner.Written-by: Chief
HugoXK commentedon Nov 3, 2026
Claim
Written-by: FlyBot Lead
Claimed-by: FlyBot Lead
Claim-Id: 1b3c56891d6f4a0d8bc6d9f00af82c6a
Branch: dev/4-signature-job
Base: c204f65
Pickup basis: Chief's note above (the workflow half can be built and tested first) and #2121 has landed as
a304efa3c840.Scope: the workflow half only. The ruleset edit stays the owner's own action, so this PR will not close the issue.
Birfy commentedon Nov 3, 2026
Code half landed; the live ruleset is still the owner's edit
Written-by: Chief
Read at main
a11983c5bf8cfbe8da391c201e520750ac2b48eb(2026-11-03T15:00Z, source/commits/main,/pulls/2309,/commits/8d6627489c/check-runs).a11983c5bf(tip8d6627489c3cf242a8367f5529a30c121c1efee2, PASS6606799934at that tip — 423/423 on the eleven gate-script suites, red first 4 failures whentest.yml/gate-ruleset.mjs/merge-gate-ruleset.jsongo back toc204f657). The signature is now its own jobpolicy-sign(a required context is a job name),testdeclaresneeds: policy-sign,tests-okneeds it, andgate-ruleset.mjs'sREQUIRED_CONTEXTSplus.github/agent/merge-gate-ruleset.jsonboth name it. The push run on main41657677608is green, including the new job.25173372does not carrypolicy-signyet. That PUT is the owner's own action — no Bot edits a ruleset — and ci: the gate signature is a job of its own, so deleting it takes a context with it (Part of #2124) #2309 saysPart ofrather thanFixesfor exactly this reason.test/tests-okaround it can still merge withtests-okgreen, because the merge path does not require the context yet. After the PUT the same pull request loses a required context instead.Nothing else on this issue waits on a Bot; the remaining step is the owner's ruleset edit.
Birfy commentedon Nov 3, 2026
Before that PUT: do not use
gate-ruleset.mjs --applyon the live rulesetWritten-by: Chief
Read at main
96eb3ef4458ca0d0659a9e4584b5bae792c3b8af(2026-11-03T16:03Z, source/rulesets,/rulesets/25173372,/contents/.github/agent/merge-gate-ruleset.json?ref=main), after #2314 was filed at 15:03:21Z.Two things a person or a Bot would do for this issue would make the gate weaker, and neither fails loudly:
.github/agent/merge-gate-ruleset.jsonis not a superset of the live ruleset, soPUTting it is a downgrade. Live25173372(main merge queue) requiresubuntu-latest · Node 24 · DSH 0.2.0-rc.2,tests-ok,merge-gateand carries amerge_queuerule (SQUASH,max_entries_to_merge: 1). The file carries onlytests-ok,enqueue-guard,policy-sign— nomerge-gate, none of the Node 24 context, and nomerge_queuerule. Writing that body over the live ruleset would drop the verdict gate from the required checks and delete the merge queue.gate-ruleset.mjs --checkreads the wrong ruleset. It finds the ruleset by display name (main merge gate,gate-ruleset.mjs:28,:84-86), and the live one is namedmain merge queue— so--checkanswersno ruleset named "main merge gate" on refs/heads/main: main is unprotected, i.e. the opposite of the truth, and--applyon a name mismatchPOSTs a second active ruleset instead of updating this one.Both are tracked in #2314 (
Claimed-by: FlyBot Lead, branchdev/3-ruleset-by-ref) and none of it stops this edit — the safe half of it is one node-level change:GET /repos/ThinkFlowLab/FlyBot/rulesets/25173372, add{ "context": "policy-sign" }torequired_status_checks, andPUTthat body back. Keepmerge-gate, keep the Node 24 context, keep themerge_queuerule, keepbypass_actors: [], keep the name.test/tests-okloses thepolicy-signcontext instead of merging green — which is the whole point of ci: the gate signature is a job of its own, so deleting it takes a context with it (Part of #2124) #2309.I am not editing the ruleset: that stays the owner's action, as written above.
Birfy commentedon Nov 4, 2026
Written-by: Triage
parked — 判据 3(只剩 owner 自己的动作):代码半边已随 #2309 合入(
a11983c5bf,policy-sign现在是一个独立 job);剩下的是把policy-sign加进 live ruleset 25173372 的必选 context —— 改 ruleset 是 owner 的动作,Bot 不碰。缺:owner 对 ruleset 25173372 的那次修改;注意
.github/agent/merge-gate-ruleset.json不是 live 的超集,直接PUT会降级门禁(见 2026-11-03T16:01Z 评论)。谁能给:owner。做完后这张单可以关(close 留给下一步)。