15 KiB
升格级联重跑设计
日期:2026-07-21 状态:已完成独立评审,P0/P1 边界已冻结 适用范围:
parse-book作品面升格管线 执行状态:P0 历史 redo 安全门已完成并验证;一次性备份、恢复演练、reset 和1..116重建尚未执行,执行前仍需用户绑定确认
一、评审结论
当前 --redo-window K 只撤销并重写第 K 窗。在串行生长的升格管线中,后窗已经消费了旧的卡、别名、出场记录、水位和向量;只重写历史单窗会制造前后代际不一致。因此,本次修复分成两个互不阻塞的阶段:
| 阶段 | 目标 | 本阶段必须交付 | 明确不做 |
|---|---|---|---|
| P0 | 立即止损并恢复 work 8 | 封死历史 redo;停止 work 8 评测读取;建立一次性可校验备份;经用户确认后执行 reset_upgrade_work;全书 1..116 正序重建;完成验收 |
不建设通用持久任务、恢复点、围栏接管和真正级联 |
| P1 | 建立可长期使用的历史重跑能力 | 持久任务、恢复点、写入围栏、强杀恢复、真正的 K..F 级联重跑 |
不作为 P0 的前置条件,不借 P0 成功宣称 P1 完成 |
P0 是本次 work 8 恢复的唯一方案。 不再根据审计是否充分选择 84..F 撤销,也不在本次恢复中实现或调用真正级联。
二、事实与边界
2.1 已确认事实
- work 8 当前设计基线末窗为
F=116。 - 已知失活触发点是 window 101;101 不是末窗,也不是 P0 的重建终点。
- 升格按窗口串行生长,后窗依赖前窗形成的卡、别名、出场记录、水位、审计和向量。
- 当前
--redo-window只处理指定单窗,不能重建该窗之后已经形成的派生判断。 - 现有
reset_upgrade_work.py会软删本书活跃升格卡,将全部窗口重置为pending,并清理本书别名、出场留档、卡水位和升格审计;旧向量行保留,但随所属旧卡软删而退出召回。 - 正常
parse_upgrade.py run会按章节顺序处理未完成窗口,可用于全书正序前滚重建。
2.2 执行前必须重新核验
F=116 是本设计的确认基线,不是允许执行时静默变化的动态参数。任何破坏性动作前必须只读核验:
- work 8 恰有 116 个有效窗口,窗号和章节范围连续,正文可读。
- 当前没有 work 8 升格写入进程,也没有评测任务正在读取 work 8。
- 正文版本、窗口边界、字段合同和必要模型配置已生成不可变摘要。
reset_upgrade_work --work-id 8的预览影响范围与备份清单一致。
任一项不满足,立即停止。特别是实际末窗不等于 116 时,不得自动扩大或缩小范围,必须重新生成设计基线并取得新的用户确认。
2.3 本文不授予执行权限
全书 reset 会软删和硬删现有派生数据,是破坏性动作。本文评审通过不等于授权执行。 只有一次性备份完成并校验通过后,向用户展示本次执行摘要并取得针对该摘要的明确确认,才能执行数据库写入或模型调用。
三、P0:立即止损与 work 8 全书重建
3.1 P0 总流程
flowchart TD
A[封死历史 redo] --> B[停止 work 8 升格写入与全部评测读取]
B --> C[只读预检并冻结 F=116 与输入摘要]
C --> D[生成一次性备份]
D --> E{读回与恢复校验通过?}
E -- 否 --> X[失败关闭,不改业务数据]
E -- 是 --> F[展示 work 8 / 1..116 / 备份 ID / 破坏影响]
F --> G{用户明确确认本次 reset?}
G -- 否 --> X
G -- 是 --> H[执行 reset_upgrade_work]
H --> I{reset 后空态验收通过?}
I -- 否 --> Y[停止并保持评测关闭,人工决定是否恢复备份]
I -- 是 --> J[按 1 到 116 严格正序前滚重建]
J --> K{P0 全链验收通过?}
K -- 否 --> Y
K -- 是 --> L[用户确认解除 work 8 评测读取禁令]
3.2 封死历史 redo
P0 第一项是让历史单窗重跑失败关闭,避免 P1 完成前再次制造代际错位:
--redo-window K指向已完成历史窗时,必须在任何业务写入前拒绝。- 不提供
--force、配置开关或“已知风险继续”等绕过路径。 - 正常运行中对当前失败窗的撤销后同窗重试不属于历史 redo,可以保留;它不能越过失败窗,也不能回写更早的已完成窗。
- 只有 P1 真正级联通过全部验收后,历史 redo 才能以新的
K..F语义重新开放。
3.3 停止 work 8 评测读取
冻结区间从生成备份前开始,到 1..116 重建和 P0 验收全部通过、用户明确同意开放为止。在此期间:
- 停止 work 8 的在线评测、离线回放、批处理评测、评测快照装配、评测导出和缓存预热。
- 停止普通升格写入、历史 redo 和其他会修改 work 8 升格派生状态的任务。
- 只允许本次预检、备份、重建和验收使用受控入口;验收查询不产生评测结果。
- 任一失败或中断都保持关闭,不能因为进程退出、窗口暂停或备份恢复成功而自动开放。
P0 必须留下冻结开始、命中拒绝、验收结束和解除冻结的记录。最终验收要求冻结区间内 work 8 的成功评测读取数为 0。
3.4 一次性可校验备份
P0 备份是本次 work 8 reset 前的唯一恢复基线,不是 P1 的通用恢复点系统。备份必须在同一个一致性读视图中覆盖:
| 状态域 | 备份范围 |
|---|---|
| drafts | work 8 全部 upgrade_book 卡,包含活跃、软删、版本和归属字段 |
| windows | work 8 全部 116 个窗口及状态、错误、边界和软删字段 |
| aliases | work 8 全部别名行 |
| presence | work 8 全部出场留档 |
| card_state | work 8 全部卡水位 |
| audits | 所有指向 work 8 升格卡的审计行 |
| embeddings | 所有指向 work 8 升格卡的向量行、内容哈希、模型和软删状态 |
备份工件必须满足:
- 生成唯一
backup_id,记录数据库标识、生成时间、代码版本、F=116和输入摘要。 - 每个状态域记录行数、主键集合摘要和按稳定顺序计算的内容校验值;备份文件另记 SHA-256。
- 备份存放在不会被
reset_upgrade_work影响的位置,只允许授权操作者读取或恢复,不得被后续尝试覆盖。 - 生成后重新读回,核对文件校验值、七域行数和内容摘要。
- 在隔离库或隔离 schema 做一次恢复演练;恢复后的七域摘要必须与源数据一致。
任一校验或恢复演练失败,P0 停止,不得执行 reset。
3.5 用户确认硬门
备份校验通过后必须停止,并向用户展示以下固定摘要:
- 作品:
work_id=8,范围:1..116。 backup_id、备份 SHA-256、七域行数与校验结果。- 将执行的破坏性入口:
reset_upgrade_work --work-id 8 --execute。 - reset 的影响:软删活跃升格卡、全部窗口置为
pending、硬删别名/出场留档/水位/审计;随后会调用模型从窗 1 重建到窗 116。 - 失败边界:P0 没有 P1 的强杀自动恢复;失败后 work 8 保持关闭,由用户决定续跑还是恢复唯一备份。
确认必须绑定本次 work_id、范围、输入摘要和 backup_id。旧确认、默认值、通用 --yes 或范围变化后的确认均无效。没有本次明确确认,流程只能停在这里。
3.6 reset 与正序前滚
获得确认后,P0 只允许以下路径:
- 执行现有
reset_upgrade_work.py --work-id 8 --execute,不得另写临时 SQL 替代,不得改走--redo-window。 - reset 后立即验证:活跃升格卡为 0;116 个有效窗口全部为
pending;别名、出场留档、卡水位和指向旧升格卡的审计均为空;旧向量只挂在软删旧卡上,不参与召回。 - 使用正常升格入口从窗 1 开始,严格按
1,2,...,116正序前滚;不得跳窗、并行同书窗口或从 84/101 起跑。 - 每个窗口只有在完整提交并通过窗后不变量后才能进入下一窗。全局
$24/6000治理或局部上限可以让运行在窗边界暂停,但 work 8 仍保持关闭。 - 普通失败按现有“当前失败窗撤销后重试/续跑”处理。发生强杀、状态不可解释或输入摘要漂移时立即停止,保持评测关闭;P0 不声称能自动接管恢复。
3.7 window 101 回归基线
window 101 是已知失活触发点,必须作为状态转移回归检查,不得只看窗 116 的最终活跃卡数:
- reset 前记录目标逻辑实体在 window 100 结束、window 101 处理后以及 102..116 的卡身份、活跃状态、归并关系、水位和审计来源。
- 重建时记录同一逻辑实体在 window 100/101/116 的对应状态。
- 验收必须证明 window 101 按当前业务证据产生了正确状态转移,且 102..116 消费的是重建后的新前态。
- 不能用“最终存在一张同名活跃卡”代替验证;新建重复卡、错误归并后复活或旧新代际叠加均不通过。
四、P0 验收与完成口径
P0 只有同时通过以下门槛才算完成:
| 验收门 | 必须证据 |
|---|---|
| 历史 redo 已封死 | 历史 --redo-window 在写入前被机械拒绝;当前失败窗重试仍正常 |
| 冻结有效 | 从备份前到开放前,work 8 成功评测读取数为 0,且无第二升格写入者 |
| 备份可恢复 | 唯一 backup_id、SHA-256、七域摘要和隔离恢复演练全部通过 |
| 确认有效 | 确认记录绑定 work 8、1..116、输入摘要和 backup_id,且发生在 reset 前 |
| reset 正确 | 执行入口和影响行数可追踪;reset 后空态不变量全部通过 |
| 顺序完整 | 窗口完成事件严格为 1..116,无跳窗、倒序、并行或旧状态复用 |
| window 101 回归 | 100→101 的状态转移符合业务证据;102..116 持续消费新前态;无重复逻辑实体或代际混合 |
| 七域一致 | 卡、窗口、别名、presence、水位、审计和向量互相一致;活跃向量哈希匹配活跃卡正文 |
| 开放受控 | 116 窗全部完成且全链验收通过后,仍需用户明确同意才解除评测读取禁令 |
以下情况只能报告局部进度,不能说 P0 完成:备份只生成未恢复演练;reset 成功但未跑满 116;window 101 最终态看似正常但过程未核验;任务暂停或回滚;只验证一张卡;评测读取未证明全程为 0。
五、P1:持久任务与真正级联
P1 在 P0 独立完成后实施。它把历史重跑从一次性运维动作升级为可恢复、可并发约束、可审计的产品能力。
5.1 持久任务与恢复点
每次历史重跑创建持久任务,至少记录:task_id、work_id、起点 K、冻结末窗 F、输入版本、当前阶段、逆序/正序游标、最近完成窗口、恢复点、围栏令牌、暂停原因、错误和终态。
- 任务创建时冻结
K..F和输入版本;范围或输入漂移时失败关闭。 - 任何撤销前创建可恢复到任务开始前的全书恢复点,并机械验证完整性。
- 每个窗口边界形成持久检查点。模型计算期间不持有数据库长事务。
- 暂停必须续接同一任务;不得另起普通升格任务越过未完成级联。
5.2 写入围栏与读取关闭
同一本书同一时刻只允许一个升格写入任务。数据库可信边界为每次任务发放递增围栏令牌;所有升格写事务都必须验证令牌。
- 租约或心跳过期只表示任务可被接管,不表示普通写入者可以进入。
- 接管者取得新令牌后,旧进程即使复活也无法提交。
- 任务从撤销开始到验收发布前,业务消费和评测读取只能看到“重跑中/待恢复”,不能读取半成品。
5.3 真正级联语义
P1 重新开放后的 --redo-window K 固定表示:冻结当前末窗 F,先按 F..K 逆序撤销,再按 K..F 正序重放。撤销和重放都不得跳窗;后窗只能读取前窗已经重放完成的新状态。
flowchart LR
A[创建持久级联任务 K..F] --> B[取得新围栏令牌]
B --> C[冻结输入并校验全书恢复点]
C --> D[关闭本书消费与评测读取]
D --> E[逆序撤销 F..K]
E --> F[校验已回到 K-1]
F --> G[正序重放 K..F]
G --> H{全链验收通过?}
H -- 是 --> I[发布新代际并开放读取]
H -- 否 --> J[恢复任务前恢复点并保持关闭]
5.4 强杀与恢复
强杀后不得猜测进度。下一执行者读取持久任务、恢复点、最近完成检查点和当前围栏令牌:
- 未开始当前窗口写入时,从该窗口继续。
- 当前窗口事务未提交时,从该窗口重新计算。
- 阶段或数据无法由检查点证明时,恢复任务前恢复点并将任务置为失败关闭。
- 恢复、接管或回滚完成前,旧任务令牌、普通写入和所有消费读取均不得重新开放。
stateDiagram-v2
[*] --> preflight
preflight --> snapshotting: 预检通过
snapshotting --> undoing: 恢复点校验通过
undoing --> replaying: 已回到 K-1
replaying --> paused: 达到治理或局部上限
paused --> replaying: 同一任务续接
undoing --> recovery_required: 强杀或状态不明
replaying --> recovery_required: 强杀或状态不明
recovery_required --> restoring: 新围栏持有者接管
restoring --> failed_closed: 已恢复任务前状态
replaying --> validating: 已重放到 F
validating --> restoring: 验收失败
validating --> succeeded: 验收通过并发布
5.5 P1 验收
P1 完成至少要求:
- 给定任意
K..F,事件顺序严格为撤销F..K、重放K..F。 - 在恢复点生成、逆序撤销、正序重放、暂停等待和最终验收阶段分别强杀,重启后都能由持久证据决定续接或恢复。
- 两个同书进程并发时只有新围栏持有者能写;旧进程复活提交被拒绝;不同作品可并行。
- 任一中间态的业务消费和评测读取均被拒绝,只有完整新代际发布后开放。
- 恢复点往返后七域逐行一致;窗口检查点不会留下半窗卡、孤儿别名、超前水位或旧向量。
- P0 的历史 redo 禁令只有在上述自动化、数据库集成和强杀演练全部通过后才能解除。
六、实施顺序
- P0 代码止损(已完成):历史 redo 安全门仅允许末窗重跑;历史窗、不存在窗、不连续窗口、正文为空和负数参数均在业务写入前拒绝。验证证据:parse upgrade 128 项、parse LLM 9 项、outline 11 项全部通过,独立复审 PASS,真实 work 8 的 redo 101 已在写入前拒绝。
- P0 执行准备(未执行):只读预检、一次性备份与隔离恢复演练尚未执行。
- 人工确认门(待执行):备份与恢复演练通过后,仍须提交绑定
work_id=8、1..116、输入摘要和backup_id的破坏性执行摘要,取得用户明确确认。 - P0 数据恢复(未执行):尚未执行 reset,也未开始
1..116正序重建和验收;只有取得第 3 步绑定确认后才能执行。 - P1 长期能力(未执行):持久任务、恢复点、围栏、强杀恢复和真正级联仍属后续范围。
当前已完成第 1 步。第 2 至第 5 步均未执行;全书破坏性 reset 仍无执行授权。