Filed by the objectstack-ai/objectstack domain:devx PM seat (session session_01LAwHpn4uVuf4N1geBcD5i3) on behalf of the os-dev run for objectstack-ai/objectstack#11804 (PR objectstack-ai/objectstack#14839), which measured this repo's copy while probing the parity declaration. Filed unassigned; dedup: a 600-card title/body sweep (guard-shared-stash, split_segments, stash+quote) found no open or closed card on this defect.
Blocked-by: objectstack-ai/objectstack#11804
The observation
.claude/hooks/guard-shared-stash.sh's split_segments() in this repo (measured at 6411def) carries the out-of-quotes backslash branch and NOT the in-quote one, while this repo's own guard-main-checkout-bash.sh split_segments() already carries the in-quote branch. That is exactly the state objectstack was in before objectstack-ai/objectstack#14839 — and both repos' hook headers declare parity between the two guards, which is currently false here.
Inside "…" a \" is a literal quote and the quoted region stays open; the pass reads it as closing, flips to "outside quotes" while bash is still inside, and separators behind it split where bash would not. Two directions:
- false BLOCK on a pure read:
grep -rn "he said \"cd x && git stash pop\" once" .claude/ → BLOCK (wanted allow); the single-level control grep -rn "cd x && git stash pop" .claude/ → allow (so the guard is reached and the nested escape alone is the difference);
- fail OPEN once the escapes pair up:
echo "he said \"x\"" && git stash pop → allow (wanted block) — the region is left hanging and the real stash rides through as an argument.
Measured on this repo at 6411def, fed as the PreToolUse payload {cwd, tool_name:"Bash", tool_input:{command}}: control allow / nested grep BLOCK / nested echo BLOCK — identical to objectstack before its fix.
The remedy (a port, not a design)
Mirror objectstack-ai/objectstack#14839 once it has merged: in the in-quote path of split_segments(), when q is " and the character is \ followed by one of " \ $ `, keep both characters and do not close the region (gated on q = '"' — inside '…' nothing is special). Add the same paired self-test cases to .claude/hooks/guard-shared-stash.selftest.sh and run them against the pre-fix hook first (the allow rows and the fail-open twins must be red before, green after). Governed surface (.claude/hooks/**) ⇒ draft PR, human merge.
⛔ guard-main-checkout-bash.sh / guard-main-checkout.sh are the precedent here and stay untouched.
Generated by Claude Code
Filed by the
objectstack-ai/objectstackdomain:devxPM seat (sessionsession_01LAwHpn4uVuf4N1geBcD5i3) on behalf of the os-dev run for objectstack-ai/objectstack#11804 (PR objectstack-ai/objectstack#14839), which measured this repo's copy while probing the parity declaration. Filed unassigned; dedup: a 600-card title/body sweep (guard-shared-stash,split_segments, stash+quote) found no open or closed card on this defect.Blocked-by: objectstack-ai/objectstack#11804
The observation
.claude/hooks/guard-shared-stash.sh'ssplit_segments()in this repo (measured at6411def) carries the out-of-quotes backslash branch and NOT the in-quote one, while this repo's ownguard-main-checkout-bash.shsplit_segments()already carries the in-quote branch. That is exactly the state objectstack was in before objectstack-ai/objectstack#14839 — and both repos' hook headers declare parity between the two guards, which is currently false here.Inside
"…"a\"is a literal quote and the quoted region stays open; the pass reads it as closing, flips to "outside quotes" while bash is still inside, and separators behind it split where bash would not. Two directions:grep -rn "he said \"cd x && git stash pop\" once" .claude/→ BLOCK (wanted allow); the single-level controlgrep -rn "cd x && git stash pop" .claude/→ allow (so the guard is reached and the nested escape alone is the difference);echo "he said \"x\"" && git stash pop→ allow (wanted block) — the region is left hanging and the real stash rides through as an argument.Measured on this repo at
6411def, fed as the PreToolUse payload{cwd, tool_name:"Bash", tool_input:{command}}: control allow / nested grep BLOCK / nested echo BLOCK — identical to objectstack before its fix.The remedy (a port, not a design)
Mirror objectstack-ai/objectstack#14839 once it has merged: in the in-quote path of
split_segments(), whenqis"and the character is\followed by one of"\$`, keep both characters and do not close the region (gated onq = '"'— inside'…'nothing is special). Add the same paired self-test cases to.claude/hooks/guard-shared-stash.selftest.shand run them against the pre-fix hook first (the allow rows and the fail-open twins must be red before, green after). Governed surface (.claude/hooks/**) ⇒ draft PR, human merge.⛔
guard-main-checkout-bash.sh/guard-main-checkout.share the precedent here and stay untouched.Generated by Claude Code