Repository navigation
fix(quota): require compute allowance for fresh replan admission - #8576
xiaobaifly7 wants to merge 1 commit into
Conversation
Signed-off-by: xiaobaifly7 <196511160+xiaobaifly7@users.noreply.github.com>
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent · gpt-6.1-sol · OpenAI · runtime_reported · reasoning_effort=max
评审提交 0024b2ae5266599727fccd2b6cc0117e5405fa75。结论 REQUEST_CHANGES。
P2 额度耗尽拦截已准入原 Turn 的重规划接续
另一 Agent 用掉最后一槽后,真实 quota CLI 返回原回执 replayed,同时把原 Turn 判为 throttled_skip,省略了结算计划。 同一身份的 turn plan 从 replan_required 变为 wait。 传入由现有回执 owner 校验的正向准入事实,限定原 Goal、Agent、Turn、义务和未结算阶段。只有等待记录的重读仍按新准入处理。
动机 / Motivation
Goal owner 需要控制新重规划的预算,并让已准入的原始 Turn 继续履行结算职责。 共享算力用完后,主干仍会因缺失 Vision checkpoint 选择新重规划。 候选阻止新重规划超出窗口。共享规则也挡住已准入的精确 Turn,原身份的 Turn plan 从可启动重规划变成 wait。 检查覆盖真实准入、已有回执的接续和启动判定,执行范围到 CLI 输出。
改动思路 / Approach
传入已正向准入的原身份,使耗尽规则只作用于新准入,已有接续和结算继续由原回执协调。 额度判断继续由共享 TypeScript reducer 持有,已准入的原身份由现有回执协调校验。 设计问题 #8571
具体改动 / Changes
5 文件,+200/-2。生产 +25/-1,文档 +16,测试 +159/-1。 新默认策略仍需 maintainer 决定。NEW-ADMISSION 的首次决策通过。ORIGINAL-RECEIPT 的同身份接续在下述情形失败。OWNER-STOP 仍走既有前置检查。主干基线 beff0f3e55d1f70eceebbd8e78c11f1cff34643b。docs/quota-allocation.md
applyGoalOverrides。用允许量和已用量判断耗尽,对本次匹配的重规划清空执行权限。 loopx/control_plane/quota/run_decision.ts_receipt_bound_guard_fields。从原始回执取出选中义务与 Turn 身份,可在这里保留正向准入事实。 loopx/control_plane/quota/live_decision.py_build_turn_decision。按原回执生成启动前的决策,当前结果让 host plan 进入 wait。 loopx/cli_commands/turn_decision.py
对主干的风险 / Risks
先以额度 1/0 提交原重规划 guard,再加入另一 Agent 的一条真实格式用量记录,额度变为 1/1。分别读取原 Turn 和新 Turn 的 guard,再用原身份调用 turn plan。 另一 Agent 用掉最后一槽后,真实 quota CLI 返回原回执 replayed,同时把原 Turn 判为 throttled_skip,省略了结算计划。
File、SQLite 在 1/1 时均阻止新重规划,重读被拒绝的新 Turn 仍需等待。额度提高到 2/1 后原身份可继续。普通等待和有额度的重规划对照正常。 TypeScript 40 项、控制面 typecheck、Ruff、quick premerge 6 项直接检查及 4 项选定检查通过。Python 默认运行 121 项通过,两个新增 CLI 用例在渐进式输出上直接读取顶层 should_run,触发 KeyError。以 LOOPX_CONTEXT_DELIVERY=off 重跑这两项均通过。建议用例显式指定原始输出,或沿默认上下文引用读取;实际回执复现使用显式原始输出。
合成数据通过真实 CLI 和 TypeScript Effect runtime,分别用 File 与 SQLite Todo authority 验证。安装后的宿主和远端 CI 尚未复验。
我的整体评价 / Verdict
传入由现有回执 owner 校验的正向准入事实,限定原 Goal、Agent、Turn、义务和未结算阶段。只有等待记录的重读仍按新准入处理。 用同一夹具验证原身份、新 Turn 和重复读取的结果。额度恢复后复验新准入,并保持真实原回执的结算可达。
English verdict: REQUEST_CHANGES for 0024b2ae5266599727fccd2b6cc0117e5405fa75. An exhausted window correctly blocks fresh replans and incorrectly suppresses the still-owed continuation of an already admitted exact replan.
| && facts.goal_health_ok && !facts.workspace_guard && !facts.automation_prompt_upgrade_required; | ||
| const quotaExhausted = facts.state === "throttled" || (facts.quota_allowed_slots !== null | ||
| && facts.quota_spent_slots !== null && facts.quota_spent_slots >= facts.quota_allowed_slots); | ||
| decision.replan_decision_allowed = replanSelected && !quotaExhausted; |
There was a problem hiding this comment.
[P2] 额度耗尽拦截已准入原 Turn 的重规划接续
另一 Agent 用掉最后一槽后,真实 quota CLI 返回原回执 replayed,同时把原 Turn 判为 throttled_skip,省略了结算计划。 同一身份的 turn plan 从 replan_required 变为 wait。 传入由现有回执 owner 校验的正向准入事实,限定原 Goal、Agent、Turn、义务和未结算阶段。只有等待记录的重读仍按新准入处理。
Goal And Delivered Outcome
mainbeff0f3e55d1f70eceebbd8e78c11f1cff34643b; the issue had no maintainer policy ruling.should_run=true/run_now.throttled_skipaction with an explicit reason when the window is exhausted. It resumes when allowance returns. The new production-entrypoint tests fail before the change (5 failures, 1 pass in the initial six-case characterization) and pass afterward.main.Author Declaration
Implemented against
docs/quota-allocation.mdat the base revision above, and this PR's explicit conservative policy proposal.quota/run_decision.ts::applyGoalOverridestest_replan_quota_exhaustion.pyEffectiveAction.THROTTLED_SKIPand should-run reasonPOLICY CHOICES
throttledstate fallback.throttled_skipand the existing reason projection rather than adding a new action vocabulary or UI/configuration.Scope And Continuation
Validation
0024b2ae5266599727fccd2b6cc0117e5405fa75.node --no-warnings --experimental-strip-types --test tests/control_plane_ts/quota_run_decision.test.ts: 40 passed, including exhausted/masked windows, malformed counts and exact integer boundaries.python -m pytest -q tests/control_plane/test_replan_quota_exhaustion.py tests/control_plane/test_quota_run_decision.py tests/control_plane/test_effect_turn_live_quota_decision.py tests/control_plane/test_dated_vision_wait_cli.py --tb=short: 123 selected instances passed across the scoped runs. Includes real local Effect runtime, CLI dispatcher with synthetic status IO, exact original Turn recovery and 4 File/SQLite blocked-replan no-debit closeouts.decision_summary.py:78no-any-return; exact-base shadow-file comparison produces the same error. No unrelated typing repair included.PYTHONUTF8=1 loopx canary premerge --from-git-diff --git-diff-base origin/main --tier quick: fixed-head gate passed, 6 direct checks + 4 executed checks, zero failures and manual holds. Validation used only a synthetic registry and disposable local runtime.PYTHONUTF8=1resolves it; the two affected pytest instances passed on focused rerun. A quick run made concurrent with staging detected the new test's index transition as a tracked side effect, while its smoke returned success; final fixed-head quick validation is recorded above. No full Python suite, full TS suite, live model, installed host or sustained automatic-loop qualification was run.Frontend / Visual Evidence
Type of Change
LoopX Area
Technical Direction
Shared-authority RFC fixture impact
N/A: no authority-provider routing, promotion, compatibility projection or RFC implementation claim. Existing real local File/SQLite settlement regressions remain covered.
Boundary Checklist
none.Signed-off-bytrailer (git commit -s).