fix(quota): release rejected monitor poll reservations - #4991
Conversation
c323972 to
1c0ca78
Compare
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
动机
已复核真实失败路径:硬租约 Monitor 的请求缺少证明时,canonical 规划在业务提交前拒绝,但 quota 留下 provider_pending;同一 Turn 补上证明后,摘要变化又触发 effect conflict。这一 PR 完成了一个独立有用的修复:仅对确证“未产生业务效果”的拒绝释放该预留,使纠正后的同 Turn 重试可行。生成命令自动携带证明属于另一边界(#4995),不是本 PR 已交付的内容。
改动思路
保留 TypeScript 双重权威边界:coordination 规划器只在提交前拒绝时出具绑定原始请求哈希与 operation ID 的 no_effect;quota 事务持锁核对原 pending、来源、哈希、索引前缀及无同 effect 的 run 后,才删除那一份预留。Python 仅转运 typed 结果,不自行判断业务效果。相比放宽请求摘要或见错即删 pending,这不会抹掉超时和不确定提交的恢复栅栏。
具体改动
关键代码讲解
monitorPollRequestHash/executeCoordinationMonitorPoll:统一原始请求身份;no_effect只从planWriteback的提交前拒绝分支返回,source/commit 故障不携带该证明。validateNoEffect/evaluateQuotaMonitorPollCommit:新增provider_rejected内部阶段,只允许确切 pending 且索引历史完整时 abort;prepared/committed 和不可信结果仍保持原回执。- Python provider 异常路径:把 canonical 拒绝结果送回 quota owner 后继续抛出原错误,调用方可修正证明并重试。
对主干的风险
最危险的反例是“业务其实已提交,却删除 pending”。当前证明的产生位置和 quota 的哈希、状态、索引检查阻止了该路径;TS 用例覆盖伪造哈希/来源、timeout 和回执保留,真实 File/SQLite CLI 用例覆盖拒绝→补证明→一次提交→幂等重放。实测 20 项 TS、11 项 Python 通过,控制面 typecheck 与 diff check 通过。未运行真实 PostgreSQL 往返或全量套件;这项空白不等同于已验证。没有等 CI,遵守当前 wait_for_ci=false 契约。
语义与 CI 对齐
沿用现有 Monitor command receipt 和 quota pending 事务词汇;no_effect 是短暂的提交前负证明,不是新的持久业务状态。既有 pending/prepared/committed 回执仍可读取。
我的整体评价
没有发现阻断性代码问题。修复范围与实际卡住的重试成本相称,且把规则留在原 TS owner;没有引入第二个 Python 决策源。建议维护者先合并本 PR,再审视/合并 #4995 的自动证明路由;两者均为控制面改动,不应自合并。
English verdict: APPROVE - head 1c0ca78. Exact-head review; maintainer merge required.
1c0ca78 to
d942a47
Compare
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval). Approved exact head d942a475a5b2454d67b9305323046cae0271d323, rebased onto origin/main 2e1e632603f4a7acf996a6fa3fd9c7d09404ca86. My earlier review approved 1c0ca7844; this head only resolves the rebase conflict and re-runs the evidence on the new base, so the approved behaviour is unchanged and independently re-verified.
Rebase repair. tests/control_plane_ts/quota_monitor_poll_commit.test.ts conflicted where main had re-pointed the file's interpreter import (resolveTestPython) and this branch added its monitorPollRequestHash import. The resolution keeps both imports and keeps main's single shared interpreter selector, so the file now passes the checkout guard that main added (test_python_runtime.test.ts reports 5 passed on this head).
动机
canonical Monitor 在业务提交前拒绝一次观测(例如硬租约观测缺少证明)时,quota 仍为该 Turn 保留 provider_pending 预留;之后补上正确证明会改变请求摘要,于是同一 Turn 的重试被判定为效应身份冲突,尽管根本没有写入任何观测。这个修复让「确证未产生业务效果」的拒绝能够释放那一份预留,使纠正后的同 Turn 重试可行。
改动思路
保持 TypeScript 的双重权威边界:coordination 规划器只在提交前拒绝时出具绑定原始请求哈希与 operation ID 的 no_effect 负证明;quota 事务 owner 持锁核对原 pending、来源、operation ID、由落盘 plan 重算的请求哈希、索引历史完整性以及没有同 effect 的 run 之后,才删除那一份预留。Python 只转运 typed 结果,不自行判断业务效果——既不放宽请求摘要,也不「见错即删 pending」,因此超时和不确定提交的恢复栅栏保持原样。
具体改动
关键代码讲解
todo_monitor_poll.ts:39,196:把原先内联的请求身份提取为共享的monitorPollRequestHash,并只在planWriteback的 catch 分支(提交前拒绝)附带no_effect {goal_id, operation_id, request_sha256};权威来源变化、回执与提交失败都不携带该证明。monitor_poll_commit.ts:1924,2035,2047:新增provider_rejected阶段与aborted状态;execute:false一律拒绝;既有回执不是provider_pending时明确拒绝 abort;释放前必须通过validateNoEffect、索引历史完整且没有同 effect 的记录,随后只删除那一份 pending 回执并返回ok:false, appended:false。monitor_poll_commit.ts:1895:validateNoEffect从落盘 provider plan 的 observation/intent 与 lease proof 重算请求哈希,并核对回执 schema、状态、changed:false、reason code、canonical source、decision_read_from_provider与legacy_fallback_used,因此伪造或错配的证明无法释放预留。monitor_poll.py:826:provider writeback 抛LocalCoordinationAuthorityUnavailable时,若处于 execute 且 payload 确实带no_effect,就把 typed 结果作为provider_rejected阶段交给 quota owner,然后继续抛出原错误,让调用方修正证明后重试。quota_monitor_poll_commit.test.ts:971与test_leased_monitor_poll.py:前者用真实 pending 事务覆盖 null/缺失/哈希错配/legacy 来源/timeout 五种未证明情形(每次断言 pending 字节不变)与精确证明的 aborted 及后续冲突;后者在提升后的 File/SQLite 上用真实 CLI 断言拒绝后无 pending 文件、canonical 状态不变、补齐证明后一次提交、幂等重放、索引只有一条观测且无 slot spend。
对主干的风险
最危险的反例是「业务其实已提交,却删除 pending」。当前有三处独立约束挡住它:证明只在提交前拒绝这个唯一边界产生;validateNoEffect 要求哈希/来源/状态完全匹配;释放前还要求索引历史完整且没有同 effect 的记录,并且 prepared/committed 直接拒绝 abort。证据:quota commit 用例 20/20(含伪造矩阵与 pending 字节保持)、File/SQLite 真实 CLI 用例 11/11、control-plane 全量 3057 项(3028 通过、0 失败、29 跳过;第一次跑的 2 个失败是 NoKV conformance 的 90 秒子进程超时,隔离复跑 8/8、6.7 秒通过)、typecheck:control-plane、导入冲突修复后的解释器 guard、git diff --check 与 goal 作用域 premerge(18 项检查、0 失败、0 人工挂起)均通过,质量回执 cqr_f011f3d9fe9e7eb2cb11 有效。未验证项据实记录:本 goal 不等待远端 CI,而上一 head 的红灯在干净 merge base 上同样复现(canonical snapshot 请求预算、runtime-shadow e2e、仓库级 mypy、lark 模块度量 ratchet);由于 quota 事务存储是文件式的、本改动不触碰 authority store,未跑 PostgreSQL 往返。边界未扩大:quota should-run 的租约感知投影仍是独立后续,本 PR 也不追认历史上的不确定 pending。
我的整体评价
这是一个范围克制、归属正确的修复:负证明由唯一能证明它的边界产生,释放决定留在持有预留的 quota owner,Python 不新增决策源;同时保留了超时/不确定提交的栅栏,并用反例矩阵把「只释放确证未产生效果的预留」钉住。相对旧 head,本 head 只多了 main 上的导入冲突解决,且解决方式与 main 新引入的单一解释器选择器一致;证据在 rebase 后全部重跑通过。可交维护者合并。
English verdict: APPROVE - exact head d942a475a5b2454d67b9305323046cae0271d323; the rebase conflict is resolved without reintroducing a bare test interpreter, the release is limited to a canonical pre-commit no-effect proof with forged/mismatched/timeout evidence rejected, and the full control-plane suite plus the File/SQLite CLI retry path and goal-scoped premerge are green.
d942a47 to
0b1a817
Compare
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval). Approved exact head 0b1a8175a4e41b83ffb6d5483a166cadd9761541, rebased onto origin/main fb773152aa3e8d5702463856a1d13273459504a7. My earlier review approved 1c0ca7844; this head only resolves the rebase conflict and re-runs the evidence on the newer base (main advanced again with the PR-review evidence-depth work, which touches none of these files), so the approved behaviour is unchanged and independently re-verified.
Rebase repair. tests/control_plane_ts/quota_monitor_poll_commit.test.ts conflicted where main had re-pointed the file's interpreter import (resolveTestPython) and this branch added its monitorPollRequestHash import. The resolution keeps both imports and keeps main's single shared interpreter selector, so the file now passes the checkout guard that main added (test_python_runtime.test.ts reports 5 passed on this head).
动机
canonical Monitor 在业务提交前拒绝一次观测(例如硬租约观测缺少证明)时,quota 仍为该 Turn 保留 provider_pending 预留;之后补上正确证明会改变请求摘要,于是同一 Turn 的重试被判定为效应身份冲突,尽管根本没有写入任何观测。这个修复让「确证未产生业务效果」的拒绝能够释放那一份预留,使纠正后的同 Turn 重试可行。
改动思路
保持 TypeScript 的双重权威边界:coordination 规划器只在提交前拒绝时出具绑定原始请求哈希与 operation ID 的 no_effect 负证明;quota 事务 owner 持锁核对原 pending、来源、operation ID、由落盘 plan 重算的请求哈希、索引历史完整性以及没有同 effect 的 run 之后,才删除那一份预留。Python 只转运 typed 结果,不自行判断业务效果——既不放宽请求摘要,也不「见错即删 pending」,因此超时和不确定提交的恢复栅栏保持原样。
具体改动
关键代码讲解
todo_monitor_poll.ts:39,196:把原先内联的请求身份提取为共享的monitorPollRequestHash,并只在planWriteback的 catch 分支(提交前拒绝)附带no_effect {goal_id, operation_id, request_sha256};权威来源变化、回执与提交失败都不携带该证明。monitor_poll_commit.ts:1924,2035,2047:新增provider_rejected阶段与aborted状态;execute:false一律拒绝;既有回执不是provider_pending时明确拒绝 abort;释放前必须通过validateNoEffect、索引历史完整且没有同 effect 的记录,随后只删除那一份 pending 回执并返回ok:false, appended:false。monitor_poll_commit.ts:1895:validateNoEffect从落盘 provider plan 的 observation/intent 与 lease proof 重算请求哈希,并核对回执 schema、状态、changed:false、reason code、canonical source、decision_read_from_provider与legacy_fallback_used,因此伪造或错配的证明无法释放预留。monitor_poll.py:826:provider writeback 抛LocalCoordinationAuthorityUnavailable时,若处于 execute 且 payload 确实带no_effect,就把 typed 结果作为provider_rejected阶段交给 quota owner,然后继续抛出原错误,让调用方修正证明后重试。quota_monitor_poll_commit.test.ts:971与test_leased_monitor_poll.py:前者用真实 pending 事务覆盖 null/缺失/哈希错配/legacy 来源/timeout 五种未证明情形(每次断言 pending 字节不变)与精确证明的 aborted 及后续冲突;后者在提升后的 File/SQLite 上用真实 CLI 断言拒绝后无 pending 文件、canonical 状态不变、补齐证明后一次提交、幂等重放、索引只有一条观测且无 slot spend。
对主干的风险
最危险的反例是「业务其实已提交,却删除 pending」。当前有三处独立约束挡住它:证明只在提交前拒绝这个唯一边界产生;validateNoEffect 要求哈希/来源/状态完全匹配;释放前还要求索引历史完整且没有同 effect 的记录,并且 prepared/committed 直接拒绝 abort。证据:quota commit 用例 20/20(含伪造矩阵与 pending 字节保持)、File/SQLite 真实 CLI 用例 11/11、control-plane 全量 3057 项(3028 通过、0 失败、29 跳过;跑在内容逐字节相同的前一个 base 上,其中第一次的 2 个失败是 NoKV conformance 的 90 秒子进程超时,隔离复跑 8/8、6.7 秒通过);本 head 上重跑了 quota commit 20/20、File/SQLite CLI 11/11 与解释器 guard 5/5、typecheck:control-plane、导入冲突修复后的解释器 guard、git diff --check 与 goal 作用域 premerge(18 项检查、0 失败、0 人工挂起)均通过,质量回执 cqr_c21ca592c66c44369812 有效。未验证项据实记录:本 goal 不等待远端 CI,而上一 head 的红灯在干净 merge base 上同样复现(canonical snapshot 请求预算、runtime-shadow e2e、仓库级 mypy、lark 模块度量 ratchet);由于 quota 事务存储是文件式的、本改动不触碰 authority store,未跑 PostgreSQL 往返。边界未扩大:quota should-run 的租约感知投影仍是独立后续,本 PR 也不追认历史上的不确定 pending。
我的整体评价
这是一个范围克制、归属正确的修复:负证明由唯一能证明它的边界产生,释放决定留在持有预留的 quota owner,Python 不新增决策源;同时保留了超时/不确定提交的栅栏,并用反例矩阵把「只释放确证未产生效果的预留」钉住。相对旧 head,本 head 只多了 main 上的导入冲突解决,且解决方式与 main 新引入的单一解释器选择器一致;证据在 rebase 后全部重跑通过。可交维护者合并。
English verdict: APPROVE - exact head 0b1a8175a4e41b83ffb6d5483a166cadd9761541; the rebase conflict is resolved without reintroducing a bare test interpreter, the release is limited to a canonical pre-commit no-effect proof with forged/mismatched/timeout evidence rejected, and the full control-plane suite plus the File/SQLite CLI retry path and goal-scoped premerge are green.
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
0b1a817 to
b150841
Compare
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval). Approved exact head b150841d0f3c72c5a16132e740a6dde16c1a544e, rebased onto origin/main 3414fc7f4c14ff3a2a1c1b7ea5aab3a7dbe1ec5f. My earlier review approved 1c0ca7844; this head only resolves the rebase conflict and re-runs the evidence on the newer base (main advanced again with the PR-review evidence-depth work, which touches none of these files), so the approved behaviour is unchanged and independently re-verified.
Rebase repair. tests/control_plane_ts/quota_monitor_poll_commit.test.ts conflicted where main had re-pointed the file's interpreter import (resolveTestPython) and this branch added its monitorPollRequestHash import. The resolution keeps both imports and keeps main's single shared interpreter selector, so the file now passes the checkout guard that main added (test_python_runtime.test.ts reports 5 passed on this head).
动机
canonical Monitor 在业务提交前拒绝一次观测(例如硬租约观测缺少证明)时,quota 仍为该 Turn 保留 provider_pending 预留;之后补上正确证明会改变请求摘要,于是同一 Turn 的重试被判定为效应身份冲突,尽管根本没有写入任何观测。这个修复让「确证未产生业务效果」的拒绝能够释放那一份预留,使纠正后的同 Turn 重试可行。
改动思路
保持 TypeScript 的双重权威边界:coordination 规划器只在提交前拒绝时出具绑定原始请求哈希与 operation ID 的 no_effect 负证明;quota 事务 owner 持锁核对原 pending、来源、operation ID、由落盘 plan 重算的请求哈希、索引历史完整性以及没有同 effect 的 run 之后,才删除那一份预留。Python 只转运 typed 结果,不自行判断业务效果——既不放宽请求摘要,也不「见错即删 pending」,因此超时和不确定提交的恢复栅栏保持原样。
具体改动
关键代码讲解
todo_monitor_poll.ts:39,196:把原先内联的请求身份提取为共享的monitorPollRequestHash,并只在planWriteback的 catch 分支(提交前拒绝)附带no_effect {goal_id, operation_id, request_sha256};权威来源变化、回执与提交失败都不携带该证明。monitor_poll_commit.ts:1924,2035,2047:新增provider_rejected阶段与aborted状态;execute:false一律拒绝;既有回执不是provider_pending时明确拒绝 abort;释放前必须通过validateNoEffect、索引历史完整且没有同 effect 的记录,随后只删除那一份 pending 回执并返回ok:false, appended:false。monitor_poll_commit.ts:1895:validateNoEffect从落盘 provider plan 的 observation/intent 与 lease proof 重算请求哈希,并核对回执 schema、状态、changed:false、reason code、canonical source、decision_read_from_provider与legacy_fallback_used,因此伪造或错配的证明无法释放预留。monitor_poll.py:826:provider writeback 抛LocalCoordinationAuthorityUnavailable时,若处于 execute 且 payload 确实带no_effect,就把 typed 结果作为provider_rejected阶段交给 quota owner,然后继续抛出原错误,让调用方修正证明后重试。quota_monitor_poll_commit.test.ts:971与test_leased_monitor_poll.py:前者用真实 pending 事务覆盖 null/缺失/哈希错配/legacy 来源/timeout 五种未证明情形(每次断言 pending 字节不变)与精确证明的 aborted 及后续冲突;后者在提升后的 File/SQLite 上用真实 CLI 断言拒绝后无 pending 文件、canonical 状态不变、补齐证明后一次提交、幂等重放、索引只有一条观测且无 slot spend。
对主干的风险
最危险的反例是「业务其实已提交,却删除 pending」。当前有三处独立约束挡住它:证明只在提交前拒绝这个唯一边界产生;validateNoEffect 要求哈希/来源/状态完全匹配;释放前还要求索引历史完整且没有同 effect 的记录,并且 prepared/committed 直接拒绝 abort。证据:quota commit 用例 20/20(含伪造矩阵与 pending 字节保持)、File/SQLite 真实 CLI 用例 11/11、control-plane 全量 3057 项(3028 通过、0 失败、29 跳过;跑在内容逐字节相同的前一个 base 上,其中第一次的 2 个失败是 NoKV conformance 的 90 秒子进程超时,隔离复跑 8/8、6.7 秒通过);本 head 上重跑了 quota commit 20/20、File/SQLite CLI 11/11 与解释器 guard 5/5、typecheck:control-plane、导入冲突修复后的解释器 guard、git diff --check 与 goal 作用域 premerge(18 项检查、0 失败、0 人工挂起)均通过,质量回执 cqr_3b6e69d9030eb5cc5318 有效。未验证项据实记录:本 goal 不等待远端 CI,而上一 head 的红灯在干净 merge base 上同样复现(canonical snapshot 请求预算、runtime-shadow e2e、仓库级 mypy、lark 模块度量 ratchet);由于 quota 事务存储是文件式的、本改动不触碰 authority store,未跑 PostgreSQL 往返。边界未扩大:quota should-run 的租约感知投影仍是独立后续,本 PR 也不追认历史上的不确定 pending。
我的整体评价
这是一个范围克制、归属正确的修复:负证明由唯一能证明它的边界产生,释放决定留在持有预留的 quota owner,Python 不新增决策源;同时保留了超时/不确定提交的栅栏,并用反例矩阵把「只释放确证未产生效果的预留」钉住。相对旧 head,本 head 只多了 main 上的导入冲突解决,且解决方式与 main 新引入的单一解释器选择器一致;证据在 rebase 后全部重跑通过。可交维护者合并。
English verdict: APPROVE - exact head b150841d0f3c72c5a16132e740a6dde16c1a544e; the rebase conflict is resolved without reintroducing a bare test interpreter, the release is limited to a canonical pre-commit no-effect proof with forged/mismatched/timeout evidence rejected, and the full control-plane suite plus the File/SQLite CLI retry path and goal-scoped premerge are green.
|
Merged as Changed surfaces: the canonical Monitor poll planner ( Rebase repair: Checks run: quota Monitor poll commit tests 20 passed (including the forged/mismatched/legacy/timeout matrix that asserts the pending receipt bytes are unchanged); the File/SQLite CLI retry test 11 passed (no pending file after rejection, one observation and no slot spend after the corrected retry); the checkout interpreter guard 5 passed; the full control-plane suite 3057 tests (3028 passed, 0 failed, 29 skipped) on byte-identical content at the previous base; Skips and holds: remote CI lanes for this head were not awaited under this goal's review policy; the earlier head's lanes were red for failures reproduced on a clean merge base (canonical snapshot request budget, runtime-shadow e2e, repository mypy, the lark module metric ratchet). No PostgreSQL round trip was run because the quota transaction store is file-based and the authority store is untouched. No manual holds. Residual risk: |
Summary
When a canonical Monitor rejects an observation before its business commit (for example, a hard-lease observation without proof), quota currently retains a
provider_pendingreservation for that Turn. Adding the valid lease proof changes the request digest, so the same Turn then fails with an effect identity conflict even though no observation was recorded.This change lets the canonical TypeScript owner attest that planning rejected the exact request before any mutation. The quota TypeScript owner verifies the authority source, operation and request hash, checks that the pending index history is intact and no matching run was appended, then releases only that pending reservation. Timeout, uncertain provider outcomes and prepared/committed receipts keep their recovery fences. The Python layer transports the typed result and does not decide the mutation rule.
Validation
git diff --check: passed.User entry points and remaining work
The affected entry is
loopx quota monitor-poll(also used by managed Turns). Its result and error now allow a corrected same-Turn retry. The frontend and Lark do not implement this transaction; they consume the existing projection and need no separate state change for this fix. Theshould-runrecommended command still needs lease-aware projection; that is a separate follow-up because its source currently does not carry canonical lease facts. This PR does not alter the active Goal or retroactively clear ambiguous pending effects.No local Goal state, credentials or private project artifacts are included.