refactor(cli): extract quota action selection owner - #4818
Conversation
Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
…dule-budget Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
|
@huangruiteng 请复审 #4818。远端 CI 已完成主要检查:静态、Dashboard、Node、Windows、E2E 和 3/4 pytest shards 全绿;唯一失败的 shard 只有两条 本 PR exact head 的 quota 提取本地验证仍为:76 个冲突/heartbeat/settlement 测试、219 个 semantic 测试、6 个 boundary/replan、32 个 CLI/import、16 个 maintainability/M6、95 个 CLI diagnostics、Ruff、目标模块 Mypy、1000 行模块门禁和 premerge 全部通过。未自合并。 |
…dule-budget Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
|
同步记录:已用普通、带 Sign-off 的 merge commit 合入 |
Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
huangruiteng
left a comment
There was a problem hiding this comment.
动机
这个 PR 解决的是一个真实且持续增长的维护问题:loopx/cli_commands/quota.py 同时承担命令分派、状态读取、渲染/日志,以及显式 Todo 选择与 heartbeat receipt 对账,已经超过仓库现行的 1000 行 CLI owner 预算。相比直接抬高预算或豁免该文件,把“action selection + receipt adaptation”作为一个完整变化原因抽出,能够让后续 quota 修改更容易定位、验证和回滚。
我按 exact head 92c5147934340debfd72f7c5ca6b4b9962e76d08 复核后,认为这不是为了过行数门禁而拆文件:新 owner 覆盖请求归一化、receipt 绑定读取、preflight、recovery、deferred retention 与最终 binding,形成了完整且已有生产调用方的边界;quota.py 保留 dispatch、status、stall writeback、rollout logging 与 rendering。该边界可独立审阅且没有新增用户协议、持久化字段或选择权限。
改动思路
入口仍是 handle_quota_command。它先通过 load_requested_quota_action_selection 把 CLI --todo-id 和同一 Turn 的 receipt 适配为 RequestedQuotaActionSelection,再把 receipt-bound/requested/retained 三种输入传给原有 build_live_quota_should_run_decision。live decision 仍是 eligibility/优先级的权威;新模块没有重建第二套决策。
live decision 返回后,reconcile_requested_quota_action_selection 保持原顺序执行:先校验 projected selection 与 receipt identity,再在 rejected/deferred 路径投影 recovery,必要时仅保留 pending_action_selection;只有 receipt reconcile/commit/readback 完成后,commit_requested_action_selection 才写入响应中的 selection_binding=heartbeat_receipt。失败和重试仍由既有的 typed error、recommended_action 与 handle_quota_command 的 rendering/logging 负责。
我专门挑战了“这只是可达、但没有必要的新 helper”这一点。仓库搜索显示,新模块直接复用了 normalize_todo_id、heartbeat receipt typed accessors、QuotaActionSelectionConflictKind、apply_action_selection_recovery 和 live decision;不存在第二个 eligibility、settlement 或 persistence owner。把预算提高或只拆一两个 helper 都会继续让 receipt 与 selection 的同一条状态机分散在 quota.py。
具体改动
quota.py:删除原来内联的约 360 行 action-selection helper,改为持有一个RequestedQuotaActionSelection,并在 live decision、automatic stall rebuild 和 receipt commit/readback 三处复用同一组绑定值。文件降到 779 行。quota_action_selection.py:新增 415 行的内部 owner,集中处理请求规范化、receipt 读取、preflight、deferred retention 和结果适配。vocabulary_v0.json:仅把既有effective_actionproducer anchor 从旧文件路径迁移到新文件路径,没有新增词汇或改变语义。test_quota_action_selection_conflict.py:把对私有 preflight helper 的直接导入迁到新 owner;断言语义未变。
关键代码讲解
RequestedQuotaActionSelection(quota_action_selection.py:34)把过去相关的五元 tuple 变成具名状态。requested_todo_id_for_decision在 receipt 已绑定 Todo 时抑制新请求;retained_todo_id_for_decision只有在没有请求、Todo binding 或 replan binding 时才暴露保留选择,保持原互斥关系。load_requested_quota_action_selection(:80)从真实 runtime root 读取 exact Turn receipt,并只从现有 typed accessors 派生 Todo/replan/pending binding;identity_upgrade仍来自既有 receipt details,而不是引入新状态。_apply_requested_quota_action_selection_preflight(:131)保留最敏感的分支顺序:settled Todo identity 冲突先 fail closed;autonomous replan replay 与 identity-upgraded retained selection 分开;只有 exact current obligation、pending delivery 或合法 workspace repair 才可通过。拒绝时仍生成相同的quota_action_selection_deferred|rejected、reason 与重入建议。reconcile_requested_quota_action_selection(:294)把原来的“preflight 后再 recovery/retain”两段编排收敛成ActionSelectionPreflightResult;只有 rejected 分支会触发 recovery 或 pending receipt append。handle_quota_command(quota.py:322,主要接线在:389-479与:573-686)仍然是公共命令 owner,且 selection binding 仍发生在 receipt reconcile/append/readback 之后。
对主干的风险
最强回归场景不是 import 失败,而是抽取后不小心改变 branch order:例如在 receipt identity 对账前绑定新 Todo,或让 retained selection 抢占新出现的 monitor/user gate。其影响会扩散到所有 heartbeat host,并可能把工作或 spend 归到错误 Todo。
我使用同一组五个公共 CLI/真实临时文件后端用例分别跑了 main@0ef7ebd749ec97a698a8fc7f2a29844dd368689b 与本 head,覆盖:未绑定 receipt 后选择新 Todo、未投影 Todo 拒绝、首次拒绝不得产生假 receipt、新 due monitor 抢占、以及新 user gate 抢占;两边都是 5/5 通过。head 上另外完整执行 action-selection conflict、heartbeat receipt 与 quota settlement CLI 套件,76 passed in 461.70s。
仓库质量证据:changed-path Ruff 通过;CLI module-size smoke 通过;semantic-vocabulary drift smoke 通过;相关 boundary/replan/CLI diagnostics 测试通过;loopx canary premerge --from-git-diff 为 18/18 passed、0 manual hold;merge-tree 对当前 origin/main 无文本冲突。
语义与 CI 对齐
这个 PR 复用现有 action-selection/receipt 词汇,仅迁移 producer symbol;没有创建或扩展协议。语义注册表与 smoke 同步通过。需要说明的非阻塞 caveat 是:仓库配置的 mypy 只覆盖固定文件清单,新模块不在该清单;若把它作为孤立 strict target 并跳过 imports,会暴露 _requested_quota_action_todo_id 的一条 no-any-return,而同一 helper 在基线中已有相同类型形状,因此它不是这次抽取造成的运行时漂移,也不影响当前仓库必需检查的通过结论。PR 描述若保留“target Mypy passed”,建议补出确切命令,避免把不同检查口径混为一谈。
我的整体评价
没有阻塞性 finding。这个改动把已有、相互依赖的一组 quota CLI 适配规则搬到正确的内部 owner,同时保持 decision、receipt persistence、failure/retry 与公共输出的权威边界不变;规模与原问题相称,也没有为了将来可能的扩展引入框架或第二套状态。
未来向检查我认为本 PR 已经做了合适的 bounded refactor:具名 dataclass 取代 loose tuple,semantic producer anchor 随 owner 一起移动;继续抽象会开始跨越 quota decision/receipt 的既有边界,当前没有必要。残余风险主要是 focused suite 未枚举的 receipt/frontier 组合,但 76 项 settlement 回归、基线/head 公共入口对照和 18 项 risk-based canary 已把该风险压到可接受范围。
English verdict: APPROVE - head 92c5147; the extraction gives quota action selection a cohesive owner without changing decision or receipt authority, with 76 focused tests, baseline/head CLI parity cases, Ruff, semantic/module-budget smokes, and 18/18 premerge canaries passing.
|
@huangruiteng #4819 已合入后,我已用普通、带 Sign-off 的 merge commit 同步 本地 exact-head 复验:quota action-selection、settlement 与两条 priority 回归共 117 passed;Ruff、目标模块 Mypy、CLI 1000 行模块门禁通过;premerge 18/18 passed。远端 CI 已重跑,请复审。本 PR 不自合并。 |
huangruiteng
left a comment
There was a problem hiding this comment.
动机
这个 PR 解决的是一个真实且持续增长的维护问题:loopx/cli_commands/quota.py 同时承担命令分派、状态读取、渲染/日志,以及显式 Todo 选择与 heartbeat receipt 对账,已经超过仓库现行的 1000 行 CLI owner 预算。相比直接抬高预算或豁免该文件,把“action selection + receipt adaptation”作为一个完整变化原因抽出,能够让后续 quota 修改更容易定位、验证和回滚。
我按当前 exact head 98e976ccff2ca41f9bfe5663a0326e2f0cf1960c 复核后,认为这不是为了过行数门禁而拆文件:新 owner 覆盖请求归一化、receipt 绑定读取、preflight、recovery、deferred retention 与最终 binding,形成了完整且已有生产调用方的边界;quota.py 保留 dispatch、status、stall writeback、rollout logging 与 rendering。该边界可独立审阅且没有新增用户协议、持久化字段或选择权限。
改动思路
入口仍是 handle_quota_command。它先通过 load_requested_quota_action_selection 把 CLI --todo-id 和同一 Turn 的 receipt 适配为 RequestedQuotaActionSelection,再把 receipt-bound/requested/retained 三种输入传给原有 build_live_quota_should_run_decision。live decision 仍是 eligibility/优先级的权威;新模块没有重建第二套决策。
live decision 返回后,reconcile_requested_quota_action_selection 保持原顺序执行:先校验 projected selection 与 receipt identity,再在 rejected/deferred 路径投影 recovery,必要时仅保留 pending_action_selection;只有 receipt reconcile/commit/readback 完成后,commit_requested_action_selection 才写入响应中的 selection_binding=heartbeat_receipt。失败和重试仍由既有的 typed error、recommended_action 与 handle_quota_command 的 rendering/logging 负责。
我专门挑战了“这只是可达、但没有必要的新 helper”这一点。仓库搜索显示,新模块直接复用了 normalize_todo_id、heartbeat receipt typed accessors、QuotaActionSelectionConflictKind、apply_action_selection_recovery 和 live decision;不存在第二个 eligibility、settlement 或 persistence owner。把预算提高或只拆一两个 helper 都会继续让 receipt 与 selection 的同一条状态机分散在 quota.py。
具体改动
quota.py:删除原来内联的约 360 行 action-selection helper,改为持有一个RequestedQuotaActionSelection,并在 live decision、automatic stall rebuild 和 receipt commit/readback 三处复用同一组绑定值。文件降到 779 行。quota_action_selection.py:新增 415 行的内部 owner,集中处理请求规范化、receipt 读取、preflight、deferred retention 和结果适配。vocabulary_v0.json:仅把既有effective_actionproducer anchor 从旧文件路径迁移到新文件路径,没有新增词汇或改变语义。test_quota_action_selection_conflict.py:把对私有 preflight helper 的直接导入迁到新 owner;断言语义未变。
关键代码讲解
RequestedQuotaActionSelection(quota_action_selection.py:34)把过去相关的五元 tuple 变成具名状态。requested_todo_id_for_decision在 receipt 已绑定 Todo 时抑制新请求;retained_todo_id_for_decision只有在没有请求、Todo binding 或 replan binding 时才暴露保留选择,保持原互斥关系。load_requested_quota_action_selection(:80)从真实 runtime root 读取 exact Turn receipt,并只从现有 typed accessors 派生 Todo/replan/pending binding;identity_upgrade仍来自既有 receipt details,而不是引入新状态。_apply_requested_quota_action_selection_preflight(:131)保留最敏感的分支顺序:settled Todo identity 冲突先 fail closed;autonomous replan replay 与 identity-upgraded retained selection 分开;只有 exact current obligation、pending delivery 或合法 workspace repair 才可通过。拒绝时仍生成相同的quota_action_selection_deferred|rejected、reason 与重入建议。reconcile_requested_quota_action_selection(:294)把原来的“preflight 后再 recovery/retain”两段编排收敛成ActionSelectionPreflightResult;只有 rejected 分支会触发 recovery 或 pending receipt append。handle_quota_command(quota.py:322,主要接线在:389-479与:573-686)仍然是公共命令 owner,且 selection binding 仍发生在 receipt reconcile/append/readback 之后。
对主干的风险
最强回归场景不是 import 失败,而是抽取后不小心改变 branch order:例如在 receipt identity 对账前绑定新 Todo,或让 retained selection 抢占新出现的 monitor/user gate。其影响会扩散到所有 heartbeat host,并可能把工作或 spend 归到错误 Todo。
上一轮审阅使用同一组五个公共 CLI/真实临时文件后端用例分别跑了 main@0ef7ebd749ec97a698a8fc7f2a29844dd368689b 与旧 head 92c5147934340debfd72f7c5ca6b4b9962e76d08,覆盖:未绑定 receipt 后选择新 Todo、未投影 Todo 拒绝、首次拒绝不得产生假 receipt、新 due monitor 抢占、以及新 user gate 抢占;两边都是 5/5 通过。本次复审先做失效检查:当前 head 只是把 main@09f10c4e37b89c6ed25f2f2354f89d641662e83c 合入分支,quota.py、quota_action_selection.py、semantic vocabulary 和 direct unit test 四个 PR 自有文件的 blob id 与旧获批 head 完全一致,因此旧结论没有被 PR 自身改动推翻。
我仍在当前 exact head 上重新执行了 action-selection conflict、heartbeat receipt、quota settlement CLI 和此次主干合入涉及的 team-plan priority integration,结果为 91 passed in 488.15s;另有 semantic production/inventory/Python production 132 passed in 17.67s。这不是只凭“代码没变”复用旧审阅,而是把旧 head→新 head 增量和整个当前 diff 都重新落到了真实 CLI/临时文件 receipt 后端上。
仓库质量证据:changed-path Ruff 通过;CLI module-size smoke 通过;semantic-vocabulary drift smoke 通过;loopx canary premerge --from-git-diff 为 18/18 passed、0 manual hold;git diff --check 通过;merge-tree 1ce7936222a0b1bf338e1544321b06a57f0e407d 对当前 origin/main 无文本冲突;分支四个 commit 都带 DCO sign-off。能力契约设置 wait_for_ci=false,因此我没有等待或轮询仍在运行的远端 CI,也没有把 CI 作为本次 verdict 的替代证据。
语义与 CI 对齐
这个 PR 复用现有 action-selection/receipt 词汇,仅迁移 producer symbol;没有创建或扩展协议。语义注册表与 smoke 同步通过。需要说明的非阻塞 caveat 是:仓库配置的 mypy 只覆盖固定文件清单,新模块不在该清单;若把它作为孤立 strict target 并跳过 imports,会暴露 _requested_quota_action_todo_id 的一条 no-any-return,而同一 helper 在基线中已有相同类型形状,因此它不是这次抽取造成的运行时漂移,也不影响当前仓库必需检查的通过结论。PR 描述若保留“target Mypy passed”,建议补出确切命令,避免把不同检查口径混为一谈。
我的整体评价
没有阻塞性 finding。这个改动把已有、相互依赖的一组 quota CLI 适配规则搬到正确的内部 owner,同时保持 decision、receipt persistence、failure/retry 与公共输出的权威边界不变;规模与原问题相称,也没有为了将来可能的扩展引入框架或第二套状态。
未来向检查我认为本 PR 已经做了合适的 bounded refactor:具名 dataclass 取代 loose tuple,semantic producer anchor 随 owner 一起移动;继续抽象会开始跨越 quota decision/receipt 的既有边界,当前没有必要。残余风险主要是 focused suite 未枚举的 receipt/frontier 组合,但 91 项 exact-head settlement/priority 回归、132 项 semantic 检查、旧/新 head blob 等价性和 18 项 risk-based canary 已把该风险压到可接受范围。
English verdict: APPROVE - head 98e976c; the extraction gives quota action selection a cohesive owner without changing decision or receipt authority, with all PR-owned blobs unchanged from the prior approved head, 91 exact-head focused tests, 132 semantic tests, Ruff, semantic/module-budget smokes, and 18/18 premerge canaries passing.
…dule-budget Reconcile the quota action-selection extraction with main's post-refactor preflight: keep the extracted quota_action_selection owner (typed RequestedQuotaActionSelection + ActionSelectionPreflightResult) and adopt main's delegated admission and recovery construction (current_action_selection_admission, build_action_selection_recovery_fields, bind_action_selection_recovery_command) instead of the retired apply_action_selection_recovery helper. Signed-off-by: LoopX Agent <agent@loopx.local>
huangruiteng
left a comment
There was a problem hiding this comment.
Exact head: d67590c4c0961b573d8f94f82395c3c554f41f89(merged origin/main@997294303)
动机
loopx/cli_commands/quota.py 已经越过仓库 1000 行 CLI 命令模块预算。更难的是:当前 main 在这条门禁上就是红的——我在一个干净的 origin/main worktree 上复现:
AssertionError: quota.py has 1023 lines, above budget 1000; extract a cohesive command owner before adding more code
同时,action-selection 的准入判定在 CLI 里被复制了一份(selection_binding / pending_selection_delivery_qualified / pending_selection_workspace_repair_qualified / exact_current_obligation_qualified),和 loopx/control_plane/work_items/action_selection_contract.py 里的真实 owner 是同一套语义。本 PR 用一个内聚的命令 owner 模块同时解决这两件事:把预算修回去,并删掉重复的判定规则。
改动思路
按"文字搬迁 + 语义归位"来拆:
- 搬走请求归一化(
_requested_quota_action_todo_id)、receipt 读取与绑定(原五元组_heartbeat_quota_action_selection_bindings)、准入 preflight、拒绝字段绑定、未提交 receipt 标注、已提交选择投影、deferred 保留,全部进入新模块。 - 留在
quota.py:命令分发、状态收集、monitor writeback、rollout 记录、渲染——即"传输与展示"的部分。 - 顺手收紧类型:用冻结的
RequestedQuotaActionSelection取代互相关联的五值元组,用ActionSelectionPreflightResult取代"bool + 四处散落的 receipt 变量",把requested_todo_id_for_decision/retained_todo_id_for_decision变成具名属性,handle_quota_command不再在每个调用点重算一次 requested id。
具体改动
新 owner:loopx/cli_commands/quota_action_selection.py(314 行)
load_requested_quota_action_selection:仅在--codex-app/--trae-app/ guided runtime profile 下读取--todo-id,并把当轮 heartbeat receipt 折叠成一个不可变读模型(含settlement_receipt_revision == "identity_upgrade")。_requested_quota_action_selection_preflight:判定顺序保持——receipt 绑定身份冲突 → 抛HeartbeatReceiptIdentityConflictError;replan 绑定且未发生身份升级 → 视为 settled replay;升级后请求了不同 Todo → 抛 retained-selection 冲突;被准入 →None;缺 qualification →UNQUALIFIED;qualification 不在{deferred, rejected}→CONFLICT。reconcile_requested_quota_action_selection:payload.update(recovery)→bind_action_selection_recovery_command(重写cli_channel.next_cli_actions与agent_channel.primary_action)→ deferred 保留 → 返回ActionSelectionPreflightResult。attach_uncommitted_action_selection_receipt/commit_requested_action_selection:把heartbeat_receipt.status=not_committed与selection_binding=heartbeat_receipt的投影保留在搬运后的位置,调用点不变。
loopx/cli_commands/quota.py 1114 → 779 行:只保留 handle_quota_command、_record_automatic_heartbeat_stall、渲染/失败上报等职责,调用新模块的五个入口;_record_automatic_heartbeat_stall 直接接收 typed selection,不再传四个字符串。
合并时的语义归位(这是本 head 的关键差异)
本 PR 原 head 98e976ccf 早于 main 的 ecb84c4ae / e3d101e6e。那两个提交把准入规则移入 contract owner,删除了 apply_action_selection_recovery,并让 preflight 返回 recovery 字段而不是 bool。因此合并不能机械取一侧,我把 main 的新语义移植进被抽出的模块:
- 准入改为
current_action_selection_admission,拒绝字段改为build_action_selection_recovery_fields,绑定改为bind_action_selection_recovery_command;模块内那份约 110 行的重复判定块被删除,不再存在第二个规则 owner。 - 同步更新两处测试导入(
test_quota_action_selection_conflict.py、test_unadmitted_selection_construction.py),并保留main的is None期望。 loopx/semantics/vocabulary_v0.json的 producer anchor 最终不需要改动:main已把quota_action_selection_deferred/rejected的产者登记为 contract 的build_action_selection_recovery_fields,合并后与main一致(drift smoke 通过)。
净 diff(对 main):quota.py −299/+55、新模块 +314、两个测试各 4 行。
两条路径的验收:准入路径——请求的 Todo 被准入时不改 payload、receipt 以 replayed 复用,commit_requested_action_selection 只在 receipt 对账之后打 selection_binding=heartbeat_receipt;拒绝路径——payload.update(recovery) 关闭 spend_after_validation / safe_bypass_allowed / 各类 delivery 授权,再绑定一条不含 --todo-id 的恢复命令,deferred 时追加一条待选 Todo 供下一轮读回。
对主干的风险
- 最低风险面:无新增 CLI flag、无新增持久化字段、无 schema/receipt 形状变化;新模块的五个入口各只有一个生产调用点(
rg全仓确认无其他导入)。回滚就是普通 revert:语义移植只有一个函数。 - 已验证:
test_quota_action_selection_conflict.py+test_unadmitted_selection_construction.py18 passed;再加 heartbeat receipt 与 settlement CLI 共 90 passed(含作者声明的 76 条集合与main新增用例);tests/architecture/test_semantic_vocabulary_drift.py114 passed;semantic-vocabulary-drift-smoke.pyok(26/26 vocabularies、51/51 owner symbols);cli-command-module-size-ownership-command-modularization-smoke.pyok;Ruff clean;loopx canary premerge --from-git-diff --git-diff-base origin/main→gate.status=passed、self_merge_allowed=true、0 failures、0 manual holds(3 项 direct diff/compile、maintainability ratchet、10/10 catalog canary、8/8 risk-profile smoke)。 - 未验证:新 head
d67590c4c的远端 CI 复核在发布本评审时仍未跑完(此前绿灯属于98e976ccf),这是本 head 最强的证据缺口;另外本轮的验证是单元 + settlement CLI + 公共 smoke 层,未跑真实 runtime root 的整轮 heartbeat 宿主 turn,也未覆盖 PostgreSQL authority 路径。 - 非阻塞 P3:
attach_uncommitted_action_selection_receipt与commit_requested_action_selection本质是 receipt/payload 投影(receipt 的 owner 是loopx/control_plane/quota/heartbeat_receipt.py),留在 CLI owner 里意味着将来改 receipt 形状时多一处要记得同步。建议后续再做一次有界搬迁,由既有test_quota_settlement_cli.py断言保护,不必在本 PR 内扩展。 - 重复度说明:本 PR 的主要价值就是消重——合并前的分支 head 拥有一份与 contract 并行的准入实现;本 head 只保留 contract 一个 owner,CLI 侧退化为输入适配、preflight 调用、拒绝绑定与 deferred 保留。
我的整体评价
方向正确、边界清晰:它把一个语义敏感的 CLI 流程从"超预算 + 双份规则"收敛成"一个 typed owner + 一个规则来源",并且顺手把 main 当前红灯的模块预算门禁修好,不需要任何预算例外。合并期的语义归位处理得当——没有把 main 已落地的 owner 覆盖回旧实现,也没有留下死符号。
结论:APPROVE。在 d67590c4c 这个 exact head 上无阻塞问题;发布前仍建议等该 head 的远端 required checks 跑绿,再按维护者流程合并。
English verdict: APPROVE - Reviewed exact head d67590c (merged up to origin/main@997294303). The extraction is a cohesive, behavior-preserving ownership move (quota.py 1114 -> 779 lines, new 314-line owner) that repairs a currently red required gate on main ("quota.py has 1023 lines, above budget 1000") without a budget exception; the merge correctly ports main's newer admission owner (current_action_selection_admission / build_action_selection_recovery_fields / bind_action_selection_recovery_command) instead of the retired apply_action_selection_recovery, deleting ~110 lines of duplicated admission rule and leaving no second decision owner. Validation: 18 passed (two direct suites) and 90 passed (plus heartbeat receipt + settlement CLI), 114 passed vocabulary architecture suite, semantic-vocabulary-drift smoke ok, CLI module-budget smoke ok, ruff clean, and the exact-diff canary premerge gate passed with 0 failures and 0 manual holds. One non-blocking P3: the two receipt/payload projection helpers still live in the CLI owner and are better placed with the receipt owner later. Residual risk: remote CI for this new head was not finished at publication time, and no full live host heartbeat turn was exercised.
Summary
quota_action_selection.pyquota.pyObservable result
loopx/cli_commands/quota.pydrops from 1,114 to 779 lines. The new owner is 415 lines, so both modules pass the existing 1,000-line CLI command budget without adding an exception. Action-selection branch order, payload strings, receipt writeback, replay, and settlement behavior remain unchanged.This repairs the
cli-command-module-size-ownership-command-modularization-smoke.pyfailure on currentmainand lets #4803 syncmainwithout inheriting that failure.Validation
python -m pytest tests/control_plane/test_quota_action_selection_conflict.py tests/control_plane/test_heartbeat_receipt.py tests/control_plane/test_quota_settlement_cli.py -q- 76 passedpython examples/cli-command-module-size-ownership-command-modularization-smoke.py- passedquota.pyretains the same five pre-existing target errors asmainloopx canary premerge --from-git-diffon the exact merged-main head - 18/18 passed, no manual holdsDelivery boundary
This is a control-plane CLI ownership change. It is ready for independent review and is not self-merged.