Repository navigation
fix(quota): recover receipt-bound todos omitted from compact views - #6524
Conversation
Signed-off-by: huangruiteng <huangrt01@163.com>
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent; model=gpt-6.1-sol; provider=OpenAI; reasoning_effort=xhigh; declaration_source=runtime_reported.
动机
需要继续上次工作的 Agent,会重放原 Turn(一次执行)的回执。原任务仍在存储中、却从精简状态视图消失时,新到期的重规划可能给它另一套结算身份。反复重试便无法完成原任务的恢复。本次让缺失任务经现有精确 ID 读取器补回,再交给原决策 owner;已延后的任务仍不能因此执行或扣额。独立 CLI 对照已验证这个修复方向。安装采用、真实宿主恢复和父级持续运行资格不在本次结论内。
改动思路
恢复事实读取与执行授权分开,方向正确。quota should-run 先读同 Turn 结算阶段;只有存在原绑定任务且尚未结算时,才尝试补全该 Goal 的内部任务快照。restore_receipt_bound_todo_source 复用 _bound_todo_item,沿原 provider-first 精确读取路径取事实,原 TypeScript 控制面仍决定重规划、任务生命周期和结算。Python 没有另建额度或优先级规则。
当前 PR 边界是原回执绑定任务被精简视图遗漏时的恢复。这个边界可独立验证和回滚,但入口函数已接近维护性预算,本次再向其中添加条件并不合适;应在现有来源补全边界内收拢分支,保留原事实与决策 owner。原记录已可见、已结算和普通新 Turn 路径继续沿旧流程。
具体改动
关键代码讲解
build_live_quota_should_run_decision(live_decision.py:616)在 retry overlay 和最终 quota 决策前补齐绑定任务,防止新的重规划候选替代已有回执身份。新增条件判断只选择事实来源,不能成为新的准入规则。restore_receipt_bound_todo_source(unsettled_host_turn.py:102)仅处理目标 Goal;用现有 planning source 识别可见记录,缺失时调用精确 reader,并为顶层及 project-asset 两份快照补充同一个原记录。它不更改磁盘生命周期、不解除 defer,也不改写回执。_bound_todo_item(同文件第 60 行,原有)复用list_goal_todos(... role="agent", todo_id=...),避免从展示上限推断对象不存在。读不到原对象必须保持拒绝,不能转向无关任务。- 新测试覆盖 legacy、File、SQLite 三种来源,每种含 0/60 个无关等待任务,以及原任务 checkbox 两种呈现;它通过真实 CLI/router/receipt replay 断言原身份、禁止执行和禁止扣额。
依据是基线 df5308c296af5e265957686eb863b989c9e07c94 的 docs/reference/protocols/quota-cli-hot-path-compaction-v0.md,其中 Ownership Boundary 要求视图精简不重算决策,本头已实现这一来源修复;原有 typed owner 与 settlement 格式保持。未把该文档更广的模型资格要求当作此局部修复的完成声明。全 diff 为 3 路径、139 行新增:43 行生产接入/来源读取,96 行回归测试,无新 schema、配置或共享词汇。
对主干的风险
[P2] 合并前修复新增的决策函数维护性超限。 新条件位于 loopx/control_plane/quota/live_decision.py:616–620。独立运行 uv run --extra test python examples/control_plane/control-plane-maintainability-ratchet-smoke.py,不可变基线通过,本头失败,唯一新增项为 oversized_decision_function:loopx.control_plane.quota.live_decision:build_live_quota_should_run_decision。同一指标从 71 statements / 59 decision points 增至 73 / 61,而现行 decision-point 上限是 60;这是本 PR 引入的必需本地检查失败,不能当作旧债或 CI 排队。
最小修复是在现有来源恢复边界内收拢这段条件,使主编排函数不继续承载可派生的来源分支,并保留原阶段判断及错误语义;随后重跑同一 ratchet、12 个回归和相邻结算测试。若认为保留该形状更合理,应按仓库既有预算决策规则给出成本/收益依据及显式受审例外;单纯调高全局阈值或删除检查不能解决此项。无需为了此修复引入第二决策 owner 或做无关大迁移。
恢复正确性证据:当前两个测试文件完整 117 passed;将当前 12 个回归原字节放到干净不可变基线,三种来源共 6 failed / 6 passed,隐藏行失败均在 settlement plan 的原任务身份断言,当前全部通过。额外删除原任务的真实 CLI 探针保持 fail-closed:退出 1、无执行或 settlement plan;它的诊断仅呈现通用 collection/writeback failure,不能宣称已验证精细错误恢复提示。临时测试路径/fixture 导入配置错误和初始过强诊断断言均保留为 reviewer harness 问题,没有据此修改产品或期望身份。
静态检查:先运行 semantic advisory,再执行完整 semantic canary、控制面 TypeScript 检查、配置内 mypy、Ruff、DCO 与 diff 检查,均通过。Canary 为 5 个 direct checks、18 个 selected/executed checks;17 项执行通过,1 项为上述 ratchet 失败,另有独立本地 quality_stale_receipt,总门未通过。没有查询、等待或启动远端 CI,没有伪造质量回执。
语义与 CI 对齐
沿用原任务/回执/结算词汇和 TypeScript owner。新增错误是通用 Goal 语义,没有产品或 benchmark 特化,没有 substring 状态分类。新的行为明确限于遗漏事实恢复;无 opt-in 承诺、新权限、自动续跑或 quota 豁免。检查失败需要原 owner 修复后再判,不以代码方向正确代替当前必需验证。
我的整体评价
REQUEST_CHANGES,精确头 e22459db46b4cd100290e929d268d098048e83df。原身份恢复是有价值、已通过真实 CLI 反例验证的增量,长期承诺保留和恢复用户体验在本次边界内改善;持续运行、安装和模型采用仍未资格化。全 PR 的机制与问题相称,但当前必需维护性检查新增失败,未来改动更易进入这段已过预算的编排函数,需先完成上述有界收拢或受审预算处理。既有来源 reader 与 typed owner 应继续保留;此评审不授予合并或 bypass 权限。
English verdict: REQUEST_CHANGES — e22459d. Receipt-bound recovery passes 117 local tests and the base/head counterexamples, but this head newly fails the required maintainability ratchet (59 → 61 decision points, limit 60). Consolidate the source-recovery branch or justify an explicitly reviewed budget decision; retain the separate quality-receipt hold.
Signed-off-by: huangruiteng <huangrt01@163.com>
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent; model=gpt-6.1-sol; provider=OpenAI; reasoning_effort=xhigh; declaration_source=runtime_reported.
动机
需要重试上次执行的 Agent,应继续履行已经写入回执的原任务承诺。原 Todo 仍在存储中、却被精简视图省略时,新到期的重规划可能给重试返回另一套结算身份,导致恢复循环。本次让遗漏的原任务经现有精确 ID 读取器补回,随后仍由原控制面判断生命周期与结算;延后的任务不会因此获得执行或扣额权限。
独立 CLI 对照确认了这个增量:相同 12 个用例在不可变基线出现 6 个隐藏行身份失败、6 个可见行通过,当前头全部通过。原承诺能被正确辨认,减少重复重试的维护成本。安装采用、真实宿主恢复和父级持续运行资格仍未完成,当前修复不代替这些验收。
改动思路
恢复事实读取与执行授权分开。quota should-run 先取得原 Turn 的回执阶段,在 retry overlay 与最终路由之前补齐其任务事实;TypeScript 的生命周期、准入、replan 和 settlement owner 保持不变。Python 承担现有 provider 的读取和内部快照适配,没有另建状态机或额度规则。
当前 PR 边界是原回执绑定任务被精简视图遗漏时的恢复。来源读取的空 ID/已结算短路放在 restore_receipt_bound_todo_source 内,主编排函数只调用一个来源恢复步骤。这是与当前修复同因、有界且可回滚的整理;复用 _bound_todo_item 和 planning source 选择器已足够,不需要新 provider、缓存或公共配置。
依据是基线 df5308c296af5e265957686eb863b989c9e07c94 的 docs/reference/protocols/quota-cli-hot-path-compaction-v0.md,其中 Ownership Boundary 要求精简展示不得重算路由或成为第二决策 owner;本次把缺失事实交还既有 owner,满足此项。整体路线图 S7 的原承诺、原身份和 once-only 结算仍由原规则持有,文档中 installed adoption、live Host 和规模化验收继续独立。未把作者的“complete”或先前评审当成当前证明。
具体改动
关键代码讲解
build_live_quota_should_run_decision(live_decision.py:616)统一调用来源补全函数,再执行overlay_active_turn_retries和原 quota 路由。它传递从 settlement readback 得到的receipt_bound_replay_phase,不自行推断原任务可执行。restore_receipt_bound_todo_source(unsettled_host_turn.py:103)对空绑定和ReceiptBoundReplayPhase.SETTLED原样返回;只查目标 Goal,用既有 terminal-inclusive planning source 判断原任务是否已可见。确实遗漏时,把同一 provider 原记录补入顶层与 project-asset 两份内部快照;不写任务、claim 或回执。_bound_todo_item(同文件第 59 行,原有)沿list_goal_todos(role="agent", todo_id=...)的 provider-first 精确读取路径取事实,校验返回 ID。读不到时保持拒绝,不能转向无关任务;公开 CLI 当前只给通用 blocked-health/write-failed 诊断,未声称已有细粒度恢复提示。test_deferred_replay_keeps_original_binding_during_replan覆盖 legacy、File、SQLite,每种包含 0/60 个无关等待任务和 checkbox 两种呈现。实际 CLI/router/receipt replay 检验原 identity、禁止工作和禁止扣额,而不是只检查 helper 输出。
完整差分为 3 路径、142 行新增:46 行生产接入/来源读取与 96 行回归测试。无新模块、schema、配置、协议词汇或第二决策 owner。恢复辅助函数新增的是本地 transport seam;既有 ReceiptBoundReplayPhase 被复用。
对主干的风险
上次 review 的维护性阻塞已在当前头独立关闭。相同仓库指标为:基线编排函数 71 statements / 59 decision points;旧头 e22459d 为 73 / 61;当前头为 72 / 59,decision-point 上限仍是 60。当前完整 ratchet 通过,没有调高阈值、添加豁免或压缩丢失义务。旧 REQUEST_CHANGES 记录保留;本次结论只绑定新头。
当前两个完整恢复/结算测试文件 117 passed;同一字节的 12 个回归在基线为 6 failed / 6 passed,当前 12 passed。失败全部发生于隐藏原任务后 settlement plan 缺少原 todo_id,而非偶发超时。当前另跑两个独立探针:删除原任务的真实 CLI 返回退出 1、should_run=false、无结算计划;来源边界的空 ID、已结算、已可见及其他 Goal 四类均保持原对象/内容且零 provider 读取。测试仅使用隔离的临时 legacy/File/SQLite 状态,未改变活跃 Goal。没有 PostgreSQL adapter 或存储规则变更,也未声称运行 PostgreSQL 集成或真实 App 恢复。
先运行 semantic advisory,再完成 full semantic canary、控制面 TypeScript 检查、配置内 mypy、Ruff、DCO 和 diff 检查,均通过。Canary 的 5 个 direct checks + 18 个 selected/executed checks 无产品失败、无 manual hold;总门仍有独立的 quality_stale_receipt,没有伪造或豁免该质量回执。代码批准不代表该质量门、平台合并就绪或 maintainer 合并授权。
额外探针首次构造的可见记录缺少合法 Todo 的 text,因此被既有来源 selector 排除;补齐必需事实后通过,保留原失败,不归因为产品问题。基线命令首次落在错误 checkout,已中断并弃用;采用正确不可变基线与源码出处重新执行。没有修改产品、断言或验收规则来获得通过。
语义与 CI 对齐
本次默认变化限于有原回执、未结算、原任务被视图省略的恢复路径。无新 opt-in、自动采用或安装提示;三个改动面均不增加新权限。fresh/settled/visible 路径仍短路,原 defer/claim/identity 冲突与结算门仍强制执行。通用错误保持 Goal/Todo 语义,无产品或 benchmark 特化、substring 状态分类或把强制拒绝称为 guidance。没有查询、等待或启动远端 CI。
我的整体评价
APPROVE,精确头 505290c2cbc020a4ce1675c03b1810c7a07d0a7c。本次修复将真实遗漏事实补回既有 typed owner,并完成了上次要求的有界整理;机制与问题相称,原身份与拒绝权限均有当前反例覆盖。调用者的恢复体验和长期承诺保留在这个局部边界内改善,真实宿主、安装采用、持续运行及独立质量门仍保留。
仓库经验中“先判断有用恢复结果”的建议适用于本次 caller/path 审查;采用其审查框架,不继承历史结论,也不把 context delivery 当成学习效用证明。未来相关整理已在当前来源边界内完成,无需新增架构或仅为仪式创建后续任务。此评审不授予 merge 或 admin bypass 权限。
English verdict: APPROVE — 505290c. Exact receipt-bound recovery passes the current CLI and File/SQLite counterexamples; the prior maintainability regression is repaired at the existing source boundary (59 decision points). Preserve the separate stale quality-receipt gate and unqualified host/adoption acceptance.
Goal And Delivered Outcome
A resumed Turn can still name its original Todo in the committed receipt while the compact status view omits that Todo. A newly due replan then supplies settlement steps for a different identity, so the original Turn cannot finish recovery.
Restore the missing row through the existing exact-ID Todo reader before routing the resumed Turn. The existing typed owner continues to decide lifecycle, eligibility and settlement; an unreadable original Todo fails closed. Fresh Turns and settled receipts retain their existing paths.
mainatdf5308c296af5e265957686eb863b989c9e07c94.Author Declaration
restore_receipt_bound_todo_sourceandbuild_live_quota_should_run_decisiontest_deferred_original_turn_binding.py_bound_todo_itemexact-ID readerScope And Continuation
Complete within this recovery scope. This is a narrow Python transport fix around the existing typed control-plane owner, with no provider migration, new lifecycle or new configuration. The related simplification pass reuses the existing reader and keeps the fresh/settled guards at the source-restoration boundary, so the main decision orchestrator does not gain branching complexity. No maintainability limit was changed. No separate successor is needed for this defect.
Validation
505290c2cbc020a4ce1675c03b1810c7a07d0a7c.git diff --check; semantic-inventory advisory found no supported new vocabulary carriers.Recovery regression command:
uv run --extra test python -m pytest -q tests/control_plane/test_deferred_original_turn_binding.py tests/control_plane/test_quota_settlement_cli.pyFrontend / Visual Evidence
Type of Change
LoopX Area
Technical Direction
Core control-plane recovery; preserve original identity across compact read models.
Shared-authority RFC fixture impact
N/A: no migration or provider-promotion claim. Existing File and SQLite fixtures exercise the same exact-ID reader.
Boundary Checklist