Conversation
1. 提取指纹前剥离 BotMux XML 信封与元数据,基于真实 payload 计算指纹,避免同机多个 Claude 会话因共享前缀导致指纹碰撞和跨会话误判。 2. 规范化输入换行符并清洗零宽/不可见字符,避免触发 Claude Code 2.1 的交互式拦截 barrier。 3. 补充指纹提取、字符清洗及兄弟会话防误匹配的回归单测。
|
自动评审的初步意见(最终以维护者审阅为准)。整体方向正确、测试也能真实变异(我把新增用例搬到改动前的 master 上跑,清洗用例确实发出了 1.(P2)指纹取自原始文本,而 jsonl 实际落盘的是清洗后文本,残留一类假失败
常规路径有
结果是这类 prompt 被误判提交失败(多发确认回车 + 用户告警),方向安全但与加固目标相悖。建议把清洗提前到计算指纹之前,指纹直接从 2.(P2)10 字符最短指纹门禁只加在了跨项目 fan-out,逐层目录扫描没有门禁
另外两个非阻断建议(P3):
测试质量不错(兄弟会话回归用例的 Enter 时序模拟尤其好);如果能再补一个「payload 前 30 字符含零宽字符时 rotation/fan-out 仍能确认成功」的用例,可以把第 1 点锁死。 |
|
补充第二轮评审意见(另一位评审独立复现了上面两个 P2,我这边又做了核实),还有三点建议,前两点建议本轮一并处理: 3.(建议本轮修)英文 locale 的头部不剥离,且同样会碰撞 不只是头部占指纹的小问题——已实测碰撞:两条正文不同的英文 prompt,只要带同一个 bot 的 handoff 头,指纹都算成 4.(建议本轮修)兜底分支漏剥 hook 注入模式( 两个开关都不是默认项,但组合起来会把本 PR 修好的跨会话碰撞原样带回。建议兜底 strip 的标签清单与 5.(可本轮顺手,也可另开)
收敛后的处理建议:第 1、2 点(两个 P2)和第 3、4 点建议本轮修掉——它们都落在本 PR 直接加固的「指纹跨会话隔离」这条路上;第 5 点可本轮顺手或另开 follow-up。最终以维护者审阅为准,辛苦了。 |
|
接上面第 4 点,new-topic hook 路径也核对完了, 按「块在 正文之前、碰撞关键、且清单缺失的(3 个块):
同位置的 role / session_id / whiteboard 现有清单已覆盖;claude-code 在 opening hook 下因 正文之后、不造成前缀碰撞但剥离清单也应一并处理的:
因此更建议按复审讨论的做法修:让剥离清单与 |
1. 统一在指纹生成前清洗输入(抽离 sanitizeClaudeInput),保证检索指纹与落盘文本一致,修复首 30 字符含零宽字符时的检索假失败。 2. 逐层目录扫描 fallback 补充 10 字符最小指纹门禁,防止短文本误匹配同目录活跃兄弟会话。 3. 扩展元数据剥离正则以覆盖英文引用头与 handoff 头,并在 fallback 模式下完整剥离 summary_memory、chat_context 等稳定块。 4. user_message 提取改用游标线性定位,消除极端多开标签无闭合输入下的二次回溯风险。 5. 补充相应场景的回归单测。
|
已根据评审意见完成针对性修复与强化(提交 commit
验证
|
|
自动评审的第二轮意见(最终以维护者审阅为准)。新 commit 已同步到最新 master 本地 rebase 复核(零冲突,rebase 结果树与整树合并逐字节一致),上一轮的收敛项逐条核对:
本地验证: 一个可选的 P3(不阻塞合入,本轮顺手或后续均可):新的游标扫描器自身仍残留一个二次复杂度形状——当输入是「连续大量 if (ch === '>' || ch === ' ' || ch === '\n' || ch === '\t' || ch === '\r' || ch === '/' || ch === '<') {我验证过:改后 12 万连续 另有一个无关紧要的小点: |
|
补充上一条 P3:经第二轮交叉验证,只加 触发条件比原版仍苛刻(需要数千个可识别开标签字面量无闭合),但把含这些标签的 botmux 源码/diff/log 粘进会话即可造,量级与原 ReDoS 同阶。 完整修法(两个方向,均已验证线性,二选一):
语义边界(供写测试时参考):这两种修法对良构输入(botmux 实际渲染的所有块:带属性的开标签/自闭合/正常闭合,20 万次随机块序列验证「指纹都从用户正文开始」零失败)与现状逐字节一致;只有当用户正文本身含有畸形嵌套的标签残片(例如字面量 仍是不阻断的 P3,本轮顺手修或记 follow-up 都可以。 |
上一提交用游标扫描替代回溯正则后,仍残留两个 O(N²) 形状: 1. 连续大量 '<' 后才出现一个定界符时,每个 '<' 都重扫整段; 2. 已识别开标签连续出现且无闭合标签时,每次 indexOf 闭合标签都扫到串尾。 标签名定界符集合补 '<'(合法标签名不含 '<'),并对已出现无闭合实例的 标签记 dead-set 跳过后续闭合查找;无闭合时不 break,继续剥离其后的其他 良构块。对 botmux 实际渲染的良构块语义逐字不变(注释写明畸形标签汤仅 尽力而为)。实测 12 万 '<' 18s→6ms、8 万无闭合开标签 3s→73ms,补两条 回归(含无闭合标签后随良构块仍被剥离)。 Co-Authored-By: Claude Code <noreply@anthropic.com>
背景与原因
在飞书会话中向 Claude Code 提交消息时,部分会话偶现输入内容停留在终端输入框内未真正提交:
<botmux_reminder>、<identity>、<user_message>等 XML 信封以及引用元数据。原先makeSubmitFingerprint直接截取前 30 个字符作为指纹,同台机器上的所有 Claude 会话均共享相同的指纹前缀(<botmux_reminder>发给你的消)。当某个会话的首轮回车未被即时记录时,findJsonlContainingFingerprint或跨项目目录检索findJsonlAcrossProjectsRoot会误匹配到同目录下其他近期有活跃的会话 JSONL,导致 worker 误判为已成功提交并篡改pty.claudeJsonlPath,retry loop 提前终止,实际输入停留在输入框中。\r的安全检查。若 prompt 中混入此类字符,终端会中断提交并显示Removed X invisible characters · review and press Enter to send,吃掉第一次提交回车;如果叠加了上述指纹误匹配,则补发的确认回车不会送出。变更内容
extractMessageContentForFingerprint,在计算指纹前先剥离<botmux_reminder>、<botmux_routing>、<identity>等系统信封及头部引用元数据,提取真实用户 payload。makeSubmitFingerprint基于剥离后的纯净 payload 生成指纹,避免不同会话共享相同前缀。writeInput发送按键前,将\r\n与\r规范化为\n,并过滤掉零宽字符与不可见字符(\u200B-\u200D、\uFEFF等),防止触发 Claude Code 2.1 的交互式审查屏障。findJsonlAcrossProjectsRoot增加最小指纹长度门禁(fingerprint.length >= 10),避免过短指纹泛匹配。minEventTimestampMs时间戳门禁,严格限定为提交前 60 秒内的事件。test/write-input.test.ts中补充信封剥离提取测试、相同 reminder 下不同 payload 的指纹隔离测试、输入清洗测试,以及同项目目录下兄弟会话不误判且重试补发回车成功的回归单测。影响范围评估
src/adapters/cli/claude-code.ts)与相关测试(test/write-input.test.ts),不影响其他 CLI 适配器。验证结果
bun test test/write-input.test.ts:147 pass,0 failbun test test/cli-adapters.test.ts test/claude-transcript.test.ts:592 pass,0 failbun run build:编译及 bundle 顺利通过,audit 无异常