refactor(control-plane): split quota should-run route and packet builder - #2965
Conversation
huangruiteng
left a comment
There was a problem hiding this comment.
Review: APPROVED
head 9965509ab。这是对 PR #2965 的完整 owner review。该 PR 是 M6 Q3 的第三片真实替换:把 quota should-run 的 route resolution、packet assembly 和私有 read-model helpers 全部迁入 bounded control-plane 模块,并按 entry/prepare/packet 拆分,避免单个超大模块触发 maintainability ratchet。
验证
- 全量 pytest:
2306 passed, 2 skipped - 聚焦 quota parity/paused/plan/policy:
49 passed - import-boundary:
14 passed - maintainability ratchet:
9 passed - ruff:通过
loopx canary premerge --from-git-diff:selected=17 failures=0,self_merge_allowed=true- GitHub checks:dependency-review / pytest / build 全部通过
结论
无 blocker。loopx/quota.py 降到 1043 行,policy 常量保留为 audited compatibility reexports 并有显式 facade evidence;should_run.py、should_run_prepare.py、should_run_packet.py 均低于 1500 行。按仓库 merge policy 路由合并。
huangruiteng
left a comment
There was a problem hiding this comment.
Review: APPROVED
head 9965509abc7c951bba642dc79575cda8431227fa。这是对 refactor(control-plane): split quota should-run route and packet builder 的完整 PR 解读,覆盖 6 个改动文件、三个 bounded quota module、loopx.quota 收窄、policy re-export 与测试。GitHub 不允许作者审批自己的 PR,因此以 COMMENTED 发布作者自有回退态,但评审结论是无 blocker。
动机
前两轮已经先后把 quota should-run 的入口和 preparation 下沉到 bounded module,但 route resolution、packet assembly 和它们依赖的 read-model helpers 仍留在 loopx.quota。这个 PR 把这些剩余阶段拆到 should_run_prepare.py 与 should_run_packet.py,让 loopx.quota 从 2174 行降到 1043 行,并越过 M6 的 2000 行 gate。
改动思路
采用“入口 + prepare + packet”三段 bounded 结构:
should_run.py:入口 decision 与 paused-contract builder;should_run_prepare.py:decision preparation chain;should_run_packet.py:route resolution 与 packet assembly;loopx.quota:只保留 public facade、兼容 re-export 与少量仍需要跨 capability 边界的 wrapper。
具体改动
loopx/control_plane/quota/should_run.py:从 638 行缩到 47 行入口,逻辑委托should_run_prepare/should_run_packet。loopx/control_plane/quota/should_run_prepare.py:664 行,承载 preparation helpers、work-lane、blocked-priority fallback、automation prompt upgrade、workspace guard 等。loopx/control_plane/quota/should_run_packet.py:1124 行,承载 route resolution、packet assembly、scheduler hint、interaction contract 等。loopx/quota.py:删除已下沉实现,保留 facade。tests/control_plane/test_quota_paused_precedence.py:monkeypatch seam 移到should_run_prepare。tests/control_plane/test_quota_policy_reexport.py:显式验证 policy constants 仍由 facade 兼容 re-export。
关键代码讲解
should_run.py::build_quota_should_run():先解析 plan/item/health,paused 走 paused builder,否则_prepare_quota_should_run_item后交给_build_quota_should_run_payload与_resolve_quota_should_run_route。should_run_prepare.py::_prepare_quota_should_run_item():准备 agent identity、workspace guard、work-lane、capability gate、todo summary 等,产出_QuotaDecisionPreparation。should_run_packet.py:从 bounded context 组装最终 quota packet,并复用_scheduler_hint/_execution_obligation/build_interaction_contract。loopx.quotafacade:保留 policy constants 与 reward-memory 相关 wrapper,避免 control-plane module 直接依赖 capability-layer。
正向路径
调用 loopx.quota.build_quota_should_run,facade 委托 should_run.py;入口调用 prepare 链,再由 packet builder 组装输出。quota.py 体积下降,bounded modules 各自拥有对应 read model。49 个 focused/import-boundary/ratchet pytest、ruff、canary premerge 均通过,git merge-tree origin/main HEAD 无冲突。
负向路径
policy constants 从 loopx.quota 移除后由 facade 兼容 re-export,test_quota_policy_reexport.py 保证旧调用方仍能访问;monkeypatch seam 更新到新 owner,避免测试继续 patch 已移动的旧符号。
对主干的风险
低。行为被 parity/plan/paused/policy 测试覆盖,loopx.quota 只做 facade;没有新增运行时副作用。剩余一个非阻塞项:should_run.py 仍从 loopx.quota import _build_quota_plan_for_goal,这个简单 helper 可以在后续 slice 移入 bounded context;should_run_prepare.py 的 _resolve_reward_memory_experiment_from_status 属于有意的 capability-boundary wrapper,不是同样问题。GitHub pytest 当前 in-progress,但本地等价验证已全绿。
我的整体评价
这是 Q3 系列里最完整的一步:route 与 packet 真正进入 bounded context,quota.py 降到目标线以下,re-export 有测试保护。无 blocker,按仓库 merge policy 路由合并;建议把最后剩下的 _build_quota_plan_for_goal 作为下一个 slice 收尾。
English Verdict
Approved (author-owned fallback; cannot formally approve). Head 9965509abc7c951bba642dc79575cda8431227fa. The quota should-run route and packet assembly are now split into bounded modules, loopx.quota drops to 1043 lines, policy re-exports are tested, and 49 focused tests, ruff, import-boundary, ratchet, and canary all pass with no merge conflict. Non-blocking follow-up: move the remaining _build_quota_plan_for_goal helper into the bounded context.
Change
Q3 third real replacement slice for M6: the remaining
quota should-runroute resolution, packet assembly, and their private read-model helpers move out ofloopx/quota.pyinto three bounded control-plane modules:loopx/control_plane/quota/should_run.py: entry decision and paused-contract builder.loopx/control_plane/quota/should_run_prepare.py: decision preparation chain.loopx/control_plane/quota/should_run_packet.py: route resolution and packet assembly.loopx/quota.pydrops from 2174 lines (after #2964) to 1043 lines, below the M6 2000-line gate. Every new module stays below the 1500-line maintainability ratchet without adding a ratchet exception.The two policy constants that are no longer consumed inside
loopx.quotaare preserved as audited compatibility reexports, with explicit facade evidence intest_quota_policy_reexport.py.Surfaces
loopx/control_plane/quota/should_run.pyloopx/control_plane/quota/should_run_prepare.pyloopx/control_plane/quota/should_run_packet.pyloopx/quota.pytests/control_plane/test_quota_paused_precedence.py: monkeypatch seam moves toshould_run_prepare.tests/control_plane/test_quota_policy_reexport.py: explicit facade evidence for preserved policy constants.Validation
2306 passed, 2 skipped.49 passed.14 passed.9 passedwithout new exceptions.All checks passed.loopx canary premerge --from-git-diff: passed,selected=17 failures=0,self_merge_allowed=true.No failures or skips beyond the pre-existing suite skips. No manual holds.
Routing
Route:
codex-side-bypass; not assigned tocodex-quality-qualification.