Repository navigation
fix(quota): recover canonical sources for lifecycle-bound replans - #6538
Conversation
Signed-off-by: huangruiteng <huangrt01@163.com> (cherry picked from commit 45a0e3180bf453aa749e93ac420cd9be3de06d9e) Signed-off-by: huangruiteng <huangrt01@163.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent | model=gpt-6.1-sol | provider=OpenAI | declaration_source=runtime_reported | reasoning_effort=xhigh
动机
使用长程 Goal 的 Agent 在处理已完成任务的收尾时,会遇到旧来源被展示窗口省略的问题。旧回合已经绑定了这次收尾,但新任务随后进入当前队列,恢复时却拿当前队列重新判断旧回合,最终报身份冲突,无法完成回写和结算。
本次修复使旧回合从完整的权威 Todo 来源恢复原始义务;在新任务或人工阻塞随后出现时,仍能完成原回合的证据回写和单次结算。验证结果同时要求新任务保持 open,人工阻塞继续约束新回合。
边界是已有生命周期回合的恢复,不扩展执行权限,不代替 Goal 验收,也不证明无限期运行或真实模型效果提升。
改动思路
真实入口仍是 quota should-run → project_live_quota_decision → restore_receipt_bound_todo_source → goal_frontier → receipt_bound_lifecycle_candidate → TypeScript replan semantics。File/SQLite 权威存储提供完整来源,Python 只搬运来源和调用已有 frontier 构造器;原始身份、时间、Actor、完成关系及结算资格仍由已有类型化 owner 校验。不能通过展示列表缺失来判定原义务已经不存在。
核心理由是:历史来源重建不能借用后来新增的队列计数或人工阻塞;去掉这些当前投影输入后,仍须命中原义务摘要,才可能恢复。实时人工阻塞继续作用于新任务准入,历史重建本身不授权执行新工作。本 PR 的边界是补齐现有恢复入口的来源与历史重建参数,保留现有身份、证据与扣费规则,不增加另一套状态或兼容协议。
| 场景 | 原路径 | 本次路径 |
|---|---|---|
| 来源超出展示窗口,新 Agent 任务到达 | 原义务身份冲突 | 完整来源恢复旧义务,新任务保持 open |
| 原回合绑定后新增人工阻塞 | 当前用户队列阻止历史义务重建 | 原回合完成收尾,新回合继续 ask_user |
| 没有证据回写或重放扣费 | 拒绝提前扣费,重复扣费不追加 | 保持相同边界 |
该表是源码流程说明;下面的真实 CLI 回归提供执行证据。
具体改动
审查整个 af56c5f4fc6120957b0ae2808f5acae3b8e67882..994ef8cce64ed05bd64f008646c71be520b487c3,共 5 个文件。规范依据为 docs/quota-allocation.md#receipt-backed-settlement-progress,spec_revision 为 af56c5f4fc6120957b0ae2808f5acae3b8e67882;同时核对该 revision 的 docs/reference/protocols/quota-cli-hot-path-compaction-v0.md#ownership-boundary。两份规范均未在本 PR 改写。
receipt-backed-settlement-progress:已实现。恢复保持原 Goal/Agent/Turn/replan identity;先有合格回写及回执,再执行原绑定的 spend,重放不重复扣费。真实 File/SQLite CLI 覆盖提前扣费拒绝、回写、结算和重放。ownership-boundary:已实现。展示压缩不是决策 owner;完整 Todo reader 补齐事实后,原 TypeScript owner 决定义务与结算,未把 compact 列表缺失解释成权威不存在。- 更广的长期稳定性、模型理解、其他平台和存储迁移不属于这次有界来源修复,未宣称完成对应验收。
关键代码讲解
restore_receipt_bound_todo_source:只在 guard-scoped replan 且 replay phase 为 OPEN 时,通过现有完整list_goal_todos恢复目标 Goal 的两个 Todo summary,其他 Goal 行不变。Todo-bound 路径仍用既有 exact-ID reader;SETTLED 不进入新增读取分支,缺失 exact Todo 仍明确拒绝。_receipt_bound_guard_fields/project_live_quota_decision:从现有 settlement readback 派生 scope 和 recorded_at,只计算一次,来源恢复与最终决策使用同一组字段,不增加一个可手工同步的状态源。build_goal_frontier_projection_context_from_status:历史 lifecycle callback 使用已验证的 completed-row summary,省略实时 frontier counts,并把当前 user summary 排除在历史重建之外。现有 typed lifecycle owner 仍比对原 obligation digest、完成身份、归属与时间;这不是忽略实时用户权限。test_hidden_completed_source_recovers_its_original_guard_after_new_work:复用原 CLI fixture,参数化 File/SQLite 和后来人工阻塞。24 个较新终态来源遮蔽旧记录后,执行完整恢复、拒绝提前扣费、证据回写和一次扣费;另验证新任务、用户任务保持 open,新回合仍禁止 delivery 并 ask_user。fixture 仅新增可选初始 Todo 输入。
对主干的风险
本次 review 在原 head 1be235f07c18acaac23b013a648f7312c3cc8c8a 复现了遗漏:同 Agent 后来新增 user gate 时,实时 user summary 抢占了历史来源重建,File/SQLite 都报原始 replan 身份冲突。修复提交 994ef8cce64ed05bd64f008646c71be520b487c3 排除这个当前投影输入,并增加持久回归。该发现已修复,无遗留阻断项。
最终 head 验证:117 项聚焦 Python 测试、21 项 TypeScript replan 语义测试、6 个独立真实 CLI 重放(普通恢复、更多无关终态记录并反转输入顺序、后来全局人工阻塞,各含 File/SQLite),以及风险 premerge 的 5 个 direct checks 和 18 个所选 canary 全部通过。不可提前扣费、重复结算不追加、后续工作不被旧回合接管均有断言。独立 immutable base 上普通回归 File/SQLite 均失败,证明测试能区分旧缺陷;原 head 的后来 user-gate 反例也先失败。前一轮新增测试把候选 selected_todo 当作准入结果而误报;核对既有权限合同后改为断言 delivery_allowed/must_attempt/ask_user,保留实际权限边界。
未查询或等待远端 CI,遵循本次管理策略;未运行付费模型、PostgreSQL、完整全仓 pytest 或新 UI 浏览器旅程。这里没有 provider 实现、存储迁移或 UI 变更,实际验证使用隔离的 File/SQLite 权威存储和源码 CLI。剩余成本是仅对未结算且绑定 replan 的恢复读取完整 Todo 来源;没有增加到普通新回合或已结算回合。回滚本 PR 可恢复旧行为,但会重新暴露上述身份冲突。
语义与 CI 对齐
复用现有 ReceiptBoundReplayPhase、guard scope、canonical Todo reader 与 TypeScript replan/settlement 词汇,无新增共享 vocabulary。diff advisory、完整 semantic vocabulary smoke、维护性 ratchet、Ruff 和 whitespace checks 均通过,未调整预算、阈值、权限或判定文字。恢复后仍明确要求 evidence-linked Vision 回写,Todo no-follow-up 本身不算 Goal 验收,也不能成为直接扣费依据。
我的整体评价
APPROVE,精确 head 为 994ef8cce64ed05bd64f008646c71be520b487c3。long_horizon:improved,累积终态记录和新任务不再使旧回合失去原始来源;user_experience:improved,恢复无需重新执行旧任务或手工改写回执,同时新回合仍遵守人工阻塞。结论限于本次有界回归,未将其外推为长期运行或模型能力证明。
方案沿用最近的来源恢复与类型化 owner,新增生产分支只负责完整事实读取;未来相关重构已落实为 guard 字段单次派生和历史/实时投影输入分离,不需要再建一个状态源或新 helper 层。whole-PR 规模与实际故障相称,持久回执兼容保留,没有新公共选项或 default-off 能力。现有 strict change-quality receipt 与最终本地验证通过;按维护者对本批次的明确授权,可在最新 readiness 返回 ready 且 head 未变后 admin bypass 合并。
English verdict: APPROVE - exact head 994ef8c. Complete canonical facts recover the original lifecycle-bound Turn across compact omissions, later work and later user gates. The review-found user-gate reconstruction defect is fixed; evidence writeback, single debit and live gate authority remain enforced. 117 Python tests, 21 TypeScript tests, 6 File/SQLite replays and all selected premerge checks pass; remote CI was not consulted.
huangruiteng
left a comment
There was a problem hiding this comment.
Reviewer: model_agent | model=gpt-6.1-sol | provider=OpenAI | declaration_source=runtime_reported | reasoning_effort=xhigh
Approval conclusion (author-owned PR; GitHub blocks formal self-approval). This records the same agent self-review under the authorized maintainer account; it is not a second independent review.
动机
使用长程 Goal 的 Agent 在处理已完成任务的收尾时,会遇到旧来源被展示窗口省略的问题。旧回合已经绑定了这次收尾,但新任务随后进入当前队列,恢复时却拿当前队列重新判断旧回合,最终报身份冲突,无法完成回写和结算。
本次修复使旧回合从完整的权威 Todo 来源恢复原始义务;在新任务或人工阻塞随后出现时,仍能完成原回合的证据回写和单次结算。验证结果同时要求新任务保持 open,人工阻塞继续约束新回合。
边界是已有生命周期回合的恢复,不扩展执行权限,不代替 Goal 验收,也不证明无限期运行或真实模型效果提升。
改动思路
真实入口仍是 quota should-run → project_live_quota_decision → restore_receipt_bound_todo_source → goal_frontier → receipt_bound_lifecycle_candidate → TypeScript replan semantics。File/SQLite 权威存储提供完整来源,Python 只搬运来源和调用已有 frontier 构造器;原始身份、时间、Actor、完成关系及结算资格仍由已有类型化 owner 校验。不能通过展示列表缺失来判定原义务已经不存在。
核心理由是:历史来源重建不能借用后来新增的队列计数或人工阻塞;去掉这些当前投影输入后,仍须命中原义务摘要,才可能恢复。实时人工阻塞继续作用于新任务准入,历史重建本身不授权执行新工作。本 PR 的边界是补齐现有恢复入口的来源与历史重建参数,保留现有身份、证据与扣费规则,不增加另一套状态或兼容协议。
| 场景 | 原路径 | 本次路径 |
|---|---|---|
| 来源超出展示窗口,新 Agent 任务到达 | 原义务身份冲突 | 完整来源恢复旧义务,新任务保持 open |
| 原回合绑定后新增人工阻塞 | 当前用户队列阻止历史义务重建 | 原回合完成收尾,新回合继续 ask_user |
| 没有证据回写或重放扣费 | 拒绝提前扣费,重复扣费不追加 | 保持相同边界 |
该表是源码流程说明;下面的真实 CLI 回归提供执行证据。
具体改动
审查整个 af56c5f4fc6120957b0ae2808f5acae3b8e67882..994ef8cce64ed05bd64f008646c71be520b487c3,共 5 个文件。规范依据为 docs/quota-allocation.md#receipt-backed-settlement-progress,spec_revision 为 af56c5f4fc6120957b0ae2808f5acae3b8e67882;同时核对该 revision 的 docs/reference/protocols/quota-cli-hot-path-compaction-v0.md#ownership-boundary。两份规范均未在本 PR 改写。
receipt-backed-settlement-progress:已实现。恢复保持原 Goal/Agent/Turn/replan identity;先有合格回写及回执,再执行原绑定的 spend,重放不重复扣费。真实 File/SQLite CLI 覆盖提前扣费拒绝、回写、结算和重放。ownership-boundary:已实现。展示压缩不是决策 owner;完整 Todo reader 补齐事实后,原 TypeScript owner 决定义务与结算,未把 compact 列表缺失解释成权威不存在。- 更广的长期稳定性、模型理解、其他平台和存储迁移不属于这次有界来源修复,未宣称完成对应验收。
关键代码讲解
restore_receipt_bound_todo_source:只在 guard-scoped replan 且 replay phase 为 OPEN 时,通过现有完整list_goal_todos恢复目标 Goal 的两个 Todo summary,其他 Goal 行不变。Todo-bound 路径仍用既有 exact-ID reader;SETTLED 不进入新增读取分支,缺失 exact Todo 仍明确拒绝。_receipt_bound_guard_fields/project_live_quota_decision:从现有 settlement readback 派生 scope 和 recorded_at,只计算一次,来源恢复与最终决策使用同一组字段,不增加一个可手工同步的状态源。build_goal_frontier_projection_context_from_status:历史 lifecycle callback 使用已验证的 completed-row summary,省略实时 frontier counts,并把当前 user summary 排除在历史重建之外。现有 typed lifecycle owner 仍比对原 obligation digest、完成身份、归属与时间;这不是忽略实时用户权限。test_hidden_completed_source_recovers_its_original_guard_after_new_work:复用原 CLI fixture,参数化 File/SQLite 和后来人工阻塞。24 个较新终态来源遮蔽旧记录后,执行完整恢复、拒绝提前扣费、证据回写和一次扣费;另验证新任务、用户任务保持 open,新回合仍禁止 delivery 并 ask_user。fixture 仅新增可选初始 Todo 输入。
对主干的风险
本次 review 在原 head 1be235f07c18acaac23b013a648f7312c3cc8c8a 复现了遗漏:同 Agent 后来新增 user gate 时,实时 user summary 抢占了历史来源重建,File/SQLite 都报原始 replan 身份冲突。修复提交 994ef8cce64ed05bd64f008646c71be520b487c3 排除这个当前投影输入,并增加持久回归。该发现已修复,无遗留阻断项。
最终 head 验证:117 项聚焦 Python 测试、21 项 TypeScript replan 语义测试、6 个独立真实 CLI 重放(普通恢复、更多无关终态记录并反转输入顺序、后来全局人工阻塞,各含 File/SQLite),以及风险 premerge 的 5 个 direct checks 和 18 个所选 canary 全部通过。不可提前扣费、重复结算不追加、后续工作不被旧回合接管均有断言。独立 immutable base 上普通回归 File/SQLite 均失败,证明测试能区分旧缺陷;原 head 的后来 user-gate 反例也先失败。前一轮新增测试把候选 selected_todo 当作准入结果而误报;核对既有权限合同后改为断言 delivery_allowed/must_attempt/ask_user,保留实际权限边界。
未查询或等待远端 CI,遵循本次管理策略;未运行付费模型、PostgreSQL、完整全仓 pytest 或新 UI 浏览器旅程。这里没有 provider 实现、存储迁移或 UI 变更,实际验证使用隔离的 File/SQLite 权威存储和源码 CLI。剩余成本是仅对未结算且绑定 replan 的恢复读取完整 Todo 来源;没有增加到普通新回合或已结算回合。回滚本 PR 可恢复旧行为,但会重新暴露上述身份冲突。
语义与 CI 对齐
复用现有 ReceiptBoundReplayPhase、guard scope、canonical Todo reader 与 TypeScript replan/settlement 词汇,无新增共享 vocabulary。diff advisory、完整 semantic vocabulary smoke、维护性 ratchet、Ruff 和 whitespace checks 均通过,未调整预算、阈值、权限或判定文字。恢复后仍明确要求 evidence-linked Vision 回写,Todo no-follow-up 本身不算 Goal 验收,也不能成为直接扣费依据。
我的整体评价
APPROVE,精确 head 为 994ef8cce64ed05bd64f008646c71be520b487c3。long_horizon:improved,累积终态记录和新任务不再使旧回合失去原始来源;user_experience:improved,恢复无需重新执行旧任务或手工改写回执,同时新回合仍遵守人工阻塞。结论限于本次有界回归,未将其外推为长期运行或模型能力证明。
方案沿用最近的来源恢复与类型化 owner,新增生产分支只负责完整事实读取;未来相关重构已落实为 guard 字段单次派生和历史/实时投影输入分离,不需要再建一个状态源或新 helper 层。whole-PR 规模与实际故障相称,持久回执兼容保留,没有新公共选项或 default-off 能力。现有 strict change-quality receipt 与最终本地验证通过;按维护者对本批次的明确授权,可在最新 readiness 返回 ready 且 head 未变后 admin bypass 合并。
English verdict: APPROVE - exact head 994ef8c. Complete canonical facts recover the original lifecycle-bound Turn across compact omissions, later work and later user gates. The review-found user-gate reconstruction defect is fixed; evidence writeback, single debit and live gate authority remain enforced. 117 Python tests, 21 TypeScript tests, 6 File/SQLite replays and all selected premerge checks pass; remote CI was not consulted.
Goal And Delivered Outcome
Follow-up to #6524: a Turn bound to a lifecycle replan has no selected Todo to recover by exact ID. When compact views omit its older completed source, later Agent work or a later user gate can make recovery fail with an identity conflict.
Restore the complete canonical Todo inventory inside the existing source-recovery boundary for OPEN, guard-scoped replans. Reconstruct the historical closed-row source independently of current frontier counts and current user Todos. The existing TypeScript owner still validates the original obligation digest, Actor, completion identity, timestamps, qualified evidence and settlement.
The original Turn retains its binding, requires evidence-linked writeback and settles once. Independent later work stays open. A new global user gate remains open and still refuses delivery on a fresh Turn. Recovery does not complete the Goal or grant new-work authority.
Scope And Ownership
main, merge baseaf56c5f4fc6120957b0ae2808f5acae3b8e67882.docs/quota-allocation.md#receipt-backed-settlement-progressanddocs/reference/protocols/quota-cli-hot-path-compaction-v0.md#ownership-boundaryat the immutable merge base.Validation
Final head:
994ef8cce64ed05bd64f008646c71be520b487c3.Commands:
Remote CI was not consulted under the configured local-validation policy. PostgreSQL, paid models, a whole-repository pytest sweep and new UI/browser qualification were not run; this PR changes no provider implementation, promotion or visual surface. Isolated canonical File/SQLite stores and actual CLI/writeback/debit readback cover the changed invariant. The extra complete read is limited to open receipt-bound replan recovery. No long-soak or model-effectiveness claim.
Delivery Boundary