Conversation
Signed-off-by: Lihua <1017343802@qq.com>
Signed-off-by: Lihua <1017343802@qq.com>
huangruiteng
left a comment
There was a problem hiding this comment.
LoopX PR review · #5332
Reviewed head: 817418d5c96bf5005bcfc67d706015a72822f209;baseline: 649826221289cd4cb3dd8880d016e0afbbaca0fc。
结论:REQUEST_CHANGES。功能修复已经复现并验证;剩下一个可直接修复的 P2 blocker:新分支没有复用已有的 action 枚举,导致本 PR 新增语义词汇检查失败。另一个在 base/head 完全一致的失败不作为本 PR 的 blocker。
动机
这里要修的是已选中自主 replan、却又被安静 monitor 的执行义务覆盖的矛盾。用户 gate 的通知和 agent 的执行义务属于不同通道;展示 gate 不应让一个已获准的有界 replan 变成无需执行。相同的两次停滞、未来才到期的 monitor 和待处理 gate,在 base 的真实 CLI 上返回 replan,但 must_attempt_work=false;head 恢复为必须执行并保留阈值。这消除了反复醒来却不能完成 replan 的局部停滞,不表示父 Goal 已达成,也不授予 gated delivery 的权限。
改动思路
权威输入仍是当前 lane 的历史、Todo/gate、已有 replan obligation,以及原来的 quota route。现有 route 先决定是否允许 replan;packet builder 再把已选中的 obligation 传给现有执行义务 owner,后者不再只依赖面向用户的推荐模式。没有新 journal、额外用户声明或第二套结算机制。
我比较了 base、head 和当前 main 的对应 owner。main 尚未包含这一修复;相关 #5287 处理的是 replan-bound Turn 的辅助 monitor 命令绑定,并非这里的义务丢失。两者边界不同,不应合并成新的通用框架。最小的相关整理是复用现有 action 枚举;不需要扩大到 quota 的整体迁移。
具体改动
全 PR 为四个文件,新增 76 行、删除 5 行:两个生产适配位置、一个现有测试文件和 quota 文档。测试覆盖 future-due monitor、agent-scoped gate、阈值传递、通知保留和 scheduler 的执行动作;文档明确说明这种组合不允许 quiet no-op,以及其他 agent 的 ACK 不能清除当前 lane 的义务。
关键代码讲解
_resolve_quota_should_run_route(should_run_packet.py:755,未修改的调用上下文)仍负责合法 route 与既有拒绝优先级。修复消费它的结果,不把“看到了 replan”当成权限。_build_active_quota_payload(should_run_packet.py:1197)仅在route.replan_decision_allowed时,给执行义务构造输入补入prepared.replan_obligation。因此阈值来自已选中的 obligation;原来的用户通知保持不变。build_execution_obligation(execution_obligation.py:9)在已有 workspace repair、只读外部证据和明确 stop 分支之后,增加 effective action 的识别。重叠场景因而得到有界 typed outcome 义务,而不是 monitor 的安静等待;这里新增的裸字面量是下面的 blocker。
独立 CLI 验证使用隔离的真实 File/SQLite authority:先确认旧缺陷,然后创建带 obligation 绑定的 successor,经 refresh、spend 和两次 replay 读回。head 的 ACK 接受新 frontier,重复调用没有重复扣费,原 gate 仍为 open。普通工作仍单独走 admission;在测试的原生 gate route 保留等待时,模拟 fixture owner 解除 gate 后同一个 successor 才进入 run,没有把 replan ACK 当成用户批准。
对主干的风险
最重要的反向风险是把“必须 replan”误解为“可以执行被 gate 覆盖的交付”。真实 CLI 的 global-gate、新建工作、无停滞和另一 agent 的历史对照保留了正常交付拒绝;无有效新 outcome 的 surface_only 写回被拒绝。另在 base/head 的 File、SQLite 中,用原生 Todo update 重命名并更换已被全局 gate 覆盖的目标,单独读回确认字段已保存,再次 quota 仍拒绝普通交付,gate 仍 open。没有新增 activation、公共协议命名、跨 agent 权限或持久化格式;这是既有默认行为的修正,不是 default-off 功能,文档已披露变化。CLI 的现有通道和 scheduler 消费该 packet;没有新增设置或编辑入口,也没有声称验证了 packaged UI/Lark 的实际采用。
验证结果:head 87 项 Python、base 86 项 Python 通过;两边各 96 项 TypeScript 通过;Ruff 和完整 diff 检查通过。head 标准 canary 的 5 项直接检查通过、19 项选中检查中 17 项通过,整体并非 green;公共边界检查通过。
语义与 CI 对齐
P2 blocker 位于 execution_obligation.py:77:effective_action == "autonomous_replan_required" 新增了 owner 之外的裸 action 使用。仓库当前的 check_literal_vocabularies 明确禁止这类使用,要求复用已有 EffectiveAction,而不是仅要求字符串已注册。相同命令在 immutable base 成功、在 head 失败,诊断精确指向此新增分支。因此这是本 PR 引入的当前契约违例,不是风格偏好或无关红检查。最小修复为导入已有 EffectiveAction,比较 EffectiveAction.AUTONOMOUS_REPLAN_REQUIRED.value;不改词表、扫描范围或预算。
重跑:uv run --extra test python examples/semantic-vocabulary-drift-smoke.py,再运行 uv run --extra test python -m pytest -q tests/control_plane/test_replan_host_context_projection.py 和标准 premerge。
另一项 interaction-contract-state-machine-smoke.py 失败在 base/head 的同一 required-reads 断言,除 checkout 位置外完整诊断相同;该 smoke、interaction owner 和 action owner 的源文件哈希也相同,受影响的 replan 不变量另有通过证据。它是单独保留的 baseline 验证问题,不要求本 PR 修复。遵循本次 capability 的 wait_for_ci=false,未查询远端 CI。
我的整体评价
这个有界修复的目标和规模成立:长期续跑改善的是 replan 的真实执行与幂等结算,用户体验改善的是通知不再错误抹掉 agent 义务,授权等待仍保留。正向变化不能抵消新增的语义 owner 违例,当前 head 暂不批准。future-facing pass 的具体边界是 action 词汇所有权:直接复用既有枚举就是足够小、可逆且有检查覆盖的整理,不需要新增抽象。
剩余验证边界包括完整 gate 生命周期排列、长期多轮公平性、并发跨进程更新和 packaged UI/Lark;本次没有改变这些 owner,也未把它们写成通过。这里证明的是 ACK 不解除 gate、全局 gate 覆盖新建与重命名/换目标的工作,以及原 owner 解除后的续跑,不是完整系统认证。修复裸 action 后需在新 exact head 复审;无关 baseline 失败单独保留,不因此强制对该 PR request changes。不执行合并。
English verdict: REQUEST_CHANGES - head 817418d. The replan fix passes real File/SQLite settlement and focused tests, but the new bare effective-action literal violates the existing vocabulary-owner gate. The independently reproduced baseline required-reads failure is not a PR blocker; remote CI was not consulted.
A periodic autonomous replan can become due while an unrelated scoped user gate and a future-due monitor remain open. In that case,
quota should-runselectedautonomous_replan_required, but the quiet monitor lane overrodeexecution_obligation.must_attempt_worktofalse. The interaction contract then advertised delivery without an attempt, and the scheduler returnedrepair_interaction_contract_projectioninstead of running the replan.The explicit replan action now owns the execution obligation and receives its selected stall threshold. User-gate notification remains visible without granting the gated action. A full quota-packet regression covers this overlap, while the existing monitor, scheduler, and replan cases verify adjacent lanes. The quota guide states the resulting precedence. The change stays within the existing execution-contract owner; no adjacent refactor is needed.
Validation: 48 focused Python cases; 3 real CLI settlement/reentry cases; Ruff check;
loopx check(7 checks, zero errors or warnings); quick premerge canary (5 direct and 4 selected checks, all passed). Ruff format was already nonconforming on the three touched Python files at the base commit, so this PR avoids unrelated file-wide formatting. This is a control-plane behavior change and is left for maintainer review and merge.