汇总已落盘的借款本金与还款、兼容历史编号的周期化编号、付款责任与回单核验、报销进度和排序、PWA/采购事务、错误原因与日期校验及ERP退役。 统一共享预算池锁序和锁后判断,恢复差旅原预算选择,补原因码固定夹具及反向完整性检查。 纳入配套迁移、测试、受管QA、分层验收合同、规约及任务记录;原始证据留在ignored artifacts。 关联任务:09-17-company-loan-principal-repayment、09-17-erp-exclusive-retirement、09-18-reimbursement-periodic-numbering、09-08-reimbursement-payment-closeout、09-18-local-concurrency-product-fixes、09-19-budget-pool-concurrency、09-05-error-explainability-payment-readiness。 预算补审由Claude定向验证2文件928项通过,原4446/28及r6结果仍仅对应各自历史输入;本轮未重跑测试。 完整新候选门禁、R1真实入口接入与12项公网义务仍开放。生产编号未启用、差旅仍冻结;不推送、不部署,不宣称发布资格。
16 KiB
隔离备份恢复演练
2026-09-19 K0 独立静态复核与范围澄清
K0 加解密合成合同经 Claude 定向静态复核 PASS,未新增运行时或真实恢复结果。它不覆盖 maskBankAccount、maskIdNumber、maskKeepEnds 的脱敏正确性,不能作为“敏感字段完整闸门”引用;本轮不扩建脱敏测试或修改产品函数。
server/src/scripts/migrate-notification-channel-secrets.js 会读取配置、连接目标数据库并批量改写通知渠道密钥字段;它属于数据迁移工具,明确排除在 K0 以及 K1/K2 的默认执行范围之外,不得为恢复验证运行或导入该入口。未来 K2 若选择通知类加密字段,只按另批绑定方案只读验证适用密文;无适用样本记 NOT_TESTED。迁移、轮换、明文回写或真实通知均需独立方案与明确授权,不由恢复批准附带取得。
2026-09-17 原密钥保管与敏感恢复后续规划
本增量的K0本地合同检查与合成验证已于本日另获批准并完成;K1/K2仍仅规划,原受限演练已经结束且不可重跑。目标从“追查密钥何时生成”改为“原密钥是否有受控保管及能否恢复对应敏感字段”;来源UNKNOWN可以继续如实记录,不能用生成新密钥替代原密钥或把格式合法等同于高熵来源已证实。
范围分三段:K0仅本地源码/环境分类合同与合成密文验证;K1另批后只核实际保管可用性;K2再绑定具体新鲜源、制品、隔离目标及受限原密钥注入方案并另批实际恢复。已有环境恢复分类与双角色保管规约复用,不新建密钥平台、不将.env装进普通数据备份。
新增验收(不替代原AC4/AC5):
- K0:本地缺密钥、错误密钥、篡改密文均停止;正确合成密钥成功,输出不含密钥/密钥摘要/密文/明文或原始异常,生产未访问。30项定向测试及7类合成检查通过;只证明本地合同,不证明真实密钥或数据可恢复。
- K1:管理员与公司责任人均有受控取用原密钥的渠道,非仅依赖原主机或单人记忆;记录角色/渠道类别/验证时间/可用状态,不保存值或保管位置细节。
- K2:在另批的隔离范围验证选定备份中实际存在的加密字段,原密钥匹配、适用字段解密检查和清理分列有据;没有适用密文时记NOT_TESTED,不拿合成通过替代。
任何保管、原密钥取用/转移、真实备份读取和恢复均非本次K0授权。无法安全取得原密钥时停止真实验证,报告影响与待批方案,不读取shell历史、不索要聊天明文、不擅自轮换。实际执行方案必须重新独立只读复核;本次主会话检查不计为独立复核。
2026-09-17 本次受限演练实际结果
已获批准的一次R3绑定恢复于01:33Z完成:DB及影子认证只读应用PASS;附件62引用中仅精确已接受历史缺件1、未知不一致0;清理及源/生产/监控后验PASS。整体PARTIAL_KNOWN_MISSING_AND_SENSITIVE_DECRYPTION_NOT_TESTED,RPO7小时2分52秒。原始全量附件标准及完整计时指标未因此豁免,敏感字段解密未验;本次无需再执行,task保留未覆盖范围,不自动归档。详情与三摘要绑定证据见implement最新节。
2026-09-17 单条历史缺件例外(已批准)
本日后续另获固定b1d25d3c源码的ARM64镜像构建批准,仅构建及元数据验证,不部署、不启动应用、不恢复、不读生产密钥。匹配制品已构建不代表R3独立复核或最终恢复源绑定完成,详见design/implement最新节;其他版本/范围不自动授权。
用户批准按design的精确身份/七类零关联条件修订验收、测试并独立复核后再执行一次受限恢复。本增量仅允许将指定历史缺件作为已接受但仍未恢复的事实,逐项报告原始不一致数、已接受数、未知数;其他缺件/大小/摘要/路径异常仍阻断,不能把任意归档件排除。原R2与NO_GO不改,最终最高结论保留历史缺件及解密未验的PARTIAL。生产零写入、资源/网络/清理边界不变。
09-15旧源现已超过24小时,禁止重用旧入口或放宽新鲜度;先完成本地修订和只读选源事实,实际重跑必须重新绑定新鲜源与同来源镜像并经复核。源/平台/风险实质变化时说明差异,未解决之前不生成可执行入口。当前批准不授权任意镜像构建、生产密钥读取或新备份写入。
2026-09-16 配对恢复规划增量(当前优先合同)
关联09-08总任务P1/P2/P3。先读取08-28的新自然备份/异机完整性事实,再冻结单次演练输入;本轮只更新规划,没有恢复授权。优先ARM最新合格正式日归档,不把09-15固定8d历史方案或09-16生产同机手工备份当默认源;若需使用后者,必须另外明确向ARM复制的范围并重新核源副本。未知/超龄/损坏不得静默换源。
恢复覆盖分为DB_RESTORE、STORAGE_REFERENCES、APP_READONLY三个独立结果;下文旧“不启动OA server”仅属于最初数据恢复阶段,本增量允许将匹配应用的一次性启动纳入拟申请范围,但未批准之前不启动。应用镜像必须绑定源build并核平台;生产镜像能归档不代表在ARM可运行,不默认仿真或随意换最新镜像。
应用只读验收的访问身份、字段解密能力、禁后台任务/外联配置必须先可证明安全。临时登录/数据库凭据只用于隔离环境且不得复用生产.env;若恢复数据的密钥不可安全提供或身份条件不满足,则记录APP_BLOCKED或APP_PARTIAL及原因,不用随机替换业务加密密钥、仅/ready成功或DB PASS代替全应用可恢复。密钥来源未知与是否获批安全使用为不同问题,不要求用户把值发给代理。
本task只有三项实际验收与清理/生产无影响证据齐全才可宣布本次配对演练完成;是否符合业务RTO另按预先确认的目标判断,不能仅因记录了耗时就认定满足SLA。历史缺失附件保留原引用,不在恢复演练中代做生产治理或删除。
Goal
在不覆盖、不暂停腾讯云生产 OA 的前提下,使用 ARM 备份机上最新的完整异机批次完成一次数据库与附件的隔离影子恢复,证明“备份存在”进一步达到“最新成对数据备份可恢复”,并记录实测数据恢复 RTO、RPO 和脱敏证据。
Scope
- 在 ARM 上选择并校验最新正式日归档,使用本轮临时副本恢复数据库与附件。
- 验证 migration、固定关键表、附件数量与 DB/附件引用一致性,记录数据恢复 RTO/RPO。
- 复核生产前后
/ready、ARM 监控状态和临时对象清理结果,形成当前 task 内脱敏证据并更新既有事实源摘要。 - 不修改产品运行代码;允许把演练 runner 模板、附件校验器和可复跑合同收敛到
scripts/qa/。生产、正式归档、企业微信和现有监控均保持只读或零变更。
Background
- 腾讯云服务器是真实 OA 生产;ARM 只承担异机备份、外部健康监控和受控恢复演练,不是 OA 生产服务器。
- 2026-08-23 只读复核确认:生产最近 14 天每日异机备份和新鲜度 watchdog 均成功,ARM dead-man 最近成功;企业微信中的“恢复通知”来自公网健康状态恢复,不代表执行过数据恢复。
- 2026-07-27 曾在 ARM 使用当时的正确异机批次完成真实格式影子恢复,但不能替代对当前最新自动备份的可恢复性验证。
- 首次演练时生产产品构建为
7b86ffb,已通过公网/ready和 migration pending=none;当时仓库与来源构建ec682565均有 65 个 Prisma migration 目录,二者之间 migration 目录无变化。该数字是本次现场事实,不再作为跨构建硬编码合同。 - 现有恢复脚本默认只接受带
shadow、drill或restore_test标记的数据库名,并拒绝生产式目标、确认值不一致、非空附件目标和危险归档路径。
Requirements
R1. 恢复点选择与前置门禁
- 只选择 ARM 正式日归档中按 UTC 时间最新的一个完整批次,不触碰 inbox、临时事务目录、旧错误批次或周检查点。
- 批次必须恰含
database.dump、storage.tar.gz、manifest.json三个普通文件;manifest 必须为 schema v1、complete,相对文件名、字节数、SHA-256 和来源构建身份全部一致。 - 批次年龄必须不超过 24 小时。manifest
buildSha必须唯一解析为本仓库已知提交,且该提交是演练开始时公网/ready实测当前构建的祖先或与其相同;未知提交、旁支/后继提交、超龄、损坏或文件集歧义判定NO_GO,磁盘空间不足判定PAUSE。两者都不得自动改选更旧批次掩盖问题。 - 构建相等只表示“当前发布后已经形成同源恢复点”,不再作为数据备份可恢复性的必要条件。若来源是当前构建的祖先,必须单独记录发布后同源恢复点滞后 finding,不能把它误报为归档损坏。
- 执行前后各做一次公网
/ready只读检查,仅用于证明生产未受影响;该结果不得充当影子恢复后的应用启动证据。
R2. ARM 隔离和数据保护
- 演练仅在 ARM 上创建本轮专属、权限
0700的临时工作区、一次性 PostgreSQL 16 容器和空附件目录;不得在开发机下载真实备份。 - PostgreSQL 不发布宿主端口,不加入现有 OA/监控网络,不复用任何现有容器名、数据库名、volume 或目录;影子数据库名必须含
drill标记。 - 先把所选批次复制到临时工作区并重新校验 manifest 与三文件 SHA-256,再对临时副本执行恢复;正式 ARM 归档始终只读,不直接解包或改名。
- 不读取或复用生产
.env、JWT、Webhook、企业微信 Secret、真实数据库口令或业务账号;影子数据库只使用本轮随机临时凭据,凭据不进入聊天、仓库、报告或命令参数证据。 - 含现场路径、命名或构建值的私有渲染 JSON 和渲染后候选不得进入 Git 历史;若位于仓库内,必须置于专用 ignored 目录,合同脚本须在创建候选前机械验证该 ignore 状态,未忽略即失败关闭。
R3. 数据库恢复验证
- 使用现有
scripts/restore-db.sh的RESTORE_SCOPE=shadow和精确数据库名确认门禁,将最新database.dump恢复到一次性 PostgreSQL 16 容器。 pg_restore --list和实际 restore 必须成功。从 manifest 来源提交动态冻结其 Prisma migration 目录集合;恢复后_prisma_migrations中成功且未回滚的 migration 名称必须与该来源集合一致,并且不存在失败、回滚中或来源未知的 migration。不得用硬编码数量替代集合核对。- 同时比较来源提交与当前构建的 migration 目录集合:集合相同则记录“当前 schema 无额外升级步骤”;当前构建新增 migration 时,原始备份恢复仍可继续验证,但“升级到当前 schema”标为
PAUSE/未验证,另行设计仅针对影子库的 migration 演练,不在本轮临时执行。 - 固定核对组织、人员、角色、采购、报销、发票池、付款批次、合同、项目及三类核心附件表的存在性和行数;只记录表名、数量和 PASS/FAIL,不记录业务字段或正文。
- 所有验证 SQL 必须只读并开启错误即停;不执行 migration、seed、DDL、数据修补或业务写入。
R4. 附件恢复与关联验证
- 使用现有
scripts/restore-storage.sh的 shadow 门禁恢复storage.tar.gz到本轮空目录;归档路径、链接类型和目标空目录检查必须通过。 - 归档普通文件数必须与解包后普通文件数一致;对数据库中本地存储型的发票、采购附件、报销附件、付款回单和请假附件引用,验证相对路径安全、目标文件存在,并在已有 SHA-256/大小字段时核对哈希或大小。
- 发现
s3:引用、缺失文件、路径逃逸、哈希/大小不一致或 DB 与附件批次不配对时判定NO_GO;不输出文件名、原始路径、票据内容或附件内容。
R5. 计时、证据和清理
RPO定义为演练开始 UTC 时间减 manifestcreatedAt;必须小于等于 24 小时才通过。本次实测值只用于当前恢复演练,不形成 SLA 承诺。- “数据恢复 RTO”从通过前置门禁后、开始复制批次到临时工作区之前计时,到 DB/附件恢复和全部数据一致性检查通过时结束;不得把历史合成演练耗时或生产
/ready计入本轮 RTO。 - 另行记录“同源恢复点可用滞后”:当前发布合同刷新时间到首个相同构建的 ARM 完整批次到达时间。该指标与数据 RPO、数据恢复 RTO 分开,不形成 SLA;即使恢复未执行,观测到的发布后空窗仍是有效演练发现。
- 证据写入当前 Trellis task,只记录日期、角色、批次脱敏标识、构建短标识、年龄、耗时、数量、状态、finding 类别和清理结果;不保存远端地址、完整目录、凭据、真实账号、业务正文或原始 payload。
- 成功或失败后只清理本轮明确创建的一次性容器、临时工作区和临时凭据;清理后确认无容器、端口、临时目录残留。任何目标身份不明确时停止清理并人工复核,绝不删除正式归档。
Acceptance Criteria
- AC1:ARM 最新正式日批次通过文件集、manifest、字节数和 SHA-256 校验,来源构建是当前构建的祖先或相同,且实测 RPO 不超过 24 小时;是否已形成当前构建同源恢复点单独记录。
- AC2:腾讯云生产在演练前后
/ready均正常,本次操作对生产容器、数据库、附件、配置、timer 和业务数据零写入、零重启、零切换。 - AC3:一次性 PostgreSQL 16 影子库无宿主端口,数据库恢复成功;恢复 migration 集合与 manifest 来源提交一致且无失败/未知项,来源与当前 migration 差异已明确;固定 12 类关键表均可读并形成仅含数量的脱敏摘要。
- AC4:附件安全恢复成功,归档与解包普通文件数一致;所有纳入范围的本地附件引用均安全且存在,适用的哈希/大小核对无不一致。
- AC5:记录本轮数据恢复 RTO、RPO、同源恢复点可用滞后、开始/结束时间、失败点或 finding、Go/Pause/No-Go 结论;即使恢复未开始也保留已观测空窗,不把任何指标表述为完整应用灾备 RTO 或 SLA。
- AC6:演练结束后本轮容器、端口、网络和临时数据全部清理,ARM 正式归档与现有 dead-man/健康监控不受影响。
- AC7:任务校验、Trellis 治理、流程合同、文档审计、敏感扫描和
git diff --check通过;证据不含敏感信息。
Out of Scope
- 不在腾讯云生产执行 restore、停机、重启、数据库 reset、migration、DDL、seed、配置修改、timer 修改或业务写入。
- 不触发新的生产备份,不删除、替换或轮转 ARM 正式归档,不发送企业微信测试消息。
- 不把真实备份下载到开发机,不把 ARM 变成 OA 部署目标或长期运行 OA server。
- 本轮不启动隔离 OA 应用容器、不做登录、报销详情或附件下载页面验证,也不对恢复库执行 Prisma migration;因此只形成“原始数据恢复 RTO”和静态 migration 兼容判断,完整应用恢复、schema 升级和切换 RTO 仍需未来灾难恢复专项验证。
- 不修改备份/恢复产品代码;若现有脚本在真实最新批次上暴露缺陷,先停止并另行回到规划,不现场放宽安全门禁。
Blocking Open Questions
- 本次受限演练已批准并完成,入口已消费,不再申请同范围重跑。完整密钥保管/敏感解密恢复、历史缺件及完整计时覆盖仍按顶部结果保留;未来新增实质恢复范围需另行规划,不复用本次单次授权。
Test Plan
- 校验最新批次 manifest、三文件集合、字节数、SHA-256、构建身份和 24 小时新鲜度。
- 通过现有 shadow 恢复脚本完成 PostgreSQL 16 和附件恢复,验证来源提交的 migration 集合、与当前构建的 migration 差异、固定 12 类表及附件引用聚合。
- 复核无宿主端口、生产前后
/ready、ARM 监控未受影响和本轮临时对象零残留。 - 运行 task validate、Trellis governance、process contract、docs registry、敏感扫描和
git diff --check。