You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
kernel authorization request: heal must enforce the FOLLOW side of Anthropic's mid-conversation system position rule (#5432) #5438
来源: #5432 分析 "Anthropic 400: mid-conversation system must FOLLOW a user message" 时发现(该 issue 正文已声明 kernel-change needed;本申请是其 Kernel Boundary 前置审批,批准前不实现)
本 issue 是授权申请,等 owner 拍板(A/B)。未批准前禁止实现。
问题一句话
Anthropic 对 mid-conversation system 的位置规则是双侧的:条目必须 FOLLOW 一个 user 消息(或以 server tool result 结尾的 assistant),且 PRECEDE 一个 assistant 消息或位于数组末尾(directive-only 形式任意位置合法)。kernel 的 healIllegalSystemPositions(kernel/src/wire/anthropic.ts:403)只查 follower 一侧——fold 覆盖掉 sidecar system 前面的 user turn 后,system 悬在 assistant 正后方,整个请求 400(messages.N: role 'system' must follow a 'user' message…),会话卡住直到客户端自己清掉 mid-conversation systems(#5432 case 1 现场,claude-code v2.1.316 + mid-conversation-tool-changes-2026-07-01,bili v0.1.210 / kernel 0.0.175)。
影响范围与严重程度:窄触发面——会话用了 server 端工具(web_search 等)且 mid-conversation system 恰好紧跟 server-tool-result assistant 轮次;严重度为体验/成本瑕疵(每次请求一次缓存击穿 + 语义降权),不是可用性缺陷(不 400)。台账缺失无运行时影响,属 CI 防线缺口。
怎么修复的:后缀匹配整个 tool_result 家族(未来 server 工具自动覆盖);双方向回归钉(真实形状保持 verbatim / 同形状 violate precede 侧仍被降级);WC-023 台账 + 镜像 heal 语义的双 lane 校验条款。
Activity
ranxianglei commentedon Nov 1, 2026
(ai: vllm-qwen/qwen3.8-27b)
查重:不重复。 多组关键词("mid-conversation system must follow"、"must precede an assistant"、"healIllegalSystemPositions"、"4457 sidecar orphan"、"anthropic system 400")检索 open+closed issue/PR:相关条目只有源缺陷 #5432 与本申请自身,无第三个提出同一 kernel 改动的条目。与 #5432 的关系:本单是其 case 1 的 Kernel Boundary 前置审批件(同机制家族,性质不同:缺陷报告 vs 授权申请),非并列重复;止血 PR #5441(case 2,宿主侧)在途未合。
标签:bug, claude-code, scope/kernel, p1(授权申请类按门禁政策挂 p1 = 决策可见性;底层缺陷严重度沿用 #5432 的 p2 判定——客户端自清可恢复,不是永久死亡)。
独立核实(未抄 issue 结论,对照当前 master 重读代码):工作树落后 origin/master 587 个提交,但
git diff wt→origin/master -- kernel/src/wire/anthropic.ts为空(仅 kernel/package.json 版本行不同,0.0.169→0.0.176),以下读码对最新 master 成立:healIllegalSystemPositions(kernel/src/wire/anthropic.ts:403-432,由 coreToAnthropic :507 调用)确实只查 follower 一侧——合法性定义 = 数组末尾或紧跟 assistant(let k = j+1; while (…) k++; const next = out[k]; if (!next || next.role === "assistant") continue;),predecessor 零检查。核心主张成立。role 'system' must follow a 'user' message or an 'assistant' message ending in a server tool result; the directive-only form (content: [] with output_config) is accepted at any position;case 2role 'system' must precede an 'assistant' message or end the array。现有代码恰好只实现了后一半。isDirectiveOnlySystem(:371-378)豁免形状(空 content + output_config)与报错原文逐字吻合;降级语义(:411-430:string→user、空串丢;block→先剥 tool_addition/tool_removal、空则丢、否则 re-voice to user)可直接复用,无新语义。orphanSystems(kernel/tests/issue4457-sidecar-system-folds.test.ts:75-96)同样单侧(:92 if (!next || next.role === "assistant") continue;),必须随 kernel 侧更新——计划已列,成立。coreToAnthropic之内(heal 就在那里跑),宿主拿到的是 heal 之后的数组;宿主再跑一遍双侧检查 = 规则复制两份必然漂移。同意 Anthropic 400: mid-conversation system must FOLLOW a user message — heal only checks the follower, and trailing nudge/notes land after a trailing system #5432 作者拒绝该方向的审核意见。审核中发现的四个实现级开放项(批准后并入同一 PR 钉死,均在既定 diff 范围内,不需额外审批):
a. index-0 边界(唯一真实回归风险点):现行为下 messages[0]=system 若后跟 assistant/末尾会原样通过。新 predecessor 判定若把「无前驱」判非法,这类当前工作正常的请求会被降级 → 工作会话字节漂移 = 回归。Anthropic 文档从本环境不可达(region-blocked),live 证据只覆盖 mid-conversation 场景。建议默认「缺前驱 = 合法」(行为零变化),有实测证据表明 Anthropic 拒绝 leading system 再翻转。
b. "assistant ending in a server tool result" 的 block 形状:报错命名了它,但精确 wire 形状(server tools 的结果落在 assistant 消息内)需实测/文档钉死后再写进判定——计划已有此纪律,保留并覆盖到 (a)。
c. heal 循环级联:[assistant, sysA, sysB, assistant] 中 sysA 降级为 user 后,sysB 的前驱变 user → sysB 转合法应保留 system。前驱扫描必须基于降级后的当前数组而非快照;补一条级联回归测试钉住。
d. WIRE_RULES 台账缺项:按 §7.3/#1304,生产环境发现的双侧位置规则应成为 wire-contract 台账永久条目(WIRE_RULES + gate + fake upstream enforcement)——现台账只有 WC-022(tool_addition/removal 位置)与 WC-014(Jinja 模板),无位置规则条目。这部分是 bili 侧测试文件(不在 kernel/ 内),并入同一 PR,不需额外审批。
八问(决策请求;第 3/5 问按选项分列):
insertBeforeTrailingSystemRun([PR] fix: insert Anthropic ephemeral tails before trailing client systems (#5432) #5441 的宿主临时副本被取代,规则只留一份)+orphanSystems测试助手更新为双侧 + 回归测试(fold 孤儿化→heal 后出站合法;trailing run + additions 插入位置;(c) 级联 case)+ kernel 版本 bump。一个 PR 一次闭环,符合连贯修复不拆片政策。选项对比:
判定:批准前严格不动手(已验证:工作树 clean,kernel 一行未动)。等你 A/B 拍板——拍 A 我立即开 kernel PR(含上述四个开放项的处理);拍 B 则收口止血线(#5441 待 CI 绿 + 你合入),case 1 作为已知限制记录在 #5432。
ranxianglei commentedon Nov 2, 2026
批准记录(2026-11-02,owner 在本机会话中确认 option A:「你直接把他修复到闭环把」)。实现 PR:#5522(kernel 半:follow-side heal + insertBeforeTrailingSystemRun 单一事实源 + acp-kernel 0.0.177→0.0.178;kernel 套件 1553/1553 全绿,宿主 anthropic wire 套件 33/33 全绿,既有 #4292/#4457 回归钉全部不变)。闭环剩余步骤(人类按钮):① 合 #5441(host 止血)+ 合 #5522(kernel)→ ② 小 follow-up PR:删 src/util.ts 临时副本、尾部注入改走 kernel 导出 → ③ 关 #5432 + 本 issue,随 0.1.212 一起发。
kernel: legitimize the real server-tool-result block family on the fo…
test(wire): WC-023 — ledger entry + tripwire for the two-sided mid-co…
ranxianglei commentedon Nov 2, 2026
(ai: vllm-qwen/qwen3.8-27b)
#5522 独立核验完成:批准范围全部落实且正确;发现 1 处真实缺陷 + 1 项漏掉的义务,已按「小问题直接修」以 2 个标注 commit 推上 PR 分支(
f06619ffc、f862e4a98),CI 全量矩阵正在对新的 head 首跑。核验结论(对照批准 diff 逐项)
prevNonSystem级联)[assistant,sysA,sysB,assistant]→[assistant,user,system,assistant]:降级后状态即时生效,splice 索引全程有效insertBeforeTrailingSystemRun导出(单一事实源)orphanSystems都已更新;CI 强制的版本纪律满足发现并已修复的两处
1(真实缺陷)follow-side 谓词只认字面
tool_result,漏掉真实线上形状。 批准 diff 第 1 条自己写了「具体 block 形状以实测/文档钉死再写进判定」——实现时猜了字面量。但真实 Anthropic 线上,server 工具结果是以<name>_tool_result家族(web_search_tool_result、code_execution_tool_result…;裸tool_result只出现在 user 消息里)骑在 assistant 消息内部的,经 #3410 sidecar 逐字透传后出站最后一块就是这些类型。后果:合法的「system 跟在 server-tool-result assistant 之后」被过度降级成 user——不 400(降级形状本身合法),但每次请求都产生字节漂移 = 一次性前缀缓存击穿 + system→user 的语义降权。修法:按后缀endsWith("tool_result")匹配整个家族(现有成员全覆盖、未来新 server 工具自动继承、没有任何非结果块类型共享该后缀)。行为变更披露(旧→新):此前这类合法形状每轮被降级重发 → 现在逐字保留为 system;precede 侧(#4457 那半边)、降级语义、豁免规则全部不变,新增双向回归钉证明两腿独立。2(义务缺失)WIRE_RULES 台账没有这条永久约束。 §7.3/#1304 要求上游验证约束的台账条目进修复 PR 本体。已加 WC-023(provenance 引用 #5432 两条现场 400 原文)+ 校验子句精确镜像 kernel heal 语义(run 级单判决、报在首个非 directive 成员、缺前驱合法、家族匹配),主 anthropic 校验器与 vertex-anthropic lane 校验器共用同一条款(两条道背后是同一个 Messages API)。门控测试断言双侧非法 + 四种合法形状;捕获的真实 vertex 客户端流量回放通过新条款无假阳性。
CI 状态说明(为什么之前是红的、现在会怎样)
ci失败标签触发的重跑(scope=skip)kernel-guard 已绿。无需改守卫代码,也不属于 master 级失败(未去 CI Control Center: Centralized CI Failure Handling & Status Sync (Comment all CI issues here; do not open new issues) | CI 总控: CI 失败集中处理与状态同步(所有 CI 问题在此评论, 勿开新 issue) #4599 刷屏)。ci失败标签反映的是已自愈的瞬态红,我没动你的标签,仅在此说明现状。结构化八问
tool_result,漏掉真实线上的<name>_tool_result家族块;同时这条永久上游约束没进 WIRE_RULES 台账。闭环剩余步骤(人类按钮,不变)
① 合 #5441(host 止血)+ 合 #5522(kernel,待本次 CI 全绿)→ ② 小 follow-up PR:删
src/util.ts临时副本、尾部注入改走 kernel 导出 → ③ 关 #5432 + 本 issue,随 0.1.212 发。CI 结果出来我再补一行终判。
Merge pull request #5522 from ranxianglei/2026-11-02_anthropic-heal-f…
kernel: heal the follow side of Anthropic's mid-conversation system r…
Merge upstream/master (d5a84f1): adopt ranxianglei#5522 anthropic fol…
merge: sync master into ranxianglei#4570 fix branch (adopt ranxiangle…
refactor: consume the kernel's insertBeforeTrailingSystemRun, drop th…