Skip to content

perf(quota): load subcommand owners on demand - #7739

Open
cocolord wants to merge 2 commits into
mainfrom
codex/quota-demand-loading-20261030
Open

cocolord wants to merge 2 commits into
mainfrom
codex/quota-demand-loading-20261030

Conversation

@cocolord

Copy link
Copy Markdown
Collaborator

Summary

quota context-read and quota replan-view return before any authority read, but importing the quota handler eagerly pulled in status collection, quota planning, live decisions, the Lark inbox, upgrade, and several capability hooks. This PR makes the quota subcommands load those owners only when a route needs them:

  • loopx/cli_commands/quota.py: authority, decision, and capability owners resolve through a module-level _LAZY_EXPORTS table. Call sites use _export(name), so monkeypatch.setattr(quota_module, ...) keeps working, and __getattr__ and __dir__ preserve attribute access and export identity. The turn-start Lark hook, goal-ref helpers, and the settlement-attachment projection now import inside the branch that uses them.
  • quota_presentation.py, quota_reward_memory.py, quota_monitor_poll.py: renderer, compaction, reward-memory, and composition-frontier imports move into the functions and branches that use them. Type-only imports move under TYPE_CHECKING.

Authority ownership (TS lease/CAS), scheduling, settlement, defaults, and output are unchanged. handle_quota_command keeps its statement count.

Measurements

These are paired fresh-process probes against the exact base a2c8c940c, the parent before the final rebase; the rebase touched none of these files, using synthetic fixtures only. mods counts imported loopx.* modules.

Route Base mods New mods Base median New median
import loopx.cli_commands.quota 419 52 — —
context-read (5 runs) 426 62 1.28 s 0.11 s
replan-view (5 runs) 426 62 1.24 s 0.11 s
status (10 interleaved runs) 517 443 1.37 s 1.09 s
plan 517 443
spend-slot 522 475
void-slot 520 473
monitor-poll 519 475
scheduler-ack 521 497
should-run 563 558

Accounting routes (status, plan, spend-slot, void-slot, monitor-poll) no longer load live_decision, upgrade, periodic_report.pending_intent, or repository_change_window. should-run still needs nearly the full composition, as expected.

I only report status wall time from the interleaved A/B run. The other accounting routes were measured sequentially on a loaded machine, and their wall-time differences were inside the noise, so the import counts are the reliable signal for them.

Behavior parity

Each of 14 quota invocations (context-read, replan-view, status, plan, status --format markdown, spend-slot dry-run, spend-slot without a Todo, void-slot, monitor-poll, scheduler-ack, should-run JSON/markdown/--turn-envelope, unknown Goal) was run against the same fixture on the base and on the new head. After normalizing fixture-random revisions, ids, and timestamps, all 14 have identical exit codes and identical JSON structure. The only remaining differences are staleness_seconds (wall-clock dependent, ±1 s) and the timestamp in the spend-record filename.

Tests

tests/test_cli_entrypoint.py adds 4 cases. All 4 fail on the base and pass on this head:

  • importing the handler defers the authority, composition, and capability owners, and every lazily exported name resolves to the same object as its owner module;
  • context-read and replan-view skip those owners. Each keeps selected-versus-full stdout/stderr parity, leaves the registry untouched, and creates no runtime;
  • spend-slot (dry-run), void-slot, and monitor-poll skip the should-run-only composition.

Validation

  • ruff check on the changed files: passed.
  • examples/cli-control-plane-command-modularization-smoke.py: passed.
  • Focused suite on the rebased head (base 8d48efabb): tests/test_cli_entrypoint.py, tests/control_plane/test_quota_*.py, tests/cli_commands/test_quota_*.py, progressive native context, selection replan re-entry, control-plane import boundaries and the maintainability ratchet ran with 1151 passed, 1 failed. The failure, test_selection_replan_reentry.py::test_native_first_selection_publishes_only_final_bound_capture, also fails on base 8d48efabb without this change. An earlier run on a2c8c940c that also included Codex context lifecycle and registry-independent context capture had 1321 passed. Its 5 failures all also failed on that base: the one above, plus the test_receipt_retry_keeps_open_vision_quiet_through_real_cli cases that the current base has since fixed.
  • loopx canary premerge --from-git-diff (run on the pre-rebase head; the rebase onto 8d48efabb changed none of these files): passed (6 direct checks, 18 selected catalog/risk-profile smokes; 0 failures, 0 warnings, 0 manual holds; surfaces control_plane, python; profiles core-control-plane, canary-runner). The first run failed only because semantic-vocabulary-drift-smoke.py needs the TypeScript dev dependencies; after a local npm ci --ignore-scripts it passed with nothing else changed.

Follow-up and future-facing pass

  • Applied in this PR: type-only imports go under TYPE_CHECKING, and the module boundaries stay unchanged. No new modules or wrappers.
  • Deferred: spend-slot, void-slot, and monitor-poll still load reward_memory, because loopx/quota.py calls _resolve_reward_memory_experiment_from_status from should_run_prepare. Deferring that belongs to the loopx/quota.py owner and is left for a separate change.

Runtime self-merge is not requested; this needs ordinary review.

Native context and replan-view return before any authority read, yet the
quota handler eagerly imported status, quota planning, live decisions, Lark
inbox, upgrade and capability hooks. Resolve those owners on first use
through a module-level export table so patches on the handler module stay
effective, and defer renderer, reward-memory and composition-frontier
imports to the branches that need them.

Authority, scheduling, settlement, defaults and output are unchanged.

Signed-off-by: lusendong.6789 <lusendong.6789@bytedance.com>
Co-authored-by: TRAE CLI <traecli@bytedance.com>
@cocolord

Copy link
Copy Markdown
Collaborator Author

Additional parity on the rebased head fbbacc86a vs base 8d48efabb (same synthetic fixture, normalized ids/timestamps): --format markdown for status, plan, should-run and replan-view, plus scheduler-ack-current and scheduler-fail-current JSON, all produce identical exit codes and byte-identical output. scheduler-ack differs only in wall-clock staleness_seconds.

@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

反复运行 quota status、plan、context-read、should-run 和具体写动作的 CLI 用户与自动执行器,目前都先加载无关的完整 quota owner 图。

原来导入 quota façade 就会导入所有子命令 owner;本 PR 让每个动作在真正调用时解析原 owner,并把 monitor、presentation、reward 的分支依赖留在所属分支。实际准入、结算和显示规则继续复用既有实现。

真实 File/SQLite 的每版本 28 次 CLI 调用在完整规范化输出、诊断与退出码上相同;例如 context-read 的 LoopX 模块数由 425 降到 61。这里验证的是无关导入减少,未宣称固定延迟或模型费用下降。

本次不改 quota 决策、读写范围、回执身份或外部执行权限,不新增缓存或 provider;也不声称整个 CLI、完整 CI 或长期模型性能已取得资格。

改动思路 / Approach

这个 façade 只负责把名字送到已有 owner,不承担准入、结算或状态判断。按需解析降低轻量命令的启动依赖,同时保留公开属性及动态替换约定;monitor、presentation 和 reward 的局部导入继续放在真正消费它们的边界。

范围是一个已有 quota façade 与三个辅助模块的依赖加载方式,以及真实入口回归。没有增加新的工作状态、权限、读回格式或恢复流程。

公开入口仍把动作分派到原函数;区别是需要哪个名字才加载哪个模块。_export 在实际调用时解析模块当前属性,避免破坏原替换接口。监视、呈现与 reward 的附属依赖只在原分支内出现,后续回执验证和失败行为仍由原实现决定。

所有目标函数原本已有模块和语义 owner。有限映射只延迟取出这些原对象,_export 在调用时读取 façade 上的现值,保留已有替换 seam;没有复制业务函数、包装另一套规则或构造全局 domain cache。

具体改动 / Changes

关键代码讲解

  • getattr:按名字取得原 owner 对象。只解析有限映射中的原函数并缓存模块属性;不存在的名字仍报 AttributeError,旧 helper 别名继续指向原实现。
  • _export:维持调用时的 façade 兼容性。每次调用读取模块上的现值,既沿用延迟加载,也保留既有调用方或测试对公开 helper 的替换;不提前固化另一份函数。
  • handle_quota_command:沿用子命令分派。原参数、动作顺序和错误 owner 不变,只把 eager-import 名称替换为按需解析的同一函数。
  • record_quota_monitor_poll_for_cli:缩小分支依赖的加载范围。monitor 路径继续使用原轮询与回执 owner;相关依赖留到实际需要该分支时导入,未把轮询结果变成准入依据。

规范基准:docs/quota-allocation.md;修订 8d48efa。按基线现有 Product Scope 与 Read-only observation scope 段落判断。下面使用原段落定位标签,不把导入优化扩张为新的 quota 或控制器协议交付。

Criterion 当前结论 对应实现或剩余边界
Read-only observation scope implemented handle_quota_command dispatches to unchanged status/plan/readback owners
Product Scope implemented Existing quota, spend, void, monitor, scheduler and should-run owners resolved on demand
Existing façade compatibility implemented _LAZY_EXPORTS, getattr, _export and original helper alias

实际验证 / Validation

本轮在 base 和 exact head 分别执行 projection、reward memory、monitor poll runtime 三个既有模块,各 100 个案例全部通过;另跑 head 的 6 个 quota selected-entrypoint 案例,覆盖延迟导入、原函数身份与动态替换。没有把作者历史 1151 个测试统计当成本轮结果。

每个版本额外执行 28 次真实公开 CLI,覆盖 File/SQLite 的 context-read、replan-view、status/plan、JSON/Markdown、spend、void、monitor、scheduler、should-run ordinary/envelope 和未知 Goal。完整规范化输出、诊断与退出码一致,SHA256 824ab45c41db902db7a1455ef7b42476bd3b66a86928be1bc2cce2a9802dae69;临时路径、生成身份和时钟之外未丢语义。File 上 context-read/replan 的 LoopX 模块数 425→61,status/plan 516→442,should-run 562→557。实际 context-read 的无关 owner 缺席断言在 base 失败、head 通过,这比单独检查 map 更有区分力。

对主干的风险 / Risks

主要风险在旧公开属性、动态替换与少见动作的延迟依赖;不是只看导入数字即可排除。已核对完整映射、调用方和别名,并执行包含真实拒绝路径的 base/head 配对与既有 consumer 测试。未发现阻断性实现问题;没有将保留重型依赖的 should-run 误报为优化失败,也没有夸大为全链路延迟保证。

语义与 CI 对齐

基线 quota 文档的读范围、权限和结算职责保持,完整 instruction/diagnostic 配对没有发现漂移;没有靠删判断或删返回字段达到数字目标。

当前远程 dashboard-browser(2) 在 goal-workspace-m2.mjs:206 的既有 1 秒 loaded-lens 切换预算失败,日志样本含 1515.93 ms;aggregate checks 红,其他分片未完成。该页面检查不在此改动的源码边界内,但本轮没有同负载 browser 基线证明,故保留未归因的合并风险,而非宣称历史失败已排除。

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

我的整体评价 / Verdict

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

长期自动循环依赖原 quota 判定、回执恢复和失败诊断;这些规则继续由原 owner 负责。轻量读取减少重复导入且不新增同步状态,因此不会把性能优化换成另一套结算语义。

原命令、诊断、Markdown 和 JSON 结果保持,用户无需改操作顺序。收益是常用轻量读取不必加载完整决策图;对于确实需要 live decision 的 should-run,仍保留它所需的完整依赖。 改动仅为 CLI 分派与导入,不涉及页面或视觉交互。

有限映射和调用时解析足以保留旧 façade,不需要增加通用插件框架或重新划分 owner。剩余 should-run 仍加载重型决策图是它的职责;不应为追求导入数字而截掉所需判断。

这里只证明实际覆盖路径上的导入缩减与语义保持,未测模型采用、完整冷启动分布或生产长期成本。远程 browser 预算仍失败,其基线归因未完成;其余 CI 未结束,不能把局部通过写成全仓合格。

English verdict: REQUEST_CHANGES — exact head fbbacc8; 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.

…ading-20261030

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

# Conflicts:
#	loopx/cli_commands/quota.py
@huangruiteng

Copy link
Copy Markdown
Collaborator

Attribution for the failing chat-bundle-browser (2) job is complete.

The CI failure occurred in research-display-language after the preceding research-history scenario ran for 251s; the page wait then hit its 30s timeout. Exact base 04c5799b8 and exact head 2c0c4cb35 have no diff in the Dashboard or personal-workspace browser scenario sources. A controlled single-scenario replay with the same qualified Python and browser dependencies passed on both revisions in effectively identical time (21.687s base, 21.693s head).

This supports a cumulative browser-shard timing flake, not a behavior change from the quota demand-loading patch. No browser timeout or assertion is relaxed here. The failed GitHub job can only be rerun after the currently pending long test shards make the workflow terminal.

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