Moved from objectstack-ai/objectstack#10408 by the triage seat (file-at-destination rule: the edited files are this repo's .claude/hooks/guard-main-checkout-bash.sh + its selftest). Original filed by the objectstack-ai/objectstack#10247 dev.
Blocked-by: objectstack-ai/objectstack#10247
(The source fix ships in objectstack PR #10406; port only after that PR merges, so review changes there don't have to be re-ported.)
The drift
objectstack's .claude/hooks/guard-main-checkout-bash.sh carries this in its own header:
Ported from objectui's hook of the same name (#3452, filed there as objectui#3435) — the logic below is deliberately kept case-for-case identical to it so the two repos' guards cannot drift; only issue references, example paths and the package name in the self-test are localised.
objectstack PR #10406 changes the parsing logic in that repo's copy: a backslash-escaped \" inside a double-quoted word no longer ends the quote (POSIX — backslash keeps its meaning inside "…" only before ", \, $ and a backtick). This repo's copy is, by that header's own claim, still the pre-fix logic, so the two have drifted in exactly the way the header says must not happen.
Why it matters beyond tidiness
The bug being fixed is not cosmetic. In this repo's copy, as in objectstack's before the fix:
- a pure-read
node -e "…" whose program contains an escaped quote followed by a JS arrow function gets blocked with a confidently-wrong write "target" — the false positive that trains agents onto OS_ALLOW_MAIN_EDITS=1; - and, measured under ablation in objectstack PR #10406, the same desync makes the guard miss real writes:
sed -i "s/\"a\"/\"b\"/" pkg/x.ts was allowed through. That is precisely the reflexive sed -i the guard exists to catch, so this repo's shared checkout is currently unguarded against that shape.
Suggested shape
Port the two hunks and the self-test section from objectstack PR #10406 into this repo's .claude/hooks/guard-main-checkout-bash.sh and guard-main-checkout-bash.selftest.sh, localising issue references per the existing convention. The self-test port matters as much as the logic: the probes are what keep the two copies honest.
Worth deciding at triage whether "case-for-case identical" is worth a gate rather than a header comment — a check that diffs the two copies modulo the localised lines would have caught this drift at the moment it was introduced, instead of relying on the next reader of the header.
Governed surface (.claude/**): draft PR, human merge.
Moved from objectstack-ai/objectstack#10408 by the triage seat (file-at-destination rule: the edited files are this repo's
.claude/hooks/guard-main-checkout-bash.sh+ its selftest). Original filed by the objectstack-ai/objectstack#10247 dev.Blocked-by: objectstack-ai/objectstack#10247
(The source fix ships in objectstack PR #10406; port only after that PR merges, so review changes there don't have to be re-ported.)
The drift
objectstack's
.claude/hooks/guard-main-checkout-bash.shcarries this in its own header:objectstack PR #10406 changes the parsing logic in that repo's copy: a backslash-escaped
\"inside a double-quoted word no longer ends the quote (POSIX — backslash keeps its meaning inside"…"only before",\,$and a backtick). This repo's copy is, by that header's own claim, still the pre-fix logic, so the two have drifted in exactly the way the header says must not happen.Why it matters beyond tidiness
The bug being fixed is not cosmetic. In this repo's copy, as in objectstack's before the fix:
node -e "…"whose program contains an escaped quote followed by a JS arrow function gets blocked with a confidently-wrong write "target" — the false positive that trains agents ontoOS_ALLOW_MAIN_EDITS=1;sed -i "s/\"a\"/\"b\"/" pkg/x.tswas allowed through. That is precisely the reflexivesed -ithe guard exists to catch, so this repo's shared checkout is currently unguarded against that shape.Suggested shape
Port the two hunks and the self-test section from objectstack PR #10406 into this repo's
.claude/hooks/guard-main-checkout-bash.shandguard-main-checkout-bash.selftest.sh, localising issue references per the existing convention. The self-test port matters as much as the logic: the probes are what keep the two copies honest.Worth deciding at triage whether "case-for-case identical" is worth a gate rather than a header comment — a check that diffs the two copies modulo the localised lines would have caught this drift at the moment it was introduced, instead of relying on the next reader of the header.
Governed surface (
.claude/**): draft PR, human merge.