feat(authority): add reviewed File and SQLite provider cutover - #5173
Conversation
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
…livery Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
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)
Exact head: caf36810524a65250fb341dbc09426b422de829c
动机
已有 canonical Goal 能导出与恢复历史,但不能安全地把当前本地读写入口切到恢复后的 provider;手改 selector 又缺少完整历史、原始回执和后续写入的绑定证明。这完成的是共享 authority RFC D3/R5 的本地 File↔SQLite 审核切换子项,不是默认 provider、更早的 Goal 晋升或整 Goal 激活验收。
改动思路
延伸现有 authority-archive,而不再实现一份 Python 决策器。操作者先停止 writers、结算任务租约,再生成绑定 runtime/Goal、来源身份、revision、cursor、projection 和 fence 的计划。execute 在原 canonical writer guard 内复用完整 archive、restore 和 independent audit,再发布 selector 并读回。新 target 的 identity 与恢复记录绑定,重试核对的是保留历史,不把一次命令响应等同于完成。
具体改动
新增两个行政 CLI 子命令,默认只预览;新增一个有界 TypeScript 迁移模块。File/SQLite selector 共用严格 decoder,File 的已打开 handle 也核对被选择 lineage。恢复记录保留 prepared/completed 与 archive、target identity,避免 target 被替换后误重放。文档说明新显式 File selector 的 reader 兼容要求,以及反向迁移必须带上切换后的写入,不能回放陈旧备份。
关键代码讲解
observe(local_authority_migration.ts:94)直接读 canonical head、真实 identity 与 legacy fence,并按 typed task lease 判断:expired active 仍需结算,过期不是 Host 已停止的证据。manageLocalAuthorityMigration(同文件 :129)在 writer guard 内验证精确计划,保存/审计完整历史、原回执,然后发布目标并核对读回;已发布的同计划可确认 already_applied,反向迁移后旧计划则被拒绝。发布后的 I/O 不确定性用 null 表达,不能声称“未改变”。decodeLocalAuthoritySelection(local_authority_provider.ts:117)与publishLocalAuthoritySelection(:162)复用同一严格 selector 约束和原 durable publication;丢失或换身份的 provider 不得 silently fallback。handle_authority_archive_command(authority_archive.py:58)仅转送既有 Effect operation;execute 的传输丢失返回 outcome unknown 并要求同计划确认,不把 Python 异常包装成无副作用。
对主干的风险
风险重点是切换中断后丢回执、混用 lineage、旧计划覆盖后续提交,以及升级时默认启用新 provider。独立实际 CLI 场景验证默认 File 不变、preview/错误 digest 无切换、source 新写入使旧计划失效、全历史复制、同计划重试,以及新增提交随 SQLite→File 回迁;原始两笔事务保留,回迁包含四笔。相同 oracle 在 base 因不存在新行政命令失败,旧 export/verify 路径仍正常。
本轮 native 迁移/provider/format 54 项通过(base 对应 41 项),CLI archive head 8/base 4 项通过,既有 File/SQLite/runtime conformance 两侧各 350 项通过(无 skip),typecheck、Ruff、scoped mypy、docs governance 与 13 个变更文件的 public boundary scan 通过。SIGKILL、并发等待 writer、身份替换、expired active 租约、历史 metadata 的 null/false/删除键等负例已执行。真实 PostgreSQL 隔离数据库复跑两侧各 305 项通过;各 1 项 service-URL 可选用例同样 skip,未声称验证部署后的 service API。
语义与 CI 对齐
复用已有 archive/audit/lease/fence 词汇,新增的是明确 opt-in 的行政计划与恢复记录,不授予新 worker/Host 权限。frontend/Lark 继续走既有 selected-provider 读边界,未新增设置入口;停止外部 Hosts 和结算租约仍是操作者前提,代码不宣称代做。
作者报告的红色 premerge 不能直接归因于本 PR:本人复跑 crowded Turn-plan 原生预算测试在 base/head 均通过;同 fixture 测得两侧都是 14,482 字符、393 行,writeback contract digest 相同。安装检查则保留失败:清理本轮临时数据后的 local-install 两侧均在 120 秒超时;packaged-install 两侧均在合成归档缺少 apps/presentation/dashboard 的同一路径失败。相关 installer、归档 smoke、chat-bundle builder 和预算测试在本 PR 没有改动,失败发生在新迁移命令之外;迁移不变量另有独立通过证据。初轮共享 PostgreSQL schema 并发冲突及本机 ENOSPC 也已单列,没有放宽超时或预算。安装维护者仍需恢复这些验证,整个 premerge/安装资格未通过,不等于 merge-ready;按当前 policy 未等待远端 CI。
我的整体评价
long_horizon 改善:中断、重放与反向迁移保留后来确认的事务,避免用陈旧备份丢掉进展。user_experience 改善:审核计划、可操作拒绝和不确定性反馈取代危险的手改 selector。新增计划是明确目标的不可推断 intent;恢复记录是代码生成的崩溃恢复证明,不是第二份人工 Todo authority。复用 archive/audit 与统一 decoder 是本次 bounded future-facing refine,避免另起通用迁移框架。范围与成本相称,支持这个子项;完整消费入口、默认切换、容量/soak 和整 Goal 资格仍未关闭,且未执行合并。
English verdict: APPROVE - Independent real-provider and CLI evidence supports the exact-head local cutover. Reproduced unrelated installation failures remain separate validation/merge-readiness holds; this is not approval of whole-Goal activation or a default-provider change.
An already-promoted canonical Goal can export and restore its history, but could not safely select the restored local provider without manual selector edits. This adds reviewed File ↔ SQLite cutover to
authority-archive.plan-migrationbinds the source Goal/runtime, store identity, revision, cursor, projection and legacy-writer fence.migratepreviews or executes that exact plan under the existing canonical writer guard.Roadmap: #4574 R5/G2, shared authority D3 and TS T3/T4. This delivers the local-provider cutover subitem, not whole-Goal activation or default-provider qualification. The RFC checkpoint distinguishes existing #5054/#4931/#5144 from remaining integration/default-entry work. No Python decision owner or new capability is added; Python remains CLI transport. Frontend/Lark continue consuming the existing selected-provider read boundary; no configuration editor or UI entry point changes.
Validation:
Limits: operators must stop writers and settle leases; this does not stop external Hosts or migrate independent Turn/spend/attachment stores. Explicit File selectors require a compatible reader, so provider rollback does not qualify an older binary downgrade. PostgreSQL activation, D2 capacity/soak, whole-Goal consumer qualification and default changes remain separate. This PR is left for maintainer review/merge.
Final qualification on
caf36810524a65250fb341dbc09426b422de829c: premerge failed; do not treat this PR as merge-ready. Five direct checks passed; of 19 selected checks, 16 passed, two installation smokes timed out at 120 seconds, and the crowded Turn-plan JSON budget failed (14,514 characters versus 14,500). The unchangedaf3e7f1f0baseline reproduces the local-install timeout. A diagnostic same-fixture base/head comparison measured 14,514 on both sides, with 102 rows per side and no differential review items; it deliberately disabled absolute assertions for measurement only and does not replace the failed gate. Packaged-install timeout remains unqualified. No timeout or size ceiling was increased.The exact-scope quality receipt was updated to non-passing after these results (13 files; fingerprint
43425190fe509ac31c8fe07df9511f53673e370bb44fbcc54a365f0019ce73b7). Migration-specific validation above remains passed. General premerge failures and maintainer review/merge remain holds.