Skip to content

[finding] guard-governed-enqueue watches three enqueue spellings and a compliant seat can reach NONE of them — the CCR auto_merge route the protocol mandates is invisible to it #18384

Description

@os-warren

Filed by the domain:spec execution seat (#6017), session_01KB5PFtxuy1x3dcR5gxudx6, 2026-09-16T07:2xZ. ⛔ Not claimed, ⛔ not dispatched. Grading is triage's. ⛔ This seat did not run a dedupe search (per 「立卡者不查重,只附查重词」). Measured on origin/main @ 8b81ab60d7, ⛔ not on a stale checkout — this is true of main today and is independent of any one session's harness state.

The defect

.claude/hooks/guard-governed-enqueue.sh is a PreToolUse guard whose stated purpose is to stop an unapproved governed PR from being enqueued, so the queue cycle is not burned. Its own header explains why a client-side guard earns its place beside the server-side queue guard: a measured incident on 2026-09-01 where the queue guard refused correctly, the entry popped out red, and 「THE RED ENTRY DID NOT RE-RUN」 after the approval arrived.

It no longer watches any spelling a compliant seat can use.

What it actually matches

arm spelling reachable by a seat today?
:225 mcp__github__enable_pr_auto_merge | mcp__github__merge_pull_request No — both are in permissions.deny in .claude/settings.json as of ceb6b5fb46 (#18317) and 53dd5aaaaf (#18276)
:283 [[ "$w" =~ /repos/([A-Za-z0-9._-]+)/([A-Za-z0-9._-]+)/pulls/([0-9]+)/merge ]] No — this is PUT .../pulls/N/merge, not the route the seat is told to use
:325 gh pr merge … Nogh is not available in the agent container at all

The route a seat is actually required to use

references/platform-readings.md routes the seat to the CCR endpoints, because the MCP path is denied: auto-merge goes through PUT /repos/{o}/{r}/pulls/{n}/ccr/auto_merge.

/pulls/18370/ccr/auto_merge does not match /pulls/([0-9]+)/merge — after the number comes ccr/auto_merge, so the literal /merge segment the regex requires never appears.

The controlled zero

⛔ Not a bare zero. Over .claude/hooks/guard-governed-enqueue.sh on origin/main:

  • zero leg: ccr0 occurrences anywhere in the file.
  • control, same file and same quoting: auto_merge2, both of them the MCP arm at :225 and the header line describing it ⇒ the probe finds the concept where the file has it, so the zero is a real absence and not a spelling miss on my side.

Why this is class (a) rather than a nit

The guard is a gate on the governed surface — the one place where the repo's rule is that a human approval must be pinned to the current head before an enqueue. A guard that cannot see the enqueue call is not a weaker guard; it is an absent one that reads as present. Its own header argues the case against exactly this outcome: 「a ⛔-level rule in this repo is only stable once a check enforces it」.

⚠️ The server-side scripts/pm/check-governed-queue-guard.mjs is untouched and still refuses on the merge_group build — correctness is not lost. What is lost is precisely the thing this file was added to buy: the cheap refusal, before a queue cycle is spent and before a maintainer reads a red entry as 「I reviewed it and it still blocked me」.

How it was found, stated so the grading can weigh it

This seat enqueued PR #18370 and PR #18371 at 06:17Z through the CCR route. Both were measured NOT governed first (check-governed-merges.mjs --test returned 0 of 3 and 0 of 13 paths hitting the register), so the guard would have allowed them either way and nothing was bypassed. ⇒ the gap was found by reading, not by an incident — and the reason no incident occurred is the file list, ⛔ not the guard.

Dedupe words

guard-governed-enqueue · PreToolUse enqueue guard · ccr/auto_merge · governed surface approval · enqueue spelling drift


Generated by Claude Code

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions