refactor(authority): unify Todo presentation and provider conformance - #4283
Conversation
huangruiteng
left a comment
There was a problem hiding this comment.
Request changes conclusion (author-owned PR; GitHub blocks formal self-review)
动机
这个 PR 的目标是把 Todo 展示、standing-decision 排序以及 authority provider parity 收敛到同一个 TypeScript 语义内核,减少 Python 适配层与原生 provider 之间的分叉。动机成立:当前调用者需要同时看到 canonical read model、稳定的排序/冲突语义和跨 File/SQLite/NoKV provider 的一致结果;如果只修一个适配器,后续 provider 或 projection 仍可能再次漂移。审阅范围是 main(6ef6838102cd1e0696bc98b046b0238f787e8f09)到 exact head 87aeef93119ba1b456c47428c55bfe02a8c2d8ab,17 个文件、+761/-157。
改动思路
实现以 todo_presentation.ts 的类型化 read model 为入口:先规范 Todo 的 schema/presentation metadata,再由 coordination_projection.ts 和 standing-decision 投影复用该结果;provider conformance 测试则用同一组状态转移比较不同 authority backend。这个分层方向比在 Python 与每个 provider 各自复制判断更容易保持一致,且没有把 authority、lease 或外部发送权限扩张给展示层。
但这条边界目前没有覆盖真实适配器输入。Python build_standing_decision_authority() 传入的 compact row 会显式携带 schema_version: null,而新的 metadata 校验只把 undefined 当作未标注 legacy 输入。结果是:合法的旧 compact row 在 projectStandingDecisions 前被当成 unsupported schema 抛错,冲突无法按既有规则保留为 unresolved。这不是测试文案差异,而是 live Python → TypeScript effect 的行为回归。
具体改动
关键代码讲解
coordinationTodoReadModel/validateCoordinationTodoReadModel(loopx/control_plane/coordination/todo_presentation.ts)把 legacy/native Todo 形状转成共享 read model,并拒绝未知 schema。当前value.schema_version === undefined的条件遗漏了 Python compact row 的null表示。todoPresentationMetadata(同文件)将 schema、source section 和 index 作为 standing-decision 排序/投影的元数据。它位于真实 Python adapter 的调用边界,因此这里的 null/省略语义必须与 adapter 的序列化契约一致。compareTodoPresentation/projectStandingDecisions(loopx/control_plane/coordination/standing_decision.ts)依赖上述 metadata 完成排序和冲突保留;上游异常会把预期的 unresolved 结果变成EffectRuntimeInternalError。authority_provider_parity.test.ts(tests/control_plane_ts/authority_provider_parity.test.ts:132-143)新增 SQLite/File/NoKV parity arm;在仓库要求的 Node 22.6 job 中 SQLite close/finalization 协议仅支持 Node 22.14+,因此新测试在最低版本上报provider_protocol_violation,而不是证明 parity。
对主干的风险
有两个独立的 P1 阻塞点:
- P1 — compact row 的 null schema 会让 live projection 崩溃。 触发条件是 Python standing-decision authority 返回
schema_version=null的两个 timeless conflicting rows;实际调用tests/control_plane/test_standing_decision_order.py::test_conflicts_survive_lane_filtering_without_granting_cross_agent_authority时,Python adapter → TypeScript effect →todoPresentationMetadata抛出EffectRuntimeInternalError。最小修复是把null视为与undefined相同的 untyped legacy marker,或在 adapter 边界统一省略该字段;对非 null 未知版本仍应拒绝,并增加真实 Python compact-row 回归,确认冲突仍是 unresolved 而不是异常。 - P1 — Node 22.6 required parity 不可执行。
.github/workflows/python-tests.yml的最低 Node 22.6 job 会运行该 parity 文件;远端日志显示 SQLite arm 在 close 时报告provider_protocol_violation,从而使node-minimum-compatibility、test-shard (4)、pytest和merge-gate失败。最小修复是沿用仓库已有nodeVersionAtLeast(22,14)guard,在 Node 22.6 保留 File/NoKV 覆盖,并把 SQLite arm 放到 Node 22.14 qualified job;不能通过删掉 provider 覆盖来“修绿”。
当前 exact head 的 10 个 focused TypeScript tests 通过,但这不能替代上述 Python real-path 与最低运行时证据。远端 27 个检查中 23 个成功、4 个失败(node-minimum-compatibility、test-shard (4)、pytest、merge-gate),其余 substantive checks 成功。默认/authority/domain-neutrality 检查没有发现额外问题;变更范围与单一 typed owner 相称,但在两个失败路径修复并复跑前不应合并。
我的整体评价
REQUEST_CHANGES。架构收敛方向正确,且没有发现需要另起框架的未来性重构;然而 exact head 在真实 compact-row 输入和声明的 Node 22.6 支持面上都尚未证明安全。请先修复 null schema 兼容边界、分层最低运行时 parity,并用真实 Python standing-decision 测试、最低版本 workflow 和 Node 22.14 SQLite parity 重新验证;所有 required checks 变绿后再请求复审。
English verdict: REQUEST_CHANGES — exact head 87aeef9; Python compact rows with schema_version=null crash the live standing-decision projection and the new SQLite parity arm fails the required Node 22.6 job. Ten focused TypeScript tests pass, but the two P1 boundary fixes and required-check rerun are needed before merge.
87aeef9 to
36f1e9b
Compare
huangruiteng
left a comment
There was a problem hiding this comment.
Request changes conclusion (author-owned PR; GitHub blocks formal self-review)
English verdict: REQUEST_CHANGES (commented fallback; formal self-review is blocked). Exact head: 36f1e9b. Key finding: Node 22.6 minimum CI runs SQLite parity tests that require Node >=22.14; legacy ordering and null/omitted-schema parity also drift.
动机
统一 Todo presentation 与 provider conformance 能减少迁移期间的重复语义;但 exact head 仍有最低 Node job 失败,并且兼容 shape 的两个排序分支不等价。
改动思路
TS 端把 presentation metadata/read model 作为共享投影 owner,Python callers 改用新的 semantic owner,File/SQLite/NoKV 以相同 fixture 做 conformance。设计方向合理,但 legacy optional index 和 compact null schema 的边界必须与 RFC/TS 同步。
具体改动
新增 todo_presentation.ts 的 schema/section/order 归一化,coordination projection 使用 canonical record,Python todo_semantics.py 新增 presentation sort 并切换多个 callers;同时新增 provider parity fixture/tests 与 RFC checkpoint。
对主干的风险
P1:.github/workflows/python-tests.yml 的 Node 22.6 minimum glob 包含新 authority_provider_parity.test.ts,远程 job 34697497676/job 103563419087 在 legacy/native 两个用例都以 SQLite authority requires synchronous statement finalization... use Node 22.14 or newer 失败,merge-gate 连带失败。最小修复是把 SQLite parity 分到 qualified Node >=22.14,或在 minimum job 明确排除该测试。另有 P2:Python presentation sort 对 legacy display_order=None 使用 timestamp/Todo-id,改变旧 stable input order;且 Python 对 schema null/省略仅在有 source_section 时认定 legacy,TS 则无条件按 legacy 处理,导致 index=5 时跨语言结果不同。
我的整体评价
REQUEST_CHANGES。远程 exact head 36f1e9b99b207359348e9550685864789f24696b 已复核;6 passed 的 Python semantic smoke 不能抵消最低运行时红灯与上述兼容性证据。修复 runtime partition、补 legacy missing-index/null-schema parity 后再复核。
dc80922 to
e9af090
Compare
Signed-off-by: huangruiteng <huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <huangruiteng@users.noreply.github.com>
e9af090 to
3248804
Compare
huangruiteng
left a comment
There was a problem hiding this comment.
Request changes conclusion (author-owned PR; GitHub blocks formal self-approval)
动机
这个 PR 收敛 Todo 展示、standing-decision 排序和 authority provider conformance 的语义边界。此前 legacy Python 适配层、TypeScript projection 以及 File/SQLite/NoKV provider 各自携带部分 presentation 判断,迁移期间容易出现 schema、source index、冲突排序和事务轨迹漂移。原 exact head 还暴露了两个真实阻塞:Python compact row 的 schema_version=null 会被 TS metadata 边界拒绝,以及 Node 22.6 minimum job 执行 SQLite parity 时违反同步 finalize 协议。当前 head 已重放到最新 main(含已合并的 Node 22.18 floor),并将 null/省略 schema 作为 legacy-compatible compact 输入;SQLite parity 在新的 Node 22.18 minimum lane 通过。这样保留旧 wire shape 的可读性,同时不为 native domain record 伪造持久化 display index。
改动思路
入口是 todo_presentation.ts 的类型化 read-model 边界:legacy todo_item_v0、compact undefined/null marker 和 native todo_domain_record_v0 被显式分类;legacy 保留 source_section/index provenance,native 从 role/archive 状态推导展示 section,并用 timestamp 与 todo id 做确定性 tie-break。coordination_projection.ts 先用既有 coordination state contract 与 authority codec 校验记录,再验证 Todo read-model 的 schema、count、digest、字段合同和 deterministic id order,因此 presentation metadata 不成为第二 authority。Python todo_semantics.py 复用同一合同和已有 priority 规则,把 display order 作为 presentation-only key;legacy 有合法 index 时保持 source order,native 不合成 index。provider conformance fixture 用相同状态转移比较 File、SQLite、NoKV,测试只观察公开 transaction trace、冲突和 read projection,不扩张 lease、claim 或外部发送权限。
具体改动
关键代码讲解
loopx/control_plane/coordination/todo_presentation.ts:36-76:集中 schema 分类、section 推导、legacy index provenance 和 null/省略 marker 兼容;未知显式版本 fail closed。loopx/control_plane/coordination/coordination_projection.ts:112-171:在 projection promotion 前验证 Todo read-model 的记录顺序、计数、摘要和字段合同,并通过canonicalTodoRecord复用同一 typed record owner。loopx/control_plane/todos/todo_semantics.py:105-181:提供 Python 侧 metadata/sort key,保留 legacy stable source index,同时为 native rows 使用 timestamp/id 的可重复排序;compact envelope 的外层 schema 不会削弱严格 authority-record 边界。loopx/control_plane/coordination/standing_decision.ts及相关 Todo create/update/archive callers:统一调用 presentation owner,移除各调用点对 legacy/native 形状的重复判断。tests/control_plane_ts/authority_provider_parity.test.ts:1-144、authority_store_conformance.ts和 production-scale fixture:对 File/SQLite/NoKV 验证同一 logical transaction trace、冲突和 projection 语义;todo_presentation.test.ts与 Python semantic-kernel tests 覆盖 null、unknown schema、legacy index、native archive 等负路径。
对主干的风险
这是 32 个文件、+1063/-182 的运行时与 RFC cohesive batch,风险主要在兼容输入和 provider transaction boundary,而不是新增 authority。未知 schema 仍会抛出 typed protocol error;legacy 缺失或非法 index 会落到确定性 timestamp/id,不会伪造持久化位置;native rows 不携带 source_section/index,因此 renderer 若需要连续序号必须在展示层临时分配。没有 opt-in capability、权限模型或默认行为开关变化,authority store 仍由既有 provider contract 持有。
验证证据:npm run typecheck:control-plane 通过;npm run test:control-plane:coverage 通过 1266/1266(包含 legacy/native SQLite parity);新增 focused TypeScript parity/presentation/production-scale 通过 11/11;Python semantic-kernel 6/6、changed-path Ruff、mypy 通过;loopx canary premerge --from-git-diff --goal-id loopx-meta 通过 18/18,0 failures、0 manual holds;change-quality strict receipt cqr_d8a16b071613926348ea 与 exact scope fingerprint d8a16b071613926348ea911cacc6dcd19a268b61244ac9e17ef16191b8e21ffb 匹配。完整本地 pytest 还观察到 3684 passed、17 skipped,以及 4 个与本 PR 无关的 tests/capabilities/test_repository_change_window.py 环境失败(尝试写入 /dev/null/reference-transaction);该路径和测试未被本 PR 修改。GitHub required checks 正在 exact head 上重跑,合并前以全部 required checks 为准。
我的整体评价
在 exact head 3248804c0aaffc9115ffb378165e33145c683284 上,前述两个 P1 边界问题已经分别由 null-compatible typed classification 和 Node 22.18 minimum runtime policy 解决;正向、负向以及三 provider parity 均有可观察证据。代码量与迁移/兼容范围相称,未发现需要另起框架的未来性重构;bounded future-facing pass 已通过复用 canonical contract 和删除重复 caller 分支完成。待 GitHub exact-head required checks 全部成功后,本 author-owned PR 可按用户授权 admin self-merge。
English verdict: NO BLOCKERS — exact head 3248804c0aaffc9115ffb378165e33145c683284 is rebased onto current main; null/omitted compact schemas are compatible, Node 22.18 minimum SQLite parity passes, typed provider/presentation boundaries are covered, and local canary/strict receipt are green. Merge only after the exact-head required GitHub checks finish successfully; four unrelated local repository-change-window failures are isolated above.
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
动机
这个 PR 收敛 Todo 展示、standing-decision 排序和 authority provider conformance 的语义边界。此前 legacy Python 适配层、TypeScript projection 以及 File/SQLite/NoKV provider 各自携带部分 presentation 判断,迁移期间容易出现 schema、source index、冲突排序和事务轨迹漂移。原 exact head 还暴露了两个真实阻塞:Python compact row 的 schema_version=null 会被 TS metadata 边界拒绝,以及 Node 22.6 minimum job 执行 SQLite parity 时违反同步 finalize 协议。当前 head 已重放到最新 main(含已合并的 Node 22.18 floor),并将 null/省略 schema 作为 legacy-compatible compact 输入;SQLite parity 在新的 Node 22.18 minimum lane 通过。这样保留旧 wire shape 的可读性,同时不为 native domain record 伪造持久化 display index。
改动思路
入口是 todo_presentation.ts 的类型化 read-model 边界:legacy todo_item_v0、compact undefined/null marker 和 native todo_domain_record_v0 被显式分类;legacy 保留 source_section/index provenance,native 从 role/archive 状态推导展示 section,并用 timestamp 与 todo id 做确定性 tie-break。coordination_projection.ts 先用既有 coordination state contract 与 authority codec 校验记录,再验证 Todo read-model 的 schema、count、digest、字段合同和 deterministic id order,因此 presentation metadata 不成为第二 authority。Python todo_semantics.py 复用同一合同和已有 priority 规则,把 display order 作为 presentation-only key;legacy 有合法 index 时保持 source order,native 不合成 index。provider conformance fixture 用相同状态转移比较 File、SQLite、NoKV,测试只观察公开 transaction trace、冲突和 read projection,不扩张 lease、claim 或外部发送权限。
具体改动
关键代码讲解
loopx/control_plane/coordination/todo_presentation.ts:36-76:集中 schema 分类、section 推导、legacy index provenance 和 null/省略 marker 兼容;未知显式版本 fail closed。loopx/control_plane/coordination/coordination_projection.ts:112-171:在 projection promotion 前验证 Todo read-model 的记录顺序、计数、摘要和字段合同,并通过canonicalTodoRecord复用同一 typed record owner。loopx/control_plane/todos/todo_semantics.py:105-181:提供 Python 侧 metadata/sort key,保留 legacy stable source index,同时为 native rows 使用 timestamp/id 的可重复排序;compact envelope 的外层 schema 不会削弱严格 authority-record 边界。loopx/control_plane/coordination/standing_decision.ts及相关 Todo create/update/archive callers:统一调用 presentation owner,移除各调用点对 legacy/native 形状的重复判断。tests/control_plane_ts/authority_provider_parity.test.ts:1-144、authority_store_conformance.ts和 production-scale fixture:对 File/SQLite/NoKV 验证同一 logical transaction trace、冲突和 projection 语义;todo_presentation.test.ts与 Python semantic-kernel tests 覆盖 null、unknown schema、legacy index、native archive 等负路径。
对主干的风险
这是 32 个文件、+1063/-182 的运行时与 RFC cohesive batch,风险主要在兼容输入和 provider transaction boundary,而不是新增 authority。未知 schema 仍会抛出 typed protocol error;legacy 缺失或非法 index 会落到确定性 timestamp/id,不会伪造持久化位置;native rows 不携带 source_section/index,因此 renderer 若需要连续序号必须在展示层临时分配。没有 opt-in capability、权限模型或默认行为开关变化,authority store 仍由既有 provider contract 持有。
验证证据:npm run typecheck:control-plane 通过;npm run test:control-plane:coverage 通过 1266/1266(包含 legacy/native SQLite parity);新增 focused TypeScript parity/presentation/production-scale 通过 11/11;Python semantic-kernel 6/6、changed-path Ruff、mypy 通过;loopx canary premerge --from-git-diff --goal-id loopx-meta 通过 18/18,0 failures、0 manual holds;change-quality strict receipt cqr_d8a16b071613926348ea 与 exact scope fingerprint d8a16b071613926348ea911cacc6dcd19a268b61244ac9e17ef16191b8e21ffb 匹配。完整本地 pytest 还观察到 3684 passed、17 skipped,以及 4 个与本 PR 无关的 tests/capabilities/test_repository_change_window.py 环境失败(尝试写入 /dev/null/reference-transaction);该路径和测试未被本 PR 修改。GitHub required checks 正在 exact head 上重跑,合并前以全部 required checks 为准。
我的整体评价
在 exact head 3248804c0aaffc9115ffb378165e33145c683284 上,前述两个 P1 边界问题已经分别由 null-compatible typed classification 和 Node 22.18 minimum runtime policy 解决;正向、负向以及三 provider parity 均有可观察证据。代码量与迁移/兼容范围相称,未发现需要另起框架的未来性重构;bounded future-facing pass 已通过复用 canonical contract 和删除重复 caller 分支完成。待 GitHub exact-head required checks 全部成功后,本 author-owned PR 可按用户授权 admin self-merge。
English verdict: APPROVE at exact head 3248804c0aaffc9115ffb378165e33145c683284. Null/omitted compact schemas are compatible, Node 22.18 minimum SQLite parity passes, typed provider/presentation boundaries are covered, and local canary/strict receipt are green. Merge only after the exact-head required GitHub checks finish successfully; four unrelated local repository-change-window failures are isolated above.
Summary
This PR builds on the merged #4279 semantic-kernel refactor and completes the adjacent provider/presentation conformance boundary. It does not duplicate or re-open #4279, and it does not change the transaction decoder delivered by #4280.
The functional projection-delivery slices from closed #4274–#4278 are already part of the #4279 base. The previously open #4283 implementation has been rewritten on top of that merged base, so #4283 remains the single review entry point for this refined scope. It does not create a new RFC; it updates the existing bilingual TypeScript migration and shared-authority RFCs.
What changed
source_sectionandindexare normalized as display coordinates (display_section/display_order), not as a second domain state machine. Native records derive their section from role/archive state and use timestamp plus Todo identity as a deterministic fallback; no fake persisted index is introduced.todo_semantics.py;projection.pyremains only as an external import-compatible facade. The null/compact-row compatibility case is fail-safe and covered by regression tests.Semantic boundaries
source_section/indexare canonical v0 display coordinates at the projection boundary. They are not used to grant eligibility, claim ownership, or alter lifecycle authority.Validation
npm run typecheck:control-plane— passed.PATH— 1256 passed, 1 skipped.ruffand strictmypyon touched Python — passed.--check— passed.loopx-metaread-only status and Todo readback — status contract errors 0; thin projection reported full-match counts (4 matched, 2 returned, 2 omitted).cqr_3f83a471201a9780228fvalid for the exact scope.The default macOS
python3launcher is Python 3.9 and causes unrelated subprocess failures in broad suites. All recorded full-suite results use the project Python runtime explicitly; the four-worker run uses isolated pytest temp state.Review focus
Please review the normalized presentation contract and the legacy/native fixture parity. The intentional non-unifications are provider revision tokens, storage envelopes, and business-selection ordering that has a different owner from display ordering.