Skip to content

feat: revise open Todo completion validators - #4833

Open
huangruiteng wants to merge 5 commits into
mainfrom
codex/todo-validator-revision-4832
Open

huangruiteng wants to merge 5 commits into
mainfrom
codex/todo-validator-revision-4832

Conversation

@huangruiteng

Copy link
Copy Markdown
Collaborator

Summary

  • add a TypeScript-owned, CAS-safe revision transaction for open Todo completion validators, with immutable digest history, actor attribution, operation replay, and private declaration readback
  • bind post-revision validation receipts to the current declaration digest so stale or unbound receipts cannot complete the Todo
  • expose the same revision state through CLI/managed Turn, Dashboard Todo details, packaged Chat assets, and bilingual operator documentation

Product entry points

  • CLI / managed Turn: todo update accepts one replacement command plus --update-operation-id, --update-expected-provider-revision, and a registered --agent-id
  • Dashboard: the existing Todo detail drawer shows validation revision, declaration digest, and revising actor; it remains read-only and does not introduce a second source of truth
  • Lark: no Lark-specific state or action is added; Lark continues to consume the canonical Todo projection

Validation

  • python -m pytest -q tests/control_plane/test_todo_completion_validation.py tests/control_plane/test_completion_validation_lane_scope.py — 56 passed
  • focused promoted end-to-end revision/readback/current-validator completion test — passed
  • CLI + coordination contract suite — 210 passed
  • TS update/completion tests — 33 passed
  • file and SQLite provider conformance, validator-revision cases — 2/2 passed for each provider (legacy and native)
  • npm run typecheck:control-plane — passed
  • Dashboard build, presentation/status schema smokes, and packaged personal-workspace browser smoke — passed
  • loopx canary premerge --from-git-diff --goal-id finance-research-goal — 19/19 passed, public-boundary scan passed

Test environment note

A full file/SQLite conformance invocation also reached two unrelated existing succession-readback failures because its spawned system Python rejects dataclass(slots=True). The new validator-revision provider cases pass under both stores, and all diff-selected premerge canaries pass.

No local Goal state, credentials, private research material, or generated dependency directories are included.

Fixes #4832

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)\n\nExact head: \n\n### 动机\n\n现有 Todo 的 completion validator 创建后不可修改;仓库移动或命令失效会让仍然有效的 open Todo 永久无法完成,并持续占用 durable work lane。这个 PR 解决 #4832:允许注册 Agent 在明确给出当前 provider revision、原 declaration digest 和 operation id 时,审计式替换 validator。\n\n### 改动思路\n\n复用现有 TypeScript Todo update authority、provider CAS 和 operation receipt,不引入第二套状态源。TS 负责 actor/lifecycle/digest admission、revision history 和 CAS;Python 只负责 canonical readback 后的 private declaration host effect,并通过同 operation id 恢复丢失响应。Dashboard、CLI/managed Turn 都消费同一 canonical projection。\n\n### 具体改动\n\n- 增加 typed completion-validation revision intent、immutable receipt/history 和 v5 update wire。\n- 增加 CLI/managed Turn replacement 参数与严格参数诊断;promoted Goal 不走 legacy fallback。\n- revision > 0 的 completion effect/receipt 强制绑定当前 declaration digest;revision 0 保持兼容。\n- Dashboard 显示 revision、digest、actor,打包 Chat 已重建;双语参考文档同步。\n- file/SQLite provider conformance、Python/TS transaction、CLI、E2E、dashboard/typecheck/build/canary 均已覆盖。\n\n### 对主干的风险\n\n最强风险是 provider commit 与 private sidecar publish 的两阶段边界:进程若在中间崩溃,该 Todo 会暂时不可完成。实现用 canonical history + same-operation replay 恢复,只补 host effect,不重复 provider mutation;stale/unbound receipt 会失败关闭。全量 provider suite 仍有既有的 spawned system Python 不支持 环境失败,但本 PR 新增的 file/SQLite conformance case 已分别直接通过,不构成本次 blocker。\n\n### 我的整体评价\n\n完成了 #4832 的完整用户路径,并符合 TS 决策归属、shared projection、provider CAS、幂等回执和产品交付规则。没有发现 blocking finding。已对 exact head 运行 result consistency check,结论为 APPROVE。由于这是作者自有 PR,GitHub 不允许 formal self-approval,因此以 COMMENTED review 记录批准结论;不自行合并,等待外部 review/merge。\n\nEnglish verdict: APPROVE - bef4ea1 implements a proportionate, typed, CAS-safe validator-revision path with current-digest completion binding, recoverable host-effect publication, shared UI readback, and no blocking findings.

@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: bef4ea1a20bc1e93929a2457888b232dc3464248

动机

现有 Todo 的 completion validator 创建后不可修改;仓库移动或命令失效会让仍然有效的 open Todo 永久无法完成,并持续占用 durable work lane。这个 PR 解决 #4832:允许注册 Agent 在明确给出当前 provider revision、原 declaration digest 和 operation id 时,审计式替换 validator。

改动思路

复用现有 TypeScript Todo update authority、provider CAS 和 operation receipt,不引入第二套状态源。TS 负责 actor/lifecycle/digest admission、revision history 和 CAS;Python 只负责 canonical readback 后的 private declaration host effect,并通过同 operation id 恢复丢失响应。Dashboard、CLI/managed Turn 都消费同一 canonical projection。

具体改动

  • 增加 typed completion-validation revision intent、immutable receipt/history 和 v5 update wire。
  • 增加 CLI/managed Turn replacement 参数与严格参数诊断;promoted Goal 不走 legacy fallback。
  • revision > 0 的 completion effect/receipt 强制绑定当前 declaration digest;revision 0 保持兼容。
  • Dashboard 显示 revision、digest、actor,打包 Chat 已重建;双语参考文档同步。
  • file/SQLite provider conformance、Python/TS transaction、CLI、E2E、dashboard/typecheck/build/canary 均已覆盖。

对主干的风险

最强风险是 provider commit 与 private sidecar publish 的两阶段边界:进程若在中间崩溃,该 Todo 会暂时不可完成。实现用 canonical history + same-operation replay 恢复,只补 host effect,不重复 provider mutation;stale/unbound receipt 会失败关闭。全量 provider suite 仍有既有的 spawned system Python 不支持 dataclass(slots=True) 环境失败,但本 PR 新增的 file/SQLite conformance case 已分别直接通过,不构成本次 blocker。

我的整体评价

完成了 #4832 的完整用户路径,并符合 TS 决策归属、shared projection、provider CAS、幂等回执和产品交付规则。没有发现 blocking finding。已对 exact head 运行 result consistency check,结论为 APPROVE。由于这是作者自有 PR,GitHub 不允许 formal self-approval,因此以 COMMENTED review 记录批准结论;不自行合并,等待外部 review/merge。

English verdict: APPROVE - bef4ea1 implements a proportionate, typed, CAS-safe validator-revision path with current-digest completion binding, recoverable host-effect publication, shared UI readback, and no blocking findings.

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.

动机

这个 PR 对应 #4832 的真实阻塞:一个仍然打开的 Todo 在测试路径移动后,旧的 completion validator 会稳定返回 pytest exit code 4,使 Todo completion 和后续 quota settlement 一直被挡住。当前 head 的方向是对的:给已有 validator 增加显式、CAS-safe、可审计的 revision,而不是手改 Goal 文件或把旧 receipt 重新解释成新声明的证据。

改动思路

整体链路已经比较完整:CLI 生成规范化声明;TypeScript provider 在现有 update admission、provider revision 与 operation receipt 上做原子修订;canonical Todo 只保存 digest、revision 和 history;Python 在 provider commit 后保存私有执行声明,并通过相同 operation id 支持崩溃后的重放修复;Todo completion 对 revision > 0 的 validation receipt 强制校验 declaration digest;Dashboard 只读展示 revision/digest/actor。

我沿着真实调用链检查了 todo update -> provider request v5 -> authority commit -> private declaration publication -> todo complete -> validation receipt,并检查了当前 head 相对旧审阅 head 的 provider-only projection 修复。

具体改动

  • provider 状态机要求 Todo 仍为 open/active、已有 validator、expected declaration digest 匹配,并追加连续 revision receipt;旧 digest、新 digest、actor、operation id 和时间都可审计。
  • Python adapter 在 commit 后核对 canonical readback 再写 0600 私有 sidecar;同 operation id 重试会从 history 还原原 CAS witness,因而能修复“provider 已提交、sidecar 尚未落盘”的中断。
  • completion transaction 仅对 revision > 0 要求 validation_declaration_sha256,保留 revision 0 的兼容行为,同时拒绝旧或未绑定 receipt。
  • projection 的最新修复明确把 revision/history 作为 provider-only 派生字段,Markdown 仍只携带执行当前 validator 所需的私有声明,避免制造第二个审计源。
  • 本地验证:Python focused suites 175 passed;TypeScript provider/update/completion suites 68 passed;control-plane typecheck passed;Dashboard schema smoke 和双 Vite build 通过;git diff --check 通过。

但当前 exact head 还有一个 P1 blocker:TypeScript authority boundary 没有真正类型化 revision declaration。decodeCompletionValidationRevision()declaration 只调用 canonicalAuthorityObject(),所以 { "unexpected": "accepted" } 这类完全不可执行的对象也会被哈希并提交 revision/history。我用当前 head 直接调用 planner,确认它返回了成功的 updates/receipt。随后 Python 的 _publish_completion_validation_revision() 才会尝试规范化/持久化,并在 canonical commit 之后失败,留下“canonical digest/history 已前进、私有可执行声明不存在”的 poisoned revision。

最小修复是在 TypeScript commit 之前复用/抽取 completion validation 的声明规则:只接受且规范化 validation_commandvalidation_command_argvvalidation_labelvalidation_timeout_seconds 四个字段;拒绝额外字段、双 command form、空 argv、非法 timeout 和错误类型;然后再计算 next digest。请补真实 request-v5/provider 回归,证明这些非法 payload 均失败且 provider revision、Todo digest 与 history 完全不变。

对主干的风险

正常 CLI 路径由 Python 先规范化,现有 happy-path 测试因此全部通过;风险主要来自直接 effect-runtime 调用、未来的新 adapter,或任何绕过当前 Python CLI 组装器的 provider-neutral caller。这里不能依赖“现在只有 CLI 会这样调用”,因为 PR 的目标正是把转移规则放进 TypeScript authority owner;如果 authority 接受的状态比执行端更宽,失败发生在 durable commit 之后,重试也只能重放同一个坏 revision,恢复成本比普通输入错误高。

两阶段 provider/sidecar publication 本身在声明合法时有合理的幂等恢复路径;当前 blocker 不是要求分布式事务,而是要求在不可逆的 provider commit 前完成同一份声明的语义校验。

我的整体评价

方向、边界划分和大部分恢复语义都很好,旧 receipt 不会静默满足新 declaration,最新的 provider-only projection 修复也解决了旧 head 的 parity 问题。不过“TypeScript 负责转移、Python 负责适配”的核心承诺尚未完全成立:authoritative decoder 仍允许非法 declaration state。结论是 REQUEST_CHANGES;修复上述 P1 并补 provider 不变性回归后,我愿意快速复审。

Reviewed exact head: d707c2e641245c7227bcff66ea057338641d8cb3

English verdict: REQUEST_CHANGES — validate and canonicalize the executable completion-validation declaration inside the TypeScript authority boundary before hashing or committing the revision; malformed request-v5 declarations currently advance canonical state and fail only during post-commit private publication.

Comment thread loopx/control_plane/todos/completion_validation_revision.ts Outdated
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
@huangruiteng

Copy link
Copy Markdown
Collaborator Author

已修复最新 review 指出的 TypeScript authority blocker,当前 exact head 为 2d40828cb5ad997b5ae8fdae40fe4b3e743df966

  • 抽出共享的 TS completion-validation declaration normalizer,planner 与 revision authority 使用同一语义;
  • revision commit 前严格拒绝未知字段、双 command form、空/非法 argv、非法 timeout、错误类型和无可执行 command;
  • digest 只基于规范化后的四字段 declaration 计算;
  • 新增真实 file/SQLite、legacy/native provider 回归,证明失败请求不改变 provider revision、Todo digest/history,也不产生 operation receipt。

验证:

  • PATH="$PWD/.venv/bin:$PATH" npm run test:control-plane:2217 passed, 18 skipped, 0 failed;
  • npm run typecheck:control-plane:通过;
  • focused revision/provider suites:39 passed + 8 provider conformance cases passed;
  • git diff --check:通过。

未改前端、Lark 或 CLI 入口:本次只收紧既有 request-v5 authority admission,所有入口继续走相同 canonical projection/receipt;非法 payload 会在 provider commit 前通过现有 typed failure 返回。请按新 exact head 快速复审;这是 control-plane 变更,不自行合并。

English: the TS authority now validates and canonicalizes the executable declaration before hashing or committing it, and provider conformance proves every malformed request leaves revision, digest, history, and receipts unchanged. Full control-plane tests and typecheck pass on the exact head.

@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 2d40828cb5ad997b5ae8fdae40fe4b3e743df966。上一轮指出的“任意/畸形 declaration 可先写入 canonical authority”已经实质修复:新增的共享 TypeScript normalizer 会拒绝额外字段、双命令形式、空 argv、越界 timeout 和错误类型,而且失败发生在 provider mutation/receipt 之前。这个方向正确,复用边界也比上一版清晰。

但当前 head 仍有 1 个 P1 原子性 blocker,因此结论仍是 REQUEST_CHANGES

核心行为与 authority 流

当前路径是:Python update_canonical_todo_if_promoted 构造 request-v5 → TypeScript decodeCompletionValidationRevision 规范化 declaration → provider 用规范化后的对象计算 digest、提交 revision/history receipt → Python _publish_completion_validation_revision 再校验 canonical digest 并写 private sidecar。

这个设计要求“TypeScript 提交的 declaration”与“Python 后置发布的 declaration”是同一个 canonical 表示;否则 canonical authority 已提交,而 private executable sidecar 无法发布。

阻塞问题

[P1] 接受的可强制转换输入会在 canonical commit 后触发 sidecar digest mismatch。

completion_validation_declaration.ts 在 strict revision 路径仍接受并转换多种非 canonical 表示,例如:

  • validation_command_argv: '["true"]'['true']
  • validation_timeout_seconds: '20'20
  • validation_label: ''null
  • 带首尾空格的 validation_command → trim 后字符串

TypeScript 使用转换后的对象提交 canonical digest;但 Python provider_update.py::_publish_completion_validation_revision 使用 request 中原始 validation_revision["declaration"] 计算 expected_digest。我实际复现了第一、二、三种组合:TypeScript 返回 ok=true 和 canonical array/int/null,而 Python 原始对象与 canonical 对象的 SHA-256 分别为 07344196...2a48d1e4...

结果不是安全拒绝:provider 会先持久化新的 completion_validation_sha256、revision 与 history receipt,随后 Python 才抛出 completion_validation_revision_publication_mismatch,private sidecar 没有对应 declaration。这样 Todo 会进入“canonical 已前进、执行声明未发布”的分裂状态,重试原始请求也不能修复 digest 差异。

最小修复有两种等价选择:

  1. strict authoritative revision 模式拒绝上述非 canonical 表示,只接受 array/int/null 等最终形态;或
  2. Python 在构造 request 前只规范化一次,并把同一个 canonical 对象同时用于 TypeScript request 与 post-commit publication。

需要补一条真实跨语言回归:从 Python adapter 进入真实 TypeScript provider,分别覆盖 JSON-string argv、numeric-string timeout、blank label、whitespace command;断言要么 mutation 前拒绝且 authority 完全不变,要么成功提交且 canonical/private digest 与 readback 完全一致。

验证证据

  • node --experimental-strip-types --test tests/control_plane_ts/todo_update.test.ts tests/control_plane_ts/completion_validation_plan.test.ts:27 passed。
  • npm run typecheck:control-plane:通过。
  • git diff --check origin/main...HEAD:通过。
  • 手工 cross-language counterexample:TypeScript 接受并规范化;Python 原始/规范化 digest 不一致,稳定复现上述 post-commit 风险。
  • 远端 PostgreSQL、desktop、dashboard 与 stage2c 检查已通过;复审时 core shards/static/forward/windows 仍在运行。CI 通过也不会覆盖这个未建模的 accepted-coercion path。

Future-facing pass

共享 normalizer 本身是合适的有界重构;下一步不要再引入第二套规则。应明确区分“transport convenience normalization”和“canonical authority declaration”,并让跨语言 commit/publication 只传递一个规范化结果。修复后这条边界会更容易局部测试、回放与恢复,无需扩展成更宽的框架。

English verdict: REQUEST_CHANGES — exact head 2d40828cb5ad997b5ae8fdae40fe4b3e743df966 fixes malformed-declaration admission, but accepted coercible inputs can still commit a canonical digest that the Python sidecar publisher cannot reproduce from the original request, causing a post-commit split state. Canonicalize once across the boundary or reject non-canonical strict-revision inputs, and add a real Python-adapter/TypeScript-provider regression.

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

Copy link
Copy Markdown
Collaborator Author

已修复当前 exact-head 复审指出的跨语言原子性 blocker,新 exact head:0b765acc22142303ef3adfaad03d9ac1496a2b7e

本轮选择在 TypeScript revision authority 上拒绝非 canonical 输入,避免把 transport 便利转换带入不可逆 provider commit:revision declaration 现在必须显式包含完整四字段,并直接使用最终 string/null、string[]/null、number/null 表示;JSON-string argv、numeric-string timeout、blank label、带首尾空格 command 和缺字段都会在 provider mutation 前失败。

新增真实 Python adapter → TypeScript provider 回归,覆盖上述四个 coercible counterexample,并验证 canonical authority 与 private sidecar 都完全不变;file/SQLite legacy/native provider conformance 同步覆盖。

验证:

  • PATH="$PWD/.venv/bin:$PATH" npm run test:control-plane:2217 passed,18 skipped,0 failed;
  • npm run typecheck:control-plane:通过;
  • Python cross-language focused:5 passed;
  • file/SQLite provider conformance:4 passed;
  • git diff --check:通过。

English: strict validator revisions now accept only the final four-field canonical representation, so transport coercions cannot create a provider/sidecar digest split. Cross-language and both provider conformance regressions prove rejection happens before either canonical or private state changes. Please re-review exact head 0b765acc22142303ef3adfaad03d9ac1496a2b7e.

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.

Control plane: existing Todo completion validator cannot be updated after test path moves

1 participant