Repository navigation
fix(benchmark): allow adjudicated runner recovery - #8462
Conversation
Signed-off-by: huangruiteng <huangrt01@163.com>
Signed-off-by: huangruiteng <huangrt01@163.com>
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
精确 head 9a8b5900a7ada946362787cf5486977b5cda5d94 未发现阻断代码问题。以下是显式状态边变化的批准,不是 merge 或 benchmark execution 授权。
动机 / Motivation
维护实验看板的操作人,在最初的运行无效判断被后续正式结果纠正后,需要用同一 run 身份读回更正状态。旧 canonical upsert 把 runner_invalid 永久锁住,即使提交满足既有校验的完成结果也拒绝更新;本次允许它单向变为 completed,保留 completed/cancelled 不能回退或重开的规则。
独立真实 CLI 对照已验证:基线拒绝同一更正输入,新提交可预览、显式写入并读回同一行;零分可保持有效计分,缺少完整性或官方指标的计分请求仍被拒绝。这只修正既有可信调用者的 canonical 看板状态;不会运行实验、检查官方产物本体、授予 paid execution 或宣称 benchmark 成绩提高。
改动思路 / Approach
现有 CLI 读取 row 后先用原 normalizer 验证,再通过同一个 transition validator 进入 File JSONL upsert。最小修正就是给原表增加一条边,preview 和 execute 同享规则,不必重建裁决服务或另造结果 ledger。preview 保持无写;显式 --execute 才更正同一 run,独立 experiment-board-show 可读回结果,操作者无需新增确认轮次。
状态与计分不变量继续归原 normalizer/transition owner,File IO 只负责既有落盘;canonical 更正和无裁决身份的 shard 合并有不同语义,不能把时间戳当成裁决。
当前范围仅一条既有状态边、对应回归与说明;不新建 adjudication 服务、第二份 authority、官方产物认证或实验启动入口。
具体改动 / Changes
关键代码讲解
完整范围三条路径 +38/−1。experiment_board.py:27 的 _RUN_STATUS_TRANSITIONS 只给 runner_invalid 增加 completed;completed/cancelled 仍只有自身边。normalize_benchmark_experiment_board_row:265 本身没改,继续要求计分时 status=completed、integrity_qualified、official_result_present,并校验声明的 primary/guardrail metrics;指标值0是合法结果。注意:它校验调用者上报的数据,不读取官方产物本体,completed 本身也不自动意味着可计分。
upsert_benchmark_experiment_board_row:480 沿原 stable key 与 domain-state merge callback 写入,先校验再写;_advance_reconciled_benchmark_experiment_board_row:509 的 shard 合并语义保持不变:同 key 互斥终态先报冲突,不能只凭较新 observed_at 把一个 terminal 覆盖为另一个。canonical 显式更正与无裁决身份的 shard fold 不是同一权限边界。README 的五行说明与新增两个回归准确表达这个差别。已有 completed→completed 可更新 metadata 的能力来自 base,本次没有新授予任意整行不可变或新增变更权。
规范为 固定 base 的 experiment-board 合同,spec_revision c22ed9fb4f1557144665155156d1c04a76b4ffa6。本次映射 BOARD-IDENTITY(稳定run身份)、BOARD-COUNTABILITY(既有计分条件与零值)、BOARD-PROJECTION(board不成为执行authority)三项均已实现。旧说明没有写出新单向边,这一边是维护者本次明确提出的 intentional change,不把新文档当独立旧规范,也不声称输出完全等价。
对主干的风险 / Risks
最重要的反例是“多开一条边”被误实现为所有terminal可重开,或只看completed就接受未具资格的得分。本轮经真实 public CLI、隔离File ledger完成 head12/base9个正负场景,fixture SHA 7bb6d1409eb2c5beae434791415a0e3e303ced75915fe0c00e8e3064b048b36c。基线的同一候选在preview/execute均exit2且ledger不变;head preview0无写,execute0更新同一行,zero/flags读回正确,重复upsert不增行且ledger字节不变。head完成后的demote/reopen、另一个新cancelled run的reopen、缺guardrail/完整性却要求计分、互斥terminal shards全部exit2且无写。
独立board套件head52 PASS、immutable base50 PASS;Ruff通过,mypy17个文件通过。标准premerge原6项direct与18项selected通过,另一个semantic scan在120.781s超时,因此那份premerge receipt仍是failed并带benchmark-sensitive manual hold1。随后正确来源的base/head扫描也各在120s超时,部分输出未保留;另一次来源不合格的PASS完全不计入资格。当前完整head在同一120s限额内38.542s通过该必要扫描,固定base随后28.413s通过,完整语义输出一致。判断基于当前实际完整扫描、未变scanner/registry与此PR既有status词汇、以及独立CLI不变量覆盖;不把历史失败改成PASS、不猜旧根因,也不声称一次green证明宿主延迟已稳定。远端CI按政策未查询。
语义与 CI 对齐
本次复用既有benchmark状态闭集,扩的是明确的一条关系,没有新Enum、私有正文分类或通用Goal门。真实caller验证了新接受边及两个相反失败方向;计分资格依旧独立于status,保留diagnostics、no-effect与stable-key读回。README属于操作指导,不能替代官方资格证据,也不能授予实验、付费、模型或合并权限。
我的整体评价 / Verdict
APPROVE。长程接续 preserved:更正沿原run身份继续,重放和其他终态约束保留;CLI用户体验 improved:既有提交/预览/显式写入/读回即可完成任务,无新增操作轮次。这个有界修正已经复用最邻近owner,同域简化已应用,不需为一条边另加层或语言迁移。已检查CLI/JSON和README;没有渲染呈现变化,截图不适用,渲染变化未验证范围为none。真实benchmark、官方产物真实性与installed adoption仍在本次验证外;原premerge manual benchmark gate、当前main集成及merge-readiness/维护者授权保持独立,不由此批准自动解除。
English verdict: APPROVE 9a8b590. Real CLI base/head tests verify the intentional one-way canonical correction, zero-score countability, stable-key readback and unchanged rejection/no-write boundaries. Current required semantic validation passes at the original limit; historical timeouts and the benchmark merge gate remain explicitly separate.
A benchmark run can fail closed as
runner_invalidbefore later post-run evidence proves that its score is valid. The board currently makes that provisional state irreversible, so deterministic adjudication cannot publish the corrected completed row for the same run identity.This change permits the one-way
runner_invalidtocompletedpromotion while keepingcompletedandcancelledterminal rows immutable. Provider-ledger reconciliation continues to reject conflicting terminal shards.Validation:
uv run --extra test pytest -q tests/capabilities/test_benchmark_experiment_board.py(52 passed)uv run --extra test ruff check loopx/capabilities/benchmark_toolkit/experiment_board.py tests/capabilities/test_benchmark_experiment_board.pygit diff --checkFuture-facing review: the existing transition table remains the single lifecycle owner; no new command or parallel adjudication path is needed.