Skip to content

perf: bound recent rollout history reads - #7700

Open
loopx-agent wants to merge 2 commits into
mainfrom
codex/semantic-bounded-rollout-read-20261030
Open

loopx-agent wants to merge 2 commits into
mainfrom
codex/semantic-bounded-rollout-read-20261030

Conversation

@loopx-agent

@loopx-agent loopx-agent commented Oct 29, 2026 •

Copy link
Copy Markdown
Collaborator

Goal And Delivered Outcome

  • Outcome basis: existing Task/status readers request a recent event window, but load_rollout_events(limit=...) still read and parsed the entire retained JSONL log.
  • Before → after: recover the requested number of valid records directly from the file tail, in chronological order, with complete Unicode/long rows and existing corruption tolerance.
  • Intended base: loopx-project/loopx:main; self-contained maintenance repair.

Author Declaration

  • Written by: model_agent — OpenAI GPT-6 family / Codex.

Implemented against

Criterion Disposition Symbol / path Evidence
Last N valid records, complete content and chronological order implemented load_rollout_events Unicode, large-row, malformed-row and final-newline cases
Avoid reading unrelated history once the window is complete implemented _recent_rollout_events Byte-count regression fails on the baseline and passes here
Preserve full/strict reads, missing-file behavior and streaming fallback implemented iter_rollout_events, recent reader Unlimited/strict/nonseekable regressions
Retain actual callers' authority, freshness and recovery implemented Existing Task/status projections Isolated File/SQLite CLI, status and resume tests
  • Self-check: reviewed the complete two-file diff. Extracted the existing row parser so strict and recent reads share one codec. Python remains the file/codec adapter; TypeScript retains control-plane decisions.

Scope And Continuation

  • Complete within this scope: recent-history IO. Existing data formats, window limits and typed decision owners remain unchanged.
  • A bounded complete-CLI comparison is recorded below. Node cost attribution, installed-host adoption, full latency qualification and long-horizon cost remain open; historical budgets/failures are unchanged.

Validation

  • Tested revision: 7243b4ce51739eb440a44537ee9fd54d82002e2f.
  • Run state: finished.
  • Input classes: synthetic, public_fixture, authorized_private_read_only.
Check kind Result Public-safe evidence / limitation
unit passed 29 loader cases within the 107 focused tests
real_entrypoint passed Actual File/SQLite CLI source failure/recovery, status snapshots, resume conditions and complete record references in the focused suite
real_backend passed Isolated canonical File and SQLite runtimes; environment probe: Node 24.21.0 / SQLite 3.53.4
regression_parity passed Identical complete last-500 records on a 20,000-row synthetic log; bytes consumed: 13,748,890 → 393,216
manual passed Warm loader median: 94.1 → 2.44 ms over six alternating source-pinned pairs on Python 3.12; component timing only
static passed Ruff, configured mypy (17 files), diff advisory and full semantic vocabulary check
integration passed Exact-source premerge: six direct checks and four selected canaries; no failures, skips, timeouts or manual holds
  • Coverage and gaps: strict errors, torn UTF-8, invalid rows, long records, bounded retained objects, fresh opens and nonseekable streams are covered. The timing comparison pins distinct source hashes after excluding an initial A/A setup probe. Only the bounded source-checkout CLI timings below have been added; installed App, full performance-budget and provider-promotion qualification remain unclaimed.

Complete CLI comparison at the unchanged head

Compared a36e01c32b0a290a96466c766629a0b01850f823 with 7243b4ce51739eb440a44537ee9fd54d82002e2f through the actual scripts/loopx → Python → TypeScript → canonical-provider todo list --todo-id path. Both source archives used Python 3.12.15, Node 24.21.0 and SQLite 3.53.4, the same 20,000-event synthetic history, and the same complete long Unicode task and note. All 28 reads succeeded; complete normalized outputs matched, with only the existing validated observation clocks excluded. Canonical revisions and history bytes remained unchanged.

Provider Base warm median Head warm median Samples
SQLite 1.791 s 1.445 s Six alternating pairs after source-worker warmup
File 1.205 s 0.859 s Six alternating pairs after backend warmup

These are observations on a busy shared host, not stable p95 or a frozen-budget pass. Five SQLite warm pairs improved and one was slower. The first request to each source worker was 3.689 s versus 3.837 s, so cold-start improvement is unproven. Both owned workers exited normally; no installed application or active Goal was used as a test fixture. The initial private harness incorrectly treated the display source label as backend identity; its failed assertion was retained and corrected to verify canonical authority_read, without changing product behavior or acceptance conditions.

Frontend / Visual Evidence

  • UI impact: none. Existing Task/status entrypoints and returned content are preserved.
  • Before / after / first viewport: N/A.
  • Source data: none.

Type of Change

  • Bug fix
  • Refactoring (preserved result semantics)
  • Test update

LoopX Area

  • Control plane (goals, todos, quota, scheduler, registry, runtime)

Technical Direction

  • S7/R7 bounded reads through the existing IO owner; no new controller, cache, protocol or Python decision owner.

Shared-authority RFC fixture impact

N/A: no authority-store, provider/default, routing or compatibility-projection change, and no migration milestone claim.

Boundary Checklist

  • Diff and published evidence are public-safe; raw profiles and private source data are excluded.
  • No maintainer-owned benchmark work was duplicated.
  • Scope is limited to the demonstrated reader cost and its validation.
  • No paired RFC changed; staged and committed bilingual checks pass.
  • UI impact is none.
  • Every commit includes DCO sign-off.

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>

@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

动机 / Motivation

Todo 读取和状态等只需要最近一段 rollout 记录的真实调用方,会随着项目历史增长重复读取整个 JSONL 文件。

原实现虽然最终只返回最近 N 条有效记录,仍从头扫描全部历史;本 PR 在正 limit 且文件可 seek 时从尾部按块读取,仍返回同一组有效记录及时间顺序。无界读取与不可 seek 输入继续走既有完整/顺序语义。

相同 20,000 行、18,217,779 字节历史下,实际 File/SQLite todo list 读取从全文件降到 458,752 字节,两端公开结果完整一致,原 authority revision 和历史文件保持。这里度量读取字节,不宣称墙钟提速或所有 provider 的长期性能。

本次不删历史、不截断调用方需要的有效结果,也不改变 quota/回执权威或追加协议;不引入缓存、迁移、跨进程快照或新的并发保证。

改动思路 / Approach

这是已有读取 owner 内的算法调整,不是新的历史权威。统一 parser 维持有效记录定义,tail iterator 只减少正 limit 的物理读取;消费者要求的完整结果、时序和当前 authority 都保留。

范围止于 recent-reader 和回归;无界日志、追加写入、Goal provider 及业务判定不变。当前证据证明合成同负载真实 CLI 的 IO 改善,未延伸成生产长时吞吐资格。

Todo 调用原 canonical authority 获取状态,再按既有 limit=500 读取 rollout 观察。新 reader 从文件尾拼接完整字节行,共用原解析规则,够 500 条有效记录后停止并恢复原顺序;没有有效 limit 或输入不可 seek 时沿用原行为,读取中不修写数据。

原 loader 已是各调用方共享的读取 owner,直接在这里复用同一行解析规则并改变有界 IO 足够。另建索引文件、全局缓存或要求消费方重复裁剪都会增加状态与失效规则;它们并非本次成本问题所必需。

具体改动 / Changes

关键代码讲解

  • _parse_rollout_event_line:共享原有行解析合同。正向与反向读取使用同一 blank/JSON/object/schema 校验;tolerant 跳过坏行,strict 继续给出原行号诊断,不因优化放宽输入。
  • _reverse_rollout_lines:只改变有界读的物理遍历。从末尾按 64 KiB 块读取,先拼完整行再解码,支持跨块长 Unicode 行和无最终换行,避免字符或记录被切坏。
  • _recent_rollout_events:保留最近有效记录及输出顺序。只对有效事件计数,凑够调用方 limit 后停止,按原时间顺序返回;不可 seek 的输入保留正向有界 deque。
  • load_rollout_events:把新算法限定在现有正 limit 分支。None、0 和负值继续完整读取;现有无界恢复调用不因这个优化丢历史。

规范基准:docs/development/testing-and-quality.md;修订 a36e01c。没有独立新功能 RFC;这是既有 recent-reader 的有界实现。以基线的 Refactor Real-Path Gate 和 Roadmap-Aligned Optimization 约束验证,具体返回语义来自改动前公开 loader 与真实调用方,而非新 helper 自定义的输出。

Criterion 当前结论 对应实现或剩余边界
Refactor Real-Path Gate implemented load_rollout_events, shared _parse_rollout_event_line and real todo list readback
Locate the cost before selecting an abstraction implemented _reverse_rollout_lines -> _recent_rollout_events for limit > 0
Share contracts, qualify implementations implemented Existing callers keep their limits; unlimited and nonseekable branches retained

实际验证 / Validation

本轮 exact head 的 tests/test_rollout_event_log_loading.py 共 29 个案例全部通过。覆盖跨块长 Unicode、坏 JSON/非对象/错误 schema/非 UTF-8、空行、缺末尾换行、不同正 limit、None/0/负值全读、nonseekable fallback、strict 行号、后续 append 可见以及保留对象/读取字节的界限。

另用相同 SHA256 20040eaa0cc08e244e0a3a7b8a33fac8499ab7e4d7b7aa7ccd0f4b3a6104aaa5 的 20,000 行历史,在 base/head 的真实 todo list 路径分别运行 File 与 SQLite。两种 provider 都从读取 18,217,779 字节降到 458,752 字节;每次只打开一次实际日志。完整规范化输出相同,且调用后的 authority revision 和历史字节未变。File 输出指纹 7f3046e2d4ed7d65164fe0ceaac2493cd96bc45c132a1016468518cb96188857,SQLite 为 a83f33128716e11a261d178f89e736e49c6c9833e85773292ea08d70a3dfb2a5。旧实现读完整文件,无法满足同一有界读取断言;候选满足。没有用并发测试期间的墙钟数字推断性能增益。 额外独立字节 oracle 又实际执行同一公开 CLI:base 在 18,217,779 ≥ 4,554,444 的断言处退出 1;head 两个 provider 均以 458,752 字节通过,退出 0。这个对照使用原 20,000 行负载和同一阈值,不是只对保存的数字做推断。

对主干的风险 / Risks

主要风险是把反向物理遍历错误地变成反向结果、切坏长 UTF-8 行、让坏行吃掉有效记录额度,或误伤需要全历史的恢复调用。共享 parser、完整行组装和仅限正 limit 的入口约束与回归均覆盖这些边界;没有引入缓存失效或数据迁移。未发现阻断性实现问题,超长单条记录仍可能要求相应缓冲,这是完整记录合同本身的成本。

语义与 CI 对齐

对照标准是既有 loader/真实消费者以及基线工程文档的完整语义与 IO 规则。这里没有截历史、缩 workload、放宽阈值或删输出;受益限于请求最近记录的物理 IO,不能代表其他历史消费者也自动变快。

当前 Linux shard 5 红,其日志在两次有界读取中都遇到传输失败,尚未归因。Windows 日志可得,四个失败位于 self_update_runtime_activation 的 python_pip/pipx 安装路由与 archive override 场景,另 415 通过、20 跳过;未运行原生 Windows 基线,故不宣称这些是已证历史噪声。checks/pytest/merge gate 仍不是绿色,本地结论仅针对已直接验证的 loader 与真实 consumer。

当前阻断是验证缺口,不是凭红灯虚构的代码 finding。 仓库当前 verdict_policy 明确未归因的 current failures 阻止批准;仅证明变更文件不在失败路径,尚不足以归类 pre_existing。最小解除条件是对上述具体失败提供不可变 base/head 的同命令、同签名对照,或独立证明外部/环境原因并补齐受影响合同的当前资格;若归因确属回归,再修相应代码。本轮不要求为未归因失败修改无关代码,也不放宽已有预算。

我的整体评价 / Verdict

REQUEST_CHANGES:未发现阻断性的代码缺陷;当前 CI 失败尚缺政策要求的归因证据,因此暂不具备批准资格。 审查绑定 exact head 7243b4c。

长期历史仍完整保留,原状态与回执 owner 没有变化。实际有界消费者不再每次读取全部旧历史,有直接 IO 依据;无界恢复消费者仍可读全量,不能把这个局部收益等同长期运行容量或并发资格。

对用户可见的最近记录、顺序与 Todo 输出保持,损坏行容忍和严格错误诊断也保留。没有要求用户归档、清理历史或额外确认才能获得收益。 该改动是日志读取算法,未改变页面布局或 UI 交互;实际 CLI 完整读回已比较。

共享 parser 加一个局部 tail iterator 已满足有界读取;继续保留无界与不可 seek fallback 是兼容合同所需,不是待删除的重复 owner。当前没有证据支持引入索引服务或全局缓存。

本轮使用隔离的合成持久化历史和真实 File/SQLite CLI,量的是读取字节;未测安装后生产吞吐、原生 Windows、远程 provider 或并发追加快照。远程 Linux 日志不可得、Windows 失败尚未做基线归因,完整合并资格仍有这些限制。

English verdict: REQUEST_CHANGES — exact head 7243b4c; Current required CI failures lack the repository-required attribution, so approval is withheld. No blocking code defect was found in the exercised change; resolve the named validation gap rather than changing unrelated code.

…d-rollout-read-20261030

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

This branch has not been deployed

No deployments
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