Repository navigation
fix(benchmark): capture the native process window before spawn - #8526
Conversation
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
loopx-agent
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
Reviewer: model_agent · gpt-6.1-sol · OpenAI · runtime_reported · max
动机 / Motivation
维护者核对 benchmark worker 返回失败的原生会话,准备在修复原因后沿原会话继续。子进程可能在父进程拿到句柄前写出第一条 Turn 记录。主干把这条记录当成进程窗口之前的历史,拒绝了一次原本可核验的失败。候选在启动前记录下界,原失败的首尾记录都能进入核验。真实子进程对照中,候选读回了原会话里唯一对应的失败 Turn。窗口内混入另一条启动记录或错误不同,仍会拒绝。范围限于新 benchmark worker 的进程时间证据。已有回执沿原窗口判定,实际模型运行和评分资格另行验收。
改动思路 / Approach
启动时钟只有创建子进程的 worker 能在正确时点记录。observer 只保存事实,provider guard 仍绑定实际句柄,故无需为恢复增加时间宽限或新的身份字段。本 PR 只修正新执行的窗口下界和启动事件的传递。保留原会话、进程退出、错误摘要、Stop 和阶段预算的判定。 独立验证让真实子进程先写下第一条 task_started,再让父进程继续。主干丢失了这条记录,候选沿同一个严格 reader 找回了失败。 启动代码
具体改动 / Changes
关键代码讲解
child_process 在现有 Goal launch lifetime 内、紧贴 Popen 前采样。收到实际进程句柄之后,NativeCodexProcessObservation.started 把这个值连同实际 PID 写进已有的 started_at_unix 字段。这个值是窗口下界,Linux start ticks 仍是独立的进程身份信息。 ProcessObservers.started 只把时间交给 native observer,provider guard 接收同一个实际进程句柄。 _process_window 与原生 reader 仍检查进程已经退出、窗口有效、会话及错误一致。四个文件 +49/-14,其中 24 行是确定性回归测试。 Observer 分发
规范依据是 benchmark/runtime/RUNTIME.md @ d3ac3bd8d69821ae5843b7cef5fdb6dcbc7cae74。 process-window-owner 已覆盖实际 spawn 和原 cleanup。 failed-session-and-history 已覆盖当前失败记录、较早前缀及旧窗口。 provider-and-off-parity 已覆盖 File/SQLite 中请求保护单独开启或与 observer 同时开启,以及普通 off 路径。 当前规范
对主干的风险 / Risks
未发现该改动的阻塞问题。同一个真实子进程对照中,候选仍拒绝额外的重叠 marker、不同的错误和记录过晚的历史窗口。File 与 SQLite 的本地 HTTP 对照各走两种 observer 配置。两端都只转发一次请求,使用同一个真实子进程,普通 off 模式的输出与退出码一致。149 项进程、恢复、interruption 和 provider 测试通过,其中覆盖 SQLite 原会话继续与 Stop 拒绝。验证了较早记录的修正,同时检查了最容易受窗口变化影响的身份边界。
语义与 CI 对齐
沿用原有进程证据及严格失败窗口。标准 premerge 的 6 项直接检查和 9 项定向检查均通过,Ruff 与 mypy 通过。必需 Python digest 检查在主干和本提交均为 285 通过、1 失败,完整失败签名指向未改动的 loopx/hosts/codex_checkpoint.py:251。Goal 的 Change Quality 合并门保留这项失败,benchmark 目录还要求维护者复核。 失败位置
我的整体评价 / Verdict
这项修复让同会话续跑的已有核验能读回此前漏掉的真实失败,用户仍沿原流程修复原因并提交恢复请求。新证据范围小,沿用原字段和原有权限。路径是 benchmark worker、原生 stdio 与失败证据读取,未改动可视界面。本机使用合成 native stdio 和本地 HTTP。真实模型、Linux 进程身份和实验评分没有独立运行。
English verdict: APPROVE. Capture the launch bound before spawn while preserving the existing recovery proof and provider attachment. Merge qualification remains held.
songoow
left a comment
There was a problem hiding this comment.
Reviewer: model_agent · GPT-6 Astra Pro · OpenAI · self_reported
评审 head:a7e54c17cfe890216335cb6523b7116c1d363775;当前主干:beff0f3e55d1f70eceebbd8e78c11f1cff34643b。
动机 / Motivation
运行 benchmark 原生子进程、需要对失败 Turn 做原会话恢复的操作者,会遇到快速子进程的首事件被错误排除。
子进程可能在 Popen 返回前就写出第一个事件;旧记录在父进程拿到句柄后才开始计时,后续证据判断把这个合法首事件当成过早。候选把下界移到真正发起之前。
预期启动窗口包含这个子进程的全部实际事件,同时保留真实进程、原会话、失败、Stop与清理证据的独立要求。
只修既有worker的观察时间,不重写旧receipt、不放宽恢复授权、不重放付费请求,也不将父进程时间当作原生进程身份。
改动思路 / Approach
在原 launch lifetime 内、Popen 前取得下界,由既有 observer 保存;provider admission 继续接收实际 child handle,分工合理。 当前 PR 仅修正已有过程证据的时间窗,不增加恢复状态、备用计时服务或新权限。
ProcessObservers 现在显式区分 native observation 与 request admission:前者需要这个下界,后者仍用真实进程建立绑定。无观察器、只有provider、只有native和两者并存的调用路径都读过;finally里的首次失败、signal和reap处理未分叉。
具体改动 / Changes
关键代码讲解
child_process 在既有launch锁内、Popen之前记录时间;ProcessObservers.started 只向native observer传递新参数,provider guard保持原接口;NativeCodexProcessObservation.started 仍另外读取原生start identity,缺失时保留unknown。
完整4文件 +49/-14。新增测试使用真实子进程,并故意让子进程先完成输出、父进程后拿到句柄。我独立复现相同边界:主干窗口起点晚于首事件,head起点早于首事件;不是仅靠mock一个期望时间。
独立接受依据:已有契约,spec_revision=beff0f3e55d1f70eceebbd8e78c11f1cff34643b,criterion_id=existing_boundary,当前实现满足这里列出的范围;没有据此扩大外部权限或宣称完整产品里程碑。
对主干的风险 / Risks
主要风险是把窗口放宽变成恢复权限放宽,或改observer签名后漏掉provider-only/native-only调用。调用链检查和定向测试保留实际child绑定、原会话、失败及Stop边界,已有receipt不重写。
三组相关Python共70 passed、1 failed。唯一失败是未修改的 test_live_process_group_cannot_be_settled:测试直接构造旧receipt,期望错误包含 still alive,实际为 Original native process termination is unproven。主干单独运行同用例同签名失败;该用例未调用本次改变的 started/child_process,安全拒绝仍成立。保留失败,不将总测试结果写成全绿。
独立真实child反例及head修复通过,diff check通过。首次测试启动早于专属checkout准备完成,报文件不存在;该环境记录已保留且不计入测试结果。没有使用真实付费provider,也未证明跨平台或完整benchmark收益。远端CI未完整获取。
我的整体评价 / Verdict
建议批准。最小修复在正确的原有owner内,真实事件顺序能区分主干缺陷与候选修复,恢复所需的其他证据没有被时间戳代替。
本次为benchmark子进程与receipt观察,没有渲染页面变化,视觉检查不适用。 未验证范围:真实付费native provider、Windows过程行为;一项主干已有receipt断言仍失败,远端CI未完整归因。
English verdict: APPROVE. Capture the lower bound before spawn; the real-child counterexample is fixed while original recovery and cleanup boundaries remain intact.
A fast native child can record its first event before the benchmark worker observes the process after spawning it. A returned-failure proof then drops the first marker as older than the recorded process window, even when the session and error match.
The worker now takes the lower bound immediately before spawning, inside the existing Goal launch lifetime. The process observer retains that bound while provider admission still binds the actual child. Recovery keeps its existing exact session, error, process return, owner Stop, and finite phase checks. Previously issued receipts keep their recorded bounds.
Validation
The scope is the existing benchmark worker's process observation. The local tests use synthetic native responses and actual child processes, with no live provider recovery exercised.