Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

[finding] guard-main-checkout.sh 只挂 Edit|Write|NotebookEdit,经 Bash 写文件(sed -i / tee / heredoc)可绕过 worktree 强制 #3435

Closed

Description

@yinlianghui

在 #3430(stash 共享栈)实现过程中读 .claude/settings.json 的钩子注册时发现,记录一下,不在 #3430 的范围内改。

现象

.claude/settings.json 里 guard-main-checkout.sh 的 matcher 是:

"matcher": "Edit|Write|NotebookEdit"

也就是说它只拦工具化的文件写入。同一个写操作换成 Bash 就完全不经过这个钩子:

sed -i 's/foo/bar/' packages/fields/src/x.tsx
cat > packages/fields/src/x.tsx  ... EOF
tee / printf / python -c ... 同理

在共享主 checkout 里这样改文件,钩子一声不响,而 CLAUDE.md / AGENTS.md 给出的心智模型是「PreToolUse 钩子强制此规则」。#3430 记录的正是同一个心智模型的另一个洞(worktree 隔离盖不住 refs/stash),两者同族:声明的强制范围 > 实际的强制范围。

为什么标 finding 而不是缺陷

今天没有用户会踩到,也没有证据表明有 agent 真的靠 Bash 绕过去写过共享 checkout —— agent 写文件基本都走 Edit/Write。属于「防线比宣称的窄」这一类观察,是否值得补由 PM 定级。

如果要补,可能的做法(未实现,仅备选)

相关

Activity

  1. self-assigned this
    on Aug 6, 2026
  2. yinlianghui commented on Aug 6, 2026

    @yinlianghui
    ContributorAuthor

    发现分诊(晋级):摘 finding 换 pm:queue,即派——objectui 分片 PM 并行批第 38 单。晋级理由:「声明的强制面 > 实际强制面」家族今日已实弹两次(#3430 stash、本条 Bash 写入),且 #3433 已建好可复用的 Bash matcher + 引号感知分段 + fail-open 基础设施,补此洞的边际成本降到最低。

    认领:
    会话:session_01GTRjn8xBqp75dk7kFupVRt
    分支:claude/issue-3435-bash-write-guard
    Worktree:objectui-issue-3435
    文件面:.claude/hooks/**(新 guard 脚本 + 自测,可复用 guard-shared-stash.sh 的解析)、.claude/settings.json(挂接)。⛔ 不动 CLAUDE.md/AGENTS.md(心智模型文字已由 #3430/#5742 双侧覆盖)。
    与在飞第 35 单(collaboration+语言包)、37 单(components/ui + sync 脚本)、39 单(workflows+docs)、40 单(console 预览素材)互不相交。


    Generated by Claude Code

  3. yinlianghui commented on Aug 6, 2026

    @yinlianghui
    ContributorAuthor

    验收:ACCEPT → PR #3452(并行批第 38 单,会话 session_01GTRjn8xBqp75dk7kFupVRt),已跑检查 7/7 绿(Lint + shards + Live E2E 进行中,改动零源码文件,构造上不可能影响),绿后转 ready + 入队。

    复核要点:

    1. 约束逐条兑现:split_segments 逐字复用、既有 OS_ALLOW_MAIN_EDITS=1 逃生阀(未铸第二变量)、fail-open、仓判定直接提取自 guard-main-checkout.sh 自身的 git-dir 逻辑——两个 hook 对「共享检出」的定义结构上不可能分叉,这是本单最要紧的设计点。
    2. 超出 brief 的两处添加都对:引号感知 tokenizer(防引号内 >/sed -i 被当真操作符——误拦是守卫被整个关掉的头号死因)与 heredoc 正文剥离(stack 渲染器读一个从未声明的 spacing 键,catalog 里 135 个节点照着它写 #4890 危害的多行形态),均有成对正反自测钉住。
    3. 反向验证的推理先行:预测「谓词只能产生 block,阉割只会减 block」→ 27 翻 43 不动,实测完全一致,证明 block 例非空绿。
    4. 诚实披露的 near-miss:写 PR 正文时真实触发 docs(plugin-report): teach the dataset-bound report as the sole authoring shape (#5047) #5140 陷阱(NUL+0x1F 落进草稿),被自己的越门自查抓住、字节未进任何仓文件——自查纪律在岗的活证。
    5. 跨仓发现 objectstack#5790(framework 同款旁路 + 缺 stash guard)已代标 pm:queue+domain:devx 转主仓 devx 车道(labeling ≠ claiming)。

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions