Repository navigation
fix(chat): review cleared native answers without replaying work - #8087
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; OpenAI; self_reported(宿主执行身份观察不可用,未声称精确后端版本)。
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
当前 head e8379e0 未发现阻塞性问题。结论只覆盖这条有界恢复路径;生产升级后的真实补回复仍须独立验收。
动机 / Motivation
原私聊管家的用户在一次处理失败后,可能看到失败提示,却收不到原生会话已经保留的答复。
同一问题的原生文本仍在,但完成标记已清除:旧版一直保留失败;修复后原回复 worker 可在重新核验来源后安排一次只读答复复核。
测试证明原回复链路可生成并核验一次独立补回复,原失败记录和业务产物保持不变。
不把残留草稿当作已验证的最终答案,不重跑原业务,也不清空其他未知或受保护的历史欠办。
上线后仍须由原管家自行核验并沿原消息补回;本次不宣称全部历史欠答或业务工作已完成。
改动思路 / Approach
保留原失败最稳妥,但会继续漏掉已经存在的可见答复。直接采用草稿缺少最终完成证据;重跑业务则缺少“此前没有效果”的证明。本次选择扩展已有只读答复复核:provider IO 只负责从稳定原生历史提取可见材料,既有 TypeScript owner 决定准入,原 Session 队列与原消息 transport 负责执行和送达。没有新增消费者、重试引擎、配置开关或手工同步账本。
决定保留此设计的原因是:证据读取、准入判断与效果 owner 没有分叉。当前 PR 边界是“已关闭、来源吻合的草稿成为复核材料”,不会成为原业务完成凭证或重新执行授权。原生步骤被清除只是一种 provider 状态,不能推导工具成功、失败或未执行。这里用文字说明分支;未另行制作或声称验收图形。
具体改动 / Changes
规范依据为 docs/architecture/rfcs/app-conversation-and-async-inbox-v0.zh-CN.md 的“Core 失败后的原生结果恢复”,固定修订 71970fb。它要求原来源与当前 grant 核验、保留原失败、未知效果不冒充完成,以及原受众实际回传。本次没有改写规范来迁就实现。
- original-source-readback:原始 prompt hash、execution ID、索引、时间与两次空闲稳定清单同时匹配;来源改变、stop、steering 和新排队输入仍阻止准入。
- preserve-original-failure:复用确定性复核预约与独立送达阶段;集成测试逐字节检查原 Turn,并保留已送达的原失败通知。
- unknown-effects-held:草稿仅进入受限复核,不能直接采用成最终答案;开放片段、混合状态、异执行、未知步骤和工具调用保持等待。
- original-return-readback:集成测试经原 transport 实际核验一次补回复,再次对账没有增加 Turn 或重复消息;生产真实消息送达仍是上线验收项。
关键代码讲解
AntigravityAdapter.interrupted_answer_observation 保留原完整、空闲、稳定、128 步与大小界限;新增分支只读取已关闭历史段最后一条 planner 的可见 response,不转发 thinking,也不把清除状态当成 no-effects proof。
planContextRecovery / interruptedVisibleResult 将 runtime_error 导向已有 planInterruptedStewardAnswer;visible_response 必须是唯一字段且为非空字符串。这个分支没有 quota_attempt,不会重跑原业务。既有来源、附件、停止、队列、容量及一次复核身份继续由同一 typed owner 判断。
既有 _checked_answer_review / execute_turn 在实际派发前重新读回原生片段,并在回答后再检查原来源。复核配置禁写、禁网络、禁委派及其他动作;原工具只执行一次。随后新普通问题不继承只读复核标记。以上 owner 均为当前生产调用路径中的已有组件。
对主干的风险 / Risks
最强反例是“草稿看起来完整,但旧工具效果仍未知”。因此不能把此改动缩成直接采用答案,也不能放开旧业务重放。新的 provider 证据只引用可见文本;实际模型可能给出有缺口的部分答案,原门禁与欠办仍需保留。测试的原 worker、ChatStore、typed planner 和 Codex JSON-RPC 配置是真实代码,模型、原生服务及消息 provider 使用合成边界;独立真实原生只读观察另证实这种历史来源形态存在,但不证明生产模型已经完成或消息已送达。
PASS:50 项恢复测试、54 项 TypeScript 状态机测试、TypeScript 类型检查、Python Ruff、4 个变更路径公开边界扫描,以及预合并 6 项直接检查和 10 项风险检查。相同 fixture 在固定旧版上暴露两个新增正例失败,修复版全部通过;原失败、旧通知、业务产物、网络/写入限制及丢失 ACK 幂等性均有断言。当前 Goal 的 change-quality receipt 策略为 disabled,并未伪造该收据。按当前评审契约 wait_for_ci=false,未获取或等待远端 CI。
语义与 CI 对齐
visible_response 是既有 visible_results 证据词汇的严格扩展,不是新的 actor、工作完成状态或权限。现有工具/文件结果与持久预约继续兼容;缺失或不完整来源仍不能证明没有工作。固定基线的语义探针未发现它支持范围内的新 Enum/Literal carrier,但该探针不证明不存在语义变化;完整 diff、真实 owner、严格负例和词汇/架构预合并检查共同覆盖这里的当前契约。扩大回归如有失败仍须逐项归因,不能用测试总数掩盖受影响的不变量。
我的整体评价 / Verdict
这是 justified_increment:long_horizon improved,因为原历史问题可在一次受限复核内继续,避免业务效果重复与无限恢复;user_experience improved,因为用户无需复制原问题或再确认已有授权即可沿原消息收到结果。没有渲染组件或页面布局变化,visual_review 为 not_applicable;生产模型答复质量和真实原受众送达尚未验收。
当前机制成本为 32 行生产新增、3 行删除,复用原 owner 与持久账本;没有需要现在另拆的兼容版本或第二状态权威。普通新问题与保留门禁未见漂移。整体同意合入这个范围,安装后必须继续核验原服务自行补回,不能把本 review、失败提示、Core 完成或已有草稿当作用户已经收到答案。
English verdict: APPROVE — head e8379e0; no blocking finding; source-bound read-only recovery and negative boundaries verified, production return acceptance remains separate.
原生会话在本地错误后可能清除完成标记,却仍保留可见答复。原消息会因此停在失败状态,既无法直接采用结果,也无法进入现有的只读答复核验。
复用原有核验流程:只有原请求身份、输入哈希、执行 ID、时间边界和已关闭的历史片段全部吻合时,才将保留的可见文本送入一次受限核验。它不代表已验证的最终答案,也不会重跑原业务。未知效果、外来执行、工具调用、开放片段、停止/纠正指令及附件仍保留原门禁。
验证:恢复测试 50 项、TypeScript 状态机测试 54 项通过;相同 50 项恢复测试在固定基线上有两项正例失败、48 项通过,修复版全部通过。扩大回归 237 项、TypeScript 类型检查、Ruff、6 项直接及 10 项风险预合并检查通过;4 个变更文件公开边界扫描通过。当前契约不等待远端 CI。生产安装和原消息回传尚待验收。