Repository navigation
fix(todos): preserve canonical migration refusals at terminal boundaries - #7452
Conversation
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent; gpt-6.1-sol; OpenAI; runtime_reported; reasoning_effort=max
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
动机 / Motivation
需要完成或归档旧Goal、并依靠错误类型决定先迁移还是修复存储的用户与Python API调用方。 完成操作把尚未迁移的明确拒绝包装成普通存储故障,归档操作又报告内部todo_snapshot;调用方既无法按约捕获拒绝类,也看不到实际请求的操作。 完成和归档仍在写入前拒绝未迁移Goal,同时保留CanonicalAuthorityRequired类型、请求的Goal及操作、备份迁移指导。 不放开未迁移Goal的写入,不创建或重建authority,不改变provider、状态格式、迁移步骤、权限或结算结果。 整版发布的其余回归、真实模型、工作台和制品核验仍在推进;本PR只修复拒绝诊断,不认证正式发布完成。
改动思路 / Approach
复用既有raise_canonical_write_failure与CanonicalAuthorityRequired,把native拒绝映射保留在Python传输边界;不新增错误类、迁移分支或第二状态owner。 本PR仅修复terminal/archive预读失败的分类与调用上下文,普通provider故障继续沿既有不可用分支抛出。 完成与归档在实际写入前都先读取canonical存储;尚未迁移是明确的拒绝结果,而已经迁移后的存储不可用是另一条恢复路径。本次保留这一区别,避免仅因为两者都无法读回就抹去原始类型。调用上下文属于正在尝试的terminal/archive,native诊断继续作为证据携带,不成为另一份请求身份。
具体改动 / Changes
规格来自既有 loopx/control_plane/coordination/local_authority.py:CanonicalAuthorityRequired 及其调用合同:source。migration-rejection 已实现:未迁移写操作保持明确拒绝、备份指导与零写入;native-error-context 已实现:请求的Goal/操作不会被内部snapshot标签覆盖,普通provider不可用继续使用原错误路径。这些标签映射现有合同,并非新增规范编号。
关键代码讲解
- CanonicalAuthorityRequired.init 在携带native payload后应用调用方Goal与operation。异常层级、错误码、write_admitted/legacy_fallback与迁移指导不变;这个构造器没有IO或状态效果。
- terminal/archive pre-read 复用既有raise_canonical_write_failure。只有canonical_authority_required被映射成迁移拒绝;其他错误继续原来的terminal不可用处理或archive重新抛出。没有捕获成功状态后继续写入,也没有创建新provider、回退旧Markdown或自动迁移。
完整变更两文件+15/-5,复用一个已有mapper而非新增错误分类器。领域决策和事务仍由TypeScript owner掌握,Python只修复native结果的异常投影。未扩大到迁移流程、CLI选项或状态模型。
对主干的风险 / Risks
86项canonical update、archive retry与team authority测试通过,覆盖真实File/SQLite正常写入、重放、display恢复及未迁移execute/dry-run无写拒绝;Ruff、diff、双语、隔离公开扫描、严格CQR与16项risk premerge通过。 最强反例是把真实provider故障误报为尚未迁移;已检查mapper只按既有精确reason/error code分类,其余失败分支保留。单看错误字符串无法发现本次缺陷,因此保留原测试对异常类型、操作名、write_admitted=false、legacy_fallback_used=false、备份恢复要求和源文件不变的完整断言。成功File/SQLite操作、archive重放与缺失display恢复同样实际执行,没有通过放宽assertion让错误变绿。没有查询、轮询或等待PR CI。
语义与 CI 对齐
沿用canonical_authority_required、todo_terminal和todo_archive词汇,没有新增Enum、prose heuristic、可选开关或默认provider变化。错误说明仍是强制迁移边界的读回,不是假称建议;拒绝不会授予写入或迁移权限。完整公开扫描与严格CQR通过,风险门零失败/零人工hold;合并还单独核对维护者授权与即时readiness。
我的整体评价 / Verdict
APPROVE,justified_increment。 long_horizon preserved,user_experience improved:存储与结算语义保持原样,调用方能正确识别拒绝并处理所请求的操作。复用既有raise_canonical_write_failure与CanonicalAuthorityRequired,把native拒绝映射保留在Python传输边界;不新增错误类、迁移分支或第二状态owner。 本PR仅修复terminal/archive预读失败的分类与调用上下文,普通provider故障继续沿既有不可用分支抛出。 没有新增持久兼容分支或人工同步负担。这是内部错误传输修复,没有页面或布局变化;整版工作台仍须单独验证。整版发布的其余回归、真实模型、工作台和制品核验仍在推进;本PR只修复拒绝诊断,不认证正式发布完成。
English verdict: APPROVE — 718851601af910888ae69c5db9634b92f3402ad2. Preserve the existing canonical migration rejection and requested operation at terminal/archive read boundaries. All86 real-provider/API/CLI tests,strict CQR,boundary and16local risk canaries pass; no PR CI was consulted. Full release qualification remains pending.
Completing or archiving an unmigrated Goal must return the canonical migration refusal before writing. Completion instead wrapped that rejection as a generic authority outage, and archive reported the internal snapshot operation. Python callers could no longer catch the documented rejection class or identify the requested operation.
Reuse the existing canonical write-failure mapper at both terminal read boundaries. Preserve the requested Goal and operation when carrying native diagnostics, keep provider outages unchanged, and retain all no-write/no-fallback and backup-before-migration behavior. No state is migrated or recreated by this fix.
Validation: 86 existing canonical update, archive recovery and team-planning authority tests pass, including real File/SQLite positive paths, unpromoted dry-run/executing refusals and missing display recovery. Changed Python Ruff, diff hygiene and public-source scan pass. Exact-head review, strict CQR and the repository risk-based premerge remain required before merge; PR CI is not consulted under the current policy.