Skip to content

fix(benchmark): preserve observed usage across interrupted Turns - #8549

Merged
huangruiteng merged 2 commits into
mainfrom
codex/benchmark-interrupted-usage
Nov 11, 2026
Merged

huangruiteng merged 2 commits into
mainfrom
codex/benchmark-interrupted-usage

Conversation

@loopx-agent

Copy link
Copy Markdown
Collaborator

Goal And Delivered Outcome

  • Outcome basis / optional anchor — A reproducible interruption and resume defect in the benchmark worker and usage reader.
  • Goal/source and gap — The runner can resume the same Codex session after the phase cutoff. The usage reader discarded the identified abort and rejected the later Turn as overlapping. The returned wake receipt also shared mutable counters with late gateway callbacks.
  • Observable before → after — On both File and SQLite, the opt-in reader can now reconcile persisted counters across the interruption and the resumed Turn. The terminal receipt preserves the pending count observed at invocation exit. See the worker and Research validation below.
  • Issue/task and intended base — Self-contained fix against main.

Author Declaration

  • Written by — model_agent (OpenAI GPT in Codex).

Implemented against

Criterion Disposition Owning path Evidence
Preserve observed counters and boundaries across an identified abort and same-session resume implemented trajectory_codex_usage.ts, trajectory_request_usage.ts Recorded requests reconcile once, including compaction. The interrupted Turn stays out of the completed count.
Maintain complete-session validation, source binding and observed-only privacy implemented trajectory_assessment_store.py CLI rejects interrupted captures in complete mode. Observed mode exposes only the bounded counter evidence.
Retain an invocation-exit snapshot when a provider callback arrives late implemented provider_request_admission.py File and SQLite real-worker comparison and gateway regression.
Read the interrupted interval in the existing Research range and download implemented research-usage-selection.ts Installed wheel with real backend and synthetic browser fixture.
  • Self-check before submission — Inspected the typed reader, evidence redaction, request association and receipt exit. Ran the listed checks and verified the output of the installed wheel.

Scope And Continuation

  • Completed scope and remaining work — The existing opt-in --include-incomplete-usage uses a matching native turn_aborted Turn ID. Legacy data and the default complete-session mode keep their integrity requirements. Unpersisted responses and complete billing remain unknown.
  • Slice boundary / successor — Complete within interrupted-usage observation. The same reproducible path covers runtime exit, evidence readback and range selection. Provider qualification and benchmark outcome comparisons require separate evidence.

Validation

  • Tested revision — d85699e0387942835c743c25437a1dd09c3c7050.
  • Run state — finished.
  • Input classes — synthetic.
Check kind Result Public-safe evidence / limitation
regression_parity passed On beff0f3e55d1 the real worker resumed the session, but the reader rejected the resumed trace as overlapping and a late callback changed returned pending from 1 to 0. On the candidate both backends retain pending = 1 and reconcile three persisted requests, including one compaction.
real_backend passed Real worker on isolated File and SQLite with scripted Codex and a loopback Responses fixture. The expired phase refuses a new launch. A permitted phase resumes the same session. The late response's unpersisted usage stays unknown.
real_entrypoint passed The isolated installed wheel's CLI refuses complete mode and reads back the observed pack. The research-turn-costs browser scenario uses the installed wheel and real local Research backend. Chinese and English checks cover source evidence, download and retry, keyboard return and narrow viewport.
integration passed 93 Python tests covering trajectory registration, provider observation, benchmark worker and request admission.
unit passed 95 TypeScript/JavaScript trajectory and range tests.
static passed TypeScript chat build, diff whitespace and privacy checks, RFC bilingual diff check, and signed commit.
  • Coverage and gaps — The scripted host exercises the production runner and gateway without making paid or external requests. Live provider billing and outcome differences remain unmeasured.

Frontend / Visual Evidence

  • UI impact — changed.
  • Before — The same native capture was rejected at registration, so there was no interrupted interval to open. The Research overview uses the same layout.
  • After — The synthetic interrupted Turn is visible as incomplete in the existing detail, with its persisted counters and Counter evidence.
  • First viewport and preview — Isolated installed wheel from d85699e03879, synthetic capture. The local test server is disposable.
research-turn-costs-overview research-interrupted-turn-1440 research-interrupted-turn-390
  • States and viewports shown — Research overview, interrupted and completed rows together at desktop and 390 px. The browser test separately checks the unmeasured final Turn and download retry.
  • Source data — synthetic.
  • Attention review — The existing range, totals and source control cover resumed sessions. There is no extra page or control to learn.
  • Craft review — The detail uses the existing row hierarchy and incomplete state at both widths.

Type of Change

  • Bug fix
  • Documentation update
  • Test update

LoopX Area

  • Benchmark boundary
  • Public docs or presentation surface

Technical Direction

  • Long-horizon benchmark evidence.

Shared-authority RFC fixture impact

N/A.

Boundary Checklist

  • The diff, description and attachments use public-safe examples.
  • The slice covers the reproduced observation defect.
  • The bilingual RFC diff check passed.
  • The visual evidence is included below.
  • The commit includes a DCO sign-off.

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.

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

Reviewer: model_agent · gpt-6.1-sol · OpenAI · runtime_reported · max

评审提交:d85699e0387942835c743c25437a1dd09c3c7050

动机 / Motivation

受影响的是在 Benchmark 恢复同一 Codex 会话的维护者,以及在 Research 检查这次捕获用量的读者。基线会把匹配的中断后启动判成重叠,且已返回的请求摘要仍随异步回调变化。候选在 opt-in 捕获中记录具名中断、后续轮次和各自的已观测计数,并给返回的摘要复制一份计数。已用真实 CLI 和隔离安装的 wheel 读回 5,900 个输入 token、9 个完成轮次、第 7 轮的 700 个输入 token,以及没有计数的末轮。仅观察已持久化计数和本地网关退出窗口。真实账单、未持久化用量和基准成果差异仍未知。退出后的响应若在网关清理期间返回,快照仍会记录清理时而非退出时的 pending。未带 ID 的 abort 也会作为证据末事件显示。

改动思路 / Approach

用量与区间共用现有计数所有者,Research 保留已有入口。两处修复分别留在原 invocation 的退役路径和已核验源的证据读回边界。 沿用 capture opt-in 和已部署的 Research 区间入口。用源摘要绑定与本地 HTTP 核对内容边界,用已分派的 loopback 请求确定退出与清理先后。

具体改动 / Changes

关键代码讲解

14 个文件,增加 219 行、删除 61 行。依据 docs/reference/trajectory-assessment.md 核对 observed-same-session、ordinary-default、original-exit-pending、readback-terminal-binding、research-range。 基线规范

TypeScript 按 native 事件和 Turn ID 关闭匹配的中断轮,计算相对上次会话累计量的差分,并保留继续轮次和请求核对。Research 对已有轮次按源行号排回时间顺序,范围聚合与导出共用投影。Python 重新读取有摘要保护的源,将起点、计数和终点剪成有限的证据。Runner 在原有 gateway lifecycle 中复制回执,复制位置晚于清理窗口。两条生产读写路径都应使用自身约定的原边界。 实现

对主干的风险 / Risks

[P2] pending 快照晚于退役。 已分派的请求在退役时 pending=1,在 gateway shutdown 期间收到响应,最终回执写 pending=0。同一 loopback 反例在基线和候选都可复现。现有新增用例在 serve 已完全返回后才放行响应,遗漏清理窗口。

[P2] 匿名 abort 被作为末事件读出。 源 CLI 将同一捕获的第 7 轮标为开放到第 30 行。Counter evidence 却输出第 29 行的无 ID abort。主干在相同输入中只读回已绑定的起点和计数。

语义与 CI 对齐

88 项定向 Python、14 项直接 TypeScript/JS、Ruff、配置内 mypy 和 packaged chat build 通过。standard premerge 的 6 项直接、19 项定向检查通过,benchmark_sensitive 保留维护者审查。全 TS 套件中两项 digest inventory 断言在主干与候选上同样失败,涉及未改的 benchmark CLI 来源模块。带匹配的测试与错误详情记录为现有失败。 全仓 Python 未跑,远程 CI 未查询。

我的整体评价 / Verdict

请在原 invocation 退役时冻结回执,再覆盖清理过程中和清理之后的两种延迟响应。让 Counter evidence 根据相同的 Turn ID 和终点资格选取 abort,覆盖无 ID 的开放尾轮与匹配中断的读回。 作者的桌面和窄屏证据

隔离 wheel 的桌面首屏保留研究历程和「来源与用量」入口。展开后,第 7 轮的未完成标记与输入 700 同行,计数证据一键可达。390 px 展开态以两列呈现计数,来源摘要留在下一层。观察使用 11 轮合成捕获。原生桌面安装、390 px 默认首屏和真实账户长历史未独立核验。

English verdict: REQUEST_CHANGES. Observed usage across a matched abort is readable. Freeze pending at retirement and prevent anonymous aborts from appearing as a Turn boundary.

@songoow songoow left a comment

Copy link
Copy Markdown
Collaborator

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 Pro · OpenAI · self_reported

Reviewed exact head: d85699e0387942835c743c25437a1dd09c3c7050 · baseline: beff0f3e55d1f70eceebbd8e78c11f1cff34643b

动机 / Motivation

在同一 Codex 会话被中断后继续运行的 Benchmark 维护者,以及在 Research 中检查已发生用量的用户,是这次修复的直接使用者。

主干会忽略有轮次 ID 的中断,随后把恢复轮判成重叠;候选让明确匹配的中断保留已观测计数,并在原有轮次范围和导出中继续阅读。

真实 CLI 和 Research HTTP 路径已经证明恢复捕获可读,但退出快照仍会被清理期间的响应改变,匿名中断也被展示为终点证据。

范围是已持久化计数、原调用退出时的请求观察和既有 Research 读回;不证明完整账单、未持久化响应的用量、模型收益或新的执行权限。

改动思路 / Approach

继续让 TypeScript 判定轮次和计数,Python 负责原文件读写与网关回执,React 只对已核验投影做排序、求和和展示,符合现有所有者分工。

这 75 行新增生产代码可以留在原路径;应把冻结点移到原 invocation 首次退役,并让 Counter evidence 采用同一投影认可的轮次终点,无需新增计费账本、生命周期状态或重试框架。

本次把带有匹配 Turn ID 的原生 turn_aborted 纳入已有观察模式:中断轮保留自己的区间和已记录差分,完成数只算真正完成轮,后续轮继续从同一会话累计计数核对。默认完整捕获仍拒绝中断。请求核对与工具关联同步关闭原轮,避免跨轮混合;已有部分用量类型被复用,没有从进程死亡或文本理由推断完成。

具体改动 / Changes

完整检查 14 个文件,+219/-61:生产 8 文件 +75/-32,测试 4 文件 +111/-5,浏览器示例 +10/-4,文档 +23/-20。基线规范是 docs/reference/trajectory-assessment.md,固定版本 beff0f3e55d1f70eceebbd8e78c11f1cff34643b。以下名称是本 review 对规范段落的索引:observed-only(只计已观察量、未知保持 null)、complete-default(默认完整模式保留资格要求)、source-bound-evidence(原来源绑定与有限计数证据)、research-range(按时间选择、排序不改成员、导出保留范围)。前三项中的来源终点读回仍有 F2;新匹配中断支持是文档明确披露的扩展,不把它误当成违反旧“不支持恢复”描述。

关键代码讲解

  • summarizeTrajectoryCodexUsage 使用 isIdentifiedTurnAbort,并核对当前 Turn ID;partialTurn 复用原计数差分规则。没有计数的尾轮仍为 null,重复快照不重复计量,错误 ID 拒绝。

  • reconcileTrajectoryRequests / summarizeTrajectoryLoopXRequests 和工具关联路径同时消费具名中断,保留镜像去重、会话/请求身份与不同计数口径;新增 interrupted_turns 不计入 completed_turns。

  • read_usage_turn 先从已注册投影找到轮次,再重读并核对整个源文件,只返回有限计数字段。F2 是此处自行把所有 turn_aborted 当作终点,遗漏投影已经要求的 ID/终点资格。

  • ProviderRequestAdmission.serve 复制原 invocation 的摘要,但复制发生在 gateway 上下文清理后。worker 的 before_cleanup 已提前调用 retire,二者之间仍有在途响应窗口。

  • researchUsageRows 合并完成、中断和开放轮,按 first_line 排序后赋序号;原 ResearchTurnCosts、范围计算和导出直接消费,仍把中断标为“未完成(仅已观测)”。

对主干的风险 / Risks

F1 · P2:原线程 4532963882 独立复核仍成立。 用真实生产网关和已分派 loopback 请求,调用 worker 使用的 before_cleanup/retire 后观察 pending=1,再在真实 gateway.shutdown 期间释放上游响应;候选最终回执为 pending=0。相同基线也得到 0,因此这是本 PR 声明修复仍未覆盖的原缺陷,不是新引入的回归。另一个对照让响应在 serve 返回之后到达:主干会从 1 变 0,候选保持 1,证明新复制确实修好较晚窗口。请在首次退役持锁冻结一次,并覆盖清理中、清理后的两种回调;不是把本应继续记录的请求事件日志停掉。

F2 · P2:原线程 4532963885 独立真实 CLI 反例成立。 同一八行源包含已完成 a、开放 b、b 的计数、无 ID abort,以及一个后续空 token_count。主干与候选都把 b 保留为开放到第 8 行,输入差分 40;但候选 Counter evidence 额外返回第 7 行 {type: turn_aborted} 作为末事件,主干只返回已绑定起点和计数。匹配 b 的 abort 对照正确产生 interrupted_turns;错误 ID 拒绝。请让证据终点与捕获投影认可的 Turn ID、终点行及事件资格一致,覆盖匿名 abort 后仍有观察事件的开放尾轮。

没有重复新增 inline;两条现存线程保留准确位置。第二条不涉及原始消息/中断理由泄漏:合成私密理由仍被剔除,来源变化会拒绝读回;风险是观察语义与读出的证据相矛盾。第一条也不证明重复派发或配额绕过,只涉及声明的退出时刻计数。

语义与 CI 对齐

独立执行 93 项 Python(55 项 trajectory store / gateway observation,加 38 项 worker / admission)、95 项 TS/JS(所有 trajectory 与范围测试)、build:chat(含 TypeScript)及 diff check,全部通过。相同输入的真实 CLI 对照中,普通完整捕获在主干和候选都成功且观察投影完全相同;带匹配中断的恢复捕获在主干被拒绝,候选仅在显式观察模式成功。实际 Research HTTP 后端与生产 React 组件在 JSDOM 的中英文交互均通过:11 轮、9 完成、1 个无计数尾轮、5,900 已观测输入;耗时排序定位第 7 轮,Counter evidence 返回匹配中断,下载仍包含全部 11 轮,第二页未知量显示为 —,无 mutation 请求且原来源不变。这不是完整页面浏览器绘制,也不复用作者声称的测试次数。

我的整体评价 / Verdict

REQUEST_CHANGES。这个扩展能把中断前后的观察接起来,现有归属、默认门控、未知量和隐私边界大体保留,范围与机制规模相称。阻塞点是两条已经验证的时间/身份边界:退出快照必须代表退出时刻,证据读回必须保持原投影认可的结束资格。修复可局限在现有两个函数,不需要扩大方案。

本轮没有完成真实浏览器布局验收:本地 Chromium 的 Unix socket 创建受限,云浏览器无法连接隔离测试服务。

桌面和 390 px 首屏、展开态及长内容的实际绘制仍未独立复看;React/JSDOM 验证只能证明组件交互和数据读回。

长期运行的用量诊断已有可验证增量,但这些结果不能推断成本降低或模型能力提高。修复后重跑上述相同反例,并补齐实际桌面/窄屏的默认和展开视图;现有测试全绿不能覆盖这两个遗漏窗口。

English verdict: REQUEST_CHANGES

…undaries

Integrate the reviewed branch with current main and address the verified review finding.

Signed-off-by: huangruiteng <huangrt01@163.com>

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator

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

动机 / Motivation

在同一 Codex 会话中断后继续运行 Benchmark 的维护者,以及从 Research 核查轮次用量的用户。 原读者忽略带 Turn ID 的中断,把恢复轮当成重叠。初版虽能读取,清理期间到达的响应仍会改写退出时 pending,且开放轮内的匿名 abort 会在证据面被误当成终点。

显式观察模式记录匹配的中断轮,继续核对同一会话后续计数。原调用首次退役固定回执,后续请求结果仍追加到事件日志。Research 从同一捕获按范围读回,只展示该投影认可的终点。

本次输出是已持久化用量与退出快照。完整账单、未持久化请求的计数、模型收益和运行授权仍由各自来源负责。

改动思路 / Approach

延用 TS 轨迹校验、Python 文件读回和 Research 既有范围控件。在原 retire() 持锁固定回执一次,独立保留网关事件日志。证据读回按已核验投影区分 completed/interrupted/open,使用原 Turn ID 与结束行筛选。

同一来源哈希继续约束读回,计数只包含可公开的数字和事件标识。一次退役快照与后续诊断日志各自沿用原存储,TS 保有中断识别和差分计数决策。 interrupted_turns 和 read_usage_turn 都从绑定会话的持久事件派生。回执是原调用退出时间截面的观察,后到的请求结果留在同一 invocation 的日志,两个来源各自表达自己的时点。

具体改动 / Changes

用同一 Turn ID 关闭中断区间并继续观察累计计数,保留已完成轮次数;匿名 abort 不改变活动边界。 summarizeTrajectoryCodexUsage

锁内第一次退役把统计复制进自己在原回执中的位置,清理期间和之后的观察继续写原事件日志。 retire

对照投影判定的结束类型、结束行与 Turn ID,完整复核原文件摘要后返回有限计数证据。 read_usage_turn

按来源行编号排列已完成、中断及开放的轮次,同一序号服务排序、范围和导出。 researchUsageRows

15 文件 +256/−67。production 8 文件 +80/−35,tests_or_fixtures 6 文件 +153/−12,docs 1 文件 +23/−20。规格依据为 docs/reference/trajectory-assessment.md 的 Solver capture registration、观察计数、源绑定与 Research 读回,版本 de684cd7eaae46114c1e51fefdadb09a920e4bae。评审映射 source-bound-observed-usage 要求 只有匹配的已观察 native Turn 和计数可进入可选投影,完整捕获仍按原资格。来源与终点一致,退出时快照和稍后到达的事件各自留证。 结果为 implemented,验证来自 pytest test_provider_gateway_observation.py、test_trajectory_assessment_store.py、benchmark/test_provider_request_admission.py、test_worker_phase_budget.py;trajectory TS/Research JS;打包 research-turn-costs 浏览器场景。

原完整捕获仍要求完整轮次。中断继续读取由 --include-incomplete-usage 显式开启。原 worker 网关启用条件和版本约束在已有 off/on 测试覆盖。普通 Research 继续使用同一列表、范围、下载与来源回读。 现有 pack 不含 interrupted_turns 时按空列表读,开放尾轮和完成轮沿用原字段;仅已接受中断的投影增加可选列表。持续使用原 CLI 和已打包 Research 控件。

对主干的风险 / Risks

错误归属会重复累计或制造一个不存在的终点。直接从已绑定投影选择结束事件,先核验文件 SHA-256。退出时快照可能包含 pending,日志可显示后来完成或拒绝,这两个数字表达不同观察时点,不能当成完整账单。

真实注册 CLI 对匹配中断和后续恢复计数做读回,默认完整模式仍拒绝中断。loopback 网关清理中或清理后收到响应时退出 pending 保持 1。真实 File/SQLite 旧请求不会被新 invocation 接收。独立安装 wheel 打开 Research,11 轮中有 9 个已完成、一个中断、一个未知计数开放尾轮,输入合计 5,900。

匿名 abort 后还有观测,开放轮计数证据只返回第 3、5、6 行,排除匿名第 7 行和私有原因。错 ID、失配捕获或替换源仍拒绝。迟到请求被原 owner 拒绝并记日志,后续 owner 的 process、统计和 dispatch 保持正确。

Python 56 项 store/网关和 54 项 worker/phase 测试通过,95 项 TS/JS 通过。TS 类型检查、Ruff、Chat 构建、wheel 安装及中英文 Research 浏览器场景通过。浏览器实际核对桌面与 390 px、展开、范围/导出和重试。 标准预合并 6 项 direct、19 项 smoke 均通过。保留 benchmark_sensitive 手工项。本次维护者评审核对真实 File/SQLite 的原有请求授权、迟到拒绝和退出观察边界,并复核合成 Research 界面。

实际服务是隔离本机网关与已打包的 Research,合成捕获使用真实 CLI/HTTP。未发付费请求,未测生产计费、真实模型用量或长程效果,也未将历史 CI 红灯标为已经归因。

我的整体评价 / Verdict

评审版本 fc50af4ab64fe2986a84a62845620ca91d96eed3。实测计数、退出回执与已打包 Research 的范围和证据已通过上述实际入口验证。原评审发现的条件均以修复前反例和当前结果对应核查。

已检查桌面与 390 px 的默认研究页和展开态。默认页将来源与用量折叠在研究历程中,窄屏仍能定位入口。展开后范围、已观测计数与来源可访问。多轮列表和中断、未知尾轮均实际通过排序、分页和证据回读。 观察使用安装到隔离环境的 wheel 与合成捕获。未覆盖真实计费、用户已安装 App 及其他设备尺寸。

English verdict: APPROVE. Head fc50af4. The reported findings are resolved and the changed behavior is covered by the stated checks.

@huangruiteng
huangruiteng dismissed songoow’s stale review November 11, 2026 10:16

Original findings verified resolved at fc50af4. The first retirement now freezes the receipt under the invocation lock. The real gateway tests cover callbacks during and after cleanup. File/SQLite delayed requests still receive the original owner refusal and the journal retains the late event. The counter reader requires the projected end kind, end line and Turn ID. The real registration/readback keeps the anonymous-abort case open and excludes the anonymous event. The matched resumed case retains its abort. The installed Research fixture passed desktop and narrow range, evidence and download checks. Maintainer review: #8549 (review). Original discussion retained.

@huangruiteng
huangruiteng merged commit ee4605f into main Nov 11, 2026
7 of 10 checks passed
@huangruiteng
huangruiteng deleted the codex/benchmark-interrupted-usage branch November 11, 2026 10:18
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.

3 participants