Filed by the domain:skills execution PM seat, session session_01HZfg2AwVX191qCizp88gQr, at 2026-09-16T04:27Z, from the #18321 dev's out_of_scope_findings (report 5691990182 on #18321; PR #18365), measured by that dev on its head and read by the seat.
Reading
.claude/hooks/guard-governed-enqueue.sh's slug_of reads a checkout's origin with sed -n 's#.*github\.com[:/]\([A-Za-z0-9._-]*/[A-Za-z0-9._-]*\)\(\.git\)\{0,1\}/*$#\1#p'. The path character class owns . and is greedy, so the optional \(\.git\) group matches EMPTY and https://github.com/objectstack-ai/cloud.git yields objectstack-ai/cloud.git — a slug that equals no owner/repo the guard is ever asked about. Measured on PR #18365's head: a throwaway sibling whose origin carries the .git suffix answers allow where the identical tree with the bare URL answers block. The real /home/user/cloud happens to carry the bare form, which is the only reason the #18321 reproduction worked at all; PR #18365's new self-test case uses the bare URL deliberately and says so in place.
The SAME expression is inlined a second time in the hook's segment_target to derive the slug for a bare gh pr merge NUMBER (no -R): a non-matching slug makes the API read 404 and the guard FAILS OPEN — on any clone made with the conventional .git URL, that spelling of the merge command is unguarded.
What is asked
Single-source the slug reader (one function, both call sites), make it strip a trailing .git before the path class can swallow it (or anchor the group so it cannot match empty), and pin both shapes in guard-governed-enqueue.selftest.sh: a sibling with the .git remote resolves (and is audited), and a bare gh pr merge N on a .git-URL clone derives the right slug (the guard reads the PR instead of 404-ing open). .claude/hooks/guard-governed-enqueue.sh + its selftest only; rules layer (.claude/hooks/**) ⇒ draft PR, four-piece + an authorized APPROVED; ⛔ never armed by the seat.
Grading (lane self-triage; class (a), a guard that fails open on the conventional clone URL): p2 · Bug · pm:queue · domain:skills. SERIAL behind PR #18365 (the same two files; its injection is what makes the new cases hermetic).
查重词
guard-governed-enqueue slug_of · .git suffix origin url · sibling checkout not resolved · gh pr merge slug derivation · fail open 404
Generated by Claude Code
Filed by the
domain:skillsexecution PM seat, sessionsession_01HZfg2AwVX191qCizp88gQr, at 2026-09-16T04:27Z, from the #18321 dev'sout_of_scope_findings(report 5691990182 on #18321; PR #18365), measured by that dev on its head and read by the seat.Reading
.claude/hooks/guard-governed-enqueue.sh'sslug_ofreads a checkout's origin withsed -n 's#.*github\.com[:/]\([A-Za-z0-9._-]*/[A-Za-z0-9._-]*\)\(\.git\)\{0,1\}/*$#\1#p'. The path character class owns.and is greedy, so the optional\(\.git\)group matches EMPTY andhttps://github.com/objectstack-ai/cloud.gityieldsobjectstack-ai/cloud.git— a slug that equals noowner/repothe guard is ever asked about. Measured on PR #18365's head: a throwaway sibling whoseorigincarries the.gitsuffix answersallowwhere the identical tree with the bare URL answersblock. The real/home/user/cloudhappens to carry the bare form, which is the only reason the #18321 reproduction worked at all; PR #18365's new self-test case uses the bare URL deliberately and says so in place.The SAME expression is inlined a second time in the hook's
segment_targetto derive the slug for a baregh pr merge NUMBER(no-R): a non-matching slug makes the API read 404 and the guard FAILS OPEN — on any clone made with the conventional.gitURL, that spelling of the merge command is unguarded.What is asked
Single-source the slug reader (one function, both call sites), make it strip a trailing
.gitbefore the path class can swallow it (or anchor the group so it cannot match empty), and pin both shapes inguard-governed-enqueue.selftest.sh: a sibling with the.gitremote resolves (and is audited), and a baregh pr merge Non a.git-URL clone derives the right slug (the guard reads the PR instead of 404-ing open)..claude/hooks/guard-governed-enqueue.sh+ its selftest only; rules layer (.claude/hooks/**) ⇒ draft PR, four-piece + an authorized APPROVED; ⛔ never armed by the seat.Grading (lane self-triage; class (a), a guard that fails open on the conventional clone URL): p2 · Bug ·
pm:queue·domain:skills. SERIAL behind PR #18365 (the same two files; its injection is what makes the new cases hermetic).查重词
guard-governed-enqueue slug_of·.git suffix origin url·sibling checkout not resolved·gh pr merge slug derivation·fail open 404Generated by Claude Code