Repository navigation
Conversation
Use pinned OAR runtime/session/event controls for LoopX-owned execution, preserve Turn authority and native compatibility boundaries, and qualify installed packages, cancellation, process cleanup and host readback. Signed-off-by: song <liusongstep@gmail.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Signed-off-by: song <liusongstep@gmail.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e84e94e4b5
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const ownedGroups = new Set<number>(); | ||
| const observeDescendants = async () => { | ||
| if (!trackDescendants || !child.pid || child.exitCode !== null || child.signalCode !== null) return; | ||
| for (const group of await descendantProcessGroups(child.pid, child.pid)) ownedGroups.add(group); |
There was a problem hiding this comment.
Register detached groups before the OAR owner can exit
On POSIX, if the OAR process crashes or is killed before cleanup starts, its detached native runtimes escape supervision. observeDescendants() is called only from clean(), and this guard skips discovery once the leader has exited; ownedGroups therefore remains empty, yet cleanup reports descendant_cleanup_complete: true. I reproduced this with runHostProcess(..., {trackDescendants: true}): a leader spawned a detached worker and killed itself with SIGKILL, and supervision returned confirmed descendant cleanup while the worker remained alive. With the new OAR-backed hosts, that can leave native tools executing or consuming provider resources after the Turn fails. Register descendant ownership while the owner is alive, and do not confirm cleanup when that ownership cannot be established.
Useful? React with 👍 / 👎.
Remove the unused whole-stream session scanner and test-only failure wrapper. Exercise the production failure observer directly and install locked OAR dependencies in the optional runtime jobs that also qualify Codex Turns. Signed-off-by: song <liusongstep@gmail.com>
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent; model: GPT-6; provider: OpenAI; declaration_source: self_reported.
REQUEST_CHANGES — 请补足 managed host 维护成本的选型依据与可核对的收益,而不只证明 OAR 接入能够运行。
Reviewed head: fa76197cac2e08461a458f52bfe95ab8b25badef。这是针对本次宿主迁移的架构与可维护性变更请求;功能等价、完整运行成本及当前 CI 失败归因仍未由本次评审独立验证,不能据此认定功能已经通过验收。
动机 / Motivation
受影响的是维护 LoopX 多宿主执行的开发者,以及运行有界 Codex/DSH Turn 的操作员。接入前 Turn 已有共同的工作请求、验证和结算边界,但底层原生协议仍需分别适配。
例如,修改取消或原生终态处理时,维护者希望减少需要同步修改和回归的位置。本次改用共享运行库,预期应减少这类重复维护,并让操作员仍能可靠地完成原来的任务;目前源码证明了接入和部分旧传输替换,还没有证明完整维护成本下降。
请将“实际降低 LoopX managed host 的总维护成本”明确为本次迁移的目标之一,给出可复核的前后比较。Pi 新能力可以有独立价值;不要求本 PR 完成 controller 全部路线图,也不要求机械的净负代码行数。
改动思路 / Approach
LoopX Turn 继续决定准入、工作身份、独立验证与结算;OAR 负责适用范围内的原生会话、事件、控制和资源释放。这一职责方向可以成立。共享运行库可能减少一些维护,也可能把原来的维护变成事件翻译、跨进程协议、额外清理与依赖升级。但已有 Turn 统一协议,以及已经收敛的 operation/session 编排,都是可复用基础,不能再算作本 PR 新交付的精简收益。
当前 PR 边界应是:在既有 Turn/Core owner 之下交付可独立验证和回退的有界宿主替换;区分新能力、必要的原生差异与待退役的重复规则,以完整路径证明收益。
C3 已有共享实现,不应再造 BaseHost 或另一个 session 数据库。C4 的 receipt/continuation 与结算决策应继续复用原 owner。C7 需要核对 OAR dispose、DSH SDK 关闭和 OS supervisor 的不同责任后才合并清理机制。C9.2 应共享通用不变量和夹具,同时保留权限、隐私、原生恢复、身份和故障恢复负例。
以上是从源码得出的边界对照,不是执行证明:
| 路径 | 原有实现 | 当前实现及仍需承担的成本 |
|---|---|---|
| 有界 Codex | codex exec 与临时结果文件 | OAR Codex app-server,加 LoopX Python/Node 桥接 |
| 有界 DSH | Python 直接使用 SDK | Python → Node/OAR → Python SDK worker → DSH |
| operation 与丰富的原生 Chat | 专有原生适配器 | 因动态工具、历史注入和后台控制契约继续保留 |
| Pi | 已有宿主内插件 | 新增显式选择的有界 Turn;插件保留其同会话用途 |
具体改动 / Changes
R1 — [P2] 强制替换已有有界宿主前,补齐维护收益与迁移成本的证据
触发与位置: 原有有界 Codex/DSH 选择经 managed_executor_binding 的 uses_oar 分支依赖 OAR 就绪;现有选择即使没有改名,也新增了安装前提。参见 host_binding.py。
证据与影响: DSH 仍需本仓库维护自定义 OAR runtime 和 Python SDK worker;丰富的原生 Chat/operation 路径继续存在。现有集成测试通过不能单独回答完整维护成本的取舍。这里指出的是缺少收益证明,不是宣称 OAR 本身无价值或所有保留路径都重复。
需要的最小修改:
- 在现有 PR 说明或相关 RFC 中列出替换/退役表:旧入口及调用方、新 owner、删除的规则或分支、保留路径的实际契约;对过渡兼容注明退出条件。额外清理的 23 行只是局部清理,不能代替完整清单。
- 选一个真实的代表性变更,例如取消、超时或终态归类,比较前后实际要改哪些生产位置和契约测试。把复杂度转移给上游的部分,与 LoopX 仍自行维护的部分分开;不设预先编造的行数或百分比目标。
- 对已有 Codex/DSH 任务比较完整调用路径,尤其 DSH:冷/热启动、额外进程与序列化、取消到实际退出、安装/升级/失败恢复。采用同一受控输入与环境,记录版本、命令、观察值和未知项;无需为本次架构比较调用付费模型或重做整套长程实验。
- 将 Pi 新能力收益与现有路径的精简收益分开。如果完整比较不能支持维护成本下降,请缩小迁移范围,或明确新能力/兼容收益为何足以接受新增成本;不要为了统一接口维持无依据的重复规则。
验收: 能从清单追到实际调用方与被删除代码;能重放代表性变更/成本比较;原权限、身份、未知效果和清理失败语义不丢失。先比较再精简,不能为了减少行数删除必要保护。
关键代码讲解
ManagedOarSession/runOarTurn:统一宿主会话与终态观察,清理失败不应形成成功结果;这不替代 LoopX 的工作验收。createDshRuntime:通过 OAR kernel 驱动 Python worker,保留原生身份并拒绝重复/排队输入;该适配仍由 LoopX 维护。run_oar_turn:复用原进程 supervisor,同时承担 JSONL 分片、身份与完整性检查。它解释了跨语言新增代码的来源,也需要计入长期成本。installation.install:显式安装锁定依赖,使用源码绑定缓存;正常 Turn 不隐式下载。升级源码/锁后重新安装和失败恢复仍是采用成本。
当前 56 个文件按 diff 分组为:生产代码与打包配置 +2058/-257;测试与示例 +2054/-86;依赖锁 +1603;文档与 CI +291/-2。生产部分净增 1801 行是维护投入的线索,不是拒绝阈值。新增 CLI、打包排除规则、doctor/readiness、Chat 中断及进程树跟踪均有实际调用方,不能只审 runtime.ts;对应的运行验证本次仍为 UNVERIFIED。
规格依据 spec_ref: docs/architecture/rfcs/controller-executor-unified-contract-v0.md,spec_revision: 90b26f2fa26835d668f4f1fb77dea87c81fda755。采用本次变更前的 职责与验收条款,不以本 PR 新写的 checkpoint 自证:
- C3.1 / C3.2: 本 PR 范围之外的已有共享基础;源码已由两种 operation adapter 采用,不要求重做,也不宣称已完成全部角色/恢复验收。
- C4.1 / C4.2 / C4.3: 本 PR 不交付这些决策迁移;保留既有 authority/settlement owner,不能计作 OAR 的新增收益。
- C7.1: 清理职责等价与净简化尚未证明,需要 R1 的责任对照与真实退出负例。
- C9.2: 有新增共享与原生测试,但保留/合并的断言映射和完整等价未独立验证。
- Responsibility convergence and contributor handoff: 减少独立决策、替换真实调用方、删除被替代路径和比较完整事务成本的证明仍待补足;不要求完成所有 package 才能交付本切片。
对主干的风险 / Risks
正常路径应由已准入的 Turn 经宿主适配、OAR 原生执行、完整根结果返回,再进入原验证与结算;失败路径包括缺依赖、请求身份不符、原生结果不完整、取消和未确认清理。源码已包含相关拒绝分支,但本次没有独立重跑基线/head 成对执行、权限与隐私负例或真实 SDK 集成,所以这些维度保持 UNVERIFIED,不能把源码阅读等同于通过。
现有 Codex/DSH 有界入口的 OAR 替换是行为变化,不是全局 default-off 功能;Pi 才是显式选择。原生 operation、自定义 DSH runner 与原生 Codex Chat 的旁路需要持续保持其原契约。Node 24 和显式安装虽有文档披露,仍须证明原操作员从旧环境升级、遇错、恢复到原任务的完整路径。
语义与 CI 对齐
OAR 的完成事件只能成为宿主观察,不能授予 Goal/Agent 权限或证明工作完成;签名、独立验证和一次性结算仍应复用现有 Turn 词汇与 owner。现有子进程清理评审线程应独立处理,不能由本次维护收益讨论视为已解决。本次未独立复现该线程,也不重复冒充其验证结果。
PASS:精确 head、完整改动清单、生产改动及相关原 owner 的源码对照。UNVERIFIED:维护成本下降、完整成本测量、基线/head 行为等价、权限/隐私/恢复负例和主干所需回归。远端 OAR integration 已成功,但当前同时存在 dependency-review、Release Artifacts build、Python kernel-static-checks 等失败及后继跳过;其原因本次未归因,保留 unresolved,不宣称为既有故障或本 PR 引入,也不以单个绿灯覆盖这些缺口。
我的整体评价 / Verdict
保留 OAR 整合方向的评估空间,请先把维护目标、实际替换收益和新增长期成本说清并落实最小必要精简。当前 problem_context 与 change_proportionality 为 not_yet_proven,故请求修改;不是因行数较多判定设计错误。
long_horizon:持续执行的成本与恢复收益尚未证明。user_experience:已有任务新增安装升级前提后的完整恢复路径尚未独立验证。visual_review:not_applicable;改动清单没有渲染布局变化,未验证范围为原生执行与操作恢复,而非页面视觉质量。已有真实原生差异有理由保留;安全清理与历史恢复契约不能为精简而删去。复审应同时核对本次 R1、当前功能/CI 缺口和新 head,不继承旧批准,也不新增与本次切片无关的门槛。
English verdict: REQUEST_CHANGES at fa76197: demonstrate managed-host maintenance payoff and account for the added runtime/migration cost. Source inspection completed for the architecture concern; runtime parity, cost measurements and current CI failure attribution remain UNVERIFIED.
Draft Status / 草案状态
This PR is in Draft for continued session-integration and communication-boundary design. The implemented and previously validated slice is LoopX-owned bounded execution. A complete replacement of rich Chat, native operation transports, and in-host plugins has not been implemented or qualified.
本轮讨论进一步明确了接入目标:复用 OAR 的执行会话、事件、控制和清理能力,同时保持 LoopX 既有业务权责与用户入口。当前仍需梳理长会话接入、双向工具回调、真实原生写入处的准入保护,以及取消和恢复语义;后续具体迁移范围与验收条件见 Architecture Discussion。
下方原有实现与验证记录继续保留;新增设计项均标为待完成。本次更新仅补充 PR 说明并转为 Draft,没有增加代码提交或重新运行测试。
Goal And Delivered Outcome
LoopX currently owns separate bounded Codex and DSH execution paths, while Pi has an in-session extension but no equivalent shared managed Turn path. This PR implements the maintainer-requested OAR integration for LoopX-owned bounded execution.
@botiverse/oar@0.75.0session, event, control, outcome and cleanup management.loopx-project/loopx:main, based on90b26f2fa26835d668f4f1fb77dea87c81fda755.Author Declaration
loopx/hosts/oar/runtime.ts,bridge.py,stdio.tscontrol_plane/turn_driver/codex_cli.pyhosts/oar/dsh.ts,dsh_worker.py, existing DSH adapterhosts/oar/turn.py,__main__.pyScope And Continuation
Complete for LoopX-owned bounded execution.
runtime.tsowns session acquisition, accepted controls, root/child attribution, terminal observation and disposal. Python remains the IO adapter; it does not introduce another Goal/Turn lifecycle. The host helper belongs inloopx/hosts/oar(capability_id: none;provider_id: loopx-core; origin: builtin).OAR has no native DSH runtime, so the adapter uses its public runtime-author kernel over the existing
deepseek-harness-sdk==0.1.5rc1. Each DSH OAR Session owns one Turn. Queue and repeated prompts are explicitly refused, and caller-supplied IDs never silently fall back to fresh sessions. DSH Chat plans a fresh native ID for each segment while preserving its stable Chat binding and bounded history; interruption really stops native work and holds the slot until cleanup.The Pi/DSH plugins inside an already running host retain their same-session behavior. Rich native Codex Chat and Codex/DSH operation transports retain their dynamic-tool, history-injection and background-control adapters because OAR does not provide all those contracts. The existing paired harness-selection RFC records this boundary and the runtime adapter owner/dependency for extending it. This PR makes no L1, Mode B, durable DSH resume, or long-horizon effectiveness promotion.
Legacy Cleanup
The bounded Codex
codex exec/temporary-result-file path and the direct DSH SDK execution path have been replaced by OAR. A follow-up call-site audit also retirescodex_cli_session_id_from_jsonland its two unused package exports, plus the test-only_event_failure_categorywrapper. The existing failure fixtures now exercise the productionCodexFailureObservationreducer directly.This cleanup removes 23 production lines. The retired session-scanner export has no repository callers or documented compatibility contract. Native benchmark helpers, the active operation transports, in-session Pi/DSH plugins and LoopX authority/settlement code retain real consumers and remain in their current owners.
Behavior And Operational Changes
python -m loopx.hosts.oar installand inspectstatus. Turns and probes never download dependencies.node_modules, and uses a source-bound atomic cache installation. Existing Codex/DSH CLI selections remain stable. Pi is an explicit signed generic-cli command.Architecture Discussion
本轮讨论的范围与结论
以下现状核对基于
fa76197cac2e08461a458f52bfe95ab8b25badef、@botiverse/oar@0.75.0。这是本轮讨论的归纳与后续设计方向;“建议 / 待完成”不表示已实现,也不把 bounded execution 的既有验证扩大为全部原生能力的兼容证明。已交付范围和原生保留边界见 OAR adapter README。
当前通信清单:传输、消息格式和进程归属
“JS”需要区分浏览器前端、常驻 TS 控制面、Host supervisor、OAR worker 和宿主内 TS 插件。它们不是同一个进程。JSONL 是消息分帧方式,stdio / TCP / Unix socket 是传输方式;是否为 JSON-RPC 取决于实际消息契约。
控制面还有受限的大快照文件通道:小控制报文走 TCP,允许名单中的大参数/结果通过私有临时文件引用传递,并核对大小、摘要及路径边界。它不是共享内存或任意文件交换服务。实现
当前 OAR 执行链路
flowchart TB P["LoopX Python Host / bridge.py"] -->|"启动请求;保持外层 stdin"| S["Node A:既有 Host supervisor"] S -->|"完整 JSON + 输入 EOF"| O["Node B:OAR 单 Turn worker"] O --> C["Codex app-server"] O --> I["Pi RPC 子进程"] O --> D["Python DSH worker / SDK"] D --> R["DSH runtime"] O -->|"OAR JSONL 记录"| S S -->|"Host JSONL:输出块与进程结果"| P这里有两种不同 EOF:Python → supervisor 的 EOF 表示 owner 离开/取消;supervisor → 当前 OAR worker 的 EOF 表示请求输入完整,随后开始执行。 因此不能简单地不断向现有 stdin 写 prompt 来得到长会话:外层 bridge 接受首条启动请求后忽略后续输入,内层 worker 读完 EOF 才执行。外层行为 / 内层行为
建议的通信实现方式(待设计与实现)
按进程归属选择传输,统一消息校验、身份关联、错误和生命周期语义。 当前分支建议沿用已有受管进程体系演进,不新增一个承接所有调用的全局 OAR daemon。
具体候选是 scheduler ACK follow-up 的内部调用,但其 evaluate 路径可能提交 scheduler 状态,不能当作纯计算而随意重试。相反,state-recovery worker 明确用于隔离不受信数据库核查,不能为少启动一个进程就搬进常驻 daemon。follow-up 提交路径 / 隔离目的
暂不引入统一 HTTP/gRPC/WebSocket 服务或消息队列;若以后有跨机器调用、多个独立消费者或持久消息投递需求,再按新增需求评估。这里的收益首先来自明确进程和状态所有权,不依赖将所有传输改成同一种技术。
持久 Session bridge 必须明确的合同(尚未落地)
上述约束的现有依据:Codex 实际写入保护、effect-runtime 重试边界、断连不撤销 handler。
替换兼容性、用户习惯与预期收益
Session 与 DSH 能力依据:ManagedOarSession、DSH adapter 限制、原生 DSH 同连接继续。
预期收益包括:减少各 Host 重复维护的会话/控制/事件/清理逻辑,让取消和资源回收的修复更易复用,让新增 runtime 集中在 adapter 与能力映射,以及让诊断能够关联请求、Session、native Turn 和 cleanup。收益成立的条件是实际迁移调用方并删除被替代实现;仅增加一层 wrapper 会保留双份维护成本。统一接口也不直接证明模型效果更好或运行更快,应分别测量冷启动、热路径、取消延迟、资源占用和完整成本。
后续推进与验收清单
以下为 Draft 阶段的待办,尚未标记完成;先确定本 PR 后续实际交付范围,再按该范围进入实现与评审。
本节记录设计判断与尚未验证的事项;没有为未实现能力添加通过记录,也不作性能、效果或完整替换的既成结论。
Validation
fa76197cac2e08461a458f52bfe95ab8b25badef; its Git tree47afd1065b098a16e92c6ccffc90a85dec47247dis identical to the locally validated cleanup tree. The standard premerge gate passed on the preceding runtime source tree; the final cleanup was qualified with the focused reducer, native Codex and shared Turn suites below.32cf309, including a wheel installation outside the checkout. CI for the latest cleanup head is pending; this PR remains open and unmerged.examples/loopx-turn-codex-cli-e2e-smoke.pythrough actual OAR and a synthetic Codex app-serverexamples/loopx-steward-managed-chat-smoke.py: profile, visible answer, envelope and read-only refusal; this environment reports sandbox backend unavailable and refuses unconfined executionCoverage and gaps: model endpoints and Codex RPC peers are synthetic. No paid/live-provider result or comparative effectiveness claim. Four phase-checkpoint cases skip because the optional
sforge.harness.checkpointsource pin is unavailable; unrelated checkpoint behavior is not claimed. POSIX process-tree behavior is exercised locally; Windows retains the existing best-effort process-tree boundary. The full repository CI matrix runs on this PR; local validation is scoped to the affected runtime/authority surfaces plus the selected premerge gate.Frontend / Visual Evidence
Type Of Change And Area
Shared-authority RFC Fixture Impact
N/A: no authority routing, storage/provider promotion or shared Goal Authority semantics change. Existing admission, validation, settlement and quota tests remain the independent oracles.
Boundary Checklist