Keep Goal Acceptance bindings ready across validator revisions - #4957
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)
动机
已确认的 Goal Acceptance Todo 在完成验证命令修订或增加后继链接后,仅因记账字段变化被投影为 stale,claim/lease 路径因此拒绝原任务。该 PR 完成的是这一有界误判修复;真实任务意图变化的自动恢复仍是独立课题。无阻断性发现。
改动思路
权威仍是 canonical Todo 与 owner 配置的验收合同。先比较原有 v0 指纹;不匹配时,只用当前可校验的验证修订链和后继列表前缀重建有限个历史记账状态。匹配才保留 ready,否则沿原门禁返回 stale。不改写旧绑定,也不扩大 Agent 权限。比直接把这些字段从指纹删掉更稳妥:后者会使大量已持久化且原本 ready 的绑定在升级时反而失效。
具体改动
acceptance_contract.ts 增加只读兼容匹配;File/SQLite 相关测试覆盖正向修订和文本、写入范围、验证必需性及破损修订链的反例;中英文参考文档说明当前行为。没有新增 schema、命令或状态 owner。CLI/managed Turn 使用同一 guard,前端与飞书继续读取原 typed projection,界面合同无需改动。
关键代码讲解
goalAcceptanceTodoDigest保持旧哈希格式,避免升级导致既有绑定集体失效。acceptanceBindingMatches先走精确匹配,再检查有上限的历史修订及后继前缀;不匹配时返回 false。acceptanceTask将匹配结论映射到既有ready/stale,claim、lease 与完成路径共享该投影。
对主干的风险
最强反例是宽松兼容吞掉真正的工作变化。文本、写入范围、completion_validation_required 与破损修订链的反例均保持 stale;未启用合同的路径保持原行为。相关 TS 测试 41 项通过,Python CLI/运行时 27 项及渲染 10 项通过,类型检查、公开边界扫描和 14 项预合并检查通过。PostgreSQL 集成测试因本机无测试库未跑;兼容搜索限定 32 次修订及 32 个后继,超界时仍会保守返回 stale。已用只读 CLI 对持久化 Goal 投影验证:受影响绑定恢复 ready,原本就绪的绑定维持就绪。
语义与 CI 对齐
复用现有 ready/stale 词汇及 owner 验收权威,未新增状态值。当前 Goal 的 PR review 配置为不等待 CI;本地必需验证已完成。代码只修误判,不把真正的任务改写自动视作 owner 确认。
我的整体评价
这是可独立交付的兼容修复,且没有另设状态权威。建议合并并在升级后读回原 Todo 的 claim/Turn 路径;真正语义漂移时的 Agent 自恢复应在后续改造中单独处理。
English verdict: APPROVE - exact head d33a6f1; no blocking finding. Focused TS/Python tests, typecheck, boundary scan, canary, and read-only CLI projection passed; PostgreSQL integration was unavailable locally.
An owner-confirmed Goal Acceptance binding became
stalewhen a Todo revised its completion validator or linked a successor, even though its work declaration and acceptance criterion were unchanged. The claim/lease gate then stopped the existing long-running task.The binding matcher now accepts only bounded, reconstructible prior validator-revision and successor-prefix states after an exact v0 digest mismatch. Persisted digests are unchanged, so existing
readybindings stay ready. Text, required validation, repository, scope, and unknown work-field changes still require reassessment. Fresh Todo validation and Goal Acceptance criterion checks remain independent.Validation: focused File/SQLite authority and runtime tests (41 passed), Python Goal Acceptance CLI/runtime tests (27 passed), TypeScript typecheck, public boundary check, standard premerge canary (14 checks), and a read-only CLI projection against a live persisted Goal. CLI/managed Turn consume the corrected shared guard; frontend and Lark read the same typed projection, with no schema or UI contract change.