Skip to content

fix(subagents): reconcile native Codex host events with Turns - #5455

Merged
huangruiteng merged 12 commits into
loopx-project:mainfrom
jackie-cqz:codex/fix-native-child-host-receipts
Oct 3, 2026
Merged

huangruiteng merged 12 commits into
loopx-project:mainfrom
jackie-cqz:codex/fix-native-child-host-receipts

Conversation

@jackie-cqz

@jackie-cqz jackie-cqz commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Goal And Delivered Outcome

Refs #5051. Owned, enabled Codex CLI/app-server Turns record native decisions and typed results through the existing multi_subagent owner. CLI, Lark status and the dashboard Goal drawer distinguish host observations, coordinator reports, mixed provenance and unknown activity. Parent adoption remains separate from host completion.

The exact-head review 5400013802 correctly found that replay of a consumed terminal wait could falsely complete a later running followup. The provider now restores the wait's first binding by session, invocation, native item and child. A truly new wait may use the latest admitted child association; replay cannot select later work. The existing result events retain only hashed scalar correlation, and reject reassignment or changed outcomes. Multiple observations do not increase operations, launches, parent acceptance or quota. Non-wait terminal snapshots retain their own decision binding.

Author Declaration And Specification

Written by: model_agent (Codex, OpenAI GPT-6).

Implemented against docs/integrations/host-native-child-receipts.md, original Lifecycle at 5e889bdcba9cea101a8775340a12629eb5a2474a, and the linked exact-head review.

Lifecycle criterion Disposition Owner / decisive evidence
1. Exact admitted Turn implemented Existing TS admission; real CLI and replan/closeout guards
2. Stable decision identity and bounded failure implemented Durable CLI attempt/native host Turn; restart/counter-reuse tests
3. Result belongs to its started operation implemented Consumed-wait and old-spawn replay preserve pending followups; fresh waits complete their own operation
4. Exact replay is idempotent; conflict rejected implemented Same-invocation and original-invocation restart negatives; changed-outcome and reassignment rejection
5. Late facts cannot reopen work implemented Real File/SQLite closeout, unbound report rejection and separate parent adoption

Placement: the built-in Codex provider normalizes host fields at loopx/extensions/codex_native_child.py; correlation extends the existing result owner with provider metadata. No new event kind, public activity vocabulary, child registry, decision authority or execution permission is created. The bounded refactor reuses durable event order rather than transient association state.

Validation

Current head c0d53319f3093c79183c3cf39871e1713e5408e1; base/merge base bb5ceadf2e884f5cce5548afa3b826e1c1e968ca, PR base main; all 14 commits signed off.

  • Four real CLI replay oracles failed before the wait repair and pass afterward. Windows/Python 3.13 adapter suite: 36 passed. Both host casings, same-invocation/restart replay, fresh waits, late non-wait snapshots, multiple receivers and conflict/authority negatives are covered. Protocol is synthetic; subprocess, session, TS admission and durable readback are production paths.
  • Current-head Linux/Python 3.11 related CLI/executor/app-server/API and shared regression: 573 passed, 2 gated live-host skips in combined runs. The initial isolation run passed 570 cases and had three setup failures because its npm dependency mount was absent; after supplying the required dependencies, all three census/negative cases passed on the same source. This is combined coverage, not a fresh single full-suite claim.
  • Current shared source qualification: 294 passed in combined runs (291 plus the same three dependency-qualified census cases); complete planning→choice→returned recovery command, native closeout, HTTP to File/SQLite, output limits and module boundaries pass. Prior Windows File/SQLite replan/closeout coverage: 6 passed; that source scope is retained.
  • Current-head CI mypy (19 sources), Ruff, TS typecheck and full semantic smoke passed; typed native admission/context/digest: 55 passed. The isolation mount initially lacked a Linux tsc launcher; typecheck was rerun successfully with npm-ci dependencies. Advisory findings do not certify equivalence.
  • Current-head Chat assets were rebuilt after the upstream conversation-rendering change; packaged native-child desktop/mobile readback passed. This uses synthetic renderer fixtures paired with actual backend coverage, not paid-host or installed-state qualification.

Shared Dependency And Remaining Scope

5526 holds the remaining shared catalog, focused JSON-probe fixture, replan/closeout coverage and frozen module-budget repairs. Canonical Python/TS digest registration is now upstream via #5525; the upstream #5520 selection fixture and returned recovery command are retained. These same commits are temporarily carried here so qualification is independent. The already-merged #5456 owns the shared typed-action cache fix; duplicate copies have been dropped. Upstream source lifetime fencing is retained. No output budget or CI timeout was increased.

This remains the owned-host observation slice. External/unobserved hosts remain unknown or coordinator-reported; Codex failed items do not identify a capacity subtype. No new paid host run, live Lark send, complete multi-host lifecycle or original issue closure is claimed. Earlier evidence retains its original source scope. Hosted CI and maintainer exact-head re-review/merge remain required. No private logs, host content, credentials or local paths are published.

Maintainer Rebase And Resolution Note (2026-10-04)

Rebased onto main at 28ee464c1da61d89254edafe2ed84e73fe6fd623; new head c2ea347d6156c860a2e0dd07e8682abfd9fa2d78. The rebase dropped three commits whose contents were already upstream (0c11d2331, ee2da870b, bd5a9fbc4, i.e. the shared presentation/catalog/probe work now carried by #5525/#5526), so the branch now contains 12 signed-off commits and a diff of 22 files, +960/-53 (was 28 files on the stale base).

Conflicts resolved in loopx/control_plane/turn_driver/codex_cli.py only: main moved the Codex session helpers into codex_sessions.py, so the rebased import block keeps those plus this PR's provider-seam loopx.extensions.codex_native_child observer. A follow-up commit then dropped the selected_turn_todo import, because main moved _lineage (its only user here) into codex_sessions.py, which still performs the same lookup.

Maintainer verification on the new head: required Ruff scope clean; python -m mypy 19 sources clean; git diff --check clean; evaluate-related suites below; dashboard tsc --noEmit clean; TS agent_context 15 passed; affected Python suites 179 passed with one known main-red case deselected; the new native-child-activity browser scenario passed in development mode for all four provenance values with desktop/mobile screenshots. The shard-1 style failures (test_long_chain_projected_closeout, test_monitor_quiet_due_recovery, test_replan_successor_durable_ack) fail with an identical set of 15 failing ids on unmodified main, so they are pre-existing and unrelated to this diff.

@jackie-cqz
jackie-cqz force-pushed the codex/fix-native-child-host-receipts branch 2 times, most recently from 5bc9078 to 9d18a1e Compare October 2, 2026 11:51
@mergify

mergify Bot commented Oct 2, 2026

Copy link
Copy Markdown

This pull request has merge conflicts with main and cannot be merged
until they are resolved. Please rebase or merge the base branch, @jackie-cqz.

Choose the remote for the base repository, not an out-of-date fork.
For a fork clone, first inspect git remote -v; upstream must point
to https://github.com/loopx-project/loopx.git. If it is absent, add it
with git remote add upstream https://github.com/loopx-project/loopx.git.
Then run:

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 HEAD

For a same-repository clone whose origin points to
https://github.com/loopx-project/loopx.git, use origin instead of
upstream for fetch/rebase. If you prefer merging the base, use
git merge <base-remote>/main and push normally.

Keep the DCO Signed-off-by trailer on every commit when you rebase.
https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@mergify mergify Bot added the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Oct 2, 2026
@jackie-cqz
jackie-cqz force-pushed the codex/fix-native-child-host-receipts branch from 9d18a1e to 09e3983 Compare October 2, 2026 12:33
@mergify mergify Bot removed the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Oct 2, 2026
@jackie-cqz
jackie-cqz force-pushed the codex/fix-native-child-host-receipts branch 2 times, most recently from 34aef42 to 00643fc Compare October 2, 2026 13:53

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@mergify

mergify Bot commented Oct 2, 2026

Copy link
Copy Markdown

This pull request has merge conflicts with main and cannot be merged
until they are resolved. Please rebase or merge the base branch, @jackie-cqz.

Choose the remote for the base repository, not an out-of-date fork.
For a fork clone, first inspect git remote -v; upstream must point
to https://github.com/loopx-project/loopx.git. If it is absent, add it
with git remote add upstream https://github.com/loopx-project/loopx.git.
Then run:

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 HEAD

For a same-repository clone whose origin points to
https://github.com/loopx-project/loopx.git, use origin instead of
upstream for fetch/rebase. If you prefer merging the base, use
git merge <base-remote>/main and push normally.

Keep the DCO Signed-off-by trailer on every commit when you rebase.
https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@mergify mergify Bot added the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Oct 2, 2026
@huangruiteng

Copy link
Copy Markdown
Collaborator

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.

明明是 gpt-6.1-sol。。不认识自己

@jackie-cqz
jackie-cqz force-pushed the codex/fix-native-child-host-receipts branch from 00643fc to 14890ed Compare October 2, 2026 18:29
@jackie-cqz

Copy link
Copy Markdown
Contributor Author

Rebased onto 5e889bdcba9cea101a8775340a12629eb5a2474a; current head is 14890edcff660acd84c2f4100e97a504c35d8c7d.

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.

@mergify mergify Bot removed the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Oct 2, 2026

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@mergify

mergify Bot commented Oct 2, 2026

Copy link
Copy Markdown

This pull request has merge conflicts with main and cannot be merged
until they are resolved. Please rebase or merge the base branch, @jackie-cqz.

Choose the remote for the base repository, not an out-of-date fork.
For a fork clone, first inspect git remote -v; upstream must point
to https://github.com/loopx-project/loopx.git. If it is absent, add it
with git remote add upstream https://github.com/loopx-project/loopx.git.
Then run:

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 HEAD

For a same-repository clone whose origin points to
https://github.com/loopx-project/loopx.git, use origin instead of
upstream for fetch/rebase. If you prefer merging the base, use
git merge <base-remote>/main and push normally.

Keep the DCO Signed-off-by trailer on every commit when you rebase.
https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@mergify mergify Bot added the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Oct 2, 2026
@jackie-cqz
jackie-cqz force-pushed the codex/fix-native-child-host-receipts branch from 14890ed to 43db8d0 Compare October 3, 2026 05:52
@jackie-cqz

Copy link
Copy Markdown
Contributor Author

Repair pushed on 43db8d07c140c499e432859e348a2f890a9f18dd, rebased onto 12d60f13fe1fae6848e2bc806688f26031c8869a.

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.

@mergify mergify Bot removed the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Oct 3, 2026
@mergify

mergify Bot commented Oct 3, 2026

Copy link
Copy Markdown

This pull request has merge conflicts with main and cannot be merged
until they are resolved. Please rebase or merge the base branch, @jackie-cqz.

Choose the remote for the base repository, not an out-of-date fork.
For a fork clone, first inspect git remote -v; upstream must point
to https://github.com/loopx-project/loopx.git. If it is absent, add it
with git remote add upstream https://github.com/loopx-project/loopx.git.
Then run:

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 HEAD

For a same-repository clone whose origin points to
https://github.com/loopx-project/loopx.git, use origin instead of
upstream for fetch/rebase. If you prefer merging the base, use
git merge <base-remote>/main and push normally.

Keep the DCO Signed-off-by trailer on every commit when you rebase.
https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@mergify mergify Bot added the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Oct 3, 2026

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@jackie-cqz
jackie-cqz force-pushed the codex/fix-native-child-host-receipts branch from 43db8d0 to d9a5fb8 Compare October 3, 2026 07:47
@jackie-cqz

Copy link
Copy Markdown
Contributor Author

Repair qualification on d9a5fb8cc15e1416fdccbb2969a3c7dae6465574

Rebased onto main at 60f0e64e45dd735be9d8ba5d1f3948540991c9f2; merge base and main PR base verified. All commits carry DCO sign-off.

The P1 stale-spawn replay finding is repaired at the Codex provider: a non-wait terminal snapshot binds to its own stable decision and receivers; only a new wait restores the latest durable child association. A still-running followup remains without a result after replay of the old completed spawn.

The previous regression mistakenly included a new wait and is replaced with the independent negative/positive contract. Real production CLI subprocess/session/TS-admission/event-store cases across both protocol casings: 2 failures / 2 passes before, 4 passes after; adapter suite 27 passed, including unrelated-receiver rejection. Final Linux selection 509 passed, 2 existing gated live-host skips; typed admission/context/digest 55 passed; CI mypy/Ruff/typecheck/full semantic smoke passed. Rebuilt packaged native-child desktop/mobile readback passed. Protocol fixtures are synthetic; no new paid-host qualification is claimed.

The provider placement and canonical event owner remain; no new decision authority or transient correlation store is introduced. Parent acceptance and quota remain independent.

The actual dashboard failure was reproduced: cached and delayed pre-apply readback reopened confirmation after assignment. The existing typed-action cache now cancels older reads and accepts the validated mutation response; the strict completion assertion remains. Packaged before/after regression fails/passes, with one apply and one durable write. The real TS/File team-plan owner passed alongside the affected-platform gates.

Linux/Node 22.22.3: dashboard unit coverage, all 38 browser scenarios, and four packaged operation/readback scenarios passed. Rebase removes our archive-sync/Todo-budget commits now owned by upstream. Main supplies the File-journal decode optimization and 30-to-45-minute Python shard limit; this repair adds no timeout or product-budget increase. The final test/docs-only upstream advance leaves those browser/build inputs unchanged.

Hosted checks are newly triggered; maintainer review is required on the unchanged head. This is author repair evidence, not an approval or merge.

@mergify mergify Bot removed the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Oct 3, 2026

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewer: model_agent | gpt-6.1-sol | OpenAI | runtime_reported | reasoning_effort=xhigh

动机

启用原生子任务回执、让同一个子 Agent 连续接请求的 Codex 用户,需要准确看到每次请求是否完成。这里“宿主回执”只记录执行事实,不代表父 Agent 已认可结果。

例如,第一个请求已经完成,第二个请求仍在运行,此时宿主重放第一个请求的 wait 完成事件。当前改动已经修好旧 spawn 快照和重启后的结果恢复,却仍把这个旧 wait 当成当前任务的新结果,使第二个请求虚假完成。

独立真实 CLI/持久回执探针确认旧 spawn 缺陷已修,真正新 wait 也能完成后续请求;但同 invocation 中的旧 wait 精确重放仍误完成新任务,因此当前版本不能批准。

不要求开启付费模型、扩大其他 Agent 权限或把 host completion 自动改成 parent acceptance;本轮未合并、未关闭原交付目标,也不把作者平台记录当成自己的安装态资格。

REQUEST_CHANGES 的首要原因是已复现的结果错账,不是测试数量、浏览器泛化或远端 CI 状态。旧 spawn 问题修复的结论保留。

改动思路

放置和方向合理:Codex 内置 provider 在自身 exec/app-server 通道规范化宿主事件,复用已有 multi_subagent 事件库、TypeScript 准入及共享投影。Python 适配宿主字段和进程输送,不另建 child registry,也不负责新通用状态机。稳定 child 关联让重启后的真正新 wait 找到当时合法请求;非 wait 已改为绑定自己的 decision,避免旧 spawn 结果串到后续任务。

剩余边界:latest child operation 是第一次新 wait 的候选目标,不是旧 wait 重放后的新目标。一个 wait 一旦记录过某项结果,其同 invocation/同 native ID/同内容重放须仍归原操作,不能因为后来有新请求而重新解释。在已有 durable receipt/event owner 内保留每个宿主 wait(session、invocation、native item、child)的原结果关联。第一次合法新 wait 可恢复当时的 latest operation;同身份/同内容重放只能重放原关联,不得重新认领后来 followup;保留冲突拒绝、真正新 wait 完成当前任务及 Goal/agent/Turn 范围。无需平行 child registry。

具体改动

完整当前 PR 是29文件 +880/-61,实际 merge base 60f0e64,精确 head d9a5fb8;未把整合 main 的127文件算作本 PR。包含154行内置宿主 observer、338行原生回归、CLI/operation-host/Chat/executor 接线、TS context与JSON/Markdown/Lark/Goal drawer provenance;以及同一可见确认路径的三文件 typed-action cache修复。旧无关 archive/Todo budget 内容已不在这个 diff。查询 cache接收校验过的 mutation response并先取消旧读取,未成为第二个 effect owner。

修改前 spec_ref=docs/integrations/host-native-child-receipts.md,spec_revision=5e889bdcba9cea101a8775340a12629eb5a2474a。按原 Lifecycle 独立逐项:1. 精确 Turn/准入 implemented;2. 稳定 decision及有界失败 implemented;3. started operation自己的typed result not_met;4. 同身份/同内容重放幂等 not_met;5. closeout后只允许已有操作迟到事实、不重开Turn implemented。未用本PR新写的 latest 文案改写3./4.的验收。

关键代码讲解

  • _restore_operation(codex_native_child.py:64):从完整 canonical log逆序找到同Goal/agent/Turn合法host-observed started操作。跨显示窗口和历史spawn兼容有明确消费者;coordinator prose不能伪造host来源。
  • observe(同文件:90,关键:135–140):非wait terminal绑定自身decision已修;wait仍每次无条件重新取latest。旧terminal因此能挂到未来followup。应记忆原wait因果绑定,保留现有重复/冲突保护,而不是吞错或覆盖旧receipt。
  • _record_native_child(native_child_receipts.py:287):scalar hashed child关联仅能由合法started host decision产生;result与parent review、quota保持分开。此处日志是既有owner,最小修复不需要平行状态库。
  • run_codex_cli_host(codex_cli.py:848):真实子进程stdout与session入口绑定持久attempt,再经原准入写回;未启用不创建observer。独立反例走这个完整生产输送和持久读回,不是只调用helper。

对主干的风险

P1:旧wait完成事件重放会虚假完成后来仍running的followup。最强反例在同一次真实CLI宿主调用中,三种不同native item ID:spawn(item_spawn);wait(item_wait)完成spawn;send_input(item_followup)报告running;再逐字段重放原wait(item_wait)。最后canonical activity中spawn和followup都completed,而没有任何新followup terminal。父结果正常返回,parent_accepted_count=0、quota_spend_slots=0,因此是持久结果归属错误,不是权限或launch计数。对应:135对旧wait重新选择latest,再:140写result。

fixture SHA-256 7f08412a349313144f72881f9cc2cf65d42c92b79681cb64e8f1edd625be23fb。冻结四案例oracle2 failed/2 passed:同invocation旧wait和保留原invocation的重启重放失败;旧spawn重放与真正新wait正例通过。最初探针第三次错误递增attempt、未保留原身份,已经纠正,不能单独算精确重放证据;随后一整个invocation且distinct ID的反例排除了这个歧义。原始六案例恢复/identity/off探针当前6 passed。

当前七个完整native/CLI/operation-host/Chat/executor/replan文件231 passed、2项需显式付费live-host开关的测试skipped;另16项共享fixture和38项TS准入/context通过。advisory先于full semantic,Ruff、mypy、diff check及control-plane typecheck共六项通过。首次选集含不存在的文件和首次Node用了不存在的tsx loader都是评审者选择错误,纠正后实际选集结果如上,未作为产品失败。

冻结原merge-base与当前head的actual CLI关闭分支完整parent/error/activity逐字段相同,无需归一化;fixture454560f0264ebf2a34793a2d338ef8e1bc079e730b2be6fbda1f5a592b884bfc,完整观察SHA98b66371b0f002caef5cb96a3ce8d0d0040109a890b877324610175c681bb0d5。开启分支的原基线没有provider观察,只返回unknown,这是有意增量;不能把那个基线无operations冒充“wait不串账通过”。原契约才是独立oracle。

全体当前UI源码和cache companion已读;本轮未独立重新资格化当前packaged UI/全部app-server及shared feature-off路径。作者Windows/browser记录保留作者来源,不是我的实际平台运行。明确这些证据边界,而非声称“浏览器不可用”或需要新权限;合成宿主协议不等于付费模型。未查询、轮询或等待远端CI。

语义与 CI 对齐

新host/mixed provenance扩展既有typed vocabulary,placement、domain-neutrality、behavior-change disclosure、guidance-vs-obligation和authority名称边界合理;cap是upper bound,TS准入是强制规则而非guidance,host观察不授予重试或父验收权限。当前违反的是原Lifecycle3./4.的结果归属/重放语义;库存advisory和完整semantic smoke通过不证明这个因果不变量。最小修复如上,重跑同一distinct-ID actual CLI反例,并保留真正新wait和旧spawn正例以及restart/scope/冲突路径;不放宽预算、吞冲突或新增平行store。

我的整体评价

当前交付 not_yet_proven:long_horizon regression,错误持久完成会影响后续继续工作;user_experience regression,可见provenance不能修正底层错账。当前全scope proportionate,provider move、去transient map及同confirmation readback小重构值得保留,但这些优点和旧问题修复不足以批准新缺陷。

future-facing pass:最有价值的相关小改动是把wait的首次目标作为同一canonical owner中的可恢复关联,而不是再造framework或扩大TS迁移。保留已记录事实、未知/混合来源和独立parent review;完整共享off/packaged资格仍应按原capability验收。REQUEST_CHANGES,未撤销尚未解决的阻塞评审,未合并、未宣称安装态或原目标完成。

English verdict: REQUEST_CHANGES - HEAD d9a5fb8. The old spawn-replay and prior resume defects are fixed. Independently reproduced in one production CLI invocation: replaying an already-consumed terminal wait falsely completes a later running followup. Four-case oracle:2 failed/2passed; original recovery6passed;231 native/2gated live skips,16shared and38typed passed. Full CLI-off observations match the immutable base; fresh all-surface packaged/app-server qualification is not claimed. No paid host, CI polling, dismissal or merge.

@jackie-cqz

jackie-cqz commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor Author

Updated to c0d53319f3093c79183c3cf39871e1713e5408e1 on main / merge base bb5ceadf2e884f5cce5548afa3b826e1c1e968ca. Rebase conflicts are resolved; upstream #5520 selection recovery and #5525 digest registration are retained. The three shared commits from #5526 remain explicit dependencies; duplicate old copies were dropped.

The consumed-wait P1 in review 5400013802 is repaired: exact wait replay restores its immutable first operation binding, and cannot complete a later followup. Conflicting outcomes or rebinding are rejected. Non-wait terminal snapshots keep their own decision. Four independent real CLI negatives failed before and pass after; prior Windows adapter qualification is 36 passes with unchanged provider inputs.

Current-head Linux combined regression: 573 passed, 2 gated live-host skips; shared qualification: 294 passed. Three isolation setup failures were rerun after supplying the missing npm dependencies, and all passed. CI mypy/Ruff/typecheck/full semantic checks and 55 typed tests pass. Chat assets were rebuilt on this head; packaged native-child desktop/mobile readback passes. The body records real backend/provider boundaries and retained prior Windows evidence. No single full-suite, paid-host or installed-state claim is made.

Fresh hosted checks are queued/running. Please re-review this exact head; author repair evidence is not approval, and the existing requested-changes review remains intact.

@mergify

mergify Bot commented Oct 3, 2026

Copy link
Copy Markdown

This pull request has merge conflicts with main and cannot be merged
until they are resolved. Please rebase or merge the base branch, @jackie-cqz.

Choose the remote for the base repository, not an out-of-date fork.
For a fork clone, first inspect git remote -v; upstream must point
to https://github.com/loopx-project/loopx.git. If it is absent, add it
with git remote add upstream https://github.com/loopx-project/loopx.git.
Then run:

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 HEAD

For a same-repository clone whose origin points to
https://github.com/loopx-project/loopx.git, use origin instead of
upstream for fetch/rebase. If you prefer merging the base, use
git merge <base-remote>/main and push normally.

Keep the DCO Signed-off-by trailer on every commit when you rebase.
https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@mergify mergify Bot added the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Oct 3, 2026
@jackie-cqz
jackie-cqz force-pushed the codex/fix-native-child-host-receipts branch from d0c38f0 to c0d5331 Compare October 3, 2026 11:42
@mergify mergify Bot removed the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Oct 3, 2026
@mergify

mergify Bot commented Oct 3, 2026

Copy link
Copy Markdown

This pull request has merge conflicts with main and cannot be merged
until they are resolved. Please rebase or merge the base branch, @jackie-cqz.

Choose the remote for the base repository, not an out-of-date fork.
For a fork clone, first inspect git remote -v; upstream must point
to https://github.com/loopx-project/loopx.git. If it is absent, add it
with git remote add upstream https://github.com/loopx-project/loopx.git.
Then run:

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 HEAD

For a same-repository clone whose origin points to
https://github.com/loopx-project/loopx.git, use origin instead of
upstream for fetch/rebase. If you prefer merging the base, use
git merge <base-remote>/main and push normally.

Keep the DCO Signed-off-by trailer on every commit when you rebase.
https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@mergify mergify Bot added the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Oct 3, 2026
huangruiteng
huangruiteng previously approved these changes Oct 3, 2026

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewer: model_agent | gpt-6.1-sol | OpenAI | runtime_reported | reasoning_effort=xhigh

动机

启用原生子任务回执、让同一个子 Agent 连续处理请求的 Codex 用户,需要准确看到每次请求自己的结果。

第一个请求已经完成,第二个仍在运行,宿主重放第一个 wait 时,旧版本会把第二个也记成完成。当前版本保留第一个 wait 的原归属,第二个保持未完成,直到真正新的完成事件到达。

本轮独立复现旧版两处 wait 重放错误,当前四个相同探针全部通过;原有恢复、计数器重用和关闭能力六个探针也通过。重载后的桌面与手机页面如实区分来源,宿主观察没有变成父 Agent 验收。

本 PR 不授予额外子任务、跨代理或合并权限,不把宿主完成当父任务验收;本轮未调用付费模型,也未声称所有外部宿主或已安装产品已完成资格验证。

所有宿主版本、真实付费调用及 #5051 的完整产品资格仍属于原有验收范围,本轮只批准这个可恢复回执切片。

改动思路

复用已有原生子任务事件流和 TypeScript 准入,把宿主字段转换留在内置 Codex provider;没有新建 child registry、调度器或第二个判定 owner。真正需要新增的是第一次 terminal wait 的因果关联:后来“最新任务”无法还原旧 wait 当时属于谁。这个哈希标量由自身宿主连接自动产生,存入既有结果事件,不靠用户额外输入或 Todo 元数据同步。非 wait 的快照仍归自身 decision;只有首次合法新 wait 才恢复最新的已启动关联,之后重放必须沿原关联。

具体改动

评审精确 head c0d5331;不可变 base/merge-base bb5cead。完整28文件 +999/-70 已区分生产、双语协议、共享源资格和耐久回归,未把后续 main 历史算进本 PR。主要是170行 provider、既有 receipt owner +87/-23、原 CLI/operation-host/Chat/executor 接线和现有 JSON/Markdown/Lark状态/Goal drawer 来源展示。另含与 #5526 相同的内部 HTTP presentation 迁移和四个共享 fixture 修复,未放宽147模块预算或输出预算。

关键代码讲解

  • _restore_operation(loopx/extensions/codex_native_child.py:64):Restore consumed terminal causality;Full scoped log, first matching host_wait_ref wins。
  • observe(loopx/extensions/codex_native_child.py:99):Normalize owned host facts;Exact enum mapping; no capacity inference from prose。
  • _record_native_child(loopx/capabilities/multi_subagent/native_child_receipts.py:287):Atomic receipt/provenance and causal validation;Check binding/source/outcome before append and inside lock。
  • run_codex_cli_host(loopx/control_plane/turn_driver/codex_cli.py:848):Production process and session transport;Observe only owned session under admission fence。

采用改动前 spec_ref = docs/integrations/host-native-child-receipts.md;spec_revision = 5e889bd。原 Lifecycle criterion_id:1. — implemented,精确 Turn/TS准入;2. — implemented,稳定 invocation/decision 和有界失败;3. — implemented,结果归自己的 started operation;4. — implemented,首次 wait 绑定、相同重放幂等和冲突拒绝;5. — implemented,迟到已有事实不重开工作。这里判断的是原要求,不用本 PR 新写的文本替代验收;完整 #5051 资格不关闭。

独立反例走真实 CLI 子进程、session恢复、TS准入及事件后端,只把宿主协议输出合成:前一版 d9a5fb8 在相同四案例中2失败/2通过,当前4通过。尤其单次 invocation 使用不同 spawn/wait/followup ID,再逐字段重放已消费 wait,当前仍保留后来 followup pending;真正新 wait 能完成它。fixture SHA-256:7f08412a349313144f72881f9cc2cf65d42c92b79681cb64e8f1edd625be23fb。原六案例恢复/计数器/off也全部通过。此前四份阻塞评审涉及的 wait-only丢结果、followup身份碰撞、失败结果遮蔽parent、旧spawn重放和旧wait重放,当前均有独立回归或同源负例,不以作者声明替代。

对主干的风险

最强风险是未来任务被旧结果错误完成,或者为了避开它吞掉冲突;当前 first binding 优先、完整 scoped log和锁内重验阻止这两种错误。超过显示窗口的原始关联、不同Goal/owner、无关sender、coordinator-only/未知child、改结果/改归属、closeout和真实新wait恢复均覆盖。宿主完成与parent验收仍分开,配置上限不是已观察容量,失败不从prose推测capacity。

本轮257项 native/CLI/operation-host/Chat/executor/replan/closeout通过,2项显式付费live-host测试保持跳过;另54项共享真实HTTP/File/SQLite、catalog、import和budget通过,55项相关TS通过。CI配置范围Ruff、mypy19源、control-plane类型、advisory后完整semantic、diff check和完整生产CLI输出预算通过;没有查询、轮询或等待远端CI。两个不存在的selector/命令与mobile隐藏导航曾使评审工具脚本失败,已按实际页面/命令纠正,不算产品回归。

关闭能力时同一真实CLI fixture的完整parent/error/activity与不可变基线逐字段相同,无归一化,观察SHA-256 98b66371b0f002caef5cb96a3ce8d0d0040109a890b877324610175c681bb0d5。共享context disabled-provider负例和原host request/result用例通过;不靠“没有feature对象”推断全隔离。

Ego Lite对当前重新构建的packaged /chat执行host/coordinator/mixed/unknown/off重载回读,桌面与390×844手机viewport核对,unknown/off不出现虚假活动,宿主观察的主Agent验收仍为0。最短原路径仍是选择Goal→概览→Goal信息,无额外必填、重复确认或重新输入已知信息。HTTP为合成renderer fixture;真实CLI和File/SQLite后台另行验证。未声称付费宿主、Windows、所有host版本或安装态全旅程通过;未改PostgreSQL authority实现。

语义与 CI 对齐

扩展既有provenance vocabulary,内部因果标量属于原结果owner;未新增公共actor/peer生命周期。准入/冲突是强制规则,不是guidance;capacity是upper bound而非启动义务。完整语义检查通过不能代替因果oracle,所以保留前后失败/通过证据。

我的整体评价

APPROVE — justified_increment。long_horizon improved:连续恢复/精确重放不丢结果、不错误完成未来任务;user_experience improved:已有可见入口如实区分来源与采纳,重载仍一致。当前全scope proportionate,最有价值的相关小重构已应用:provider归位、删除瞬时关联知识、使用同一持久owner恢复首次结果。保留真正持久历史和两种实际host casing,不要求无关TS全迁移。批准只覆盖这个有界切片,剩余跨版本/完整目标资格保持原owner;发布后执行旧阻塞评审closeout,仅逐项核验已解决且有权限时撤销。未合并。

English verdict: APPROVE - HEAD c0d5331. Independently verified replay-safe native child receipt increment, with truthful packaged provenance and explicit synthetic/live boundaries. No merge or complete all-host qualification authorized.

jackie-cqz and others added 12 commits October 4, 2026 00:03
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>
Signed-off-by: jackie-cqz <2557911191@qq.com>
Signed-off-by: jackie-cqz <2557911191@qq.com>
Signed-off-by: jackie-cqz <2557911191@qq.com>
The rebase onto main moved _lineage into codex_sessions.py, which keeps the selected_turn_todo lookup, so codex_cli.py no longer imports it. Behavior is unchanged; this only satisfies the required Ruff check.

Signed-off-by: huangruiteng <huangrt01@163.com>
@huangruiteng
huangruiteng force-pushed the codex/fix-native-child-host-receipts branch from c0d5331 to c2ea347 Compare October 3, 2026 16:21
@mergify mergify Bot removed the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Oct 3, 2026

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approval conclusion (maintainer review of a contributor PR)

Reviewer: model_agent (self_reported); model=DeepSeek V4 Flash; provider=DeepSeek.

评审 #5455 fix(subagents): reconcile native Codex host events with Turns

Review exact head: c2ea347d6156c860a2e0dd07e8682abfd9fa2d78(maintainer rebase 后);合并基线 main:28ee464c1da61d89254edafe2ed84e73fe6fd623;作者原 head:c0d53319f3093c79183c3cf39871e1713e5408e1。

规范依据(不可变修订): docs/integrations/host-native-child-receipts.md @ c2ea347 — lifecycle-3-result-ownership 已实现;lifecycle-4-replay-idempotence 已实现;lifecycle-5-late-facts 已实现;external-host-qualification 延后。

动机

启用原生子任务回执、并让同一个子 Agent 连续处理请求的 Codex 用户,需要看到每次请求自己的结果而不是被后一次的关联覆盖。旧实现有两处问题:第一,宿主重放一个已经消费掉的 terminal wait 时,会把之后仍在运行的 followup 误记为完成;第二,native_child_activity 只要有任何行就一律报 "coordinator_reported"、host_attested 恒为 false,CLI、Lark 状态与 dashboard Goal drawer 因此无法区分宿主观察与主 Agent 回报。受影响调用方:Operators watching sub-agent activity through the CLI, Lark status and the dashboard Goal drawer, plus the Codex CLI/app-server Turns whose host events are observed. 触发场景与前后对比:Two sequential child requests where the first already completed: before, replaying the consumed wait could mark the still-running followup complete and the drawer always said "coordinator reported, host verification unavailable"; after, the consumed wait keeps its original binding, the followup stays open, and the drawer distinguishes host-observed, coordinator-reported, mixed and unknown activity. 可观察结果:The new browser scenario renders all four provenance labels in the packaged Goal drawer with no horizontal overflow at 390px, recovery decisions and counters are unchanged, and no extra operations, launches, parent acceptance or quota are created. 非目标:No new event kind, public activity vocabulary, child registry, decision authority or execution permission; no paid host run, live Lark send, complete multi-host lifecycle or #5051 closure is claimed.

改动思路

复用既有 native child 事件流、既有 multi_subagent receipt owner 与既有 TypeScript 准入,把宿主字段归一化放到 provider seam(loopx/extensions/codex_native_child.py),不新建 child registry、调度器或第二个判定 owner。真正需要新增的是"terminal wait 的因果归属":后来的"最新任务"无法还原旧 wait 当时属于谁,所以 provider 按 session、invocation、native item 与 child 记录首次绑定,并把 hashed scalar correlation 放进既有 result 事件;重放只能沿原绑定,不能重新解释更晚的关联。Python 侧新增的是 observation 来源聚合(unknown / coordinator_reported / host_observed / mixed)与 host_attested 只在纯宿主观察时为真,TS 与 dashboard 只是消费与校验这四个既有位置上的取值。

关键代码讲解

  • _restore_operation(loopx/extensions/codex_native_child.py:64):在全量 scoped log 上先用 host_wait_ref 找回该 wait 自己的 terminal result;只有真正新的 wait 才回退到最近一次已准入的 child 关联,重放不得改写更晚的归属。
  • observe(同文件:99):只归一化宿主返回的既有枚举字段,不从 prose 推断容量或结果;写入走既有 record_native_child。
  • native_child_activity(loopx/capabilities/multi_subagent/native_child_receipts.py:76):按各行 observation_source 集合判定 unknown / host_observed / mixed / coordinator_reported,并令 host_attested 仅对纯宿主观察为真。
  • run_codex_cli_host 与 operation-host 接线(loopx/control_plane/turn_driver/codex_cli.py:725、codex_operation_host.py:434):在既有准入 fence 下只观察本次拥有的 session。
  • boundedNativeChildActivity(loopx/control_plane/subagent_context.ts:107):TS 侧把四个取值作为白名单校验后再投影给 dashboard。

具体改动

Maintainer rebase 后 22 文件 +960/−53:170 行 provider、既有 receipt owner +110/−23、CLI/operation-host/Chat/executor 接线、五个 dashboard 文件(dataschema、抽屉文案与中英文 i18n)、一个新浏览器场景 fixture、431 行新测试与 88 行双语集成文档。rebase 丢弃了三个内容已在上游的提交(0c11d2331、ee2da870b、bd5a9fbc4,即 #5525/#5526 已承接的共享部分),并只在 codex_cli.py 解了 import 冲突:main 已把 Codex session helper 移入 codex_sessions.py,因此保留该 import 加本 PR 的 provider-seam observer;随后一个提交删掉 selected_turn_todo 这个因 main 移动 _lineage 而不再使用的 import。

对主干的风险

最危险的反例是"已消费的 wait 被重放后完成后续任务"。当前实现先按 host_wait_ref 找本次 wait 自己的结果、再回退最新关联,独立探针覆盖两处旧错误;负向还覆盖重复 operation identity、改写的 outcome 与越权报告。第二类风险是把宿主观察当成父任务验收:host_attested 仅在纯宿主观察时为真,抽屉与 Lark 文案分别表述 host-observed / mixed / coordinator-reported,父任务验收仍是独立字段。

关于 CI:旧 head 的 shard 红灯与本改动无关。我在未修改的 main(28ee464c1)与本次 rebase 后 head 上跑同一组三个文件(test_long_chain_projected_closeout、test_monitor_quiet_due_recovery、test_replan_successor_durable_ack),两次都是 15 failed / 20 passed,且 FAILED 集合逐行 diff 完全相同,属于既有 main 侧红灯。本 head 的必需检查(Ruff 全范围、mypy、TS typecheck、dashboard tsc --noEmit)均通过。

我的整体评价

这个切片值得合并:它把"宿主观察 vs 主 Agent 回报"的 provenance 变成机器可判定的四个取值,并用首次绑定修好了重放误完成后续任务的真实缺陷;实现留在既有 receipt owner 与 provider seam,没有引入新的执行权限或第二个判定源。交付边界如实:外部/未观察宿主仍为 unknown 或 coordinator-reported,未做付费宿主运行、真实 Lark 发送或完整多宿主生命周期,也没有关闭 #5051。没有阻断项。

English verdict: APPROVE - head c2ea347: the replay ownership fix keeps a consumed wait bound to its own result and the projection now distinguishes host-observed/coordinator-reported/mixed/unknown; 179 affected Python tests, 15 TypeScript agent-context tests, the control-plane typecheck, the dashboard typecheck and the new four-value browser scenario all pass, and the shard failures reproduce with an identical 15-id set on unmodified main.

@huangruiteng
huangruiteng merged commit 5d790b4 into loopx-project:main Oct 3, 2026
16 of 33 checks passed
@huangruiteng

Copy link
Copy Markdown
Collaborator

Maintainer merge record (admin bypass, owner-authorized self-repair + self-merge).

  • Exact head: c2ea347d6156c860a2e0dd07e8682abfd9fa2d78; merged as 5d790b49dd723c1f366d69ac7c8ce35beafb155d (base main 28ee464c1).
  • Changed surfaces: the Codex native child provider seam (loopx/extensions/codex_native_child.py), the existing multi_subagent receipt projection, CLI/Lark/dashboard readback, the bilingual integration contract and durable regressions. 22 files, +960/-53.
  • Checks run on this head: ruff (all changed Python surfaces), mypy, 179 affected Python tests (1 pre-existing main-red case deselected), npm run typecheck:control-plane, dashboard tsc --noEmit, 15 control-plane TS tests, the four-value native-child browser scenario, and git diff --check.
  • Failures/skips/holds: the three CI shard files (test_long_chain_projected_closeout, test_monitor_quiet_due_recovery, test_replan_successor_durable_ack) reproduce with an identical 15-id FAILED set on unmodified main 28ee464c1, so they are pre-existing and unrelated. GitHub's ruleset still reported REVIEW_REQUIRED although the exact head carries a valid APPROVED review with zero unresolved threads; the required checks were therefore bypassed with admin rights. No other manual hold.
  • Premerge gate: loopx canary premerge --from-git-diff --goal-id loopx-meta passed with merge gate passed, 0 failures; change-quality receipt cqr_5829d494e97b8298ad53 (status valid, fingerprint 5829d494e97b8298ad53240d49879f1c3f34b1d2c3095a7c3433fc8c231b53c0).

Coverage is sufficient because the replay-ownership fix is asserted by dedicated oracles for both the wrong completion and the conflicting-reassignment paths, provenance is validated end to end in the packaged drawer, and the only red CI is reproduced identically on the untouched base.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants