You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
specs/queen/merger_gate.t27 disagrees with the merger it models (unreadable ruleset, pending and zero checks) #7300
specs/queen/merger_gate.t27 (module QueenMergerGate, written for #5776 in 36a393b) does not describe the merger it is named after, .github/workflows/auto-merge-ready-prs.yml (Find ready PRs), and its header claims a link that does not exist.
False header. Line 4 says "The runtime mirrors these functions line for line from t27c gen-js output." t27c gen-js specs/queen/merger_gate.t27 prints fn red_check_passes was not emitted -- this backend lowers declarations, not bodies for all three functions, and the workflow is bash + jq that never reads the spec. Nothing mirrors it.
Opposite verdict on one case. The test gate_open_unreadable_fails_closed asserts gate_open(false, true) == false: an unreadable ruleset keeps the gate closed even when every check is green. The workflow opens it. With REQUIRED=null the BLOCKING filter lists only checks that are neither SUCCESS nor SKIPPED, each as "ruleset unreadable, nothing is discountable". Its own self-test pins both halves:
tools/bees/merger_gate_selftest.py scenario "ruleset unreadable: a discounted red check still blocks" -> not ready;
Two rules the spec does not state. The workflow skips a PR when no check has posted ("zero checks is not zero failures") and when any check has not concluded (PENDING, EXPECTED or an empty state). The spec has neither rule, so a spec-level reader cannot tell that a running check blocks.
Expected
The spec states the rule the merger runs, and says where the two are compared:
an unreadable ruleset makes every check count as required, so no red is discountable;
a check that has not concluded blocks;
zero posted checks blocks;
the gate opens only when at least one check posted, all concluded, and each one passes.
Every test is one of the self-test's scenarios, named after it. The header names merger_gate_selftest.py as the place where spec and workflow meet, not gen-js.
Decision taken here: the spec follows the workflow on the all-green unreadable case, because the workflow's choice is deployed and pinned by its own self-test, while nothing runs the spec. If the stricter rule (no merge at all while the ruleset is unreadable) is wanted, the change belongs in the workflow (the #5777 lane), and the spec's test flips back with it.
Acceptance criteria
t27c parse, typecheck and gen for specs/queen/merger_gate.t27 exit 0, and zig test on the gen output passes every test.
Spec side done locally as eb11532 (branch claude/merger-gate-7300); it opens as a PR after the queue ahead of it (one PR at a time). It does not touch the workflow or tools/bees.
One gap stays outside this issue: tools/bees/merger_gate_selftest.py has no scenario where no check has posted, so the workflow's "zero checks is not zero failures" skip (auto-merge-ready-prs.yml, the POSTED = 0 branch) has no test. The spec now asserts gate_open(0, 0, 0) == false; the matching self-test scenario belongs to the #5777 lane.
Activity
gHashTag commentedon Oct 7, 2026
Spec side done locally as eb11532 (branch claude/merger-gate-7300); it opens as a PR after the queue ahead of it (one PR at a time). It does not touch the workflow or tools/bees.
One gap stays outside this issue:
tools/bees/merger_gate_selftest.pyhas no scenario where no check has posted, so the workflow's "zero checks is not zero failures" skip (auto-merge-ready-prs.yml, thePOSTED = 0branch) has no test. The spec now assertsgate_open(0, 0, 0) == false; the matching self-test scenario belongs to the #5777 lane.spec(queen): merger_gate states the rule the merger runs (Closes #7300)…
t27b: tuple locals, @sqrt, out-of-range compares, unreached &repeat a…
self-host: t27core accepts compound assignment, byte-identical to gen…
t27core: numeric literal forms and pub var, byte-identical to gen-c (C…