Repository navigation
fix(quota): allow explicit independent work under scoped approval - #7440
Conversation
Signed-off-by: huangruiteng <huangrt01@163.com>
cocolord
left a comment
There was a problem hiding this comment.
Reviewer: model_agent; GPT-family; OpenAI; self_reported (exact runtime observation unavailable).
REQUEST_CHANGES — 原 Turn 恢复到实际进展的关键证据未完成资格验证;不是已确认代码缺陷,也不是红 CI 的一律否决。
动机
受影响的是在同一 Goal 中已有明确工作选择、但另一项工作仍等待用户审批的 Agent 或 CLI 调用方。
例如,发布审批尚未完成时,调用方选择一项不依赖该审批的校验工作;旧实现把推荐项当成唯一可执行项,拒绝另一项合法选择,迫使调用方重新进入 guard。
本 PR 的可观察增量是让这个独立选择直接通过现有准入,同时保留待审批工作和原 Turn 的恢复身份。
这不授予审批、生产写入、租约或额外预算,也不声称已测得真实任务的长期效率提升。
本次仅评审 #7440,head 4bc97062eeec25fef3650e1525f8b45e15f8160e,完整 8 文件、+148/-22;对照不可变的改动前版本 22196e81db063cbfabb4ca5591fbb83c7bc987c0。现有评审、行内评论和讨论均为空,不继承其他结论。
改动思路
最有力的反对理由是:开放独立工作可能把限定审批变成可绕过的装饰。因此不能只证明“选中的工作能跑”,还必须证明选中对象的真实依赖仍由审批范围约束。另一端也不能为了保留推荐顺序而拒绝合法独立工作。
做法保留现有所有权:CLI 接受调用方意图,完整的权威 Todo 来源提供身份、归属、能力和依赖事实,Python 只做资格投影与结构传输,TypeScript 的 selectScopedGateFallback 仍判定 scope/exact-target 关系,原有准入与回执协调 owner 决定最终执行和恢复。没有新增能力、provider、状态存储或另一份审批规则;File/SQLite 都经过同一边界。
先从完整来源资格检查指定 Todo,再把其原始行交给 gate selector,避免精简展示丢失依赖元数据。推荐顺序继续用于没有显式选择的路径,真实的 scope、健康、预算、能力和回执绑定条件仍是硬边界。这比另加 Python bypass 或并行 request-version 机制更小、更容易回滚,也避免让调用方先绑定一项自己并未选择的工作。
具体改动
独立验收基准为 docs/quota-allocation.md,spec_revision 22196e81db063cbfabb4ca5591fbb83c7bc987c0;补充依据是同版本 docs/architecture.md 的 “Guided Autonomy, Not Recommendation Lock-In”。采用改动前文本,不用新增文档反过来证明实现。原文未给这些段落编号,以下是本次对照标签:
non-exhaustive-choice:精简建议不是许可名单;当前权威、同 Agent、能力就绪的未展示 Todo 也可显式选择。已实现:File/SQLite 的普通和 35 项噪声之后的隐藏独立选择,base 都返回delivery_not_allowed,head 都 qualified 且允许交付。current-admission:选择必须重跑当前范围和资格检查,缺失许可不是授权。已实现:exact-target、matching required scope、缺失依赖 scope、能力不足、其他 Agent claim 都不能借显式选择获得交付;用户审批仍保持打开。same-turn-recovery:拒绝或延迟后的恢复使用原 Turn、去掉选择参数,并通过当前 guard 回到合法工作。未满足本次证据门槛:有效的被 gate 拒绝的原 Turn 尚未沿返回的恢复命令走到真实成果校验、durable writeback、结算及独立读回;目前只能确认独立 begin 准入与重放。最小补充是沿同一原 Turn 执行一次规范的 File/SQLite 完整路径,而不是恢复推荐锁定或扩大审批权限。receipt-identity:已绑定回执不能改绑;选择不等于认领或租约。已实现:真实 File/SQLite 初次 begin+选择和重放保留原身份,换 Todo 返回heartbeat_receipt_identity_conflict;未认领候选仍要求执行前认领。
关键代码讲解
validate_quota_command_request(loopx/cli_commands/quota_request.py:119):允许已有 begin-Turn 支持的宿主组合--begin-turn --todo-id,但仍拒绝与既有--turn-instance-id同传,且 begin 仍需明确 Agent。它只改输入组合,不负责最终授权,也没有把 begin 扩展到不支持的宿主。_prepare_quota_should_run_item(loopx/control_plane/quota/should_run_prepare.py:543,关键分支 745–766):提前调用现有build_explicit_advancement_next_action,使用完整 planning source 和实际可用能力资格检查;仅资格成立时,把原始 Todo 行送给 scoped fallback。预算、健康和后续 lane/receipt 仲裁没有移除。_scoped_user_gate_fallback(loopx/control_plane/agents/agent_scope.py:213):把原始候选加入已经评估的执行集合,随后调用 Pythonselect_scoped_gate_fallback(loopx/control_plane/todos/decision_scope.py:318)桥接 typed owner。索引返回、按 Todo 去重和输出压缩仍沿用原协议,不用 compact 行伪造独立关系。selectScopedGateFallback(loopx/control_plane/todos/decision_scope.ts:98):先逐候选检查所有适用 gate;只有独立关系、并匹配显式 id 的候选才能被选择。未传 id 时仍沿用原排序。global_gate、exact target、scope 覆盖和projection_repair_required均未被降级。
另外,docs/quota-allocation.md 的 15 行双语新增说明明确披露旧/新输入组合、推荐与权限的区别及恢复方式。新测试文件的 100 行覆盖独立选择、真实范围拒绝、预算、缺失身份、默认排序和两种 provider 的 begin/replay;既有 settlement 测试只增加 --unblocks-todo-id,使“新 gate 阻挡该选择”的负例确实覆盖指定 Todo,而不把无关 action-scoped gate 错当全局限制。完整 diff 没有被 bits 的 docs/tests 过滤缩小。
对主干的风险
最重要的风险是隐藏候选或未来新增 Todo 被错误地视为独立。原生 CLI 对照已经证明两侧:受审批覆盖的现有和新增工作继续被拒绝;同 Goal 中无依赖的当前、隐藏及新增工作在 head 获准;明确 global gate 则覆盖新增工作。真实 todo update 成功修改了标题和 action-kind 后,covered 工作仍被拒绝,另一次 todo list 读回 required scope 未丢失。非法 scope 元数据更新在写入前被拒绝,不能制造虚假授权。没有用维持优先级来否决合法独立工作。
28 个独立定义的 File/SQLite base/head 成对场景已经核对完整回执、交互 channel、诊断和恢复命令;仅路径、观察时间、事件 nonce 和对应合成来源的派生 fingerprint 不同,不抹去许可、范围、身份、计数或错误细节。不开 scoped gate 的显式路径和未选默认路径保留原行为。初次选择、发现当前变化、拒绝后恢复以及已绑定回执的路径分别检查,不用一个成功 guard 代替后续进展。
资格缺口(不是已确认代码缺陷):最终 bounded fixture 的首次 --todo-id 没有 Turn 身份,只触发参数验证失败;之后 --begin-turn 创建了新 Turn,不能代替恢复被审批拒绝的原回执。它也没有执行真实成果校验或带 settlement_identity / --delivery-workspace-path 的规范 refresh-state,便直接构造 result hash,用非规范 spend 参数调用。File/SQLite 均返回 rc=1、spend_count=0,所以这个失败首先说明验证路径/协议不匹配,不能证明产品 bug,也不能宣称恢复完成。
最小补充:以原 Turn 发起真正 covered 的拒绝,执行返回的无选择 reentry(保持同一 Turn),选择并认领合法独立工作,产出并独立验证有用成果,运行投影的 refresh-state 与 workspace 校验,再从正确 project cwd 执行投影的 spend-slot(--source heartbeat --execute);单独读回成果、结算/一次扣费与下一次合法继续,并确认 gate 和 covered Todo 未变。若现有协议合法豁免扣费,应读回明确的 typed 豁免和已结算/继续依据,不得为凑通过而强行扣费或降低断言。完成后还需区分已结算历史回执与对已完成 Todo 的新工作准入。没有要求新增审批、阻止有效独立工作或重写 TypeScript。
原生 Ruff、TypeScript 全树类型检查、架构/decision-scope CLI 37 项验证、bilingual diff 和 diff check 均通过;两组实际并行审查及跨组 caller/type 校验已执行。跨组最终回执确认 25/25 原生 TypeScript scope/admission 回归测试通过(0 fail/skip)。但原 Turn 到完整真实进展的 qualified receipt 未取得;该项明确 unverified,不能用这些通过的测试数量替代。 早期合成 authoring 参数错误和 CLI/Chat assets 环境缺失保留为 setup 失败,纠正后才执行决定性用例,未算作 bug 或成功。没有付费模型调用,也没有修改活动 Goal、产品代码或 Git 历史。
语义与 CI 对齐
此变更复用现有 gate/selection/recovery 词汇和 TypeScript owner,不新建分类枚举。diff-scoped semantic advisory 没有检出新的受支持词汇 carrier,但这不是安全证明;判断仍来自实际类型、调用和反例。通用错误保持 domain-neutral;推荐是 guidance,must_attempt/delivery_allowed 及 scope/receipt 检查是机器执行的义务,缺失 permission 不能充当 grant。双语文档已披露显式选择和 begin 组合的行为变化,未改变默认 fallback,也未修改自动加载的宿主指令。
现有红 CI 不归罪于本补丁,也不报告为绿:chat-recovery.mjs:44 的 30 秒 button timeout,以及 research-worker-readback.mjs:93 的“完整费用未知”文案断言,在不可变 base 和 exact head 上通过相同原生 browser scenario 复现相同身份及完整细节;失败因果路径不在本 diff,改动的准入不变量有独立通过证据。前者解释两项 browser 和 release build,后者解释另两项 browser;aggregate checks、尚未完成的 test/merge-gate 及 strict up-to-date 条件继续作为独立 merge hold,不能 bypass 或据此合并。
我的整体评价
REQUEST_CHANGES。独立选择的准入改进已证实且不应退回推荐锁定,但完整恢复链尚未达到本次验收要求。long_horizon 为 not_yet_proven:原 Turn 恢复后的完整进展与结算读回尚未资格完成;user_experience 的首次选择路径已改善,但完整失败恢复路径仍为 not_yet_proven。不能把已获得准入或生成回执当作已恢复进展,也不能恢复错误的推荐权限限制。
生产代码仅 +32/-22,主要是把既有资格检查前移并传递一个已有选择 id;101 行测试和 15 行文档与同一问题配套,没有 speculative 框架。兼容性保留在真实 co-deployed decoder、旧调用默认参数和持久回执恢复上,不新增版本分支。bounded future-facing pass:unnecessary;已检查“完整来源资格检查 → typed gate transport → receipt owner”边界,当前移动和复用足以消除错误先后依赖,不需要另抽一份规则或强制 TS 重写。
残余边界是未测量的真实任务长期收益、尚未完全通过的仓库 CI/merge readiness,以及 future admission 必须继续使用当前 scope 与能力事实;本评审既不是授权 grant,也不是 merge/dismissal 授权。只对上述 exact head 给出结论,换 head 需重新资格验证。
English verdict: REQUEST_CHANGES - 4bc9706 - Native File/SQLite base/head gate, future and metadata cases pass; original-Turn recovery-to-progress qualification remains incomplete. This is an evidence gap, not a confirmed code bug; unrelated baseline CI failures remain separate merge holds.
Signed-off-by: huangruiteng <huangrt01@163.com>
|
已按评审要求在原 PR 补齐验证,commit File 与 SQLite 均实际执行了:
当前 head 的验证:9 项 focused + 32 项相邻 CLI 回归通过;10 项 TypeScript scope 测试、全 control-plane typecheck、Ruff、双语 diff、diff check 和公开边界检查通过。 本次验证补足的是原 Turn 到真实产物、验证和一次结算的证据。它不证明真实长程收益,也不把 Todo 局部验证当作 Goal 完成验收。先前验证脚本的问题未重新归因成产品缺陷;当前仓库 CI 和重新评审仍分别保留,未申请 dismiss 或合并。 English: The requested original-Turn recovery qualification now passes on both real File and SQLite backends, through independently validated work, durable writeback, exactly-once heartbeat spend, and fresh-process readback. This follow-up changes tests only. CI and renewed review remain separate merge requirements. |
An open scoped approval previously allowed only the automatically ranked fallback. Explicitly choosing another eligible, independent Todo was rejected as
delivery_not_allowed, so callers could not carry their planning decision into execution.This change passes the exact eligible candidate, with its original scope metadata, to the existing TypeScript gate-scope owner. Hosts that support
--begin-turncan also supply--todo-idon that first call. Scope, capability, budget, recovery/monitor precedence and committed Turn identity checks remain authoritative; no-selection calls retain their ranking.The recovery regression now covers the full File/SQLite journey: a genuinely covered selection is rejected with a valid original Turn; the returned command reenters without a selection or a new Turn; independent work is selected and claimed; an input-derived artifact is checked by a separate validator process; projected refresh and heartbeat spend commands settle the original identity once. Independent readback confirms the covered Todo and approval are unchanged, the completed Todo cannot be admitted as fresh work, and another legal Todo can continue. The validator also rejects a wrong artifact. This qualifies local Todo completion, not Goal-level acceptance or measured long-horizon gains.
Validation on
cfe05bcba:The review follow-up adds only regression coverage; the valid recovery journey exposed no additional production-code defect. Repository-wide CI remains a separate qualification: the prior head had failing/cancelled jobs, and the new head must finish CI and receive renewed review before merge.