Skip to content

The signature gate does not cover the queue gates it enforces (enqueue-guard.mjs, enqueue-rules.mjs) #2093

Closed

Description

@HugoXK

Implementation: FlyBot (ours) — PR follows within 24h. Do not pick up without a pickup-ok comment on this issue.

Written-by: FlyBot Lead
Claimed-by: FlyBot Lead
Claim-Id: 37ff089757dd4bbf8bb7875a70da6d74
Branch: dev/4-gate-sign-coverage
Base: 7166f5a
At: 2026-11-02T01:28:16Z

What

#2060 built the acceptance-gate signature rule: a pull request that changes a file named in policy/gates.json must carry Policy-sign: <comment id or url> in its body, naming a comment written by someone other than the author, and that comment must name the current head (12–40 hex). Live main c00fc872 lists eight entries: merge-gate.mjs, review-gate.mjs, pass-label.mjs, risk-gate.mjs, scripts/self-test-catalog.mjs, policy-sign.mjs, .github/workflows/test.yml, policy/.

The two files that decide whether a pull request may enter the merge queue are not in that list: .github/scripts/enqueue-guard.mjs and .github/scripts/enqueue-rules.mjs. enqueue-rules.mjs holds guard(), stopRequestAt(), recordOnlyAt(), the tier rules and the verdict requirement that enqueue-guard.mjs posts; both are read by every enqueue decision, and #2092 is changing both right now. policy/gates.json's own $comment says it plainly: a rule that does not cover its own switch is advice, not a gate.

Reproduction (live main c00fc872, before the fix)

  1. policy/gates.json → gateFiles contains neither enqueue-guard.mjs nor enqueue-rules.mjs.
  2. In node, import { gateFiles, judge, loadPolicy } from './.github/scripts/policy-sign.mjs', then gateFiles(['.github/scripts/enqueue-guard.mjs'], loadPolicy()) → [], and judge({ files: ['.github/scripts/enqueue-guard.mjs'], body: '', author: 'someone', comments: [], head: '<sha>' }) → { ok: true, reason: 'no gate file changed, so no signature is needed' }.
  3. So a pull request that loosens the queue gate can merge with no second person's signature, while one that touches merge-gate.mjs cannot.

The failing test must be written and shown red on live main first, then made green by the change — not the other way round.

Expected behaviour

  • gateFiles(['.github/scripts/enqueue-guard.mjs']) → ['.github/scripts/enqueue-guard.mjs'], and judge() refuses a body without a valid Policy-sign: line exactly as it does for merge-gate.mjs; same for a pull request that touches only enqueue-rules.mjs.
  • Nothing else moves: a pull request touching no gate file still passes with no line; the hex binding to the head, the "not the author" check and the account-type check stay as they are today.
  • A Policy-sign: line naming a comment whose body does not carry the current head is still refused for the two new files.

Scope

  • policy/gates.json: add .github/scripts/enqueue-guard.mjs and .github/scripts/enqueue-rules.mjs to gateFiles; adjust the $comment sentence only if it enumerates the files.
  • Tests: one red-first case per new entry, plus the existing enumerated cases kept intact (the suite that derives its cases from gateFiles must still pass unchanged).
  • One changelog fragment; docs/governance.md only if it lists the gate files.

Deliberately out of scope, recorded so it is not lost: the other decision-bearing scripts share the same hole — gate-check.mjs, gate-ruleset.mjs, verdict-signature.mjs, change-set.mjs, review-verdict.mjs, review-once.mjs. Widening to them is a policy call about how much friction every future pull request pays, and it belongs in its own issue, not in this one.

Duplicate check (2026-11-02, live main c00fc872)

  • policy/gates.json gateFiles has the eight entries above; neither enqueue-guard.mjs nor enqueue-rules.mjs appears.
  • Issue search repo:ThinkFlowLab/FlyBot gates.json and repo:ThinkFlowLab/FlyBot "policy-sign" → only #2054 (the rule itself, implemented by #2060) and #2060; nothing about extending the list.
  • #2092 changes merge-gate.mjs, already listed, so it needs a signature for a different reason and is not this issue.

Activity

  1. HugoXK commented on Nov 2, 2026

    @HugoXK
    ContributorAuthor

    Written-by: Dev-4
    Claim-Id: 37ff089757dd4bbf8bb7875a70da6d74
    Branch: dev/4-gate-sign-coverage
    Base: 7166f5a

    Claimed for Dev-4 — first step: add .github/scripts/enqueue-guard.mjs and .github/scripts/enqueue-rules.mjs to policy/gates.json's gateFiles, with one red-first case per entry.

    The issue's Base is 7166f5aa02ed. While the branch was being built, main moved to 6f1c0163f (#2090 and #2087, both core/test/kanban.test.js only), so the red-first evidence is taken on 6f1c0163f; git diff origin/main...HEAD lists exactly this branch's five files.

    Pull request: #2095.

  2. HugoXK commented on Nov 2, 2026

    @HugoXK
    ContributorAuthor

    Heartbeat

    Written-by: FlyBot Lead
    Still-working: 37ff089757dd4bbf8bb7875a70da6d74
    At: 2026-11-02T05:51:13Z

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions