Repository navigation
fix(benchmark): retain terminal provider failures - #7090
Conversation
7038698 to
a60aeae
Compare
Signed-off-by: huangruiteng <huangrt01@163.com>
a60aeae to
b156068
Compare
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent; gpt-6.1-sol; OpenAI; runtime_reported; reasoning_effort=max
[P2] 诊断观察失败时仍须执行容器清理。 新增 observe_terminal_provider_failure 在 super().cleanup_container 之前运行,未隔离解析异常。会话尾部含 {"type":"event_msg","payload":{"type":[]}} 时,set membership 抛出 TypeError: unhashable type: 'list',整个 cleanup 提前退出。我在实际 Docker/SForge 边界验证:正常 429 会收集并移除容器,这一未知形状则留下仍在运行的容器;实际 base 正常移除。请验证类型并保证观察失败也不跳过必须的 stop/remove,增加真实清理后置条件回归。位置:sforge_backend.py:129–132,触发点为 provider_failure.py:62。
动机
使用既有 benchmark runner 的维护者,需要从运行回执直接区分已知提供方终止失败,避免重新翻阅包含私有内容的会话档案。
此前原生会话可能记录终止 429,但运行回执只有笼统 runner_failed;本 PR 希望在原回执保留最小结构化失败类型和 HTTP 状态,减少重复人工诊断。
本次已经验证已知失败可归约且不带消息或路径,但未知事件形状会阻断容器清理,诊断辅助尚未与必须执行的资源回收隔离。
范围只是运行后观察与回执传播,不改变评分、任务语义、终止验收、运行权限或启动任何实验。
改动思路
实现复用原有私有会话收集流程:从收集到的 JSONL 文件读取有限尾部,按结构化终止事件及已知提供方变体筛选,只返回规范化类型与整数状态。原 run.py 在成功和异常分支把这一诊断投影加入现有回执;后续成功事件不应重放更早失败,消息正文不进入新字段。
把该观察留在 benchmark provider 适配层、复用原 runtime receipt 是合适的;必须的容器清理不应依赖可选诊断解析成功。
当前 PR 的边界是可丢失的最小失败诊断,不改变原 runner 的清理、容量归还与终止结果所有权。
完全不改会留下人工重读档案的成本;让报表重新扫描完整私有会话则扩大敏感面。当前有界归约比新状态服务更小,但应把异常留在观察边界内,或用可靠的清理控制流保证 stop/remove。这里以文字描述顺序和异常分支,未生成或认证流程图。
具体改动
独立规格采用修改前 benchmark/runtime/RUNTIME.md,spec_revision 为 770b11c9512eb7f9097329417072a4ad72d0af78,并核对同版本原生 Docker cleanup owner。逐项映射:Configure the native job 的已知结构化状态、未知错误保持未知及私有正文边界已实现;Results, timeout and recovery 的原始终止结果/部分结果边界在测试中保持,但未知会话形状导致资源清理未满足;Native SForge task entry 的原生 worker、权限与任务所有权未改变。新增文档只说明诊断字段,不是扩大实验执行授权。
当前完整 PR 为 7 文件、250 行新增、4 行删除:113 行新 reducer、6 行后端接线、4 行运行回执传播、8 行文档以及三组测试。已核对 head 从 a60aeaef33eeabfb67c3b40bdd99916520eef3f3 重基到 b156068abc91ffdceae3b2c501b06ce6b9873345,benchmark blobs 未变;共享基线已变,因此对当前 head 重跑相关套件、实际容器反例及 premerge,而非沿用旧结论。
关键代码讲解
_jsonl_tail(19 行)限制每文件尾读,丢弃截断首行并跳过无效 JSON;这限定了诊断覆盖,未命中不是“没有发生失败”的证明。_terminal_provider_failure(56 行)把上游 camel/snake 已知错误归为本地诊断,严格过滤消息、路径和非整数状态;62 行未先验证payload.type为字符串,是异常触发点。observe_terminal_provider_failure(84 行)按文件修改时间最多选择 32 文件,反向寻找最近终止事件;同文件后续成功优先于旧失败,不据自由文本分类。RecordingDockerBackend.cleanup_container在私有收集后读取诊断,但位于原 stop/remove 之前;benchmark/edgebench/run.py的 417/443 行是成功及异常回执的实际消费者。应保留该 consumer,同时隔离观察异常。
新 schema 是适配层的诊断提示,来源是收集到的原生事件,不是手写同步状态或新的评分权威。原有 NativeTurn 解析负责正在执行的 worker 结果;这里处理运行后归档,两者资源与失败 owner 不同,分离有依据,不应强行合并成通用控制面框架。
对主干的风险
当前 head 的实际依赖套件为 416 通过、3 项显式 Docker smoke 跳过;使用隔离环境中的 SForge 193cecda05661380575b16c9fcc88a8c16ece9f3 和 Harbor 0.20.0。另对本次改变的收集/清理边界执行实际 Docker 负例,使用无网络、无模型的专用合成容器;正常 429 的回执只含 schema、kind 和状态,未知形状抛 TypeError 并留下运行容器。测试善后已单独回收这些容器,这不代表产品 cleanup 成功。
quick premerge 的 5 项直接检查与 3 项选中 canary 均通过,仍正确保留 benchmark-sensitive 人工评审 hold;没有把 hold 说成测试失败或合并许可。最初缺少 benchmark import path/可选依赖的运行也保留;当前测试采用正常源码入口与真实依赖覆盖,未宣称当时的跳过已经执行。没有触碰真实会话、凭据、模型、现有运行或评分提交。
语义与 CI 对齐
未知提供方内容应保持未知,诊断观察不能破坏原资源清理。当前 payload.type 的 set membership 让一个未知形状阻断 mandatory cleanup,导致容器继续运行并可能影响容量与后续任务。最小修复是显式类型检查及观察异常隔离/可靠 finally;复验需同时断言正常状态归约、未知内容不泄漏、容器确已停止移除,保留实际 base/head 对照。类型别名属于外部输入规范化的本地词汇,未扩展 LoopX kernel 的任务或配额枚举。按当前策略未获取、轮询或等待 GitHub CI。
我的整体评价
结论为 REQUEST_CHANGES,针对完整 exact head b156068abc91ffdceae3b2c501b06ce6b9873345。最小失败回执有实际诊断价值,新增代码规模和 provider 层归属合理;但诊断失败阻断资源回收使 long_horizon 和 user_experience 均为 regression。应在现有 cleanup owner 内做有界修复,保留正常归约和成功恢复语义,再审完整 head;无需新状态系统或改评分。
已检查 runner、原生 worker、回执及报表消费者;没有渲染呈现变更,视觉评审不适用。本轮未认证真实模型任务、全部 Docker 平台、活动实验采用或可比长程净收益。缺失该诊断字段仍兼容旧回执,消费者不把它当完成/计分许可;没有 default-off 新能力,观察在既有运行清理路径自动执行,故应明确失败隔离。采用评审上下文对真实恢复结果的建议,未继承历史 verdict,也不把上下文送达当收益证明。
English verdict: REQUEST_CHANGES — b156068. An unknown JSONL payload shape raises before mandatory Docker cleanup, leaving a running container in the real backend probe; the immutable base removes it. Current focused tests pass (416, with 3 explicit Docker skips). Isolate diagnostic parsing failures and assert actual stop/remove postconditions. Benchmark review/merge authority remains separate.
Signed-off-by: huangruiteng <huangrt01@163.com>
|
Addressed the requested cleanup blocker at exact head
Validation:
Scoring, task semantics, and launch authority remain unchanged. |
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent; gpt-6.1-sol; OpenAI; runtime_reported; reasoning_effort=max
动机
结论:APPROVE,完整 head 8fedd5674473ad04377bd979d22530b5f0d4c162,实际合并基线 770b11c9512eb7f9097329417072a4ad72d0af78。此前请求修改的容器清理问题已经通过真实后端反例验证修复,旧评审保留为历史讨论。
维护 benchmark runner 的操作者需要区分提供方终止失败,避免为了一个 HTTP 状态重新打开包含私有内容的会话档案。旧运行回执可能只有 runner_failed,原生会话中已经存在的结构化 429 原因没有传到最小诊断投影。
本提案把已收集会话里的已知终止变体归约为类型和 HTTP 状态,并传入原 runtime receipt。它保持原生完成、部分结果、评分和运行权限的 owner,不把一个诊断字段变成任务验收或新的执行许可。
本次验证的可观察结果是:正常 429 得到最小结构化诊断;未知事件不会泄漏私有正文或阻断容器移除;可选观察器本身抛异常时,也会执行原生清理。完整模型实验、现场采用与长期净收益没有由本评审认证。
改动思路
把观察留在现有 benchmark provider 适配层并复用 runtime receipt,诊断失败与必须执行的资源清理已隔离。
当前 PR 交付有界、可丢失的最小失败诊断及可靠清理,不改变评分、任务语义、执行权限和原生终止结果所有权。
完全不改会继续保留人工重读档案的成本;让报表重新扫描完整会话会扩大敏感面;添加新的失败状态服务则重复原生运行与回执 owner。当前设计沿原收集边界读取有限尾部,再由原成功/异常分支携带可选投影,范围合适。
最强反对理由是:一个自动运行的诊断解析器会增加清理路径的成本,甚至把未知输入异常变成资源泄漏。上轮 b156 的实际 Docker 反例证明这不是假设。现在 payload 类型先检查、观察异常只记录异常类,外层 finally 无条件进入 native cleanup;内层 finally 再验证容器确实不存在才归还注册容量。没有为通过评审增加另一套资源状态或人工确认流程。
这是现有 collector 内的有界简化和失败隔离。Python 留在已存在的 SForge/Harbor 外部 provider 适配层有依据,不需要为该归档观察建立新的共享控制面或类型化决策 owner。这里按真实调用顺序说明控制流,没有用图示充当执行证据。
具体改动
独立规格采用 benchmark/runtime/RUNTIME.md,spec revision 770b11c9512eb7f9097329417072a4ad72d0af78,并检查同版本 SForge native cleanup。逐条映射:Configure the native job 的结构化错误、未知保持未知和私有正文边界为 implemented;Results, timeout and recovery 的原生结果与资源回收为 implemented;Native SForge task entry 的既有任务、权限、预算和 worker owner 保持。新增说明是诊断文档,没有扩大实验执行授权。
当前完整差异为七文件 +365/−52。与上轮 b156 相比,修复集中在事件类型验证、诊断异常隔离、cleanup 的 finally 结构及相应回归。原 run.py 的两个回执消费者和新增文档段落未变;没有把只读修复差异当成完整 PR 的批准依据。
关键代码讲解
_jsonl_tail限制单文件尾读为 2 MiB,丢弃截断首行,跳过无效 JSON;符号链接和不可读文件不作为新诊断输入。观察有覆盖边界,未命中不能证明没有发生错误。_terminal_provider_failure先确认 event_msg、Mapping payload 和字符串事件类型,再对已知 terminal/error variant 与整数 HTTP 状态归约。未知变体、自由文本、消息、路径和不合法状态不进入新回执;本地闭集只规范化上游 Codex 事件,不扩展 LoopX kernel 的任务词汇。observe_terminal_provider_failure最多检查 32 个最新文件;反向选择最近终止事件。同文件中较晚的成功覆盖较早的失败;这是一份有界诊断提示,不是原生结果的第二权威。RecordingDockerBackend.cleanup_container保留两个 session home 的既有私有收集和 native Goal 回执读取。诊断异常把 provider_failure 清空,并只写入 error_kind;无论收集、反馈关闭还是观察是否失败,都会到达super().cleanup_container。容器仍在时拒绝release_registration,不能把“调用过 cleanup”当成资源已经释放。benchmark/edgebench/run.py仅在原成功及异常分支附带 provider_failure;final_result、partial_result、score_countable 与 native_goal_outcome 的决定仍由原 runner 承担。三组测试覆盖 reducer、实际 collector 和真实 CLI 回执消费者。
这次没有改变普通任务参数或已有模型提示。新字段缺失时旧消费者继续处理原回执;未知错误没有通过 substring、自由文本或异常消息被猜成已知提供方类别。
对主干的风险
当前精确头的五个 provider/runtime/native outcome/online/report 测试文件共 418 通过、4 项显式 Docker 跳过,使用实际 SForge 193cecda05661380575b16c9fcc88a8c16ece9f3 与 Harbor 0.20.0。另显式运行新增实际 Docker 异常清理回归,1 通过。默认套件中的四项跳过没有被改称一次全绿,其中另外三项 opt-in Docker 场景本次未运行。
独立探针使用无网络、无模型的专用合成容器,分别在实际 base/head 输入正常 429、末尾 payload.type=[] 和深层未知记录;产品 cleanup 后实际 Docker 查询均确认容器已不存在。当前已知失败诊断只包含 schema、kind、整数状态。上轮同一个未知形状留下运行容器的反例没有被重标为历史通过;当前重新执行证明修复。
又独立注入三个失败窗口:观察器抛 TypeError,产品仍完成实际 stop/remove 且不复制异常消息;feedback.close 抛 RuntimeError,原异常保留但实际容器仍移除;native cleanup 被故意置为保留实际容器,容量释放回调为零并明确拒绝。容量回调使用注入观察器核对顺序,未宣称真实在线容量服务资格;容器状态来自实际 Docker。所有自有测试容器最后均已回收,善后与产品清理后置条件分开记录。
quick premerge 五项直接检查和三项选择 canary 均通过,整体仍保留 benchmark_sensitive 的 maintainer review hold。这个 hold 没有被解释成测试失败或自动合并许可。实际 base/spec 和依赖边界已核对,改动路径的源代码、原生结果与报表消费者已重审。
语义与 CI 对齐
mandatory cleanup 不依赖 optional diagnosis 成功,这一原约束已由 finally 控制流和真实资源反例建立。诊断内容是从既有原生事件派生的 hint;它不授予完成、评分、重试、网络、费用或新任务权限。
本功能在既有已授权 trial 的清理路径自动观察,没有声称新增 default-off 开关。无会话、未知变体、自由文本和较晚成功的对照保持原结果行为;原有 default-off 的执行模式、权限和 prompt 未变。没有获取、轮询、等待或调度 GitHub CI;本地通过也没有被当成 hosted qualification。
我的整体评价
本次对完整 8fedd head 的判断是 goal_achieved、proportionate,long_horizon 与 user_experience 为 preserved。已经证明的是最小失败诊断和故障下资源清理;减少未来人工成本的程度、完整模型任务与可比长期收益仍未测量。
最初的问题可由现有 owner 的小范围修复解决,当前实现已完成这项修复,没有新增运行时服务、持久同步义务或用户操作。原公开阻塞已被独立反例解除,本轮没有新增 blocking finding;旧评审、讨论、人工 hold 和合并权限分别保留。
已检查 runner、原生 worker、回执及报表消费者,没有渲染呈现变更,视觉评审 not_applicable。全部 Docker 平台、活动实验/现场安装、真实模型采用、在线容量服务和完整成本资格均不在本次证明范围。批准代码不授予 merge、dismiss、安装或运行实验的权限。
English verdict: APPROVE — 8fedd5674473ad04377bd979d22530b5f0d4c162. The prior diagnostic-induced container leak is fixed. Actual Docker base/head probes remove normal and malformed-session containers; injected diagnostic and feedback failures still clean up, while a deliberately retained container prevents capacity release. Current focused tests: 418 passed, 4 explicit Docker skips; the new explicit cleanup test also passed. Benchmark-sensitive maintainer hold and broader model/platform/merge qualification remain separate.
Official EdgeBench workers can exit after a structured terminal provider error while their runtime receipt records only
runner_failed. Capacity and failure observers then miss terminal 429s unless they re-read private session archives themselves.This change reads only a bounded tail of the newest collected Codex JSONL sessions after container cleanup. It accepts the allowlisted structured
responseTooManyFailedAttemptsvariants, retains only the normalized kind and HTTP status underruntime-receipt.json.provider_failure, and ignores free text, unknown variants, messages, and local paths. A later successful terminal event takes precedence over an earlier failure.Validation:
git diff --checkpassed.The generic semantic-inventory advisory is scoped to
loopx/and rejectsbenchmark/paths. The full semantic-vocabulary drift smoke passed after installing the repository's TypeScript development dependencies. The new closed sets remain local to the EdgeBench adapter and normalize an upstream Codex event vocabulary; they do not extend the LoopX kernel vocabulary.