5.9 KiB
运行中气泡续接独立审查
审查结论
服务端续接、完整运行态保存、取消门禁及前端折叠/复制通过。本次发现 3 项 P2 均已修复并通过原函数回归;当前没有未解决的 P1/P2,审查通过。
审查服务端基线为 /tmp/ccweb-streaming-retry-server-before.js,仅核对本任务新增差异;未把上一任务完整历史归档改动重复归入本任务。
发现及处理
| 级别 | 问题与触发条件 | 位置 | 当前状态 |
|---|---|---|---|
| P2 | A 的 turn/start 已发出但原生 ID 未知时取消,旧 entry 曾被释放;此时开始同线程 B,A 的 turn/started 先于 A RPC 回包到达,会按 thread 匹配到 B,旧通知能够写入或结束 B。 |
server.js 的 findCodexAppEntryByRuntime、startCodexAppTurn、handleCodexAppAbortSession |
已修。未知 ID 取消保留门禁,通知/RPC 确认身份后只中断精确旧回合;RPC 超时仍保留门禁,app-server 明确退出后提交旧正文并释放。 |
| P2 | 重连可显示完整 105/130 条工具,但完成或历史读取仍经 40 条工具上限,变成 40 条记录加省略标记;done 重建气泡会再次缩短工具列表、输入及结果。 |
server.js:5796 的 sanitizeMessageForTransport;public/app.js:9237 的完成气泡重建 |
已修。完成/历史单消息读取保留完整 toolCalls,实时 tool_start/tool_end 预览上限保留。 |
| P2 | 单条回复超过折叠阈值且包含多个自然段时,默认 .assistant-single-collapsed 以 420px 高度裁剪正文。点击“定位”仍直接选择末文本段并滚动,没有展开,目标段落继续被 overflow:hidden 隐藏。 |
public/app.js:2468 的 scrollAssistantBubbleToLastSection;public/style.css 的 .assistant-single-collapsed .assistant-reply-content |
已修。定位前点击已有展开控件,同步展开状态后再计算末段坐标;原函数测试验证展开先于定位,多原生段气泡保持原收起状态。 |
失败证据与修复验证
取消竞态先用真实路由/退休函数 VM 验证:退休 turnId:null 的取消 entry 后,建立同线程 turnId:null 的 B,路由旧 A 通知得到 { retired: 0, routedToNewEntry: true }。
新增真实开轮/路由/通知回归在修复前失败于“旧 A 身份未知时必须阻止同线程 B 开始”,实际 beforeIdentity.ok=true。工具完整读取断言在修复前失败于 130 条工具不能按预览上限替代完整列表。两项修复后均转绿。
取消回归执行真实 startCodexAppTurn、handleMessage、findCodexAppEntryByRuntime、findCodexAppRouteByRuntime、adoptCodexAppUnroutedTurn、handleCodexAppNotification、handleCodexAppAbortSession、handleCodexAppServerExit 和完成保存函数;仅模型 RPC、时钟及无关配置/生命周期回调由隔离夹具替代。覆盖:
- A 通知先于 A RPC 返回,未知身份时禁止 B 开轮;身份确认后中断 A,再开始 B;A 的迟到完成不能结束 B,B 的正文只归档一次且前后文完整。
- A RPC 超时后仍保留未知身份门禁;晚到 ID 通知触发精确 A 中断,随后 B 正常完成。
- A 取消且 ID 未知时 app-server 明确退出,先保存 A 既有完整前文,再释放 B 门禁;B 完整完成。
最终执行结果
所有单元/专项命令使用 60 秒上限,存储测试使用 /dev/shm 隔离临时目录。此前普通 /tmp 存储专项达到 60 秒上限;改用 /dev/shm 后完整专项约 12 秒通过,无需放宽超时。
| 命令 | 结果 | 退出码 |
|---|---|---|
TMPDIR=/dev/shm timeout 60 node scripts/codexapp-retry-history-unit.js |
21/21,含真实 mock 协议三轮续接 | 0 |
TMPDIR=/dev/shm timeout 60 node scripts/history-runtime-unit.js |
13/13,完整 130 条工具及 24006 字输入、48006 字结果读回;实时预览仍有界 | 0 |
timeout 60 node scripts/assistant-bubble-controls-unit.js |
最终 8/8,末原生段、多自然段/代码、Markdown 空白语义、围栏及未完整分界不误复制,单条长回复定位先展开 | 0 |
timeout 60 node scripts/streaming-retry-frontend-unit.js |
5/5,多次续接、刷新/重连/切换、完成与保存失败气泡 | 0 |
两个所改测试文件 node --check、限定文件 git diff --check |
通过 | 0 |
验证版本
| 文件 | SHA-256 |
|---|---|
scripts/codexapp-retry-history-unit.js |
8ff35d8e3722fec5fd2ba8fac5ffac94b69e711f5bcddf2150bc10c865e73b54 |
scripts/history-runtime-unit.js |
0e1e549f2ece5337eb7808f235b6cadc4ec9192c7cf9561a77b71eca66c35ae4 |
server.js |
c964060ad121bf16edd44caf94226455cf8a434bb8b14b9f5c434a3215d6b404 |
lib/codex-app-runtime.js |
6fe66921ed8998ed1b1478eb804c0ad965ff40fff7a18dd8086e3de42b67c122 |
public/app.js |
433b4e68a9e91440eada679199a86ca7a84cf28b0f979eb3f46044be99fe757e |
scripts/assistant-bubble-controls-unit.js |
f60bb8c1c393503c461885fd2ee7ef7636dacd2a94c3654ddcac470dc449ca63 |
验证边界
- 本代理只修改上述两个测试文件及本报告,不修改实现、真实会话、原生 rollout、生产服务或其他任务 CSV。
- 本代理没有执行全量回归或真实浏览器验收;主代理执行全量回归。前端代理已完成正式浏览器验收,退出码 0,证据在
/dev/shm/ccweb-streaming-retry-browser-G8wkN6,本代理只读核对报告与实现。 - 原函数/隔离 mock 回归证明修复实现,不证明生产已部署或目标会话旧前文已补回 UI。
- 完整正文用于复制;折叠仅控制 DOM 可见性。原生段复制包含该段原始 Markdown、多自然段及代码,不含工具、分隔时间或按钮。
工具调用简报
本地使用 FastCtx 读取任务契约、当前源码及基线差异,执行隔离回归;codebase-memory 起初索引 ready 且成功定位函数,之后 snippet 返回索引不可用,降级到精确本地源码读取。没有对外发送会话内容。