fix(control-plane): restore current quota contracts - #4847
huangruiteng merged 8 commits into
Conversation
Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
|
@huangruiteng 请审阅这个主干基线修复。它只更新 |
…ed-output-budget Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
|
已用普通、带 Sign-off 的 merge commit 同步最新 |
Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
|
@huangruiteng 已用普通、带 Sign-off 的 merge commit 同步 |
Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com> # Conflicts: # examples/control_plane/cli-output-base-head-differential-smoke.py # examples/control_plane/cli-output-probe-runner.py # loopx/control_plane/testing/cli_output_budget.py
|
@huangruiteng 已同步 |
…ed-output-budget Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
|
@huangruiteng 已用普通、带 Sign-off 的 merge commit 同步 |
Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
|
@huangruiteng 旧 head 的 |
|
@huangruiteng 当前 exact head |
huangruiteng
left a comment
There was a problem hiding this comment.
评审 exact head:11df6db8b5d0e033d3536e794a3cf21abd80fd32
动机
这个 PR 收敛的是三处已经进入主线、但彼此没有完全对齐的 contract regression:protocol_action_packet 已退役后 settled-replay 测试还在读取它;Todo-bound long-chain replan 已要求 evidence-linked Goal vision 后,selection-reentry 测试仍直接执行带占位符的 refresh-state;以及显式 --todo-id lookup 扩展时误删了 blocked_transition_notices 的生产 caller,导致 quota 明明设置 notify_user=true,interaction contract 却只能退回通用的一句话,丢失 task、cause、impact、recovery 和 next action。
当前 exact-head diff 已去掉被 #4823 supersede 的 output-budget 工作,只保留 9 行生产恢复和两处 current-contract fixture 修正。范围与根因匹配,是一个完整、可独立验证的 repair slice。
改动思路
生产实现没有发明第二套 notice:_blocked_priority_fallback 继续拥有“哪个 higher-priority item 真正阻塞”的判定,复用现有 build_blocked_transition_notice 生成 typed payload;blocked_transition_notice.py 仍独占 task/cause/evidence/impact/responsible party/recovery/next action 的内容规则;interaction_contract 继续只消费首个 notice 并保留 legacy prose fallback。
这也保留了关键的 authority separation:notice attachment 是 machine-enforced projection,但 delivery.state 仍是 pending,没有把“应通知”伪装成“已投递/已读”;agent-owned blocker 不要求 owner action,且 fallback execution、quota spend、scheduler 与 Todo 状态都没有被这次恢复修改。
两个测试改动同样选择了现有 contract owner:selection reentry 在 tmp_path 生成合法的 goal_vision_replan_contract_v0,再替换 CLI 生成命令中的 evidence placeholder;settled replay 则明确断言 retired field 不存在,而不是重新引入兼容字段。
具体改动
关键代码讲解
loopx/control_plane/quota/should_run_prepare.py:213的_blocked_priority_fallback先固定 executable fallback,再扫描它前面的 open items。scheduled future monitor 仍只算 deferral;普通 open advancement 仍不算 blocker;只有status=blocked或未满足的 normalizedresume_when才设置 owner-visible blocker。loopx/control_plane/quota/should_run_prepare.py:275对上述真实 blocker 调用已有build_blocked_transition_notice(item, selected_executable=selected),因此 notice 的 impact 能说明 fallback 仍在继续,同时 responsible-party 规则决定owner_must_act,quota caller 不复制这些语义。loopx/control_plane/quota/should_run_prepare.py:305只在现有blocked_priority_fallback_v0上恢复blocked_transition_notices[:3];blocked_items、selected_executable、notify_user与 recommended action 均沿用既有路径。tests/control_plane/test_selection_replan_reentry.py:90为 Todo binding 补 evidence-linked vision/path-delta fixture,继续真实执行生成的 refresh command,证明 reentry 能在当前 contract 下完成且只 settle 一次。tests/control_plane/test_settled_replay_construction.py:20将protocol_action_packet加入 absent-field 集合,固定 settled turn 不重建 successor、replan 或已退役 packet 的语义。
历史对照也支持这个边界:e35a97d5d 最初接入 typed notice,9ee5c6fbc 在扩展 authoritative --todo-id lookup 时删除了 caller;本 PR 恢复原有调用,同时完整保留 9ee5c6fbc 的 lookup 行为,没有回滚或复制那条功能。
对主干的风险
最强回归风险有三类:把 future monitor 当成 blocker 造成噪声通知;把 agent-owned blocker 误投影成 owner gate;或者 notice 恢复意外阻止已选 fallback。现有路径和本地 counterfactual validation 覆盖了这些边界:blocked advancement、resume-pending advancement 会得到 typed notice;future monitor 仍是 quiet deferral;普通 open item不生成 blocked fallback;agent-owned notice 保持 owner_must_act=false;selected fallback id 不变。legacy payload 没有 notice 时仍能渲染 generic reason。
验证结果:五个相关模块共 34 passed in 74.20s;Ruff、py_compile、git diff --check 全部通过;loopx canary premerge --from-git-diff 运行了 16 个 control-plane/planning/monitor/refresh-state/architecture/canary-runner checks,16/16 通过,无 failure、warning 或 manual hold。按 capability 配置 wait_for_ci=false,没有等待远端 CI。
当前 PR 显示 BEHIND,但与最新 origin/main 的 merge-tree 没有冲突。rebase 会改变 exact head 并可能使这次 review 失效,届时应按新 head 复核;这不构成当前代码语义 blocker。
语义与 CI 对齐
本 PR 复用而非扩展 vocabulary:blocked_priority_fallback_v0、blocked_transition_notice_v0、goal_vision_replan_contract_v0 和 settled-replay 的 absent-field contract 都已经存在。没有 substring/prose classification,没有把 guidance 写成 obligation,也没有把 pending delivery 宣称为 completed delivery。premerge 的 quota/work-lane、monitor、autonomous-replan、refresh-state 与 semantic-vocabulary smokes 均通过,和这一判断一致。
我的整体评价
这是一个比例合适、ownership 清晰的 control-plane repair。生产 diff 仅恢复既有 typed caller,测试修正把真实 CLI/replay fixture 对齐当前主线 contract;没有新持久化状态、CLI 参数、scheduler/quota authority 或 speculative framework。bounded future-facing pass 已经体现在复用单一 notice builder/renderer,当前相邻边界不需要额外重构。
我没有发现阻塞问题,批准该 exact head。残余边界是:本 PR 不实现 notice delivery/readback ledger,payload 也诚实地保持 delivery.state=pending;批准不把这个 future slice 视为已交付。
English verdict: APPROVE - head 11df6db8b5d0e033d3536e794a3cf21abd80fd32 restores the existing typed blocked-transition notice caller without changing fallback, spend, scheduler, or delivery authority; 34 focused tests, Ruff, py_compile, diff/merge-tree checks, and all 16 selected premerge canaries pass, with external notice delivery correctly remaining out of scope and pending.
…backoff Conflict was tests/control_plane/test_selection_replan_reentry.py: main's #4847 fixed the same stale contract independently (authoring the evidence-linked vision packet for the todo binding). Take main's reviewed version verbatim; this branch's equivalent repair is superseded. Signed-off-by: LoopX Agent <agent@loopx.local> Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
…backoff Conflict was tests/control_plane/test_selection_replan_reentry.py: main's #4847 fixed the same stale contract independently (authoring the evidence-linked vision packet for the todo binding). Take main's reviewed version verbatim; this branch's equivalent repair is superseded. Signed-off-by: LoopX Agent <agent@loopx.local>
Summary
protocol_action_packetrefresh-statecommand9ee5c6fbcaccidentally removed while widening explicit--todo-idlookupRoot cause
Three mainline changes left contract regressions behind.
aa81a2aedremoved the legacy protocol action packet,129bb1fe7made Todo-bound long-chain replans require--agent-vision-json, and9ee5c6fbcdroppedblocked_transition_noticeswhile adding authoritative Todo lookup.The original CLI output-budget changes in this branch were superseded by #4823. This PR now contains only the three focused contract repairs above.
Validation
30 passed85 passedpy_compile, and diff checks: passedloopx canary premerge --from-git-diff: passed, 16/16 selected checks, no manual holdsExact head:
11df6db8b.This PR is awaiting maintainer review and will not be self-merged.