Repository navigation
Verify bound Chat history against the final Session scope - #8664
Conversation
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent · gpt-6.1-sol · OpenAI · runtime_reported · max
本次评审对应提交 8ab20d27dd8f63e708ac609de2bb1f66043198f6。
没有阻塞发现。
动机 / Motivation
用户从工作区打开绑定的外部对话,想继续读原会话的消息。旧版读完分页历史后只确认绑定和 Session ID 还在;如果最后一次查询返回相同 ID、不同会话范围,刚读完的消息仍会返回给显示层。新版在返回消息前核对最后一次查询的会话范围。范围变化时拒绝这批快照;范围不变而原对话追加消息时,下一次读取仍能复用已核验的前缀。验证的是打包客户端的数据入口和本地 HTTP/SQLite;仅改变合成夹具的最后一条响应,未连接真实外部账户或已安装桌面应用。
改动思路 / Approach
最后一次绑定查询仍由原服务负责;前端把它的 Session scope 与刚核完的快照用同一个比较器对齐。只补绑定历史发布前的 scope 对照和已有 smoke 的反例,保留缓存、分页、权限和重试所有者。 仅比较 Session ID 会留下触发条件;比较整份 Session/摘要会误拒合法追加。复用原 scope 字段是更小的边界。
具体改动 / Changes
关键代码讲解
最终绑定复核 使用 已有比较器,与 后缀路径 保持同一 scope。网络中断仍只暂存已验证快照;明确 scope 冲突直接返回失败。合成 HTTP 对照每次先读三页,只改最后发现的 channel 或 project。旧版都返回 452 条,新版两次都拒绝,没有新消息进入返回值。
按 docs/development/frontend-delivery.md @ 1cb6cafadf758e3c4b2f213aabc94660e9c2f0db 核对 ORIGINAL_SESSION_SCOPE、VERIFIED_PREFIX_RECOVERY。
对主干的风险 / Risks
不能把 transcript revision 混进 scope,否则合法追加会被挡住。独立在最后发现前真实追加一条:两版都先返回 452 条,下一轮用 known_history 读到 453 条。普通 Session 仍只读它自己的记录。
语义与 CI 对齐
独立两版 HTTP 配对;npm run smoke:bound-conversation 普通及 Steward fallback;TypeScript、打包及 quick premerge。 未查询托管 CI。
我的整体评价 / Verdict
批准这个 head。最后一道来源核验覆盖同 ID、不同 scope 的情况;正常追加、同源恢复和普通 Session 保持原行为。已核对 Dashboard 的 useConversationHistory 与本次 src/data/chat.ts 的原读取/失败分支。只补入已有历史请求结果的拒绝条件,没有改任何视图结构、样式或新增交互。验证的是打包客户端的数据入口和本地 HTTP/SQLite;仅改变合成夹具的最后一条响应,未连接真实外部账户或已安装桌面应用。
English verdict: APPROVE. Approve this head. Final bound Session scope mismatches reject the downloaded snapshot; unchanged-scope append and recovery remain intact.
After a bound Chat history read, a source response can still return the same binding and Session IDs with different canonical scope. Compare that final scope with the downloaded snapshot before showing its messages. A normal append keeps the existing verified prefix behavior.
The regression changes the channel only in the final source response from the HTTP and SQLite fixture. It fails before the fix and passes with it. The bound-conversation smoke passed for both the ordinary and steward fallback configurations. The Chat bundle, TypeScript check, and quick premerge checks also passed.