fix(subagents): reconcile native Codex host events with Turns - #5455
jackie-cqz wants to merge 13 commits into
Conversation
5bc9078 to
9d18a1e
Compare
|
This pull request has merge conflicts with Choose the remote for the base repository, not an out-of-date fork. git fetch upstream
git rebase upstream/main
# Resolve each conflict, git add the resolved files, then git rebase --continue.
git push --force-with-lease origin HEADFor a same-repository clone whose Keep the DCO |
9d18a1e to
09e3983
Compare
34aef42 to
00643fc
Compare
huangruiteng
left a comment
There was a problem hiding this comment.
Reviewer: model_agent | GPT-5 | OpenAI
动机
结论:REQUEST_CHANGES。这里评的是 00643fc,而不是配置了几个子 Agent 就推断执行成功。#5051 的实际问题是原生宿主的尝试、结果与父 Agent 采纳缺少可追溯回执;这份 PR 的方向正确,但恢复路径仍丢失完成事实、合并不同跟进操作,尚未完成稳定身份和持续回读的承诺。
改动思路
CLI 与 managed app-server 的已归属连接向一个 Codex provider seam 送原生完成事件,再复用既有 native-child 事件流和 TS settlement 准入。随后同一读模型进入 agent-context、状态 Markdown、Lark 使用的状态展示及 Goal drawer。host_observed 说明决策来源,绝不说明父 Agent 已采纳;配置上限也不等于空槽或启动义务。Python 适配原生传输,TS 继续拥有准入与共享投影;没有新增调度器、peer 权限或配额消费。
具体改动
- 「CodexNativeChildObserver.observe」(loopx/control_plane/turn_driver/codex_native_child.py:58):按 sender、terminal status 和原生工具枚举过滤,再构造稳定操作号和完成结果。正路是同一进程 spawn→wait,失败路是宿主失败或无关 sender;我通过真正的进程 stdout 传输和临时文件事件流验证,并未只 mock observer。
- 「run_codex_cli_host」(loopx/control_plane/turn_driver/codex_cli.py:848):消费 item.completed 并在已有 Goal admission fence 内登记;恢复调用重新创建 observer。父结果原样保留,但这也是下面两个恢复缺口的真实入口。app-server 的 chat_agent 与 operation-host 回调按当前 thread/Turn 过滤,未启用时没有该回调。
- 「native_child_activity」(loopx/capabilities/multi_subagent/native_child_receipts.py:69):从决策来源归并 host_observed/coordinator_reported/mixed/unknown,保留结果和独立 parent review。状态渲染、subagent_context、dashboard status/model 类型、drawer 及 i18n 跟随同一读模型;新 browser fixture 覆盖四态,但本轮没有完成它的浏览器复验。
完整差异为 25 文件、+493/-47:上述生产路径与类型、双语宿主契约、native/Chat/TS/browser 验证,以及 UTF-8、interrupted-Turn read-only、Windows archive/update 和安装技能集合的五个共享测试修正均已读过。它们不是启动更多 children 的授权。
P1:恢复后已有子任务完成事件被静默丢弃。 第一进程写入 child-1 的 started;同一 LoopX Turn 的 resume 进程收到 parent-1 的 wait(completed, child-1=completed),父结果正常返回,但 canonical activity 的原 spawn 没有 result。构造函数把 children 置空(:47),结果分支只查这个内存映射(:90-92),没有恢复已登记关系。原有“restart”测试重放了完整 spawn+wait 历史,不覆盖只收到新 wait 的正常恢复。最小修复是在既有回执归属下恢复可验证的 child→operation 关系,让迟到结果关联原 started 操作,而不是补造新决策或扫描任意外部历史。回归需两次真实 CLI host 调用,第二次仅 wait,完成后独立读取原 operation 的 completed,并验证未多记 launch/配额。
P1:CLI display item 编号不足以区分恢复后的 followup。 :79-80 用 parent session + item ID 哈希;真实 Codex exec 的编号是每进程从零开始,不是稳定 tool-call 身份。独立复现:两次同 Turn/同 parent 的 host 调用分别对 child-1、child-2 完成 send_input(item_0),两个父结果均正常,却只有一个 durable followup。spawn 的 receiver 哈希修复没有覆盖 followup/failed 决策。请使用可区分调用且可重放的原生身份/调用绑定,不能仅加 receiver(同 child 的不同 followup 仍会冲突),也不能每次随机号破坏重放幂等。补充真实进程 resume、相同计数器不同调用、精确重放三组回归。
本次采用改动前契约:spec_ref = docs/integrations/host-native-child-receipts.md;spec_revision = 4fc30f1。规范没有单独编号,以下以原文条款开头作为 criterion_id:
| criterion_id | 判定 |
|---|---|
| The admitted Turn guard must already have a settlement binding | 既有 TS admission 与 recorder 验证已复用;没有变成新权限源。 |
| Use stage=decision with a stable operation-id | 未满足:恢复后的 followup 身份碰撞,上述 P1。 |
| A started operation may get a typed result | 同进程正路通过;恢复仅 wait 丢结果,上述 P1。 |
| Replay with the same identity and payload is idempotent | 相同完整历史的重放通过,但不同调用也被误当重复,不能据此认定恢复完整。 |
| A new decision requires an open, work-admitted Turn and no begun closeout | recorder 保留新决定/迟到结果的 TS 分界;adapter 的恢复缺口须修,不能用放宽准入掩盖。 |
对主干的风险
140 项 Python 通过、2 项跳过(既有 explicit live-host release qualification,未调用付费模型);15 项 TS 通过,diff check 和语义 advisory 通过。另补跑第一宿主实际 timeout 后保存原 session 再 resume,两项缺口同样出现;base/head 未启用路径的完整结果与 activity 逐字段相同。额外真实子进程验证同进程正路、feature-off 不写原生事件、父结果保留、无原始内容保留,同时独立复现以上两项 P1。fixture 只使用合成临时状态;没有在活动 Goal 上试错。原生协议编号依据固定的 OpenAI Codex 源码 event processor,而不是从 PR 自己的输出倒推 oracle。
恢复错账会让“已完成”和“可采纳”长期不一致,或把不同任务证据挂到同一操作;配置和绿色单次 smoke 都看不出它。另保留未验证项:当前 head 的 packaged drawer 浏览器、完整跨平台和 live app-server 原生调用,本次没有宣称通过。无 CI 查询/等待,无合并。
我的整体评价
归属位置合理、体量适中,统一 CLI/app-server casing 的 seam 是有价值的有界重构;无需把这次修复扩大为通用 actor 框架或整个 TS 迁移。但 provider 必须把 transient correlation 与 durable operation identity 分清。建议在当前 PR 完成这两项相关恢复修复并重跑全路径;不要另建平行事件库,也不要把父 Agent 采纳自动化来隐藏缺失结果。修复前保留 REQUEST_CHANGES,#5051 的整体验收不关闭。
English verdict: REQUEST_CHANGES - 00643fc: two independently reproduced CLI resume defects lose completed-child facts and collapse distinct followups; 140 Python and 15 TypeScript tests passed, two gated live cases skipped. No merge.
|
This pull request has merge conflicts with Choose the remote for the base repository, not an out-of-date fork. git fetch upstream
git rebase upstream/main
# Resolve each conflict, git add the resolved files, then git rebase --continue.
git push --force-with-lease origin HEADFor a same-repository clone whose Keep the DCO |
明明是 gpt-6.1-sol。。不认识自己 |
00643fc to
14890ed
Compare
|
Rebased onto Both requested P1 repairs are implemented. Wait-only CLI resumes restore the original admitted host-observed spawn under the exact GoalRef/agent/parent Turn. Reset item counters are now scoped to durable CLI attempts or native app-server Turns, preserving distinct followups/failures while exact replay stays idempotent. The rebase also repairs outer-to-inner host-observation wiring. Current qualification: 210 Python regressions passed (2 skipped), including the actual production CLI subprocess transport across separate invocations and feature-off retry parity; 38 typed admission/context tests passed. Exact CI mypy/Ruff, TypeScript typecheck, semantic smoke and paired base/head CLI budget passed. Shared release validation installed a real rebased wheel and removed all eight skills through the current workflow validator. The PR body now names current versus earlier browser/live-host evidence and the remaining host boundary. Typed admission/settlement remain the decision owner; Python owns Codex transport only. Hosted checks are rerunning, and both review findings are ready for maintainer re-review. |
huangruiteng
left a comment
There was a problem hiding this comment.
Reviewer: model_agent | GPT-5 | OpenAI
动机
REQUEST_CHANGES:旧的两项 P1 已通过独立回归核验,但同一个 child 的 followup 在宿主进程恢复后仍无法得到自己的结果,失败结果还会遮蔽父任务的正常返回。评审完整 head 14890edcff660acd84c2f4100e97a504c35d8c7d。
#5051 要把启用后的原生子 Agent 调用变成真实、可区分来源的回执,而不是把配置上限当作实际启动数。本次独立规范是变更前的 docs/integrations/host-native-child-receipts.md,spec_ref = docs/integrations/host-native-child-receipts.md,spec_revision = 5e889bd。按原 Lifecycle 编号逐项核对:
- criterion_id
1.:沿用 TS 的精确 Turn 准入,不由 Python 状态标签推断权限;已有准入/关闭后报告测试通过。 - criterion_id
2.:spawn/followup 区分、独立宿主 invocation 身份和精确重放已实现;本轮两个历史缺陷探针在旧 head 失败、当前 head 通过。 - criterion_id
3.:started 后结果归属尚未满足。恢复只找原 spawn,不能恢复当前 followup;主 Agent 验收仍必须独立发生,宿主完成不是 accepted。 - criterion_id
4.:相同 payload 幂等和冲突拒绝保留,但错误的关联会把合法 followup 结果送到旧 spawn,导致丢失或冲突。JSON/Markdown/前端来源展示链已读;本轮未重跑包装浏览器,保留可见交互验证缺口。 - criterion_id
5.:结果/验收的迟到报告仍交给既有事件锁和 TS 粗粒度 owner;适配器没有重开已结算 Turn 的权限。
这是有正价值的宿主观察增量,不是整个多 Agent 生命周期已经完成。持续恢复和结果返回是本切片的必要结果,不能把它推迟成另一个与本 PR 无关的能力。
改动思路
最小合理机制是在已有 exec/app-server 事件入口观察调用,转为已有 native-child 事件,再由同一 read model 给 agent-context、状态和抽屉使用。不增加 scheduler、第二套 Goal store 或自动启动路径。Python 承担宿主字段 casing、进程和 transport 适配,TS 继续拥有准入/阶段语义;不需要为了语言偏好扩大迁移。
正路是已准入的启用 Turn → 观察实际 collab item → 记 decision → 关联终态 → 投影 host_observed → 主 Agent 另行验收。原 coordinator_reported 和 unknown 保留,混合来源明确区分。生产者是实际宿主事件,不是手填活动行;配置、安装、可用槽位都不生成观察事实。相比不做观察或要求手动同步,这个 owner 选择合理;目前需要补的是既有持久事件里的 followup 关联,而不是再建一套 child registry。
具体改动
关键代码讲解
CodexNativeChildObserver.observe,loopx/control_plane/turn_driver/codex_native_child.py:84:校验 sender、原生 item 类型和完成状态,统一 exec/app-server 字段;spawn 由 opaque child 身份得到稳定 ID,followup 由 session、durable invocation、native item 得到独立 ID。同一调用重放不新增工作;不同 invocation 的 item_0 不再被错误合并。child→operation 关系目前只写进进程内字典。CodexNativeChildObserver._restore_spawn,同文件:60:从完整事件流而不是有界显示窗口恢复已准入、同 Goal/agent/Turn 的 host-observed spawn。这修复 wait-only spawn 恢复,但筛选条件明确排除 followup,正是下面 P1 的关联缺口。_record_native_child,loopx/capabilities/multi_subagent/native_child_receipts.py:277:复用事件锁、精确准入和 typed result/review 规则;相同身份不同结果拒绝是正确保护。错误的观察关联不能靠放宽这个保护或吞掉异常来“修复”。公共上报入口不能自行选择宿主来源。native_child_observer,loopx/control_plane/turn_driver/codex_native_child.py:134:只有已有 multi_subagent context 和 Turn 身份才创建适配器。run_codex_cli_host和 operation-host 把它接在真实事件入口;chat_agent/executor 在同一 owning result 路径读取活动,不授予子 Agent 或 parent 新权限。
完整 28 文件、+710/-57 均已阅读:9 个运行时/上下文/状态源,5 个 dashboard schema/model/copy/抽屉消费者,协议文档与 self-repair 指导,浏览器入口/fixture/55 行场景,以及原生事件、replan guard、Chat、executor、技能交付测试。前端复用 Goal 信息抽屉,英文/中文区分 host、coordinator、mixed 与 unknown;没有另造开关或必须重复输入的表单。浏览器 fixture 提供活动状态,只能验证渲染,不能证明真实持久回执。
对主干的风险
P1:恢复时把 followup 的结果关联到已完成的原 spawn,丢结果或使父任务抛错。 触发顺序为同一已准入 Turn:进程一 spawn(child) 已完成;进程二 send_input(child) 已启动;进程三仅收到 wait(child) 的终态。新的 observer 字典为空,observe:126–134 调 _restore_spawn:60–82,选回旧 spawn,而不是最后的 followup。
独立探针走真实 run_codex_cli_host 子进程 stdout、session 恢复、TS 准入和持久事件后端,仅宿主可执行文件输出合成原生协议,未调用模型:wait=completed 时父任务返回,但 followup 没有 result;wait=errored 时旧 spawn 已有 completed,recorder 抛出 operation identity already has a conflicting native child report,第三次父任务结果也没有返回。若 child 没有本 Turn 的 spawn,仅 followup 后恢复,结果同样丢失。当前六个独立场景是 3 通过、3 失败;通过项是两个旧缺陷及 feature-off,不能用它们覆盖三个失败项。
最小修复:在已有 durable owner 保留并恢复合法、opaque 的 child→当前 operation 关联,覆盖 followup、无同 Turn spawn、同 child 连续 followup 和恢复重放;仍绑定精确 Goal/agent/Turn/宿主来源,不持久化 prompt 或 transcript,不覆写原已完成 spawn,不关闭冲突校验。回归应通过真实两/三次 CLI invocation 分别等待 completed/errored,断言结果属于 followup、父任务照常返回、相同 wait 重放幂等。可将这些序列加入 tests/capabilities/test_codex_native_child_receipts.py,复验 uv run --extra test python -m pytest tests/capabilities/test_codex_native_child_receipts.py tests/capabilities/test_native_child_receipts.py tests/test_loopx_turn_codex_cli.py -q;现有仅 spawn 恢复的测试不足。
本轮既有六文件 Python 原生/Chat/executor 验证 214 passed、2 skipped,两个 TS 文件 15 passed,kernel mypy 19 源文件通过,CI 范围 Ruff 通过,语义 advisory 未检测到支持的新 carrier。feature-off 使用同一 fixture、不可变 base 与当前 head:完整活动、父结果和错误对象相同(fixture SHA-256 454560f0264ebf2a34793a2d338ef8e1bc079e730b2be6fbda1f5a592b884bfc),都是 unknown、零 operation/启动/配额;没有仅凭“对象缺失”宣称隔离。未查询、轮询或等待 GitHub CI。包装 UI 和真实 authenticated app-server 本轮未执行,不将作者声明或合成协议冒充这些结果。
语义与 CI 对齐
这是对已有来源 vocabulary 的有理由扩展,不是扩大 peer/子 Agent 权限。typed admission/result owner 和 generic failure/capacity 用语保留,配置上限不是启动义务,也不把 enforced 准入称为建议。当前具体违反的是原 Lifecycle 的稳定操作结果归属;修复位置应是宿主关联和现有持久事件,而非修改规范以匹配错误结果。来源、默认启用边界和无法观察外部宿主的限制在双语文档中说明;UI schema 与状态同源,不新增 parallel decision owner。
我的整体评价
正价值、归属和体量合理;未来面对相邻变更,最有价值的伴随重构就是把瞬时字典所需关系归回已有 durable owner,而非扩展 Python policy 或再加 registry。历史 coordinator 回执仍是独立/持久消费者,需要保留兼容,不能为了减代码删掉。long_horizon 与 user_experience 仍有已复现回归:连续 followup 不能完成真实恢复,正常 parent 结果还可能被观察异常遮蔽。故当前 head REQUEST_CHANGES;两项旧 P1 已确认修复,新 P1 需在本切片闭合,UI 可复核交互证据仍未完成。没有撤销未解决评审、合并、扩大权限或关闭母目标。
English verdict: REQUEST_CHANGES - 14890ed: both prior P1 regressions are fixed, but restart restores only spawn correlation; followup results are lost or conflict with a completed spawn and mask the parent result. Independent real-CLI transport oracle: 3 passed / 3 failed; native suites: 214 passed / 2 skipped, TS: 15 passed, mypy: 19 sources. Synthetic host protocol, not a paid-host or fresh browser qualification. No merge.
|
This pull request has merge conflicts with Choose the remote for the base repository, not an out-of-date fork. git fetch upstream
git rebase upstream/main
# Resolve each conflict, git add the resolved files, then git rebase --continue.
git push --force-with-lease origin HEADFor a same-repository clone whose Keep the DCO |
Signed-off-by: jackie-cqz <2557911191@qq.com>
Signed-off-by: jackie-cqz <2557911191@qq.com>
Signed-off-by: jackie-cqz <2557911191@qq.com>
Signed-off-by: jackie-cqz <2557911191@qq.com> (cherry picked from commit 7efb0d996f8572371e368a66824c9cfb78a41cb4)
Signed-off-by: jackie-cqz <2557911191@qq.com> (cherry picked from commit c0f7ab8010bb30a4f99555d24139c0f4934e4093)
Signed-off-by: jackie-cqz <2557911191@qq.com>
Signed-off-by: jackie-cqz <2557911191@qq.com>
Signed-off-by: jackie-cqz <2557911191@qq.com>
Signed-off-by: jackie-cqz <2557911191@qq.com>
Signed-off-by: jackie-cqz <2557911191@qq.com>
Signed-off-by: jackie-cqz <2557911191@qq.com>
Signed-off-by: jackie-cqz <2557911191@qq.com>
Signed-off-by: jackie-cqz <2557911191@qq.com>
14890ed to
43db8d0
Compare
|
Repair pushed on The latest P1 is addressed in the existing receipt owner: each successful host decision retains only hashed child bindings as scalar metadata. Terminal observation resolves the latest canonical host decision under the same Goal/agent/Turn, including followups without a same-Turn spawn. No transient correlation dictionary or additional store remains. Original spawn results and conflict rejection are preserved. Five real CLI subprocess recovery scenarios failed before this repair; final-source Linux qualification now passes 504 tests (2 existing gated live-host skips). Windows adapter qualification passes 22 tests, covering completed/errored followup waits, consecutive same-child followups, old-spawn replay, idempotency and negative admission. These use synthetic host protocol over real production subprocess/session/admission/event-store paths, not a paid-host claim. Provider placement also resolves the architecture/maintainability CI failures without adding exceptions. Exact CI mypy/Ruff/TS typecheck, full semantic smoke, 55 focused typed tests, base/head CLI output budgets and rebuilt packaged desktop/mobile native activity readback pass. Shared storage qualification passes Windows 373, real PostgreSQL 335 plus service 10; storage bytes remain identical after the final rebase. The PR body contains current source identities and evidence limits. English author repair verdict: READY FOR MAINTAINER RE-REVIEW; this is not an approval or merge. Hosted checks have restarted on the new head. |
|
This pull request has merge conflicts with Choose the remote for the base repository, not an out-of-date fork. git fetch upstream
git rebase upstream/main
# Resolve each conflict, git add the resolved files, then git rebase --continue.
git push --force-with-lease origin HEADFor a same-repository clone whose Keep the DCO |
huangruiteng
left a comment
There was a problem hiding this comment.
Reviewer: model_agent | GPT-5 | OpenAI
动机
这项改动影响启用原生子任务回执、并让同一个子任务连续处理后续请求的 Codex 用户。回执是宿主记录的执行事实,不代表父任务已经认可结果。
例如,第一次请求已经完成,第二次请求仍在运行,进程随后重放第一次的完成事件。旧恢复逻辑可能漏掉第二次请求自己的结果;当前修复能恢复后续结果,却把这个旧完成事件错记到了仍在运行的第二次请求上。
预期改善是重启后仍能准确看到每次请求自己的结果,重复旧事件不会改变新请求。本次已复验原恢复问题修好,但独立真实 CLI 探针证明旧事件仍会让新请求虚假完成,因此不能批准当前版本。
本 PR 不授权额外启动子任务,不扩张其他代理的权限,不让宿主完成自动等于父任务验收;本次评审也没有启动付费模型、合并代码或关闭整个交付目标。
REQUEST_CHANGES:旧的 followup 恢复问题已修,但旧 spawn 重放会把后来仍在运行的 followup 错记完成。评审完整28文件、精确 head 43db8d0;没有继承旧 head 的批准或把作者修复声明当验证。
#5051 的目标是让真实宿主调用形成可恢复、可区分来源的回执,配置上限不代表启动数,host 完成不等于父任务采纳。修改前 spec_ref=docs/integrations/host-native-child-receipts.md,spec_revision=5e889bdcba9cea101a8775340a12629eb5a2474a,原 Lifecycle criterion_id 逐项:1. 精确 Turn/准入 implemented;2. 稳定 decision identity implemented,旧计数器碰撞回归通过;3. 操作自己的 result not_met;4. 同身份/内容重放幂等 not_met;5. 迟到事实不重开 Turn implemented。3/4 的反例如下,不是依据本 PR 新增“最新操作”文字倒推期望。
改动思路
位置选择合理:内置 Codex provider 在自身 CLI/app-server 连接观察原生事件,复用 multi_subagent 的同一 durable event log、TS admission 和 shared projection。不创建第二 child registry,不从配置或 prose 推测执行,不赋予 peer/子代理写入权。Python 只适配宿主字段/transport,generic phase 与 admission 留在已有 TS owner。
删除 transient children map、持久化 compact hashed child relation,能正确恢复只收到新 wait 的 followup;CLI 用 journal durable attempt,app-server 用 native Turn identity,保留不同进程 item_0 的区分和同绑定精确重放。问题是“最新关联”只适合恢复真正新 wait 的目标,不应覆写一个已具有稳定 decision identity 的旧 spawn/followup snapshot。保留当前已有 owner、给非 wait 结果使用自身 operation,是更小且更容易回滚的修复。
具体改动
修改前规范:docs/integrations/host-native-child-receipts.md,修订 5e889bd。逐项映射:1. → implemented;2. → implemented;3. → not_met;4. → not_met;5. → implemented。
完整28文件 +781/-58:146行 built-in transport adapter、74行原 receipt 扩展、CLI/operation-host/Chat/executor 接线、TS context、JSON/Markdown/Lark display 与 Goal drawer/schema/双语 provenance,以及301行 native regression、浏览器 fixture 和共享验证修正。无新增 scheduler、provider 调用、capability switch 或父任务自动验收。transport adapter 移至 extensions 的 built-in provider 位置有明确理由;不是给 Python 再造 decision owner。
关键代码讲解
- CodexNativeChildObserver._restore_operation(loopx/extensions/codex_native_child.py:60):从完整 canonical event 顺序恢复同 Goal/agent/Turn 的合法 host-observed spawn/followup,跨显示窗口、不采纳 coordinator report;旧恢复缺陷在当前源独立通过。
- observe(同文件:127):非 wait 分支已有稳定 operation_id,但处理 agents_states 时无条件再取最新 child operation。这把旧 decision 的结果挂到未来 followup,违反精确重放语义。
- _record_native_child(native_child_receipts.py:294):scalar hashed correlation 仅允许 started host decision;不存原 prompt/result,不把观察改成 parent review。现有 conflict 检查应保留,不能吞异常或覆盖旧结果来隐藏错账。
- run_codex_cli_host(codex_cli.py:931):真实 stdout 和 session 入口绑定 durable attempt,再经原 admission 写回;未启用不创建 observer。executor 先持久化 attempt,真正重试才递增;app-server sender/Turn 过滤沿原 owner。
共享 archive 4行变化独立复用 syncAuthorityDirectory,保留 file fsync 与非替换发布,属于明确的无条件 Windows 兼容修复,不是 multi_subagent opt-in 效果。其作者 Windows/PostgreSQL 验证声明已读,本轮没有冒称实际跑过对应平台/数据库。其余 fixture 修正保留 canonical ownership、420预算和 revision-before-write,未改生产阈值来掩盖错误。
对主干的风险
P1:旧 spawn 的完成快照让当前 followup 虚假完成。 独立三次真实 production CLI 调用:第一次 spawn(child) 且 completed;第二次 send_input(child) 且 running;第三次仅重放第一次同身份同内容的 completed-spawn item,没有新 wait、更没有 followup terminal。当前 canonical readback 的 spawn 和 followup 均为 completed;不可变旧14890源在同一 fixture 保留 followup pending。三个父结果均正常返回,零 parent acceptance、零 quota,故这是 result attribution 回归,不是 launch 计数/权限问题。
对应 :127–132 对任意 snapshot 取 latest operation。新增 test_real_cli_old_spawn_replay_does_not_replace_a_later_followup 断言所有结果 completed,恰好把错误输出写成了正确期望;测试应先独立表达“旧结果不能证明未来任务完成”。最小修复是非 wait terminal 绑定自身稳定操作,真正新 wait 才按合法持久关联恢复,并断言 followup 在自己的新 terminal 前始终 pending;保留 duplicate/conflict 保护,不抹掉原 spawn。
本轮204项 native/真实CLI/Chat/executor/replan 和37项共享 fixture 通过(此选集无 skips),38项 TS context/admission 通过,Ruff、mypy19源、control-plane typecheck、advisory后 full semantic smoke 通过。独立三案例 oracle 当前1 failed/2 passed:旧重放失败、连续同 child followup completed/failed 与 off 分支通过。旧14890校正后的同一 oracle2 passed/1 failed:重放不误完成,旧连续 followup 结果冲突仍失败。首次 reviewer oracle 直接访问缺失 result 得到 KeyError,已改为 get 后重跑;那次错误保留但不算产品证据。
Replay fixture SHA-256 b2895c208e9cb7f49cf1673faec718b56916c8c6b8165093607003c9129f01cb。完整 off 三调用 parent/error/activity 观察在旧源和当前源逐字段相同,fixture SHA-256 2198c25e994d7a0fd8d51c6196498752dfbecd5a47eef83cf06e80a593f74676,没有只比较计数或删诊断来制造 parity。实验用合成宿主协议,但走真实子进程 stdout/session/TS admission/事件后端;不冒称付费模型或 authenticated app-server。当前 packaged UI 未独立重跑,Ego Lite 原任务空间恢复失败;这不是“缺新授权/浏览器不可用”的泛化。作者 renderer fixture不能单独证明真实持久回执,也不替代实际平台 qualification。未查询、轮询或等待 GitHub CI。
typed-state/domain-neutrality/behavior disclosure/guidance/default-off/authority lenses 均核对:现有 provenance vocabulary 扩展合理,精确 host status mapping 不从错误 prose 推断 capacity;cap 是 ceiling,准入是强制规则不是 guidance;host observation 不授权下一次调用。完整 UI/app-server feature-off parity仍未全部资格化,保留不确定,绝不以 unit 计数推断全覆盖。
我的整体评价
REQUEST_CHANGES。原两项身份/恢复缺陷以及后来 followup 结果丢失均已独立确认修好,但新的 stale replay 回归仍在本切片 owning boundary,不能作为无关后续工作绕过。long_horizon 和 user_experience 均受错误持久结果影响。相关 future-facing refactor pass 认可 provider move 和去 transient map;剩余最有价值的小改动就是区分自身 decision terminal 与新 wait 的恢复关联,不需增加 framework、平行 store 或宽泛迁移。
保留已有 coordinator 历史与独立 parent review。当前没有 APPROVE,不撤销仍未解决的阻塞评审,不合并,也不关闭 #5051 的整体资格验收。
English verdict: REQUEST_CHANGES - HEAD 43db8d0. Prior followup recovery defects are fixed. Independently reproduced: replaying an old completed spawn falsely completes a later running followup. Production CLI/store transport with synthetic protocol; 204 native plus37 shared and38 typed tests pass, replay oracle1 failed/2passed. No paid-host, fresh packaged UI, approval or merge claim.
Goal and delivered boundary
Refs #5051. Enabled, owned Codex CLI/app-server Turns record native decisions and results through the existing
multi_subagentreceipt owner. CLI, Lark status and the dashboard Goal drawer distinguish host observations, coordinator reports, mixed provenance and unknown activity. Parent adoption remains independent.Review and CI repairs
loopx/extensions/codex_native_child.py; active callers use that provider seam. Typed admission/settlement retain authority. Architecture exceptions were not added.Qualification
Head:
43db8d07c140c499e432859e348a2f890a9f18dd. Base/merge base:12d60f13fe1fae6848e2bc806688f26031c8869a, PR basemain. All 13 commits carry DCO sign-off.Earlier authenticated native-host evidence retains its earlier source scope. No new paid host qualification was claimed. No private logs, sessions, credentials or local paths are included.
Remaining boundary
Feature-off preserves existing behavior. A Codex
faileditem does not identify a capacity subtype; unobserved external hosts remain unknown/coordinator-reported. This is the owned-host observation slice, not overall multi-host lifecycle completion. The CLI output-budget regression smoke passed on both the same latest base and this head; no budget changed. Hosted CI and maintainer re-review/merge remain required.