Skip to content

fix(replan): unify typed checkpoints and preserve successor causality - #4655

Merged
huangruiteng merged 2 commits into
mainfrom
codex/replan-checkpoint-owner-20260917
Sep 17, 2026
Merged

huangruiteng merged 2 commits into
mainfrom
codex/replan-checkpoint-owner-20260917

Conversation

@huangruiteng

Copy link
Copy Markdown
Collaborator

Replaces #4645 with a single typed frontier checkpoint path.

A semantic replan writeback dropped the agent-owned frontier identity, so a peer claiming shared work could reopen an already acknowledged chain. A successor insertion also changed the frontier it was meant to acknowledge, making the subsequent writeback reject a valid successor.

todos/frontier_revision.ts now owns checkpoint construction, freshness and bounded predecessor reconstruction for observation, semantic writeback and successor ACKs. Python retains legacy codecs, successor eligibility and the existing obligation-id derivation. Terminal-inclusive planning preserves the material field manifest, and compact history retains successor lineage. The successor path reads both frontier identities in one bridge request instead of two.

Peer changes retain an accepted owned ACK; own material changes rearm. Legacy revision-only ACKs still match exact revisions. Incomplete sources, ambiguous successors, wrong origins, stale transitions and unrelated material edits fail closed. The 15/20 thresholds and write authority are unchanged.

Validation: independent regressions fail on main; current real CLI paths cover writeback and successor creation through durable history, peer claim and own-work rearm, including the real canonical File provider. Focused Python and native TS regressions, typecheck, mypy, Ruff and public-boundary scans pass. The bilingual TS RFC checkpoint records this bounded rule group without claiming the broader collaboration journey complete. No frontend or Lark configuration change is needed for this shared quota/writeback rule.

This PR is independent of the same-turn selection recovery in #4654 (fixing #4650). Runtime integration remains a maintainer merge.

Final gate: all 19 selected standard premerge checks pass, with zero failures or manual holds. Exact-scope receipt cqr_7c04202abbf47c3c4b93 qualifies this 15-file diff. Rebased frontier regressions pass 63 tests; the native suite passes 13.

Local performance: 32 interleaved baseline/head pairs in the same physical checkout measured complete-CLI p50 1320.68/1242.13 ms and p95 2264.96/1860.35 ms. The native successor rule measured 0.084 ms warm p95 across 896 samples. Separate-checkout timings varied with Python module I/O and remain diagnostic evidence. Remote CI was not polled.

Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
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.

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

Reviewed exact head: acf44344b823537a680bc815884a9531edd8f717 (docs(control-plane): reconcile frontier checkpoint ownership).

动机

两个都是真实缺陷,而且我用对照实验确认过它们与本次修复互相独立(详见验证):语义 replan 写回丢掉 agent-owned frontier 身份后,peer 认领共享工作会把已经 ACK 过的长链重新打开;而插入 successor 会改变它本来要确认的那个 frontier,导致随后写回拒掉一个合法的 successor。第二个尤其隐蔽——插入动作本身让「新鲜度」判定失效。

改动思路

把 checkpoint 的构造、新鲜度与有界的前驱重建交给已经拥有 revision 的 TypeScript 侧(todos/frontier_revision.ts),Python 只保留 legacy codec、successor 资格与 obligation-id 派生;把两条读合并成一次 bridge 调用。关键设计是把「绑定」变成类型化的两种:exact(同一 obligation 的 successor)与 predecessor(在阈值条件下、唯一且新鲜地重建出「去掉候选行之后的 revision」)。Python 侧再用 ensure_replan_novelty_policy 重新派生前一版 obligation id,只有它等于 successor 自己的 origin 才接受——这比原来的时间戳比较强得多,也让「重建」必须自证。

具体改动

15 个文件、+503/-198(生产侧净减):

  • loopx/control_plane/todos/frontier_revision.ts:新增 triggerCheckpoint(s)(单一 receipt 形状,owned identity 只允许出现在 long-chain trigger 上,且不能单独存在)与 successorCheckpoints(唯一候选 + 单 trigger + 时间不早于 frontier + 重建后 revision 确实改变,才产出 predecessor 绑定);新增 trigger_checkpoints/successor_checkpoints 两个 operation。
  • loopx/control_plane/todos/frontier_revision.py:删除 _owned_identity/advancement_frontier_owned_identity/selectable_advancement_frontier_owned_identity(确认无残留调用)。
  • loopx/control_plane/goals/goal_frontier/{ack_policy.py,long_todo_chain.py}:Python 侧不再自建 checkpoint,改为消费绑定并用 obligation-id 复核;semantic delta 增加 successor_origin_obligation_id。
  • progress_observation.py、autonomous_replan_ack.py、summary_item.py:适配统一形状;两份 RFC 记录这次有界规则组,并明确未宣称更大范围的协作旅程已完成。
  • 4 个测试文件(+220):含两个新的独立回归。

我复核的证据(都在这个 head 或 main 上自己跑过):

  • pytest -q tests/control_plane/test_replan_successor_frontier_causality.py tests/control_plane/test_replan_successor_durable_ack.py tests/control_plane/test_goal_frontier_replan_rules.py tests/control_plane/test_canonical_frontier_revision.py → 67 passed。
  • node --no-warnings --experimental-strip-types --test tests/control_plane_ts/frontier_revision.test.ts → 13 passed。
  • 独立性对照:把两个新回归文件复制到 main 工作区运行 → 16 failed / 4 passed(含 test_successor_proves_exact_predecessor_before_closing[ambiguous/truncated] 与 test_long_chain_ack_survives_real_cli_history_and_peer_claim[writeback/successor/canonical-successor]);跑完已删除副本,工作区干净。也就是说正文「independent regressions fail on main」属实。
  • 删除的 Python helper 已无任何调用点(除测试里对 payload 字段名的断言)。

遗留问题(非阻塞,P3)

新前置条件 (priorAdvancement >= 15 || priorOpen >= 20 && priorAdvancement > 0) 依赖 && 优先于 || 才等价于「15/20 规则」,而同一个文件在另一处把同一条规则写成 advancement >= 15 ? 15 : open >= 20 && advancement > 0 ? 20 : null。同一规则两种写法,未来很容易只改一处;混用运算符也容易在评审时读错。最小修法:抽一个小 helper 两处共用,或至少加括号 + 注释点名 15/20 规则。

对主干的风险

真正变强的是「谁有权承认 successor」:原来靠时间戳比较,现在必须提供可重建的前驱 revision,并用 obligation-id 复核与 successor 的 origin 一致;模糊(多候选/多 trigger)、截断(源不完整)、错误 origin、陈旧转移都 fail closed,而 peer 认领不会撤销已接受的 owned ACK、只有本 lane 的实质变更才重新武装。权限面没有放宽:15/20 阈值与写权限明确未变,legacy revision-only ACK 仍按精确 revision 匹配,所以没有迁移负担。未验证维度:PR 声称的 19 项 premerge 与本地性能测量我没有复跑(远程 CI 按契约未轮询);predecessor 分支刻意很窄,形状不同的合法插入会「不绑定」——方向是 fail-safe,代价是可能少承认而不是错承认。回退成本一个 commit。

我的整体评价

结论 APPROVE。这是把一条规则收到正确 owner 的正向改动:Python 少一份构造与两个 helper(净减行数),TS 产出类型化绑定,Python 用 obligation-id 独立复核「重建是否自证」。两个回归我都用手工对照证明它们在 main 上确实失败、在此 head 通过,另有 67 + 13 项聚焦测试通过;删除的 helper 无残留调用。唯一 P3 是同一阈值规则的两种写法。

English verdict: APPROVE - exact head acf4434. The change moves checkpoint construction, freshness and bounded predecessor reconstruction into todos/frontier_revision.ts, returns typed exact/predecessor bindings from one bridge call, and verifies a reconstructed predecessor by re-deriving its obligation id in Python; Python's duplicate construction and two identity helpers are deleted with no dangling callers. I ran 67 focused Python tests and the 13-case native TS suite at this head, and proved the regressions are independent by copying both new test files onto a main worktree where 16 of 20 fail. One non-blocking P3: the reconstruction predicate encodes the 15/20 rule with operator precedence while the same file spells it out again as an explicit ternary.

@huangruiteng
huangruiteng merged commit a10f1bf into main Sep 17, 2026
29 checks passed
@huangruiteng
huangruiteng deleted the codex/replan-checkpoint-owner-20260917 branch September 17, 2026 15:31
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.

1 participant