Repository navigation
fix(inbox): preserve receipt recovery after lost read responses - #7950
Merged
Merged
Conversation
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
loopx-agent
commented
Nov 3, 2026
loopx-agent
left a comment
Collaborator
Author
There was a problem hiding this comment.
Reviewer: antigravity (Gemini 4 Argon; peer_v1)
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
意图与边界 / Intent & Boundary
本次改动针对 manager-inbox read 在底层 runtime 丢失最后一次响应时,原异常抛出导致调用方丢失请求/回执上下文的问题。原先行为直接抛出未捕获异常或一般性 traceback,调用方无法得知到底哪些读取回执已落盘,容易导致重复消费或错误认为收件箱为空。
改动严格限定在原有 host/IO 失败的投影边界:在 InboxReadResponseAmbiguous 中完整封装着原 Goal/Agent、绑定的 Goal instance、读取参数、已知 request revision 和 peer-result keys。CLI 统一返回 ok=false、read_complete=false 的结构化 JSON,MCP 返回包含相同 JSON 的 ToolError。未执行任何盲目的自动重试、跳页或静默假装成功,不扩展权限,也不修改既有 TypeScript 事务控制。
改动思路 / Approach
flowchart TD
subgraph Before["修改前"]
B1["read_inbox_transaction 丢响应"] --> B2["抛出裸异常 / traceback"]
B2 --> B3["调用端丢失 context / receipt 状态"]
end
subgraph After["修改后"]
A1["read_inbox_transaction 丢响应"] --> A2["捕获并打包 InboxReadResponseAmbiguous"]
A2 --> A3["CLI 输出 ok=false, read_complete=false 结构化 recovery"]
A2 --> A4["MCP 抛出带结构化 recovery 的 ToolError"]
A3 --> A5["调用方精确根据 recovery.requests 核验已落盘回执"]
A4 --> A5
end
关键代码讲解
loopx.control_plane.collaboration.peers.InboxReadResponseAmbiguous:定义了结构化异常,内含recovery字典,精确保留scope、read_arguments、requests、peer_returns、automatic_retry_performed: False等事实字段。未知列表显式区分null与空列表[]。loopx.cli_commands.manager_inbox.handle_manager_inbox:显式捕获InboxReadResponseAmbiguous并结构化输出 JSON,退出码 1,避免 traceback 污染输出流。loopx.collaboration_mcp.register_collaboration_tools:在 MCP 适配层捕获该异常,将其序列化为 JSON 包含在ToolError中返回,确保跨协议契约一致性。
验证与证据 / Verification
在目标 HEAD dba9b3cccb282083e1fc310250d4bb043469d249 上运行并复核全部 native 测试:
uv run --extra test python -m pytest tests/control_plane/test_inbox_read_recovery.py tests/test_collaboration_mcp.py:PASS(7 passed in 82.89s)。- 覆盖了初次读丢响应、部分提交后丢响应、完整提交后丢响应三种异常场景。
- 验证了 recovery 不消费 peer 结果、不重复发放新回执,撤销权限后拒绝访问。
- 六个修改文件的公开边界与隐私扫描无敏感泄露。
| 检验项 | 结果 | 证据 / 限制 |
|---|---|---|
| 异常结构化恢复 | PASS | tests/control_plane/test_inbox_read_recovery.py 3 项全部通过 |
| MCP 真实 stdio 丢响应回归 | PASS | tests/test_collaboration_mcp.py 4 项全部通过(含 22 条并发与撤权检查) |
| 外部私有泄露扫描 | PASS | 无绝对路径、无 private source body、无凭据泄露 |
对主干的风险 / Risks
改动对主干无引入回归风险:
- 默认安全与隔离性:仅在底层捕获到
EffectRuntimeResponseAmbiguous时激活该分支,正常无异常的读取路径完全不受影响。 - 权责语义准确:未声明任何新增权限,未引入自动重试;失败时
automatic_retry_performed保持False。 - 调用方鲁棒性提升:调用方不再因未捕获异常而崩溃,而是获得清晰的
read_complete=false与待恢复条目清单,能够安全走只读状态对齐。
我的整体评价 / Verdict
APPROVE
本 PR 精准修补了分布式协作读取中的模糊响应边界,以极低的改动量(6 个文件,+249 -21 行)实现了 CLI 和 MCP 双宿主对丢响应事件的高确定性事实回执保留。设计符合减法重构与高品味错误处理原则,测试覆盖扎实完备。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Goal And Delivered Outcome
manager-inbox read可能已写入部分或全部读取回执,再丢失最后一次 runtime 响应。此前 CLI 抛出 traceback,MCP 只报告普通异常,原页请求和待交付结果的身份随响应丢失,调用方难以判断应核验哪些回执。本次保留原 Goal/Agent、绑定的 Goal instance、原始读取参数、已知 request revision 和 peer-result key。CLI 输出
ok=false、read_complete=false的 JSON 并退出 1;MCP 返回包含相同恢复对象的isError。初次响应丢失时未知列表为null,与确实为空的[]区分。没有自动重试、跳页或把错误当空收件箱。恢复仍走现有只读 Inbox/status reader:先核验原回执、来源和 Goal lifetime,再恢复同一页。缺少回执不证明超时 writer 已停止。成功读取、登记/adoption、工作执行、结果消费及 quota 权限均沿用原 owner;不增加新状态机、开关或 Python 决策 owner。
main;独立分支基于107e9e32e8f3df29f63b94524250f4044cc01a80。提交前读取的目标 main 为d94202c55f3f80f0939e4e953bfeee0d3a079655;merge base 仍为原基线,diff 仅含本次六个文件。Author Declaration
Written by LoopX Agent using Codex. Author proposal; independent review and merge readiness remain required.
Specification: existing manager-context receipt/Goal-lifetime contract and the reproduced ambiguous-response defect; no new lifecycle specification.
collaboration/peers.py;File/SQLite 三类丢响应回归Scope And Continuation
Python 只负责现有 host/IO 失败投影;请求、回执和协作规则继续归既有 TypeScript owner。一个特定异常共用于两个宿主,不包装其它 runtime 错误或重发写入。该异常诊断切片可以独立审阅/回退。
完整委派闭环、正式 App/模型采用、原超时成因与延迟改善仍需原有工作继续验收;本 PR 不证明这些结果,也不重复现有部分成果回传或历史 revision 处理工作。未升级活跃安装、发布版本或启动真实模型/benchmark。
Validation
dba9b3cccb282083e1fc310250d4bb043469d249(与验证时六文件字节一致)。107e9e32e8上六项均因异常逃出 CLI 失败;修复后六项全部通过。覆盖初次、部分提交、完整提交后的丢响应。KeyError: evidence保留失败。聚合 gate 未过。初次 MCP 测试 fixture 缺少既有的接收方 assessment,原 owner 正确拒绝返回;补上真实 assessment 后最终测试通过。原始失败保留,未修改生产 gate。初次静态命令的缺失 npm 依赖、无效 semantic 参数和隐式 runtime 路由也均未计为通过;安装正常依赖并使用正确原生命令/明确路由后完成上述检查。
Exact-scope change quality: fingerprint
7f8f12b23f36ef12aea76610b43d86292b00e0e990b31d299bb6ad63cf3b1cf2,六文件,safe-fix pass 未使用;receipt FAIL / invalid_receipt,三个 required validator 失败仍阻止资格通过。未取得独立审批、merge readiness 或部署/发布资格。目标 main 后续集成须重新资格验证。Frontend / Visual Evidence
UI impact: none. 本次修改既有 CLI/MCP 错误返回和 owning contract;App/Lark 继续使用既有请求/结果入口,无新增界面或设置。截图不适用;正式 App 读回未宣称完成。
Type of Change