记录(08-23-isolated-backup-restore-drill): 固化Attempt 4执行前门禁

这个提交包含在:
2026-08-25 13:20:45 +08:00
父节点 5ec7db13b2
当前提交 f216387837
共修改 3 个文件,包含 46 行新增和 1 行删除
@@ -1374,6 +1374,10 @@ validate_copied_batch(private/batch, source_metadata)
start, dump list, target confirmation, restore apply and storage restore each start, dump list, target confirmation, restore apply and storage restore each
append a fixed stage marker and their private output, so a later failure does append a fixed stage marker and their private output, so a later failure does
not erase earlier-stage diagnostics before final teardown. not erase earlier-stage diagnostics before final teardown.
- A source migration fingerprint enumerates only direct directory objects under
`server/prisma/migrations` at the source commit, validates every directory
name, sorts the names and hashes that exact non-empty set. Files such as
`migration_lock.toml` are not migrations and must never enter the fingerprint.
### 4. Validation & Error Matrix ### 4. Validation & Error Matrix
@@ -1398,6 +1402,9 @@ validate_copied_batch(private/batch, source_metadata)
remains valid for a locally protected render. remains valid for a locally protected render.
- Any raw-log truncating redirect after initialization, or a missing fixed stage - Any raw-log truncating redirect after initialization, or a missing fixed stage
marker -> tracked contract failure; do not publish a candidate. marker -> tracked contract failure; do not publish a candidate.
- A source-tree listing that mixes migration directories with ordinary files ->
reject the generator result or filter by Git directory object type before
hashing; never reinterpret the extra file as schema drift.
- Candidate differs from the deterministic render or has not passed the tracked - Candidate differs from the deterministic render or has not passed the tracked
contract -> do not upload or install it. contract -> do not upload or install it.
@@ -1436,6 +1443,9 @@ validate_copied_batch(private/batch, source_metadata)
- Statically require exactly one raw-log truncation at initialization and fixed - Statically require exactly one raw-log truncation at initialization and fixed
append markers for container start, dump list, target confirmation, restore append markers for container start, dump list, target confirmation, restore
apply and storage restore. apply and storage restore.
- Build a source-tree fixture containing migration directories plus
`migration_lock.toml`; assert the fingerprint includes only sorted directory
names and still matches the restored successful migration set.
- Directly test source/copy identity, dynamic migration fingerprint and the - Directly test source/copy identity, dynamic migration fingerprint and the
tracked attachment validator. Run `check-sensitive-content.mjs` explicitly on tracked attachment validator. Run `check-sensitive-content.mjs` explicitly on
all three tracked runner assets and require zero findings. all three tracked runner assets and require zero findings.
@@ -106,7 +106,8 @@
- [x] `.gitignore` 增加 `/.restore-drill-private/` 专用目录;合同分别证明仓库内未忽略的私有 JSON、未忽略的现场候选均在创建输出前失败,ignored 输入/输出正例通过。 - [x] `.gitignore` 增加 `/.restore-drill-private/` 专用目录;合同分别证明仓库内未忽略的私有 JSON、未忽略的现场候选均在创建输出前失败,ignored 输入/输出正例通过。
- [x] 私有原始日志保留唯一初始化截断,五个固定阶段均以标记分隔并追加写;静态合同拒绝后续阶段再次截断。 - [x] 私有原始日志保留唯一初始化截断,五个固定阶段均以标记分隔并追加写;静态合同拒绝后续阶段再次截断。
- [x] 完整复跑 runner 合同、既有隔离备份/恢复演练和自动异机备份 74 项;task、Trellis、process、默认/定向敏感扫描及空白门禁通过,测试容器和本地私有路径残留均为 `0`。 - [x] 完整复跑 runner 合同、既有隔离备份/恢复演练和自动异机备份 74 项;task、Trellis、process、默认/定向敏感扫描及空白门禁通过,测试容器和本地私有路径残留均为 `0`。
- [ ] Attempt 4 候选尚未渲染或上传;实际恢复前须再次选择最新批次并取得明确批准。 - [x] Attempt 4 最新批次只读探针重新执行并通过;候选已由提交 `5ec7db1` 的跟踪模板确定性渲染,完整合同、依赖钉住和 SHA-256 复核通过。
- [ ] Attempt 4 候选尚未上传或安装;实际恢复须在本次探针和候选证据审查后另行取得明确批准。
## 验证命令类别 ## 验证命令类别
@@ -291,3 +291,37 @@ Attempt 4 的 runner 产生过程已从个人 workspace 人工产物改为“跟
- 本轮新增门禁回归全部 `PASS`;完成完整质量门禁并形成可追溯 Git 提交前,仍不得准备或上传 Attempt 4 候选。 - 本轮新增门禁回归全部 `PASS`;完成完整质量门禁并形成可追溯 Git 提交前,仍不得准备或上传 Attempt 4 候选。
完整本地门禁随后通过:runner 合同全部 `PASS`,既有隔离备份/恢复合成演练 `PASS`,自动异机备份合同 `74/74 PASS`;task validate、Trellis governance、process baseline、默认敏感扫描和三个新增文件定向敏感扫描均 `PASS`。文档审计错误 `0`,仅保留既有未登记文件 warning;`shellcheck` 在本机不可用,已以 Bash 语法、真实双路径集成回归和仓库合同覆盖。测试容器、本地私有渲染目录及候选残留均为 `0`。 完整本地门禁随后通过:runner 合同全部 `PASS`,既有隔离备份/恢复合成演练 `PASS`,自动异机备份合同 `74/74 PASS`;task validate、Trellis governance、process baseline、默认敏感扫描和三个新增文件定向敏感扫描均 `PASS`。文档审计错误 `0`,仅保留既有未登记文件 warning;`shellcheck` 在本机不可用,已以 Bash 语法、真实双路径集成回归和仓库合同覆盖。测试容器、本地私有渲染目录及候选残留均为 `0`。
## Attempt 4 环境差异预先裁决规则
本节在 Attempt 4 新批次探针和实际恢复之前追加,不能按执行结果事后改写。
- Attempt 2 的源/副本身份重绑和 Attempt 3 的三阶段诊断已经由提交 `5ec7db1` 下的可复跑合同机械把关;合同失败时不得生成或上传候选。
- 若同一提交的合同、候选 SHA-256 和 ARM 安装前摘要均通过,但 Attempt 4 再次在恢复完成前暴露演练器侧失败,则默认 finding 升级为“本地合同环境与 ARM 实际执行环境存在系统性差异”,不再直接归为又一个孤立 runner 缺陷。
- 后续调查必须先形成脱敏环境差异矩阵,至少比较 Docker/Podman 实现与版本、PostgreSQL 16 镜像摘要和工具版本、shell/coreutils/openssl/python 行为、文件系统与权限/SELinux/AppArmor、可用 PATH、恢复脚本及依赖摘要、网络模式和资源约束。未取得差异证据前,不继续逐点放宽或修补 runner。
- 该规则不把任何失败预判为 ARM 环境问题,也不改变备份内容判定。若阶段诊断明确证明 dump、数据库对象、migration 或附件内容不满足既有合同,仍按对应数据恢复 finding 如实分类。
## 2026-08-25 Attempt 4 执行前最终探针与候选
本节仅追加最新批次只读探针、候选本地渲染与合同结果;未上传或安装恢复候选,未执行 Attempt 4 实际恢复,未写腾讯云生产或 ARM 正式归档。
| 检查项 | 结果 |
| --- | --- |
| ARM 最新正式批次探针 | `PASS`;动态重选后仍为同一最新批次 |
| 最新批次构建短标识 | `7b86ffb3` |
| 来源与当前生产构建关系 | `SAME` |
| 批次年龄 | `38572` 秒,约 10 小时 43 分,`within_24h=yes` |
| run id 与目录配对 | `PASS` |
| DB/附件大小与 SHA-256 | `PASS` |
| source image digest | 存在 |
| manifest 脱敏摘要前缀 | `ee1f97a5b42d` |
| 探针临时 root 入口/sudoers 残留 | `0/0` |
| 普通用户探针暂存 | 再次通过 SHA 清单后逐一删除,残留 `0` |
| ARM dead-man/健康 timer | `active/active` |
| 来源/当前 migration 目录 | `65/65`,差异条目 `0` |
候选由提交 `5ec7db1` 的 `scripts/qa/offhost-shadow-restore-runner.template.sh` 和 ignored 私有 JSON 确定性渲染。私有 JSON 权限为 `0600`、精确 20 个字段,runner 权限为 `0700`,输入与输出均命中仓库根锚定 ignore。两次独立渲染的字节和 SHA-256 完全一致;候选 SHA-256 为 `81f4eca2cf173196e1a57b781d28629412de7b7fe1a09b001b02d2025950391c`,合同报告值与本地 `sha256sum` 重算一致。
完整 runner 合同再次全部 `PASS`:源/副本身份、三条身份负例、dynamic migration、附件安全、五阶段追加日志、失败先诊断后清理、真实 `restore-db.sh` Docker stdin/host-file 双路径、退出码和敏感输出边界均通过。私有候选包共 6 个文件(runner、附件校验器、两份现有恢复脚本、sudoers、SHA 清单),包内 SHA 清单复核 `PASS`;runner 钉住的三份依赖摘要全部匹配,sudoers 固定命令与 runner 自身路径一致,`scripts/restore-db.sh` 相对生产构建仍无字节漂移,本地测试容器残留 `0`。
准备过程有一次安全失败:首次来源 migration 枚举误把 `migration_lock.toml` 当作 migration 名称,现场显示 `66/65`。该错误发生在候选渲染前,没有产生候选;随后改为只读取来源提交 `server/prisma/migrations` 树下的目录对象,并与当前工作树目录集合独立比较,结果为 `65/65`、差异 `0` 后才生成私有配置。Attempt 4 若获批准,安装前仍须在 ARM 复核上述候选包 SHA 清单;批次年龄和最新批次身份也须以实际执行开始时为准,超过 24 小时或最新批次变化时重新探针,不沿用本节结论。