Repository navigation
fix(inbox): honor exact source reads without draining pending work - #6808
Conversation
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
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 · reasoning_effort=max
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
未发现当前阻塞性问题。完整评审绑定 head 2a1b0aa7f02e02835d7ef1774accaefbf7cdcbcd、实际 merge base 860e42d4b63b45c4798ee7f08622a27c146a2610;未继承他人或历史批准。
动机
接收协作请求的本地 Agent 或操作者,在后续工作中需要按原 request ID 重读完整原始请求,包括已经结束的请求。 旧 CLI 虽接受 --request-id,却仍读普通待办页:找不到已结束来源,还可能顺便标记其他请求已读、交付无关结果;现在一次命名读取只返回所指请求。 当前 head 已验证完整正文、当前修订与历史状态可读,未知/错接收者/错 lifetime/混合游标明确拒绝,其他请求和结果仍可由后续普通读取处理。 此修复恢复既有本地 CLI 选项的行为,不新增来源授权、执行或启动权,不把读取当作接收、完成或结果采用。
改动思路
复用原命名条目查找、Goal/lifetime 校验、类型化回执和 read journal,抽出共同投影供命名及普通读取使用;无需第二份 inbox 或 Python 决策规则。 本 PR 完成既有 --request-id 的可信本地读取、无关副作用隔离与真实 CLI/HTTP 回归;App、MCP、来源授权和结果采用继续使用原有归属。
已有请求条目、原文与修订决定“读的是什么”,既有类型化回执决定“它现在是什么状态”,Goal/接收者/lifetime 决定“是否可读”。本次只让显式 ID 通过这些原归属,并避免顺便执行普通待办页的结果交付与委派采集。完整原文、当前修订、读取事实与实际工作相分离,没有新增手工维护的“已处理”状态。普通无 ID 读取继续承担原来的待办和结果交付。
具体改动
完整差异为 6 个文件、+247/-33:三个 Python 既有生产文件完成参数传递、命名读取和共享投影;README 增补行为/拒绝条件;148 行专用回归及 6 行 HTTP fixture 补齐已演进的 Host 接口。这里的 Python 是既有 CLI/存储 IO 适配,不再建类型化决策归属,也未增加 schema、版本、CLI 选项或页面。
验收依据为变更前 loopx/capabilities/manager_context/README.md,固定版本 860e42d4b63b45c4798ee7f08622a27c146a2610;本次新增说明不能自行证明实现。映射的 source-grant-boundary、full-source-and-current-amendment、receiver-read-is-not-decision、exact-audience-and-lifetime、ordinary-pending-and-return-continuation 均有原归属与当前真实 CLI/HTTP 证据:来源授权不等于工作/执行权,完整来源与修订不丢失,读取不等于决定,接收者/lifetime 不可串用,无关承诺与结果保持可继续。已有 --request-id 被忽略的基线反例补足具体修复依据,不把新文档当旧保证。
关键代码讲解
handle_manager_inbox()把已有 request_id 传给 reader,仅普通模式附加普通待办/ACK/report 跟进。已知 ID 的用户无需增加一次确认或手工搜索。pending()对显式 ID 先拒绝混合游标,再复用_entry、原 schema 与类型化 lifetime 校验;未知来源明确报错,历史 settled 可读但不重新打开工作。空字符串仍属于显式输入,不会走普通 fallback。_inbox_item()是从原分页分支抽出的共同投影,保留完整 brief、当前修订、已记录决定及 warning 优先级,历史已结束来源补上“仅查看、不重开、不获执行权”的说明。read_inbox()只有无 ID 模式收集无关 peer return/delegation;准备来源后在读取回执提交前重新校验原 Goal/lifetime,避免 IO 期间重建 Goal 后借用旧身份。显式读取仍走原 read journal。
对主干的风险
重点反例是“旧请求已结束,而同 Goal 有新待办或另一个待交付结果”。当前真实 File/SQLite CLI 返回完整原文(含 300 行中文上下文),不修改原条目、决定或 conclusion 字节,不读新待办、不交付另一结果;随后普通读取仍拿到这些工作/结果,说明既防意外消费又不阻断继续。未知/路径形式/错接收者/混合游标/新 lifetime 均在写回前拒绝,未用空成功页掩盖问题。原分页、冲突、当前修订、不可用 linked work、重启、legacy JSON、App/MCP 来源边界也有当前覆盖。
当前四文件原生套件 150 passed,135.45 秒。我在不可变 860e42d4b63b45c4798ee7f08622a27c146a2610 上运行同一份最终 15 项 exact-request 测试,得到 11 failed、4 passed,21.27 秒:断言直接显示 ID 被忽略、未知/错接收者接受、无关结果交付及旧 lifetime 未拒绝;混合游标四项原本就拒绝。当前 head 同组全部通过。这些基线失败是修复敏感性,不能列成当前失败,也不是导入/超时问题。
HTTP fixture 中 recover_exited_turn/close 是 scripted no-op,实际 HTTP/存储/来源断言保持;同一最终 fixture 的 69 项在不可变基线上亦全部通过,48.25 秒。它修复测试 Host 接口,不证明真实退出进程恢复。当前标准 premerge 6 个直接及 18 个选中检查通过,0 hold/失败/警告,changed-path Ruff 通过。没有查询或等待 CI,没有降低阈值、删断言或把跳过当通过;未运行 live model、可选 PostgreSQL 实服或安装升级验证。
语义与 CI 对齐
复用现有请求身份、typed lifecycle/receipt 词汇和原 read/result journals;新 helper 仅本地投影,无新共享语义集合。无 ID 的默认行为和指导保留;显式 ID 的完整历史读取、错误及副作用收窄已在 help/README/回归中披露。当前修订与 warning 指导未丢,settled 文本也不冒充新的机器执行义务。v1/v2 持久条目与独立来源客户端有真实兼容理由,本次没有增加并行请求解码或迁移框架。
我的整体评价
APPROVE,goal_achieved。 long_horizon:improved,限于原始来源在后续工作中的恢复及无关承诺继续;user_experience:improved,同一已有命令完成原任务,无新增确认、配置或已知信息重填。复用原命名条目查找、Goal/lifetime 校验、类型化回执和 read journal,抽出共同投影供命名及普通读取使用;无需第二份 inbox 或 Python 决策规则。 本 PR 完成既有 --request-id 的可信本地读取、无关副作用隔离与真实 CLI/HTTP 回归;App、MCP、来源授权和结果采用继续使用原有归属。 共享投影是已落实的同域简化,整体机制与真实失败成本相称。最强缺口是 scripted Host 没有资格证明真实进程退出恢复,且未验证 live model/安装升级;本修复不改那些行为,也不提出那些完成主张。独立证据、旧阻塞清理、合并资格与维护者合并授权分别判断。
English verdict: APPROVE — 2a1b0aa7f02e02835d7ef1774accaefbf7cdcbcd correctly honors exact source reads, preserves full/current or concluded source and lifetime boundaries, and leaves unrelated pending work/results available. All150 current native tests, standard premerge and Ruff pass; the same15 exact-reader tests expose11 baseline failures. No merge authority is implied.
Goal and delivered outcome
manager-inbox read --request-id <id>accepted the option but ignored it: reading an original request could instead return and record reads for unrelated pending work and deliver unrelated peer results. A concluded original request was not recoverable through that command.The option now reads only the named request in the existing Goal, receiving Agent and Goal lifetime, including concluded requests. It preserves the full current brief, original ancestry and typed receipts. Unknown/wrong-scope identities and mixed cursor arguments fail without falling back to the queue. Omitting the option preserves the pending inbox, peer results and operation handoffs.
Author declaration and specification
Written by: OpenAI Codex, GPT-6 family agent, using the
loopx-agentGitHub identity.Implemented against the existing manager-context inbox/receipt contract at base
860e42d4b63b45c4798ee7f08622a27c146a2610(loopx/capabilities/manager_context/README.md), with the concrete CLI defect above as the change request._entry,CollaborationGoalScopeand typed receipt owner; exact-read CLI regressionsread_inboxexact branch; receipt snapshots and subsequent ordinary read_inbox_itemprojection, existing peer/source/lifetime suitesScope and continuation
This is a complete, reversible CLI inspection fix. It reuses the existing TypeScript lifecycle/receipt decisions; Python adapts lookup and I/O. The bounded refactor shares the item projection between pending and exact reads. No new capability, configuration, state vocabulary or migration machinery is added.
The companion test-only commit supplies the HTTP fixture's scripted Host lifecycle controller. Current main already fails those tests before inbox projection because the fixture omits that controller; the assertions and real HTTP/store path are retained. This does not test actual Host process recovery.
Project/App source admission, receiver adoption and original-conversation return remain separate existing work. This PR does not claim that broader journey is complete.
Validation
Tested revision:
2a1b0aa7f02e02835d7ef1774accaefbf7cdcbcd; run state: finished. Inputs: synthetic and public fixtures only. Runtime: Python 3.14.8 and Node.js 24.21.0. All runtime fixtures use disposable roots; no active Goal was used as a test fixture.uv run --extra test python -m pytest tests/control_plane/test_inbox_exact_request.py tests/control_plane/test_peer_source_store.py tests/test_manager_context_tracking.py tests/test_collaboration_goal_instance.py -q: 150 passed. Real File/SQLite and HTTP/store paths; scripted Host liveness.-I). Source harness prepares disposable fixtures; this is not installed App/Host acceptance.python -m mypy(17 configured files), semantic advisory followed by full semantic check, maintainability ratchet, six-path public-boundary scan andgit diff --check. No vocabulary, budget or ignore-list exceptions added.uv run --extra test loopx canary premerge --from-git-diff: all six direct checks and 18 selected catalog/risk/public-boundary checks passed, with zero failures, warnings or manual holds. Fresh exact-scope change-quality receipt passed; it grants no merge authority.Earlier setup/build attempts and a broad, noncanonical mypy invocation failed; final checks above used the normal checkout environment and configured typing scope. Historical failures remain recorded; this change does not claim all legacy modules are type-clean. The initial canary preview reported a stale receipt; a fresh qualification was recorded for this exact diff.
Frontend and boundaries
UI impact: none. Existing trusted local CLI only; the capability README documents the changed option and its errors. No first viewport or App interaction changes.
codex/branch, based on upstreammain.