Why: between the review round and the approval decision another session completed and merged svc-autorecover (PR #396/#400/#401/#402), so the (a)-decision tracking must reflect the landed slice and the remaining U2 delta. Evidence: SELF - merged main history c622372 and archived card .task/archive/feature-svc-autorecover.md (10/10 tests, 146/146 governance, CI green on e0b49d1). Impact: review record, INDEX; proposal r2 body unchanged. Refs: PR #396 #401
9.1 KiB
服务重启与全量数据恢复方案 r1 文档审阅
日期:2026-10-12(Asia/Shanghai)。对象:主方案。 方法:ce-doc-review,non-interactive;六个独立上下文的原生子代理加作者源码复核。以下为审阅意见及处置摘要;来源为SELF,不是人工批准、业务验收、REPLAY或GATE。没有外部跨供应商模型评审;未跑业务测试或故障试验。
| 角色 | 原始发现数 | 处置 |
|---|---|---|
| coherence | 1 | 修正灾难恢复的分档RPO验收 |
| feasibility | 1 | 与design同一问题合并,修正动作与整run的结算边界 |
| security-lens | 1 | 加入新目标恢复前的旧写路径隔离门禁 |
| design-lens | 1 | 与feasibility同一问题合并,复用原状态/卡片展示 |
| scope-guardian | 0 | 无需扩大或缩小当前目标范围 |
| adversarial | 1 | 收紧非幂等动作的确定未执行证据 |
共5条原始发现、4项独立修正;全部已纳入候选r1,不涉及用户需求的取舍变化。人工评审仍未发生。
审阅意见与处置依据
- 分档验收不一致。 初稿目标允许灾难档RPO≤5分钟,U7却无条件要求“零已确认数据遗漏”。后果是按目标建设的备份也无法按U7签收。按已声明的故障分档,R3/U7/故障矩阵明确RPO=0档零遗漏,灾难档恢复点差距在批准范围内、点内完整并报告点后缺失。没有暗改用户的零丢失合同,所有量化指标仍待人工批准。
- 一个外部动作完成不等于整任务完成。 初稿状态图直接
hold→completed,可能跳过必要后续步骤。作者复核Nativeruntime/loop.go:385–402确认工具结果持久化后还继续模型回合;因此与design/feasibility意见一致。现改为记录operation receipt后回recovering,继续剩余步骤,只有全部必要步骤及业务结果完成才结算整run。 - 独立恢复库不能围栏旧库的执行者。 初稿对新目标恢复已有数据、权限和组合对账,但未明确切生产前如何阻断原权威复活。旧、新库各有有效epoch时,单库租约不能避免双执行。现加入默认隔离验证模式、旧执行者/已发请求写路径隔离、新恢复权威代次、专用资源权限边界及无法证明时hold;同时对账恢复点后的外部效果。验收增加旧实例复活和恢复点后已执行动作。
- 暂未查到结果不足以安全重试。 初稿“查询确认未执行”可能被理解为目标当前无结果;旧请求稍后完成则重复副作用。现要求确定未执行的终态及旧执行者/已发请求不会再生效的证明;普通查询空结果、发送取消或本地退出均不充分。补外部请求延迟完成而恢复者不得发第二次请求的故障场景。
作者另核实并修正一处事实表述:Native已有tool intent/result与safe replay机制,Backend生产Session已接线;本案复用该基础,将其与run/epoch/hold关联、指定统一恢复裁决,而不是重建第二套彼此独立的恢复政策。证据命令原始输出由Dev任务卡make evidence保存。
最终对象与检查
主方案SHA256:cfc9b768a4596a268810e20101cddc2a6040e24a640e6e34dbda17b838cd45ed。
固定源码对象:Dev 5e57029b439e5690f28dc6002f9784f0b08920eb,Backend eb12f102f23d8d026c3458be7ea8b2fef07ada93;任务分支中的后续提交只记录启动/同步元数据,业务源码未改变。
任务卡保留precheck、task-sync、源码调查、Native接线核对以及最终文档检查的工具收据。检查范围为差异空白、相对链接、需求/增量/决策ID、证据完整性;通过仅证明对应文档检查,不证明服务或数据恢复。
草稿、入口和子仓改动尚未提交为固定组合;check-evidence.py对含未提交非任务卡改动的收据报告unverified。原始输出及方案内容摘要已保存,这些记录仅作为本地调查辅助,不能用于正式合入/运行验收。后续正式审核应先固定候选组合、同步并由有权审阅者重放对应检查,不能靠反复执行或更换来源标签消除此限制。
实施前仍需人工确认故障档/RPO/RTO、目标实例与独占管理权、数据归属清单和在途任务分工。按policy/delivery.md,此次审阅与候选修正不能代替任何阶段的人工批准。
第二轮:外部源码复核(2026-10-11)
复核者:ZCode 独立上下文;对象:r1(SHA256 cfc9b768…)。方法:对主案第2节差距表、基线与自审记录引用的源码断言逐项独立重验;未运行服务、测试或故障试验。来源SELF。
核验结果(抽查全部命中):五个基线SHA与任务工作区一致且Dev基线为HEAD祖先;svc.sh:1373 resolve_db_config统一解析;runmgr ReconcileInterrupted(≈2046)统一封印中断;SetRecoveryHold与RenewExecution均仅有定义、无生产调用;claimCommand pending→consumed后执行(kill窗口无重领);app.go HTTP停机超时(现状5秒)即返回并跳过mgr.Shutdown事件清冲;ListSurfaceEventsPending默认limit=100;notice启动载入内存队列、投递后独立DELETE非事务;native loop.go:385–402工具结果持久化后继续模型回合。
修订处置(r1→r2,需求与指标未变):
- U3补停机预算来源变更:现状5秒须显式替换为批准预算并实测校准。
- U1验收补“更换二进制路径/程序版本、不同cwd调用svc后身份一致”场景(对齐R2)。
- U4补“新增公开状态前先交付Core→Backend→Frontend→下游最小状态映射表”。
- 第9节svc-autorecover协调改为明确的人工二选一归属决策项(实施载体 vs 放弃合并,两权威不得并存)。
流程修订:r1先按被审对象原样提交固定(documents 54fc24e、Dev 39f719f),r2为后续修订提交;恢复会话按门禁完成precheck(READY,R0 555fb2162f)并task-sync后实施修订。r2 SHA256:9cfda2520b913e6966c68fb3f66fb7bc8382a8f7a2b69cb364122216dcdb72cd。
遗留(人工事项):svc-autorecover归属二选一、首批实施范围、故障档/RPO/RTO与停机预算批准;全部指标维持待批准未实测。
追加(2026-10-11 task-sync 后):漂移检查与 svc-autorecover 实况
- task-sync 将 backend 指针由 eb12f102 前移至 25fbea85(collab-storage U5-outbox #157 合入)。漂移检查(工具收据见任务卡证据表)确认 r2 引用的差距在新指针全部成立:RenewExecution 与 SetRecoveryHold 仍无生产调用、claimCommand 仍为认领即 consumed、HTTP 停机超时仍跳过事件清冲、Surface 待投影默认仍 100 条。该合入新增
EnqueueCommandInTx(与业务提交同事务投递命令)与AppendEvents内同事务pg_notify,属 KTD10 可直接复用的原语,不改变差距结论。 - svc-autorecover 实况修正归属决策的信息基础:其工作区并非空壳,含未提交的 autostart 期望态 +
svc.sh recover(postgres 先于应用)+ systemd 用户级 watchdog(每分钟拉回)+.start.lock生命周期锁 + pidfile/cmdline 校验(svc.sh +317 行、docs/svc.md +61 行、Makefile +10 行)及回归测试 tests/test_svc_recover.py;但任务卡零登记(无 precheck 收据、无卡内记录、无提交),且 2026-10-11 观察其自测 10 例中 5 例未过(failures=2、errors=3)——定位是“有价值的半成品”,不是可合入实现。选项 (a)(作 U2 实施载体)价值因此上调,但需先补登记(precheck/任务卡/提交)、修复未过用例,并与本案 manifest 合同(KTD1/KTD2)对齐;选项 (b) 则须显式处置这批在途工作而非视同空白。裁定仍属人工。
批准记录(2026-10-12)
用户(weichen)批准方案 r2(拆解/评估/需求表/方案设计/实施计划五阶段一并),并裁定 svc-autorecover 归属选项 (a):作 U2 实施载体,先补登记、修复未过用例、对齐 KTD1/KTD2。实施按第 7 节 U1–U7 与批次 A/B/C 推进;量化指标(RPO/RTO/停机预算)在对应增量验收前固定。来源:用户对话(本记录为 SELF 转述);阶段评审明细见 Dev 任务卡。方案 r2 正文未因批准改动(SHA256 9cfda252… 不变),批准状态以本记录、任务卡与 INDEX 为准。
落地追踪(2026-10-12 补记)
裁定后核实:svc-autorecover 在途工作已由另一会话完成并合入 main——PR #396(autostart 期望态 + recover + watchdog)、#400(任务卡回填)、#401(KillMode=process 修复)、#402(闭卡归档)。归档卡验证摘要:tests/test_svc_recover.py 10/10、make test-governance 146/146(SELF)、CI GATE 绿(PR HEAD e0b49d1,test+test-pg,一次抖动重跑);如实登记的残留:postgres 实例真实 recover 仅代码审查未实测、agent SQLite 数据目录尚无自动备份。裁定 (a) 的“补登记、修复未过用例”已被事实完成;其对齐要求(KTD1/KTD2 manifest 合同、服务组依赖与单一监管者)转为 U2 余量增量。本记录早前“373 行未登记半成品”的表述为当时(2026-10-11)观察,已被后续事件取代。