Skip to content

fix(refresh): admit checkpoint-only validator recovery - #4841

Merged
huangruiteng merged 1 commit into
mainfrom
codex/checkpoint-supplement-recovery
Sep 21, 2026
Merged

huangruiteng merged 1 commit into
mainfrom
codex/checkpoint-supplement-recovery

Conversation

@huangruiteng

Copy link
Copy Markdown
Collaborator

Goal

Fix #4840 so an already-admitted checkpoint-only retry can repair a missing vision decision even when the bound open Todo declares controller completion validation.

Change

  • derive checkpoint_supplement immediately from the exact settlement recovery decision;
  • skip the terminal completion-validation fence only for that admitted recovery mode;
  • preserve the original delivery workspace, outcome, progress observation and classification;
  • retain rejection for replayed mutations, mismatched settlement identity and conflicting vision decisions.

Validation

  • python -m pytest -q tests/control_plane/test_refresh_checkpoint_recovery.py tests/control_plane/test_replan_completion_validation.py tests/control_plane/test_completion_validation_lane_scope.py tests/control_plane/test_canonical_planning_consumers.py — 60 passed
  • python -m pytest -q tests/control_plane/test_refresh_checkpoint_recovery.py::test_checkpoint_only_recovery_bypasses_open_todo_completion_validation — 1 passed
  • python -m ruff check loopx/state_refresh.py tests/control_plane/test_refresh_checkpoint_recovery.py
  • python -m compileall -q loopx/state_refresh.py tests/control_plane/test_refresh_checkpoint_recovery.py
  • git diff --check origin/main...HEAD

Product entry points

This changes the existing refresh-state/managed-Turn settlement path only. No frontend or Lark companion change is needed: neither surface owns or edits the internal same-Turn recovery payload, and the existing shared receipt projection is preserved.

Control-plane change: proposed for maintainer review; not self-merged.

Closes #4840.

Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exact-head self-review: 2929e87f2fb90185e2e76cf598d6634718345ef0

动机

#4840 reproduces an impossible documented recovery: the semantic writeback commits without a required vision checkpoint, mutation replay is correctly rejected, but the checkpoint-only retry is also blocked by the open Todo's completion validator. This PR completes that scoped recovery without changing Todo completion semantics.

改动思路

Reuse read_heartbeat_settlement as the authority for exact Goal/Agent/Todo/Turn, delivery, mutation and vision-digest admission. Compute its existing supplement_checkpoint decision before the terminal completion-validation fence, skip only that fence, and keep the later checkpoint-satisfied check plus original delivery attribution.

具体改动

  • refresh_state_run: derives the admitted supplement decision immediately after settlement readback; all non-supplement accountable refreshes still call require_accountable_completion_validation.
  • End-to-end CLI regression: open validation-bearing Todo + committed semantic replan + missing checkpoint; exact mutation-free supplement succeeds, while mutation replay, wrong Todo binding and conflicting vision remain rejected with zero spend.

关键代码讲解

  • loopx/state_refresh.py:933: consumes the existing typed recovery decision; no new CLI flag or persisted state.
  • loopx/state_refresh.py:1129: documents and enforces the narrow validator bypass.
  • tests/control_plane/test_refresh_checkpoint_recovery.py:298: proves the positive and negative same-Turn paths through the real CLI fixture.

对主干的风险

The material risk is accidentally bypassing validation for a normal open Todo. The bypass cannot be caller-set directly and is reached only after settlement-reader identity/mutation admission; build_vision_checkpoint must still satisfy the missing decision. Local evidence: 60 related tests passed, the focused recovery suite passed, and Ruff/compileall/diff checks passed. Remote full CI is still running and remains a merge hold.

语义与 CI 对齐

This reuses refresh_recovery_v0/supplement_checkpoint; it does not create or broaden an authority vocabulary. Normal completion validation, workspace attribution, quota spend and receipts are unchanged.

我的整体评价

APPROVE (self-review conclusion, COMMENTED state). The mechanism is proportional and domain-neutral, with no frontend/Lark companion required because those surfaces do not own same-Turn recovery payloads. Residual holds: remote CI and independent maintainer review. This control-plane PR must not be self-merged.

@huangruiteng

Copy link
Copy Markdown
Collaborator Author

CI update for exact head 2929e87f2fb90185e2e76cf598d6634718345ef0:

  • node-minimum-compatibility timed out at its 10-minute job ceiling.
  • The contemporaneous main run failed the same job in the same way (35556674737 / 106201555929, 10m16s), while this PR changes only Python recovery code/tests.
  • This is a baseline CI-capacity failure, not evidence against the PR diff. Tracked as CI: node-minimum-compatibility now exceeds its 10-minute hard timeout #4842; the gate remains a merge hold until the required check is restored/rerun.

Other completed checks are currently green; independent maintainer review is still required.

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

Exact head reviewed: 2929e87f2fb90185e2e76cf598d6634718345ef0

动机

#4840 暴露的是一个真实的事务矛盾:首次语义 replan 写回可以合法提交并留下 missing_required Vision checkpoint;随后唯一正确的“只补 checkpoint”重试,却会先被仍为 open 的 Todo completion validator 拦截;如果重放首次 mutation,又会被 checkpoint_supplement_must_not_repeat_mutations 正确拒绝。结果是两种重试都不合法,Turn 无法完成已有契约明确允许的恢复。

这个 PR 在正确的边界解决了完整问题:允许的不是“绕过 Todo 验证的一般 refresh”,而只是 TypeScript settlement owner 已经判定为 supplement_checkpoint 的 exact Goal/Agent/Todo/Turn 恢复。没有新增 CLI 开关、持久化状态或第二套 recovery authority。

改动思路

权威链路保持为:refresh-statequota.settlement.read → TypeScript refreshRecovery → Python orchestration。refreshRecovery 仍负责比较原写回、settlement identity、delivery fields、mutation digest、vision digest 与 later vision;只有 exact retry、原 checkpoint 确实缺失、无 mutation replay、无 delivery 冲突且无 vision 冲突时,才返回 supplement_checkpoint

Python 现在在 require_accountable_completion_validation 之前读取这个既有 typed decision,只跳过这一个 terminal validation fence。随后仍必须通过 build_vision_checkpoint,并且 vision_checkpoint.satisfied 必须为 true;写回时继续恢复原 row 的 workspace、outcome、batch scale、progress observation 和 classification。因此 completion validation 仍归属于后来真正完成 Todo 的动作,不会被此次 checkpoint 修复“顺带满足”。

具体改动

  • loopx/state_refresh.py:把 checkpoint_supplement 的派生提前到 settlement readback 后;所有非 supplement_checkpoint 的 accountable outcome 仍执行原 completion-validation fence。
  • 同一函数保留原 checkpoint satisfaction guard,并在 supplement append 前复用原 delivery/accounting snapshot,避免把恢复调用者当前目录或参数重新归因给既有交付。
  • tests/control_plane/test_refresh_checkpoint_recovery.py:增加真实 CLI 回归,构造带 validation_command 的 open Todo,先提交 semantic replan,再验证 mutation-free Vision supplement 成功;同时覆盖 mutation replay、错误 Todo binding、冲突 Vision 和 zero-spend 负例。

关键代码讲解

  1. refresh_state_run 的 settlement readback(约 line 933)直接消费 TypeScript refresh_recovery_v0reject/replay 等分支仍会在 refresh_recovery_payload 返回,不会落入新例外。
  2. completion-validation fence(约 line 1135)新增的条件是 exact typed token,而不是文本启发式、CLI flag 或调用者声明;普通 append/replay/workspace supplement 的行为不变。
  3. checkpoint satisfaction guard(约 line 1162)确保所谓 supplement 真的产生有效 Vision decision;没有 existing Vision 时,仅给 unchanged reason 仍会失败。
  4. 新回归(test line 298)跨过实际 Python CLI、TypeScript effect runtime、runtime receipt files 与 git fixture,不是 mock-only 证明。

对主干的风险

最强风险是把这个例外错误扩大成“open Todo 可以跳过 completion validation”。当前实现没有这个问题:开关来源是 TypeScript refreshRecovery 的 exact state transition;它在 Python fence 之前已经拒绝 binding/delivery/mutation/vision 冲突。相关 60 个 control-plane tests 全部通过,包含普通 completion-validation 路径与新增正负例;Ruff、compileall、git diff --check 也通过。

语义与 CI 对齐

本 PR 复用 refresh_recovery_v0/supplement_checkpointvision_checkpoint_v0,没有创建新 vocabulary,也没有把 machine obligation 写成 guidance。功能语义已经被 focused tests 验证;但 exact head 当前仍为 BEHINDnode-minimum-compatibility 被取消且 merge-gate 失败。因此这份 approval 只表示 diff/语义审阅通过,不表示 merge-ready;应在 rebase/required checks 恢复后重新运行 merge-readiness gate。

我的整体评价

这个修复规模与风险相称:生产改动仅 +14/-4,复用正确的 typed owner,把例外限制在已有 admission decision 上,并用真实 CLI regression 补上此前 tests 未覆盖的“open validated Todo”组合。我没有发现新的 actionable blocker;未来向重构也无需再抽象一层,因为 recovery rule 已集中在 TypeScript,Python 这里只保留必要的 orchestration adaptation。

English verdict: APPROVE for exact head 2929e87f2fb90185e2e76cf598d6634718345ef0. No actionable code finding remains. This is not merge-ready until the branch is updated and required checks, including node-minimum-compatibility/merge-gate, are green and the exact-head readiness gate is rerun.

@huangruiteng
huangruiteng merged commit 1c67753 into main Sep 21, 2026
23 of 25 checks passed
@huangruiteng
huangruiteng deleted the codex/checkpoint-supplement-recovery branch September 21, 2026 05:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(refresh): admit checkpoint-only recovery for open validated Todo

1 participant