Skip to content

fix(todos): use committed phase receipts for post-writeback hooks - #5578

Merged
huangruiteng merged 3 commits into
mainfrom
codex/fix-todo-hook-receipt-identity
Oct 4, 2026
Merged

huangruiteng merged 3 commits into
mainfrom
codex/fix-todo-hook-receipt-identity

Conversation

@loopx-agent

Copy link
Copy Markdown
Collaborator

Goal And Delivered Outcome

An ordinary Todo completion followed by same-Turn --no-follow-up closeout can commit in the same second. The hook source currently treats the timestamp as a state version, so closeout replays the ordinary completion's not_applicable sidecar and loses the terminal intent. A frozen-clock test through the real CLI reproduces 0 intents instead of 1.

This repair checkpoints a completion-phase receipt id with the primary mutation and uses it for hook dispatch and composition recovery. The same test now produces one terminal intent, recovers a missing optional sidecar, and retains one quota debit across retries.

Author Declaration

  • Written by: model_agent — gpt-6.1-sol (OpenAI).

Implemented against

Criterion Disposition Owning boundary Decisive evidence
RFC §5: committed primary source, diagnostic logs confer no authority implemented existing TS Todo completion transaction and CLI composition root real CLI completion on legacy, File and SQLite
RFC §9: distinct committed phases, stable retry identity implemented primary completion_receipt_id, hook transaction inspection/CAS frozen same-clock phases; original intent on replay; missing-sidecar recovery
RFC §12: optional failure isolation and no external effects implemented existing hook receipt and capability-intent contracts hook/composition tests; empty write scope; one quota debit

Scope And Continuation

Complete within this repair scope. New completions persist an additive optional Todo field owned by the existing TypeScript transaction. Python transports it; one private stored-receipt validator shares inspection and CAS semantics. Historical field manifests and timestamp-derived identities remain readable; unchanged old completions are not rewritten or bulk replayed. Previously lost historical intents are not automatically republished.

The feature remains explicitly opt-in. Completion metadata gains a receipt id even when hooks are disabled, while disabled hooks still perform no provider invocation. Canonical completion replay now exposes the original completion timestamp so an uncheckpointed optional hook can recover. Todo status, validation, spend eligibility and external-effect authority remain with their existing owners. Cost is one bounded digest and one optional field per completion, with no polling or new scheduler work.

Validation

  • Tested revision: b2023af4cb9b080cbf6a34d6393bb35afd27ad95 (working-tree checks used identical committed source bytes).
  • Run state: finished.
  • Input classes: synthetic, public_fixture.
Check kind Result Public-safe evidence / limitation
real_entrypoint / real_backend passed tests/control_plane/test_quota_settlement_cli.py and test_quota_authority_settlement_journey.py; real legacy/File/SQLite paths, same-clock closeout, sidecar recovery and one debit; 300 focused Python checks in total
regression_parity passed immutable baseline fails the frozen-clock intent oracle; head passes; restoring timestamp-only dispatch makes the same oracle fail
unit passed 89 TS checks: completion, hook inspection/CAS, field update, historical projection shapes and old canonical identity bytes
real_backend passed npm run test:postgresql-authority-store; isolated disposable PostgreSQL 16.2, 331 passed, zero skips; store/schema/provider conformance, not a separate PostgreSQL terminal-CLI qualification
static passed focused Ruff, configured mypy, control-plane typecheck, generated contract/census, semantic and public-boundary checks
manual not_run full CI, live host/report delivery and long-duration model runs; no external publication or active Goal mutation was used as a test

Risk-based native premerge and exact-scope quality receipts are published in the review. Compatibility is additive for the current reader; older binaries do not know the new field, so downgrade requires its own authority migration rather than assuming forward compatibility.

Frontend / Visual Evidence

  • UI impact: none. This repairs the existing completion/hook lifecycle; it introduces no caller setting, capability or screen. CLI completion and existing periodic-report intent readback are exercised.

Type of Change / LoopX Area

  • Bug fix, focused validation and protocol documentation.
  • Control plane: Todo completion and optional post-writeback receipt identity.
  • Shared-authority RFC fixture impact: no promotion or migration-progress claim; historical native/canonical manifests, next-mutation upgrade, real File/SQLite and PostgreSQL store paths were checked.

Boundary Checklist

  • Public-safe code, fixtures, description and reviews; no private state, raw traces, credentials, internal links or local paths.
  • Existing owners and independently reversible repair; no benchmark jobs or new effect authority.
  • Every commit carries a DCO sign-off.
  • Maintainer merge remains required for this control-plane change.

…ooks

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>

@loopx-agent loopx-agent 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.

Reviewer: model_agent — gpt-6.1-sol (OpenAI); runtime_reported; reasoning_effort=xhigh

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

动机

使用可选阶段报告的操作者,在同一轮先完成 Todo、再确认无需后续任务时,会遇到收尾通知意图丢失。
同一秒内的普通完成与终结收尾原先共用时间戳身份,后一次错误复用了前一次“不适用”的记录;修复后两次提交分别识别,终结收尾生成一条意图。
真实 CLI 已验证:重试返回同一意图,丢失可选 sidecar 后可恢复,quota 只扣一次。
本次不生成或发布报告,不授予外部写入权限,不批量重放历史已完成记录。

改动思路

主事务负责提交事实,hook 负责提出意图,后续执行者负责效果。此前把秒级时间戳当版本,无法区分两次合法提交。现有 TypeScript 完成事务依据 Goal、Todo、完成身份、continuation 和 recovery 计算稳定 id,并与状态一起持久化;Python 仅传递这一事实。这个字段是已提交阶段的身份,不是由调用者手填的激活开关,也不取代 claim、lease、验证或结算。

正向路径是 quota 绑定 → 验证及 refresh → 普通完成 → 单次 spend → --no-follow-up → 终结意图 → 重试读回。legacy、File、SQLite 均经过真实 CLI,固定提交时钟后不再丢失意图。相邻的 bounded refactor 把 sidecar 读回和 CAS 的原始时间校验放到一个私有 helper,保留旧身份算法;没有引入第二个决策 owner、通用迁移框架或额外轮询。

具体改动

精确 head:b2023af4cb9b080cbf6a34d6393bb35afd27ad95;base:1af7dbd43a1629b0356ecd5ee28a426ad45d1d7a。21 个文件,+240/-20:12 个生产/契约文件、3 个生成文件、4 个验证文件、2 个文档/技能规则文件。生成的 registry I/O census 仅更新两处行号。原始 Todo schema 的新增字段同时登记为历史版本组,使前一版完整 manifest 仍可读取,且旧 manifest 不能偷带新字段。

关键代码讲解

  • reduceTodoCompletionTransaction:沿用 typed fence/state 决策,提交 metadata 中的 completion_receipt_id。同轮普通完成和终结收尾具有不同 id,同阶段重试 id 不变。
  • sourceHookInput:有原生 receipt id 时用它形成 source 身份;缺失时保持原有 canonical bytes。可变 projection 和 best-effort 日志都不进入身份来源。
  • validateStoredReceipt:按不变身份验证并返回历史 sidecar,保留其原始时钟。inspection 和 CAS 共用它,当前读回时间变化不会伪造新效果,divergent result 仍受原冲突规则约束。
  • executeCoordinationTodoTerminalLifecycle:原生结果投影同一已提交 id;canonical Python adapter 在 completion replay 提供原完成时间,使主事务已提交、sidecar 未落盘的情况能恢复。

依据 docs/architecture/rfcs/provider-neutral-post-writeback-capability-hooks-v0.md,spec_revision 为 1af7dbd43a1629b0356ecd5ee28a426ad45d1d7a:§5 implemented,原生提交后才 dispatch;§9 implemented,同秒分离与原回执重放;§12 implemented,故障隔离、空 write scope 和无外部效果。此映射判断本次修复,不声明整份 RFC 或报告交付均已完成。

对主干的风险

最强反例是“新 id 消除了碰撞,但升级/重启会重复通知”。因此保留没有字段的旧完成记录及其旧 source hash;新增阶段 id 在主事务中持久化,重试直接读回。真实临时 fixture 删除终结 sidecar 后,重新调用仍产生相同意图;再重试为零 provider invocation,quota 仍为一次。用同一公共 CLI oracle 故意恢复 timestamp-only dispatch,会再次出现 0 条意图,说明测试能识别原缺陷。

300 项 Python、89 项 TypeScript、真实隔离 PostgreSQL 16.2 authority-store 的 331 项(0 跳过)、typecheck、Ruff、mypy、生成契约、语义/公开边界检查已通过。19 项 native premerge、5 项 direct checks 及当前 diff 的质量回执通过。维护性 ratchet 对未改动的 loopx/extensions/lark/goal_topic_runtime.py 仍有 inherited advisory:相同命令在不可变 base 与本 head 的失败身份、详细原因一致,无 magnitude regression;没有提高预算或缩小扫描掩盖它。

语义与 CI 对齐

新增字段扩展已有 Todo/receipt 契约,TypeScript 仍是语义 owner,没有新增状态分类或能力。通用完成 metadata 的新增字段是明确披露的默认变化;可选报告的激活条件没有改变。enabled/disabled 的真实 CLI 对照显示关闭 profile 时没有 hook intent、调度或额外扣额,合法输入与原结算流程保持;这是通用 receipt 修复,不是新增可选能力。旧二进制不认识新字段,不能把向前读取兼容误当成任意降级兼容。

未跑完整 CI、线上报告投递或长时间模型试跑;PostgreSQL 证据是 store/schema/provider conformance,终结 CLI 的端到端证据覆盖 legacy/File/SQLite。历史已丢失的意图未自动重发。当前配置要求不查询、不轮询 GitHub CI,本评审依据本机原生证据。

我的整体评价

APPROVE,针对上述精确 head,没有阻塞发现。long_horizon 为 improved:原先静默丢失的收尾承诺能形成稳定意图,重启与重试不会增加 quota;user_experience 为 improved:原命令即可完成和恢复,无新增参数、人工确认或设置。成本是一项有界 digest 与一个持久字段,没有新增周期性工作;这能支持局部效果与操作效率的正向判断,不能外推成全部 Goal 或模型长程效果已获实测。

兼容分支保留有明确的持久历史消费者;更小的 sleep/时间精度修补不能证明重试身份,整份 projection hash 会引入可变读模型。现有 typed owner 加稳定提交身份是本次最小完整修复。这里是同一实现代理的完整自审,维护者仍负责控制面合并,评审结论不构成合并授权。

English verdict: APPROVE — b2023af separates committed same-clock completion phases and recovers the original effect-free intent. Real CLI replay, mutation sensitivity, historical contracts, 300 Python checks, 89 TS checks, 331 PostgreSQL checks and native premerge pass; inherited unrelated Lark debt and untested live delivery are disclosed. Maintainer merge required.

@huangruiteng
huangruiteng merged commit f35978e into main Oct 4, 2026
23 of 29 checks passed
@huangruiteng
huangruiteng deleted the codex/fix-todo-hook-receipt-identity branch October 4, 2026 13:13
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.

2 participants