fix(quota): recover undeclared capabilities before fallback selection - #4285
Conversation
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
动机
我按 exact head 409484d43517715380f35ccd26b5ecca323b0227 重新审阅了整条 origin/main...HEAD。旧行为的问题是真实且会持续累积:当 action_portfolio 仍要求显式选择时,selected_todo 只是建议值,但 Python re-entry 投影会先用它过滤候选,因此更高优先级、缺少 agent-owned runtime capability 的 Todo 可能完全不出现在 agent_channel.next_task_action,agent 只看到 fallback selection。
我用同一 public CLI integration fixture 对 detached base bfd1ec8db846bca3af47e559aa5fe7e515e57370 和当前 head 做了对照:base 因缺少 next_task_action 失败,head 的 selection-required true/false 两条路径均通过。最小的单点 Python 条件虽能修眼前分支,但会继续让 capability eligibility、优先级、receipt binding 与 authority exclusion 跨 Python/TypeScript 双重维护;把这条规则放回既有 TypeScript capability gate 是更小的长期所有权变更。
改动思路
入口仍是现有 build_interaction_contract / quota should-run projection;权威输入仍来自 typed capability gate、action portfolio、Turn receipt、host-observed capabilities 与 scheduler execution context。新的 projectRuntimeCapabilityReentry 只做纯投影:receipt 优先于 advisory selection,primary_blocked_todo_id 优先于列表展示顺序,并排除 credentials、production_access 以及已观测能力。它不会写 Goal lease、永久 grant、settlement 或 advancement checkpoint。
Python runtime_capability_reentry.py 现在只负责 effect runtime 调用、argv 渲染及映射到既有 agent/CLI channel;interaction_contract.py 只构建一次共享结果。这样 CLI/managed Turn 继续共用同一 projection。前端没有对应的 capability 配置控件或第二套状态,因此本 PR 无需新增 frontend companion;Lark 继续消费既有 capability-gate projection,本 PR也没有把 Lark live delivery 冒充为已验证。相关 PR #4283 未修改这些 owner symbols;若它先合并,仍需 rebase 后重跑 exact-head evidence。
具体改动
整条 PR 共 9 个文件、+234/-146:核心生产变化集中在 capability_gate.ts +67/-1;runtime_capability_reentry.py +73/-112 与 interaction_contract.py +16/-29 合计删除了重复 Python policy,并把 follow-up 的 channel adapter 从 1549 行的 interaction contract 移到现有 re-entry facade,使该文件降至 1528 行,修复 maintainability ratchet,而非放宽阈值。其余为 public CLI/installer 回归、TypeScript negative cases,以及中英文迁移 RFC。
关键代码讲解
capability_gate.ts:116 projectRuntimeCapabilityReentry是唯一决策 owner。它从结构化 binding/blocked candidate 构建候选,receipt 绑定优先,primary binding 决定优先级;无 eligible candidate 时返回null。runtime_capability_reentry.py:19 build_runtime_capability_reentry_packet是薄兼容层。repair_missing为空时提前返回,避免健康路径产生 TypeScript hop;非空时调用 typed effect,并仅把command_argv渲染为 shell-safe command。runtime_capability_reentry.py:106 apply_agent_channel_projection将同一 typed result 映射为非 settlement、非 advancement 的 verification action;失败后仍保留显式 selection 作为 fallback。interaction_contract.py:1417 build_interaction_contract只计算一次 re-entry packet,再注入既有 agent/CLI channel,避免重复运行或第二数据源。
对主干的风险
最强反例是跨 runtime 漂移:TypeScript 决策正确,但 Python adapter 可能遗漏 channel 字段;另一个风险是错误地把 owner-held capability 当作 agent 可修复权限,或让 advisory selection 覆盖已提交 receipt。当前 head 用 exact-string typed arrays/objects 和明确的 receipt precedence 防住这些路径,没有 substring/prose classification。
验证覆盖:TypeScript capability gate 11/11;受影响 Python 267 tests;ruff、control-plane typecheck、git diff --check、maintainability ratchet、public/private boundary scan;detached base/head public CLI regression;install-local-smoke 单独在约 99 秒内通过,并以 300 秒 per-check timeout 重跑完整 premerge;远端 Sign-off、4 个 test shard、pytest、merge-gate、Sonar、Windows 与其余 required checks 全部通过。无 blocking finding。剩余风险主要是将来同时修改 TS owner 与 Python adapter 时的 contract drift,以及 #4283 先落主干后的集成变化;任何 head/base 变化都应重跑本结论。
我的整体评价
结论为 APPROVE。该变更修复了真实的 priority inversion,决策所有权与仓库架构一致,机制是纯派生投影且不扩张权限;follow-up 还实质性消除了 maintainability failure。用户入口上,CLI 与 managed Turn 已验证,generated /loopx 安装说明有覆盖;没有新增配置,所以无需前端改造,Lark 仍沿用共享 projection 而不是另建 source of truth。
由于这是 author-owned PR,GitHub 不允许正式 self-approval,所以我以 COMMENTED review 记录 approval conclusion;它不构成 merge authority,也不替代 owner review。
English verdict: APPROVE at exact head 409484d43517715380f35ccd26b5ecca323b0227; no blocking findings, all required checks pass, and the change keeps TypeScript as the single decision owner without granting durable authority. This is an author-owned commented conclusion, not merge authorization.
A runnable recommendation could suppress runtime-capability verification for blocked work before explicit Turn selection. For example, a P1 local task hid the re-entry route for a P0 network task even though network was merely undeclared. Preserve verification before selection; successful checks re-enter the same Turn, while failed checks retain the explicit fallback command. Committed Todo bindings remain immutable.
Move verification-target selection, authority exclusion and the recovery contract into the existing TS capability-gate owner. Python retains host/scheduler adaptation and shell rendering. Update the generated /loopx skill and the bilingual TS migration RFC. Runtime observations remain host-local; no shared-authority grant, lease or provider write is added.
Validation: 99 Python tests (re-entry, real CLI selection/settlement, compact projection, generated skill installation); 11 TS tests; control-plane typecheck; Ruff; diff check. A baseline-versus-patched fixture reproduces the missing route. LoopX check: zero errors, three pre-existing registry warnings.
User entry points: CLI and managed Turn reuse the existing runtime_capability_reentry and selection-command projection. There is no new setting, API schema or frontend control to expose; no frontend assets change. Generated Codex skill readback is covered. This PR does not claim live Lark delivery acceptance.
Migration economics:
Scope: bounded host-local read-plan cutover, not complete quota/interaction migration or shared-authority promotion.