Repository navigation
fix(quota): fail closed when the Goal's active state is missing - #6802
Conversation
`loopx status` reports a per-goal `state_file_missing` finding with the reconnect/retire repair, but `loopx quota should-run --goal-id` still returned should_run=true with normal delivery allowed and a required read of the missing ACTIVE_GOAL_STATE.md. `goal_status_health_ok` only consulted the status contract diagnostics and `global_registry.ok`, so an automatic host turn kept being authorized for a Goal that has no state to advance. Treat the per-goal `state_file_missing` finding as a status health failure. Source-registry provenance findings are deliberately shadowed by the status projection and stay non-blocking. Before/after on a native Windows source checkout at a54c030: a Goal whose state file was deleted returned status_health_ok=true, decision=run, should_run=true, normal_delivery_allowed=true; the same command now returns status_health_ok=false, decision=skip, should_run=false, and a healthy Goal still returns run. The two new regressions fail without the fix and pass with it. Signed-off-by: JasonBuildAI <jasonbuildai@gmail.com>
The first commit fails the automatic turn closed, but the skip packet still carried the live lane's generic "run the first read-only adapter tick" action and reason. A host that displays the packet's guidance would still be pointed at work it cannot do. Reuse the status finding's reconnect/retire recommended_action for the packet's reason, recommended_action, state, status and source when the gate blocks for a missing active state file. The end-to-end regression now asserts the repair guidance, the blocked_health state, the state_file_missing status, the global_registry source and must_attempt=false; it fails with only the first commit and passes here. Signed-off-by: JasonBuildAI <jasonbuildai@gmail.com>
The previous commit rewrote the top-level state, status, reason and recommended action of any skip packet that coexisted with a state_file_missing finding. That relabeled operator-gate and terminal-closure skips as blocked_health, which can hide a legitimate user prompt or block terminal completion of a canonically closed Goal. Restrict the rewrite to the eligible quota skip that the health gate itself blocked: status health false, effective_action=quota_skip, state=eligible and no safe bypass. Other skip routes keep their own state, effective action and interaction/user channel. Add helper-level regressions for operator-gate, terminal-closure, monitor-quiet, safe-bypass and should-run packets, and keep the target health skip assertions. Signed-off-by: JasonBuildAI <jasonbuildai@gmail.com>
The cross-state regression used status_health_ok=true for the operator-gate packet, so it did not mirror the real coexistence shape: an operator gate plus a missing-state finding makes status health false. Use the real false variant; the effective_action check still keeps the gate state and user channel unchanged. Signed-off-by: JasonBuildAI <jasonbuildai@gmail.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
Exact head: 97e9f2caf5194af603fe2e0d9a46b9c70603b479
动机
项目仍登记在本机、但 Goal 的状态文件已经缺失时,自动调度调用者需要知道该 Goal 暂时不能交付,以及应修复哪个入口。
在同一个双 Goal 环境中删除其中一个状态文件,旧 status 已报告 state_file_missing,quota should-run 仍允许运行;本修改使该 Goal 返回 blocked_health,并保留另一个健康 Goal 的运行路径。
源码与普通安装包的真实 CLI 都会在目标 Goal 有精确缺状态 finding 时拒绝正常交付,并给出该 finding 原有的修复建议;其他健康 Goal 继续,原文件按原字节恢复后目标 Goal 也恢复运行。
范围是消费 status 已产生的、精确匹配 Goal 的 state_file_missing finding;不声称缺失/畸形诊断容器、state_file_not_declared、stale global entry、主机唤醒前拦截或用户通知策略都已修复。
改动思路
复用 status 现有 finding 作为事实,在现有 health 投影和 should-run 的拒绝提示边界补齐消费即可;没有新增持久 health 状态、通用 Python 调度决策源或要求所有 Goal 重配。
当前 PR 交付精确 Goal 缺状态诊断到 quota health/修复建议的可用闭环;生产者未报告 finding 的其他健康诊断与主机通知属于既有 status 和 host owner 的独立边界。
先从 status 的现有 global_registry_health.findings 中按 kind 和 goal_id 精确找事实,传入已有 health 决策。只有普通 eligible quota_skip 且无 safe bypass 时补上缺状态的拒绝原因;终态、operator、monitor quiet 等分支不被这层投影接管。没有新增存储或用户设置。
具体改动
完整 a54c030ee79ea9270fed4ca94f9592f32a19232a → 97e9f2caf5194af603fe2e0d9a46b9c70603b479 差异:2 existing quota Python production files (82 added lines) and 1 focused existing test module (216 added lines); three paths total,+298/-0。
- goal_missing_state_blocker:new exact lookup of existing diagnostic;输入 status global_registry_health findings,关键条件 only exact state_file_missing + exact goal_id。结果由 goal_status_health_ok and guidance 消费,失败仍由 missing/malformed containers return None; not a new generic fail-closed promise 处理。
- goal_status_health_ok:matching missing state now returns false;输入 current status plus current goal,关键条件 unrelated Goal/source provenance remains separate。结果由 typed quota decision input 消费,失败仍由 existing other health logic retained 处理。
- _apply_missing_state_health_guidance:missing state reason/action replace generic quota text;输入 not running, unhealthy, eligible quota_skip, no safe bypass,关键条件 terminal/operator/monitor-quiet/bypass routes retain their owner。结果由 CLI interaction contract and operator 消费,失败仍由 repair source/reconnect then rerun 处理。
- build_quota_should_run:applies bounded guidance after normal payload decision;输入 status capture and goal_id,关键条件 does not create a second store or bypass existing decision。结果由 native quota should-run 消费,失败仍由 existing health repair 处理。
规范来源 #6799,spec_revision=2026-10-18T08:24:16Z。state_file_missing:status 的目标 Goal 缺状态 finding 应使自动 quota 不再正常交付。(implemented,goal_missing_state_blocker / goal_status_health_ok;paired source/global native CLI + installed wheel);goal_scope:其他 Goal 与来源注册表诊断不能误挡当前健康 Goal。(implemented,exact kind + goal_id matching;health-beta and new health-gamma public CLI);repair_guidance:拒绝时复用真实 finding 的 reason/recommended_action。(implemented,_apply_missing_state_health_guidance;independent status finding vs quota output readback)。基线规范在完整 diff 前读取;本 PR 对文档的修改也作为被审内容,并未当作独立授权。
测试继续放在原 quota health 模块,覆盖精确 kind/Goal、其他来源 finding、正常运行及终态/operator/bypass/quiet 分支。后几类是源码 builder 的路由保留检查,不是新增的真实主机 operator-gate 实验。健康事实生产者与既有 TypeScript admission owner 保留,没有按文案前缀分类。
对主干的风险
Common synthetic two-Goal fixture through bootstrap/status/quota should-run: baseline missing-file refusals/guidance fail the independent oracle; exact source head and noneditable wheel each pass 7 cases. Additional new-Goal-after-finding, reordered global registry and byte-identical restoration counterfactuals pass.
70 focused Python tests passed (49.10s), including health matching, decision summary/capture and live decisions. 6 direct + 16 selected checks passed; zero failing commands/manual holds. Managed qualification is held only by stale_receipt.
真实 CLI 对照包含原始健康、source/global 缺状态、健康 sibling、新建健康 Goal、global 顺序变化和按原字节恢复。缺状态 guard 退出 1 是预期拒绝,不是执行器故障;修复动作与独立 status finding 对比,未硬编码某个 retire 命令。返回仍为 DONT_NOTIFY,本 PR 未改变 host 通知或消除模型唤醒。
正常 dashboard Chat build 与普通非 editable wheel 构建通过,改变的生产文件与 wheel 逐字节一致,隔离安装后重跑实际入口。初次从仓库根误调用不存在的 npm build:chat 脚本,改到真实 dashboard 目录后才完成构建;没有把该调用错误归因于产品。补充探针中的回执路径/旧 Turn 前置条件也按真实契约修正,原失败保留,未移除独立 oracle。
No remote CI consulted or Windows execution. Author historical cp936/mypy failures remain unverified historical claims; current Mac selected checks pass without claiming the old cause was repaired. Stale exact-scope quality receipt remains a separate merge hold. Notification/host wake suppression, malformed/missing diagnostic containers and other status findings are not qualified.
本轮没有查询、轮询、等待或触发 CI。最新 main 与相关工作核对后,没有发现生产 owner 已完成的同义修复;共享文档的其他行或无关 successor passthrough 不构成本 PR 的重复。
我的整体评价
复用 status 现有 finding 作为事实,在现有 health 投影和 should-run 的拒绝提示边界补齐消费即可;没有新增持久 health 状态、通用 Python 调度决策源或要求所有 Goal 重配。
当前 PR 交付精确 Goal 缺状态诊断到 quota health/修复建议的可用闭环;生产者未报告 finding 的其他健康诊断与主机通知属于既有 status 和 host owner 的独立边界。
有界目标判定 goal_achieved:交付了可读回的拒绝和继续路径,不以文件数、测试数或回执存在代替结果。long_horizon=improved,重放/恢复/独立新 subject 的实际验证支持后续继续;user_experience=improved,沿既有 CLI 读回真实状态和恢复建议,无新增配置、复制信息或确认步骤。
有界未来重构检查:共享精确 finding helper 已足够,维持事实生产、health 输入和提示投影的现有分工;为此进行完整语言迁移或扩大诊断分类没有必要。代码层面 APPROVE 仅对本 exact head;托管质量凭据、原生 merge readiness 与维护者显式合并授权仍是独立条件。
English verdict: APPROVE at 97e9f2caf5194af603fe2e0d9a46b9c70603b479. Common synthetic two-Goal fixture through bootstrap/status/quota should-run: baseline missing-file refusals/guidance fail the independent oracle; exact source head and noneditable wheel each pass 7 cases. Additional new-Goal-after-finding, reordered global registry and byte-identical restoration counterfactuals pass. 70 focused Python tests passed (49.10s), including health matching, decision summary/capture and live decisions. 6 direct + 16 selected checks passed; zero failing commands/manual holds. Managed qualification is held only by stale_receipt. No remote CI consulted or Windows execution. Author historical cp936/mypy failures remain unverified historical claims; current Mac selected checks pass without claiming the old cause was repaired. Stale exact-scope quality receipt remains a separate merge hold. Notification/host wake suppression, malformed/missing diagnostic containers and other status findings are not qualified.
Goal And Delivered Outcome
A Goal whose declared active state file is gone no longer receives a normal delivery authorization, and its skip packet now points at the documented repair instead of the work it cannot do. Before this change
loopx quota should-run --goal-idreturnedstatus_health_ok=true,decision=run,should_run=true,normal_delivery_allowed=trueand a required read of the missingACTIVE_GOAL_STATE.md, even though the same status payload reported the per-goalstate_file_missingfinding with a reconnect/retire repair. Host automations that follow the gate therefore spent a turn every cadence on a Goal with no state to advance; at the documented initial 30-minute App cadence (app_automation_initial_rruleindocs/quota-allocation.md) that is up to 48 authorized turns per day for one stale entry. After the change the same command returnsstatus_health_ok=false,decision=skip,should_run=false,state=blocked_health, andreason/recommended_actioncarry the finding'sretire-global-goalpreview, while a healthy Goal still returnsrun.docs/status-data-contract.md.loopx/control_plane/quota/decision_summary.py::goal_status_health_okguarded automatic compute on contract diagnostics andglobal_registry.ok, but never on the per-goalstate_file_missingfinding, so the quota gate kept authorizing a normal delivery turn with a required read that cannot succeed. The skip packet also carried the live lane's generic "run the first adapter tick" action instead of the status finding's repair action.real_entrypointandregression_parityrows below.Fixes #6799; basemainata54c030ee79ea9270fed4ca94f9592f32a19232a.Author Declaration
Implemented against
docs/status-data-contract.mdata54c030ee79ea9270fed4ca94f9592f32a19232a(state_file_missing: "the goal's declared active state file no longer exists"; action findings are lifted into the attention queue with their recommended action) and the request in [Bug]: quota gate authorizes automatic turns for a Goal whose declared active state file is missing #6799.state_file_missingaction finding must prevent normal delivery authorizationgoal_status_health_oktests/control_plane/test_contract_health.py::test_quota_does_not_authorize_a_goal_whose_declared_state_is_missinggoal_missing_state_blockertests/control_plane/test_contract_health.py::test_missing_active_state_finding_blocks_only_its_goal_apply_missing_state_health_guidancestate=blocked_health,status=state_file_missing,source=global_registry, theretire-global-goalreason/action andmust_attempt=false_GOAL_MISSING_STATE_FINDINGstale_source_registryfinding for another Goal non-blocking_apply_missing_state_health_guidancetests/control_plane/test_contract_health.py::test_missing_state_guidance_keeps_other_skip_routes_unchangedScope And Continuation
state_file_missingglobal-registry finding as a status-health failure, and the eligible health skip packet'sstate,status,source,reasonandrecommended_actionfollow the finding's repair action. Other skip routes (operator_gate_notify,terminal_no_followup,monitor_quiet_skip,automation_prompt_upgrade_required, safe bypass, real runs) keep their own state, effective action and user/agent channel. No schema or field additions. Deliberately untouched: the status projection still lists the live run lane beside the registry finding, andquota status/quota planstill count the Goal as eligible whilehealth_blockersreports the finding; those are separate read-only projections. Their hosts are expected to usequota should-runas the automatic-turn gate, but aligning the plan projection is a reasonable follow-up.control_plane_health_repairturn for this finding (instead of a skip) can be added later by projecting the finding into the item's health blockers; the default policy hascontrol_plane.self_repairdisabled, so today the skip is the fail-closed outcome.Validation
97e9f2caf5194af603fe2e0d9a46b9c70603b479(commits30cffa2degate,3b6a3d735guidance,18222bf40scope,97e9f2cafreal operator-gate test variant)staticpassedpython -m ruff check tests loopx/canary loopx/control_plane loopx/domain_packs loopx/presentation:All checks passed!.git diff --checkclean.scripts/generate_semantic_inventory.py --changed-from HEAD: no supported new vocabulary carriers.unitpassedpytest -q tests/control_plane/test_contract_health.py: 12 passed; focused quota suites plus quota markdown renderers: 156 passed.regression_paritypasseda54c030eethe end-to-end regression fails onstatus_health_ok(assert True is False); at the gate-only commit it fails on the guidance (assert 'eligible' == 'blocked_health'); at this head both pass. The cross-state regression asserts operator-gate, terminal-closure, monitor-quiet, safe-bypass and should-run packets are unchanged; the live target packet still carries the repair guidance. The helper scoping test fails at parent as well.real_entrypointpassedstatus_health_ok=true,decision=run,should_run=truebefore this diff; at this head it returnsfalse,skip,false,state=blocked_health,status=state_file_missing,source=global_registry, theretire-global-goalpreview inreason/recommended_action,must_attempt=false,primary_action="do not run delivery work for this goal in this turn"and no required reads. A healthy Goal remainstrue,run,true.integrationpassedwith one pre-existing host failureloopx canary premerge --from-git-diff --git-diff-base upstream/mainat the final head97e9f2caf: 16 selected checks, 15 passed; risk-profile smokes 8/8.examples/control_plane/quota-plan-smoke.pyfails on this cp936 host withUnicodeDecodeError: 'gbk' codec ...in the smoke's own subprocess reader andTypeError: ... not NoneType; the identical failure occurs with the parentdecision_summary.pyata54c030ee, and the smoke passes unchanged withPYTHONUTF8=1. Not caused by this diff.static(mypy)blocked(host)python -m mypyon native Windows reports 6 pre-existing POSIX-attribute errors inloopx/extensions/process_runtime.pyandloopx/control_plane/effect_runtime.py; none in the changed files. CI runs mypy on Linux.hosted(windows-powershell)not_runstate_file_not_declaredfinding, and malformedglobal_registry.findingsshapes (the guard fails open on missing/malformed containers). The status and quota-plan projections still list the Goal as eligible; the automatic-turn gate isquota should-runand is now fail-closed. The cp936 smoke-harness failure is pre-existing host behavior, not a changed path.Frontend / Visual Evidence
Type of Change
LoopX Area
Technical Direction
Shared-authority RFC fixture impact
Boundary Checklist
.loopx/,.codex/goals/, and liveACTIVE_GOAL_STATE.md).none.Signed-off-bytrailer (git commit -s).AI disclosure: this change was drafted with AI assistance at my request, under my direction and review.