Repository navigation
fix(guardrails): read a quoted prompt as one argument and judge only a merged branch's own lines - #9852
Conversation
extract_candidates split each segment on blanks and only trimmed quotes from token edges, so the words of a quoted prompt joined the subcommand chain and its --words bound as flags: the machine-health setup skill's scheduled prompt reported "claude on-demand --scheduled". Quote state is now carried across tokens, and nothing inside a quoted argument is a flag or a subcommand. Flags after the closing quote are still judged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…verify A pushed branch that already exists on the remote ranged from the remote tip to the local tip, so after merging main every line main brought in was judged as the branch's own: a finding on main blocked every branch that merged it, and the push ran the verifiers over all of main's files (26.7 s for 121 files against 3.5 s for the branch's one file). When the tip's merge-base with the remote's default branch is not already behind the range base, keep only the lines added both since the last push and against that merge-base, and count a file new only when both lack it. The range is never wider than before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
claude-security-review reviewed No security issues found in the incremental change ( The change makes quote handling in No manifest, trusted-path or instruction-surface deletion is involved. PR context contains no embedded directives. This review has no cost implications. critical-findings: 0 |
|
claude-review reviewed Incremental review of What changed. Checks.
Closing issue. The PR states "No related issue", so there are no acceptance criteria to check. Cost and holds. The change does not alter model or API spend. It touches no trusted path and has no CRITICAL security finding, so I set no hold. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0fb7a2cc80
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…ckslashes `"C:\\Temp\\" --bogus` closes its quote: the two backslashes are one literal backslash. Dropping escaped backslashes before escaped quotes keeps that flag checked. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
No related issue: urgent unblock of the session write queue; the false positive was found on pushes to #9836.
Summary
The guardrails pre-push entry (
reference-verify) refused every push of a branch that had merged main since #9670. Its cli-flag verifier read the slash-command argument inside a quotedclaude -pprompt (machine-health setup SKILL.md) as aclaudesubcommand and flag, and the entry judged lines that came in from main as the branch's own.Metric: pushes refused by this false positive. Baseline: every session push of a branch merged with main since c39a5fe (#9670), seen 3 times today on #9836. Expected: 0.
Fix
plugins/guardrails/hooks/cli-flag-verify.sh,extract_candidates):read -rasplit segments on blanks and only trimmed quotes from token edges, so the words inside a quoted prompt joined the subcommand chain and its--wordswere read as flags. Quote state now carries across tokens (single and double quotes, a quote opened mid-token as in--x="a b", and\"inside a double quote). Nothing inside a quoted argument is a flag or a subcommand. A flag after the closing quote is still checked.plugins/guardrails/git-hooks/reference-verify.sh): a branch already on the remote was checked from the remote tip to the local tip, so after a merge of main every line main added was checked. When the tip's merge-base with the remote default branch is not already behind the range base, the entry now keeps only lines added both since the last push and against that merge-base. A file counts as new only when both bases lack it. The range is never wider than before. The shared generatedcheck-lib.shis untouched.split_segmentsruns before tokenizing and does not see quotes, so a;,(or backtick inside a prompt can still cut a stray segment.Verification
cli-flag-verify.test.sh(double- and single-quoted-pprompt, quoted positional prompt in markdown, quoted flag value, escaped quote) and 2 new cases inreference-verify.test.sh(merged-main lines stay quiet, the branch's own line after the merge still fires). All failed before the fix. Must-fire cases for--bogus-flag, a flag after a quoted prompt, and a subcommand chain after a quoted prompt pass after the fix.scripts/affected-tests.sh --run --jobs 4: 31 shell suites passed (1 host-conditional skip: Windows spelling cases);cli-flag-verify113/0,reference-verify32/0;node --test lib/exec-bash.resolver.test.mjs1/0.origin/main(121 files in the push range), and one more own commit: old entry 26.7 s and refused on the SKILL.md line; new entry 3.5 s and passes. Per-file verifier dispatch costs about 0.2 s per file, and the merged-in files were most of the cost. Aclaude ... --helpcache miss is not the cause (0.17 s here). The 77-100 s seen on today's pushes was not measured here (UNVERIFIED); larger merged ranges andaz/gh--helpcache misses would scale it the same way.scripts/check-changelog-fragments.sh --checkand--check-required origin/mainpass.Related
lefthook.ymlruns the guardrails entries from main's copy, fetched under.git/info/lefthook-remotes/and refetched every 24 h, not the pushed branch's copy. Blocked branches clear once this merges and that copy refreshes.🤖 Generated with Claude Code