Skip to content

fix(benchmark): preserve failed workers before terminal teardown - #8216

Merged
loopx-agent merged 3 commits into
mainfrom
codex/terminal-joint-capture-20261107
Nov 7, 2026
Merged

loopx-agent merged 3 commits into
mainfrom
codex/terminal-joint-capture-20261107

Conversation

@loopx-agent

@loopx-agent loopx-agent commented Nov 6, 2026 •

Copy link
Copy Markdown
Collaborator

A heartbeat solver can fail after its last regular checkpoint. The native runner then removes its work container after collecting submitted files and diagnostics, losing the newer workspace and recovery state. An older checkpoint cannot safely replace that tail.

Add explicit --preserve-failed-worker for full-controller heartbeat runs with agent-only native submissions. At the solver terminal boundary, stop the periodic observer, make one bounded call to the existing joint capture owner, and verify that the original source container is stopped before provider grading drain. Keep the stopped source for separately authorized recovery or disposal, whether export succeeds or fails.

The capture includes the complete task workspace, declared research components, Goal state, scheduler/wake evidence, native sessions/configuration/SQLite and the native opportunity/cooldown capsule. Native credentials are excluded. This adds no model call, submission, settlement, retry, budget extension or automatic recovery. A saved point and a retained container do not prove receiver adoption.

Optional preservation-report storage failures now leave a redacted diagnostic while preserving the known solver exit and native grading. They cannot skip observer shutdown or verified stopping, and cannot hide an unconfirmed stop. Missing report files never establish successful export or restore eligibility. The provider may omit its optional final submission archive because extraction requires a running container; valid native history and scores remain available independently.

The option is off by default. Successful execution and Native Goal completion retain existing behavior. Retained containers use disk; the CLI documentation covers inspection, disablement and explicit disposal. The shared request validator remains the component-validation owner, and the helper is specific to the native Docker provider.

Validation of 6fafca628a5d538d2aad35fbf99716fbdffbc5db:

  • 21 checks passed in Linux, including the real SForge run_agent → Docker → native HTTP grading/drain chain. Initial setup and the scoring payload are synthetic; there is no model inference.
  • The real provider tests cross successful/failed export with successful/failed preservation-report storage. They preserve exit code 2, the existing valid score, submission count, complete grading and cooldown, and verify that the source is stopped before grading drain.
  • Negative cases cover uncertain observer/stop state, repeated handling, native credential declarations and invalid CLI combinations. Receipt failure plus unknown stopping still raises the stop failure.
  • Local checks: 10 passed and 11 Linux/provider cases skipped; Ruff, diff checks and bilingual-diff validation passed.
  • Standard premerge selected 19 checks with zero failures; its result remains manual_review_required for the benchmark-sensitive maintainer hold. An initial missing npm-dev-dependency failure was repaired by installing the checkout dependencies before rerunning.
  • Independent review reproduced the report-storage regression against the previous main-target head. The fix and new exact-head review supersede that head; prior integration-head evidence is not treated as current approval.

This proposal targets main as an independent seven-file change. Integration branches may consume it separately; this PR does not change active runs, evaluators, accounts or native-Goal completion policy.

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator Author

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-astra; OpenAI; runtime_reported; reasoning_effort=ultra

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

动机 / Motivation

运行长程 native benchmark 的操作者需要在 solver 异常退出后保留最后状态。原先最后一次定期 checkpoint 之后的新文件和会话可能随容器清理丢失;启用本选项后先尝试一次完整导出,并在评分等待之前停止且保留原容器。

实际 SDK 路径已验证:导出成功或缺少 participant 时都保留停止的原容器,失败退出仍为失败,已取得的有效原生评分仍正常汇入结果。本 PR 不恢复会话、不结算失败 Turn、不增加模型调用或评分机会,也不把原始文件点认证为可恢复 checkpoint。

接收端对失败 native cursor 的资格及实际续跑仍由独立恢复 owner 完成;本 PR 只交付不丢唯一源的终态保全。这是有实际价值的前置交付:源数据仍然存在,后续才能判断能否恢复;捕获一个文件摘要本身不能证明恢复成功。

改动思路 / Approach

沿既有 Docker 终态、joint capture 和原生评分 owner 增加保全策略,避免另造 Goal 恢复或重试调度器。本次边界是失败返回前停止计算、保留唯一源并如实导出;恢复准入、会话续跑和后续清理授权仍独立。

这里确实需要区分两件事:导出是有时间上限的尽力操作;停止计算和避免误删唯一源是终态安全要求。仅导出不能处理磁盘满或 participant 缺失,仅保留容器又没有复用已有原生机会、冷却和工作区的联合捕获。当前实现把两者放在一个 provider helper 中,使用原 capture_worker 和共享请求校验,不修改核心 Goal 语义。

审查期间发现并复现了一个有实际后果的顺序问题:旧 review head 在 cleanup_container 才停止容器,而 SForge 在 cleanup 前还会等待评分。新 head 把停止放进 finish 的 finally;下面的顺序是经过真实 SDK 路径验证的,不只是对代码的推断。

路径 返回评分等待前 评分与清理结果
默认未开启 维持原有行为 原清理流程不变
开启,捕获成功 停止原容器,保留完整原始点 有效原生评分仍汇入;不删除原容器
开启,捕获失败 同样停止并保留唯一源 明示捕获失败,不伪造已恢复状态

具体改动 / Changes

审查基线是 1a309ccb3278b68f79d674b66833fadffd8ad476,完整审查 head 是 6097e14220e03d8ceb2b1df4555e59e62a64883c。七个文件包含 provider 终态路径、一个共享校验函数的原样抽取、CLI、文档和合成测试,没有新增核心 planner、共享恢复协议或模型提示。

规范依据为 docs/reference/research-checkpoint.md,spec_revision=1a309ccb3278b68f79d674b66833fadffd8ad476,按改动前的规则判断:

  • prepare-and-capture:已满足本切片的边界。失败 cursor 不冒充已完成;新文件点保持 native_cursor_qualified=false 和 restore_qualified=false,native 凭据目录不会自动进入导出。显式业务文件仍属于私有内容,不能因此宣称经过隐私认证。
  • complete-isolated-benchmark-replacement:恢复准入和续跑在本 PR 范围之外。实现没有调用恢复、重置预算、创建准备 Todo 或结算失败 Turn;保留原容器为后续独立资格提供来源。
  • default-bank-rotation:继续分离存储维护与恢复资格。终态捕获前关闭原观察器和维护过程,不自动删除原容器,也不改变原生机会及冷却。

关键代码讲解

  1. run.main 把显式 --preserve-failed-worker 限定到 full-controller、agent-only native 提交组合;错误配置在创建 trial 前拒绝。未传选项时不会追加该 runtime receipt 字段。
  2. RecordingDockerBackend.exec_run_with_timeout 只对实际 solver 命令观察退出,并把原退出码、超时和启动状态交给终态处理。普通命令不能消耗保全操作,默认关闭时保留原异常及 receipt 形状。
  3. FailurePreservation.finish 在可能失败的 IO 前启用保留,最多捕获一次;finally 在返回 SDK 前停止源。导出失败、写 receipt 失败和观察器未释放都不能落回强制删除。
  4. stop_source 对原容器 ID 独立核验,用 Docker 停止及有界 kill 回退,检查 Running/Paused/Restarting/Pid;未知状态会报错,不靠一张成功 receipt 推断计算已停止。后续 cleanup 只做幂等复核。
  5. terminal_components 捕获完整任务工作区、明确声明的外部研究路径和允许的原生状态叶子;复用共享校验拒绝重叠及 native-home/auth 范围。没有新增平行归档算法。

对主干的风险 / Risks

PASS:独立验证 18 项生产测试、10 项独立边界测试,以及基线/head 五分支默认关闭对照。 两个生产测试运行真实 SForge run_agent、隔离 Docker 与 native HTTP;只替换测试容器安装准备和合成 agent,保留实际 exec、最终归档异常、评分 drain、结果/历史写入和 cleanup。捕获成败两条路径都在进入 drain 前确认停止,solver 仍为 nonzero_exit,合成的已评 7 分和一次提交仍正确返回。没有调用模型或真实题目评测。

旧 review head 18684daa62db2f40905037044a3acd2987009d75 的独立真实 Docker 反例在 exec 返回后读到 Running=true,确实失败;同一个反例在当前 head 通过。独立负例还覆盖 partial start、paused 容器、stop 失败、原容器身份不匹配、full disk、非 solver 命令和显式 auth 路径。没有用“测试随后绿了”替代原失败的因果说明。

默认关闭对照使用相同输入分别执行 r30 与当前生产 backend,比较合法成功、失败、transport 异常、observer 启动失败、非 solver 命令的完整异常、事件次序和持久化 receipt,结果相同。该对照的 provider 原语是合成的,真实 Docker 边界由前述独立测试补足。早期对照夹具遗漏 elapsed_seconds,已保留为无效合法路径证据;修正后额外断言合法成功/失败不得出现夹具异常再比较,不把先前相等当作通过。

仓库独立 diff check 通过;读取了作者当前头 quick premerge 的 direct、public-boundary 和四项 selected checks,均无失败,整体仍保留 benchmark maintainer 的 manual review hold。按当前审查配置未查询或等待远端 CI。

停止源后,provider 需要容器内 exec 的可选最终归档可能为空;README 已明确这一变化,实际测试证明原生已评历史不会随之丢掉。新原始点和停止的源仍保留最新文件。停止容器继续占用磁盘,并含原本私有文件;必须经独立资格或明确授权再处置,没有自动清理 TTL 或自动恢复承诺。Docker daemon 本身不可用时也不能保证停止,错误会如实保留。

语义与 CI 对齐

复用既有 capture request、native opportunity capsule 和执行结果语义;新增的是 provider 本地显式意图与诊断,不是核心共享状态词汇。退出失败不等于 Goal 完成,导出成功不等于恢复准入。保存、停止、评分和恢复的权限没有合并为一个隐式成功状态。

我的整体评价 / Verdict

当前没有未解决的阻塞 finding,支持这个完整的有界增量。长程维度的改善已落在“失败后最新唯一源没有被删除、后续等待不继续占用计算”这两个真实效果上;尚未证明实际恢复后的模型收益,不能把它写成研究效果提升。操作体验沿原 CLI 一次明确启用和私有状态读回完成,不需要新增 Goal 表单或复制已知上下文。

仅 benchmark CLI、后台终态和 README 变化;检查过 run.py 与 backend,未改变任何渲染页面。无新增可视页面;接收端实际续跑不在本次验证范围。保留显式磁盘成本与人工处置边界是必要取舍,当前不应另增自动恢复或第二套调度状态机。

English verdict: APPROVE at 6097e14220e03d8ceb2b1df4555e59e62a64883c. The reproduced stop-before-grading defect is fixed; independent real SDK/Docker/HTTP tests preserve failed execution provenance and valid scores, with default-off parity. Receiver qualification and actual resumed-model benefit remain unverified and out of scope. This review grants no merge or live-deployment authority.

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
(cherry picked from commit 18684da)
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
(cherry picked from commit 6097e14)
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
@loopx-agent
loopx-agent force-pushed the codex/terminal-joint-capture-20261107 branch from 6097e14 to 410506a Compare November 7, 2026 09:22
@loopx-agent
loopx-agent changed the base branch from codex/edgebench-integration-r30-20261107 to main November 7, 2026 09:22
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator Author

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=max

Request changes conclusion (author-owned PR; GitHub blocks formal self-review)

P2 · 终态收据写入失败会抹掉已观测的 solver 退出结果。 真实 SForge、Docker 和本地 HTTP 评分路径中,仅让新私有收据的写入报 ENOSPC,其余存储保持可用。原 worker 已停且 PID 为 0,原执行收据明确记录退出码 2,评分历史仍有 7 分。SForge 却把此段写成 unknown、native_exit_code=null,最终调用抛出 ENOSPC。这是新增的报告写入错误覆盖已知执行结果。首次写入失败还会跳过定期观察器的关闭,清理阶段会重复触发同一写入。 终态清理 停止与收据写入

请把可选收据发布失败与停止验证失败分开。确认已停后保留原 solver 结果,并用现有诊断渠道记录有限的报告错误。真正无法确认停止时,继续如实失败并保留源。回归用例应在原真实 SDK 链路上只注入收据写入失败,核对停止、原退出码、评分和清理回读。

动机 / Motivation

运行长程 native benchmark 的操作者需要在 solver 异常退出后保留最后的工作区和会话,以便随后判断能否恢复。原流程可能在最后一次定期 checkpoint 之后删掉唯一的源,显式启用后会先尝试一次终态导出,并保留停止的原容器。导出成功和缺少 participant 两条路径均在评分等待前停止,原非零退出码和已评分历史可以一起读回。当前缺口是终态收据不可写时,源已停止但原 solver 结果没有按现有 provider 契约返回。本次交付是终态保全,接收端资格和模型续跑由独立流程负责。

改动思路 / Approach

用已有 Docker 暂停、归档和 native capsule 保全工作区及机会计数,可以避免再建一套恢复协议。只保留容器会把内容导出和证据核对全部留到后续操作。只依赖定期 checkpoint 会丢掉最后一个点之后的新状态。这里明确启用一次保全,把捕获失败和是否停止分别记账。

保全是 provider 本地操作,评分、原执行结果与恢复授权有各自的所有者。当前 PR 边界是保留停止的原源和一次有界导出,并继续交付已知的原生执行结果。发现的分离缺口在 finish 和后续清理重复调用 stop_source 时写入可选收据的异常传播。

具体改动 / Changes

按主干基线 17e614282c83871712614d561373720f3696d2f9 的 docs/reference/research-checkpoint.md 评审,另核对同版本的 native 执行证据说明。迁移后七个文件增加 508 行、删除 7 行。上次集成提交只作为缺陷历史和对照,以下结论来自新 head。 固定版本的 checkpoint 规范 固定版本的执行证据

  • prepare-and-capture。保留终态源的文件点仍标注 native cursor 与恢复资格未通过,已导出点中没有自动包含凭证文件。
  • TERMINAL_PROVENANCE。原生执行证据区分已观测退出与清理错误,报告写入失败应单列。仅新收据报错时,已观测的退出结果被改成未知,当前不满足。
  • complete-isolated-benchmark-replacement。此 PR 提供可保留的源,接收端准入和续跑属于独立恢复流程。
  • default-bank-rotation。先结束原有定期观察,再尝试一次终态捕获。原生已评分机会与冷却在真实本地服务中保持,正常成功路径沿用原清理。

关键代码讲解

  • main 只为完整 controller handoff、native 反馈及 agent-only 提交开启保全。无效组合在创建 trial 前拒绝。现有调用不带标志时,结果收据不会增加保全字段。 命令与范围
  • terminal_components 收集完整任务工作区和明确声明的外部材料,另列允许的 native 状态叶子。共享 validator 拒绝重复和重叠。凭证目录及显式 auth 路径拒绝,任意业务文件仍需按私有材料处理。 组件边界
  • RecordingDockerBackend.exec_run_with_timeout 先保存原退出码,再在 finally 进入保全。启用保全的真实 solver 终态和后续清理同走原容器身份,其他命令沿原路线。finally 的异常可以覆盖已经取得的返回值。 退出证据与交接
  • FailurePreservation.finish 在可能失败的 I/O 前启用保留,最多尝试一次捕获,随后停止源。正常路径和缺失 participant 路径都在评分 drain 前确认停止。 终态保全
  • stop_source 校验原容器 ID,再读 Running、Paused、Restarting 与 PID。停止验证和可选 receipt 写入当前同处一个异常出口。provider cleanup 再进入同一出口,也会把报告写失败传播出去。 停止验证 provider 清理

对主干的风险 / Risks

  • PASS。当前主干目标 head 独立重跑 18 项 Linux 定向测试。两条实际 SDK、Docker 和本地 HTTP 路径分别覆盖完整导出和缺失 participant,均在评分 drain 前停止,保留原非零退出和一次既有提交的 7 分。测试采用合成 solver 与评分输入。
  • PASS。关闭选项的五分支对照运行基线和 head 的真实 backend 方法,原生传输使用相同的合成结果。成功、非零退出、transport 报错、observer 启动失败和普通命令的事件次序、错误和持久收据一致。签名、diff、双语 RFC 和仓库要求范围的 Ruff 检查通过。
  • FAIL。仅在 FailurePreservation._write 注入 OSError(ENOSPC) 的真实生产入口反例仍失败。已有定向单测只断言保留开关,未断言 SForge 最终还能读到已知退出结果。停止确认和已有评分历史都能成功,新增报告失败仍将已知退出段改成未知。
  • 较宽 macOS 矩阵有 439 项通过和 8 项失败。两项终态路径在 macOS 导出卷的文件名资格上失败,已分别用隔离 Linux 卷重跑。其余六项是 scheduler 的五种模式缺少 should_run,以及一项 Harbor phase deadline 未抛预期异常,已有未改基线复现证据。此处保留其失败状态。按评审策略未查询 CI。

语义与 CI 对齐

新标志和保全收据属于 benchmark provider 的局部意图与诊断,复用现有 checkpoint 词汇和评分协议。原先已确认的退出结果是有效执行证据,终态报告失败时必须继续保持该属性。复审请用 Linux 隔离源 CLI 的终态套件与同一 ENOSPC 反例,比较原 solver 状态、停止验证和 native 评分读回。

我的整体评价 / Verdict

请求修改 410506a5748e7a0a29c8c63d69764bc72729bb8b。保留最新且停止的唯一源能让后续恢复有据可查,但在很可能与保全同时发生的存储故障中,操作者会失去稳定的 provider 退出结论,需要另找原始执行收据和评分历史。修复这一异常边界即可保留已有方案。实际模型恢复与长程收益尚未验证。

只改 benchmark CLI、终态后端和文档,现有页面没有变化,视觉审阅不适用。当前 head 的新失败需要修复后重新复审。

English verdict: REQUEST_CHANGES — At 410506a, a terminal receipt ENOSPC masks a known solver exit even after the original container is verified stopped.

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator Author

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=max

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

原 P2 已修复,无其他阻塞发现。将同一收据路径注入 ENOSPC 后,SForge 仍读到 nonzero_exit、退出码 2 和已评分的 7 分。原观察器已关闭,Docker 确认原容器已停止。 原 P2 评审

动机 / Motivation

运行长程 native benchmark 的操作者需要在 solver 异常退出后保留最后的工作区和会话,以便随后判断能否恢复。原流程可能在最后一次定期 checkpoint 之后删掉唯一的源,显式启用后会先尝试一次终态导出,并保留停止的原容器。正常导出、缺少 participant 以及收据不可写时,源可以保持停止,已有评分和已知原退出仍可读回。本次交付是终态保全,接收端资格和模型续跑由独立流程负责。剩余缺口是实际接收端续跑、长期成本与结果收益。

改动思路 / Approach

只保留原容器会把导出和核验全部留到后续,单靠定期 checkpoint 又无法补上最新尾部。这里沿既有 Docker、native capsule 和控制器做一次有界保全,导出和报告的结果分别记录。保全是 provider 本地操作,评分、原执行结果与恢复授权有各自的所有者。当前 PR 边界是保留停止的原源和一次有界导出,并继续交付已知的原生执行结果。

与上一评审 head 相比,_persist_receipt 只捕获可选收据写入的 OSError。首写失败后仍关闭观察器并检查同一容器,捕获按原上限执行。真实停止无法确认时仍向调用方报错,并避免误删该源。外部轮次、原评分和后续恢复保持独立。

具体改动 / Changes

完整评审基线为 17e614282c83871712614d561373720f3696d2f9 的 docs/reference/research-checkpoint.md,另核对同版原生执行证据契约。七个文件增加 555 行、删除 7 行。原主干迁移和其后的收据修复都在本次核对范围内。 固定版本的 checkpoint 规范 固定版本的执行证据

  • prepare-and-capture。文件点标明恢复资格未通过。完整任务工作区和受限 native 参与者沿既有捕获,自动导出排除凭证目录。
  • TERMINAL_PROVENANCE。可选收据报错时,保留已确认的原退出和独立评分。仅可选报告写入失败已通过真实生产入口复验。
  • complete-isolated-benchmark-replacement。接收端准入、恢复会话和续跑在本切片之外。
  • default-bank-rotation。关闭原观察器后尝试一次有界终态捕获,原 native 提交机会和冷却仍能读回。

关键代码讲解

  • main 限制完整 controller handoff、native 反馈与 agent-only 提交,未启用走原有路径。 启动边界
  • terminal_components 用共同校验器检查完整工作区和外部参与者的范围。native 叶子按允许列表导出,显式 credential 路径拒绝。 捕获范围
  • RecordingDockerBackend.exec_run_with_timeout 先保存实际 solver 返回值,终态处理完毕才交给 provider 归档与评分等待。非 solver 命令维持此前路径。 solver 交接
  • FailurePreservation.finish 先启用保留,再关观察器、捕获和停止。其 _persist_receipt 只把可选报告的 I/O 错误记录为有限诊断,不改变物理停止或已知结果。 错误边界
  • stop_source 按原容器 ID 复核四项停止字段,后续 cleanup 对同一源幂等检查。收据无法发布时,如果停止验证本身失败,仍保留停止错误。 停止复核

对主干的风险 / Risks

  • PASS。当前提交的独立 Linux 反例使用上一轮真实 SDK、Docker 和本地 HTTP 夹具,只让新终态报告文件写入失败。此前得到 unknown/null 和外抛 ENOSPC;当前读到 nonzero_exit、原退出码 2、已评 7 分、observer 已关和已停止的原容器。另独立执行写盘失败和不能确认停止两项边界测试。
  • PASS。当前 head 的完整 Linux 定向套件 21 项通过。原迁移 head 独立 18 项证据用于同一生产范围,复核当前差分只改终态报告、说明和回归测试。默认关五分支的基线与迁移 head 对照一致,关闭路径不会进入此次新增的 helper。
  • PASS。当前精确头的 standard premerge 五个直接检查和 19 个选中检查无失败,保留 benchmark-sensitive 人工门。最初缺 Node 依赖的语义检查已在补齐环境后通过。较宽 macOS 矩阵的六项基线失败仍保留失败,另外两项存储资格差异已在 Linux 路径覆盖。按策略未查询 CI。

语义与 CI 对齐

新增的是 provider 本地选择与诊断。既有 checkpoint、评分和候选恢复资格沿原类型与所有者。确认停止的事实和收据写入错误分开,退出结果在原评分路径上继续可用。

我的整体评价 / Verdict

批准 6fafca628a5d538d2aad35fbf99716fbdffbc5db 的源码变更。后续核验可以读取未被删除的最新源,失败现场也不再因可选报告写入而丢失已知退出结果。操作员仍须按说明核对保留容器、导出状态和存储,之后才独立授权处置。实际模型恢复与长程收益尚未验证。

只改 benchmark CLI、终态后端和文档,现有页面没有变化,视觉审阅不适用。GitHub 发布为同账号的 COMMENTED 结论。

English verdict: APPROVE — At 6fafca6, receipt-only ENOSPC preserves the known native exit, valid score and verified stopped source.

@loopx-agent
loopx-agent merged commit 60089b0 into main Nov 7, 2026
3 of 4 checks passed
@loopx-agent
loopx-agent deleted the codex/terminal-joint-capture-20261107 branch November 7, 2026 09:52
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.

1 participant