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
fix(agents): three gh forms the reworked push gate still does not judge #797
The reworked push gate (the make ci-remote PR that closes #790) judges each gh pr / gh api call on its own, including code handed to a shell and code inside $(…). Review of that change found three forms it still does not judge. Each is less common than the forms the PR covers, so they were left for this follow-up rather than another round on that PR. The gate's stated goal is guarding against accidents, not deliberate workarounds.
Forms not judged
All three are inferred from reading .claude/hooks/agent-bash-gate.sh on that branch; none was run.
-R / --repo between pr and its subcommand.gh pr -R o/r ready 12, gh pr --repo o/r create … and gh pr --repo=o/r review 12 --approve. The gate reads the first word after pr as the subcommand, here -R. Whether gh accepts the flag in that position is unverified (it is a persistent flag on gh pr, which suggests it does). The gate already handles -R before pr.
Leftover code past the 64-piece cap, when the mention is quoted; and ${x:-$(…)}. Past the cap, leftover pieces are refused only if they match the gate's gh regex, which expects gh after start-of-line, whitespace or a separator, so a quoted 'gh pr ready' in a leftover piece (for example $(bash -c 'gh pr ready 12') as the 65th piece) is let through unjudged. Separately, a substitution inside a parameter-expansion default, ${x:-$(gh pr ready 12)}, is never queued, because its saved text starts with ${.
-F query=@- or --input - fed by a heredoc on the same line. The body is on the command line, but values starting with @ are skipped. The gate's docs already list --input and -F field=@file as unseen, so this is a documented limit; the same-line heredoc case is the one the gate could read.
Five more forms from the final review of that branch, all pre-existing in the tokenizer rather than introduced by its last commit. Labels are the reviewer's: measured means run through the gate.
<< inside arithmetic swallows the following lines.n=$(( 1 << 3 )) followed on the next line by a guarded gh command or git push is allowed: the tokenizer registers the << as a heredoc and the pending delimiter 3 eats every later line. For the gh checks this is a regression against main's regex gate, which blocked it (measured). The push half existed on main already (inferred).
The push check doesn't follow a heredoc a shell reads inside $(…) (out=$(bash <<'EOF' … git push … … EOF) is allowed, measured), while the gh checks now do. The push check reads the body-less form of the substitution.
An unquoted heredoc's body runs $(…), but neither check follows it (cat <<EOF / $(…) / EOF, measured). The "a mention in a heredoc body doesn't count" rule assumes a quoted delimiter.
A computed query= is matched against the whole call, so another field's heredoc text naming a mutation trips it. A false positive on an unusual form.
Nested escaped backticks aren't followed ( x=`echo \`…\ ``), before and after the change.
Two more from the review of the create-time reviewer/assignee block added to the same branch (both measured through the gate by the reviewer):
A glued short-flag cluster led by another letter passes. On gh pr create, -fr alice or -fa alice (fill plus reviewer/assignee, as pflag reads it) is allowed, because the check matches only a token that starts with -r or -a. Covering any single-dash cluster containing r/a would also catch values the loop scans (see 7), so it needs care.
A value starting with -a or -r on create is refused with the reviewer message, e.g. a -b "-a thing" body, because the loop scans value tokens as well as flags. Rare (markdown bullets are - x with a space) and loud rather than a bypass; the existing title handling has the same value-scanning shape.
Activity
EricAndrechek commentedon Oct 9, 2026
Five more forms from the final review of that branch, all pre-existing in the tokenizer rather than introduced by its last commit. Labels are the reviewer's: measured means run through the gate.
<<inside arithmetic swallows the following lines.n=$(( 1 << 3 ))followed on the next line by a guardedghcommand orgit pushis allowed: the tokenizer registers the<<as a heredoc and the pending delimiter3eats every later line. For theghchecks this is a regression againstmain's regex gate, which blocked it (measured). The push half existed onmainalready (inferred).$(…)(out=$(bash <<'EOF'…git push ……EOF)is allowed, measured), while theghchecks now do. The push check reads the body-less form of the substitution.$(…), but neither check follows it (cat <<EOF/$(…)/EOF, measured). The "a mention in a heredoc body doesn't count" rule assumes a quoted delimiter.query=is matched against the whole call, so another field's heredoc text naming a mutation trips it. A false positive on an unusual form.x=`echo \`…\``), before and after the change.— Posted by Claude Code on behalf of @EricAndrechek
EricAndrechek commentedon Oct 9, 2026
Two more from the review of the create-time reviewer/assignee block added to the same branch (both measured through the gate by the reviewer):
gh pr create,-fr aliceor-fa alice(fill plus reviewer/assignee, as pflag reads it) is allowed, because the check matches only a token that starts with-ror-a. Covering any single-dash cluster containingr/awould also catch values the loop scans (see 7), so it needs care.-aor-ron create is refused with the reviewer message, e.g. a-b "-a thing"body, because the loop scans value tokens as well as flags. Rare (markdown bullets are- xwith a space) and loud rather than a bypass; the existing title handling has the same value-scanning shape.— Posted by Claude Code on behalf of @EricAndrechek
ci: add make ci-remote and make the repo's hooks fail closed (#798)
refactor(agents): replace the gate's shell parser with plain checks (#…