docs(hook-pitfalls): 订正 #32 第 1 条修法——我推荐的 assert 实测是 fail-OPEN 的 - #298
Merged
Conversation
上一提交在 #32 里把 `assert len(qmask) == len(out)` 当作首选修法推荐。 落地到守卫本体时实测发现,在那个调用点上 assert 的方向正好是反的: 该 python 块的判定结果不靠退出码、靠 stdout 回传给 shell(FORM=$(python3 …)), 且它自己一律 sys.exit(0) 收尾。所以未捕获的 AssertionError → stdout 空 → FORM 空 → 被读成「没有违规」→ hook 退出 1;而 PreToolUse 只认 exit 2 为 block, 非 2 的非零是「非阻断错误、工具照常执行」。 强制触发断言的变体实测:git commit -a -m x → exit=1 → **照样放行**。 换成显式 `if len(qmask) != len(out): 按违规上报` 后实测:危险命令与健康命令 均 exit=2(保守方向,Tier-0 闸门该往这边倒)。 所以条目里补了一条可泛化的判据:**一个绊线是 fail-open 还是 fail-closed, 是「调用点怎么消费结果」的属性,不是语言构造的属性**——同一个 assert, 放在「退出码即判定」的 hook 里是 fail-closed,放在「stdout 即判定」的块里 就是 fail-open。判定方法是强制触发一次、读退出码,不是靠直觉。 「不如改存元组、从结构上消灭断裂可能」那半句保留,它本来就是更好的答案。 守卫本体的对应修复见私有仓 daymade/scripts 93b9b9b。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
接 #297。那个 PR 把
assert len(qmask) == len(out)当作首选修法推荐;把它落地到守卫本体时实测发现方向正好是反的,这里订正。
为什么 assert 在那个调用点是 fail-OPEN
该 python 块的判定结果不靠退出码、靠 stdout 回传给 shell
(
FORM=$(python3 …)),且它自己一律sys.exit(0)收尾。所以:未捕获
AssertionError→ stdout 空 →FORM空 → 被读成「没有违规」→ hook 退出 1;而 PreToolUse 只认 exit 2 为 block,非 2 的非零是
「非阻断错误、工具照常执行」。
git commit -a -m xgit commit -m x沉淀下来的判据
同一个
assert,放在「退出码即判定」的 hook 里是 fail-closed,放在「stdout 即判定」的块里就是 fail-open。判定方法是强制触发一次、读退出码,
不是靠直觉——我就是靠直觉写下那条推荐的。
「不如改存元组、从结构上消灭断裂可能」那半句保留,它本来就是更好的答案。
守卫本体的对应修复在私有仓(
daymade/scripts93b9b9b);套件仍 74-0。🤖 Generated with Claude Code