fix(todos): allow fenced first completion validator binding - #5192
Conversation
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
评审结论:APPROVE,未发现阻塞性问题。评审范围为 7e4b290;这是修复原 Todo 的首次完成验证绑定,不是宣告 managed worker 或整个 Goal 已验收。
动机
旧 canonical Todo 没有验证 digest 时,公开更新路径在 Python 传输层提前拒绝,导致后来补独立完成检查只能考虑重建任务。同一 File/SQLite 夹具在不可变主干版本上复现拒绝,状态不变;修复后一次提交、原操作重试不重复修改。这个增量直接消除身份与验收关联丢失的修复摩擦,但保留后续真实 worker 交付的门槛。
改动思路
沿现有 Todo 更新事务扩展明确的 v1 首次绑定语义,而非新增命令、存储或 Python 决策源。TS 判断旧状态确实没有验证权威,捕获原有字段,再由原 CAS/租约/操作回执完成提交。私有命令仍由原 publication 协议发布与读回;Goal consumer 复用同一个历史校验器。这里保留的是原 owner 的任务关联,旧 Goal verification 不会因此自动有效。
具体改动
关键代码讲解
decodeCompletionValidationRevision(completion_validation_revision.ts:142)严格区分旧替换与 v1/null 的首次绑定;省略、v0/null 和数组伪 schema 都拒绝,不能靠隐式空值取得权限。planCompletionValidationRevision(同文件:191)只允许 open/active、确实不存在 digest 的任务;required=true 但缺 digest 是损坏状态。记录第一条 null previous digest 及准确旧字段,保留原 claim/lease,绑定不执行也不完成任务。acceptanceBindingMatches(acceptance_contract.ts:203)复用 TS 完整历史链,将声明恢复到原 owner 关联时的形态;任务文本、范围、缺失关联或伪造历史仍为 stale/unbound,不能自动晋级。_completion_validation_revision_request(provider_update.py:47)仅传输缺失事实与原操作历史;随后 publication 必须核对当前 digest。旧首次绑定在更新后的验证器上重放会报告 publication mismatch,不能恢复旧命令。
前端配套是共享 Todo 状态 schema 对 nullable previous digest 的读回,未新增配置控件:实际配置入口仍是现有 CLI/managed todo update --validation-command-json。真实公开 Todo list 保留 digest/history 且不暴露命令;Dashboard/Chat 打包已通过。Lark 未新增发送行为,不把 schema smoke 写成线上群聊验收。11 个文件中生产改动 +105/-34,其余为持续回归和双语操作说明。
对主干的风险
最大风险是损坏状态被误作首次绑定、错误重建 owner digest,或丢失发布后重试覆盖更晚的验证器。对应回归验证了错 actor/lease/CAS、done/archived、malformed history、失败真实验证保持 open、丢失 private publication 的原操作恢复和后续替换。三种真实后端 conformance 913 通过、零跳过;Goal/Todo 92 通过、零跳过。不可变 baseline 的既有89项也全部通过;同一公开 File/SQLite 对照保持备注持久化、旧替换、重放和 stale-CAS 完整异常/诊断/无副作用等价,仅首次绑定是披露的预期变化。
语义与 CI 对齐
遵循 TS 重构 RFC 的单一决策权威和当前 correctness/parity 契约;v1 是现有 revision vocabulary 的明确扩展,旧 v0 持久回执继续可读,并删除 Goal consumer 的重复解析。没有放松验收范围、租约、预算或工作义务。typecheck、Python adapter/CLI 回归、ruff、共享前端 schema 和 Dashboard/Chat packaged build 均通过。冻结 exact head 后的 premerge 为19项检查和5项 direct checks 全部通过,公开边界扫描11文件无命中。首次 premerge 因我运行期间提交新测试文件触发 tracked-side-effect 检测,保留为流程失败;不算通过,冻结重跑已恢复。按 Goal 评审策略不查询/等待远端 CI。
我的整体评价
这个修复足够通用,机制集中于现有 TS owner,旧格式兼容服务于真实持久回执,不是双轨决策。边界有用且可独立验收:恢复原任务声明更新,但不替 owner 改标准、不宣告 whole Goal 成功。剩余风险是 backend 与 packaged frontend 必须同步升级,旧读者无法理解 v1/null;已有 v1 回执后不能无迁移降级。这是 LoopX core PR,仍需 maintainer 合入;未自合并、未安装未合入代码。合入后由实际使用者验证原工作绑定、真实 worker 交付与结果返回,不能把本地夹具冒充运行采用。
English verdict: APPROVE - 7e4b290; fenced first validator binding repairs the public File/SQLite path while preserving existing replacement/replay/CAS and owner acceptance boundaries. Real three-backend conformance (913), focused tests (92), packaged frontend and frozen premerge passed. Core maintainer merge and aligned adoption remain separate.
|
Merge-readiness hold at 当前原生合入条件核验返回 请先将分支更新到当前主干。更新后的新 head 需要重新完成相应验证、exact-head 评审及 本次遵循配置的本地验证策略,没有查询或等待远端 CI,也没有合并或改动作者分支。 Readiness: HOLD — update the branch, then requalify the new exact head. The existing reviewed head remains approved; this observation grants no merge authority. |
Summary / 摘要
The canonical Todo update path could replace an existing completion validator but could not bind the first one to an old/imported Todo. The Python transport rejected the absent digest before the existing TypeScript transaction could decide. This left independently checked completion unavailable without recreating work.
旧/imported Todo 没有完成验证 digest 时,现有路径只能替换旧验证,不能首次绑定。Python 传输层提前拒绝,导致无法沿原任务声明建立独立完成检查。本 PR 在现有 TS 更新事务内修复,不重建任务、不改 owner Goal 准则、不绕过租约或完成验证。
User journey / 用户路径
Configuration uses the existing
todo update --validation-command-jsonCLI/managed-agent path, not a new capability setting. There is no existing frontend completion-validator editor or changed visual control. The necessary frontend companion is the shared Todo status decoder, tested with both receipt versions; desktop and Chat packaged bundles were built. Public Todo list readback carries the digest/history and omits the private command. Lark retains the existing shared projection, with no independent configuration store or new outbound message behavior.配置复用现有 Todo 更新 CLI/managed-agent 路径。未新增 capability 配置项或视觉控件;前端配套为共享状态解析器。实际公开 Todo 读回检查 digest/历史回执且不外露命令,Lark 继续消费现有统一投影。未声称新增浏览器编辑流程或执行线上 Lark 发送。
Validation / 验证
9eaacfbf2ff93d5386cee82ddf0847d9c739e78a: the publicloopx.todos.update_goal_todopath rejects first binding withTodo has no current completion validation digest to revise; canonical state is unchanged.npm run typecheck:control-plane; targeted Python adapter tests;ruff check; frontendsmoke:presentation-surface-schema; packaged Dashboard and Chatnpm run build; diff hygiene.Boundaries / 边界
Binding is not execution, completion, Goal acceptance or spending. A broken required validator with a missing/null digest is not eligible for first binding. New receipts remain single-authority TypeScript-owned; Python stays transport/private publication only. No task-class, Goal scope, budget, scheduler, model, source-data, trading or account permission changes are included.
This is LoopX core control-plane work: maintainer review/merge required. No self-merge or installation of this unmerged head. Mixed-version deployments should update the packaged frontend with the backend before using first binding; older decoders do not understand its explicit null previous digest. Local test state, raw receipts and generated bundles are excluded from the branch.