# 生产密钥恢复与环境文件外置:实施计划 ## 0. 边界 - [x] 本任务按 Phase 1、Phase 2 分开批准、提交和验收;Phase 1 批准不授权生产访问或迁移。 - [x] 不读取、打印、哈希或提交生产 Secret;只处理键名、类别、布尔状态和计数。 - [x] `FIELD_ENCRYPTION_KEY` 版本化/keyring/重加密登记为后续任务,不在本轮顺手实现。 ## 1. Phase 1:恢复卡与分类合同 - [x] 从 `.env.example` 自动提取当前键集合,逐项归入 5 个固定类别;对 `FIELD_ENCRYPTION_KEY`、数据库口令、JWT/pepper、外部平台凭据做人工复核。 - [x] 新增无值的 JSON 分类合同,并扩展 `validate-env-contract.js`:全集相等、恰好一次、类别固定、键名格式正确、内容不含疑似赋值/Secret 正文。 - [x] 更新 `deploy/trialrun/runbook.md` 顶部恢复卡,写清 5 类影响、责任人与恢复后验证;数据库为隔离停机重置,不写成明文找回。 - [x] 更新 `.trellis/spec/hyb-oa/deployment-trialrun.md`,固化环境恢复分类、双人托管、`preserve_original` 最高风险和 keyring 延期边界。 - [x] 增加聚焦单元测试:正常 164-key 合同、漏键、重复键、多余键、未知类别、非法键名/疑似值、`FIELD_ENCRYPTION_KEY` 与 `POSTGRES_PASSWORD` 错误分类。 - [x] 运行环境合同、聚焦测试、server 全量测试、JS 语法、task/governance/process/docs/sensitive/diff 门禁。 - [x] Phase 1 单独提交;证据明确“未访问或修改生产”,不把文档完成冒充密钥已封存。 ## 5. Phase 1 验证证据(2026-08-01) - 环境合同:PASS,`.env.example` 164 个键,恢复分类 164 个键,恰好覆盖一次。 - Prisma 与语法:`prisma validate`、validator/test `node --check` 均 PASS。 - 服务端全量:173 个测试文件、1144 个测试 PASS;其中恢复分类聚焦用例 8/8 PASS,既有部署安全用例 7/7 PASS。 - 治理门禁:task validate、Trellis governance、process contract、sensitive-content scan、`git diff --check` 均 PASS;docs registry audit 为 0 error、1 个既有汇总 warning(22 个未登记 docs 文件)。 - 人工复核:五类语义、双人托管、PostgreSQL 隔离停机重置与 `FIELD_ENCRYPTION_KEY` 原值保留边界一致;清单仅含键名和类别。 - 操作边界:本阶段未连接、读取或修改生产;未创建密码库条目,未迁移 env,未修改 Compose/systemd,未重启服务,也未删除任何生产文件。 ## 2. Phase 2:代码与脚本准备(仍不自动迁移) - [ ] Compose 四个 service 使用显式 `${REMOTE_ENV_FILE}`;部署、备份、WARCH3、巡检和 QA 脚本移除同步树内生产默认。 - [ ] `deploy.sh`、preflight 和环境合同拒绝 env 与同步树重叠,校验 root owner、`0600`、普通非 symlink 文件;保留 rsync exclude 仅作纵深防御。 - [ ] 更新 runbook、checklist、管理员手册和 OPS7 中所有生产路径示例;本地示例明确使用非生产测试 env。 - [ ] 扩展合成回归,覆盖旧路径拒绝、新路径通过、Compose v1/v2 config、4 个 unit 参数一致、rsync 前失败和旧副本否定检查。 - [ ] 运行 Docker Compose config、部署合同、备份合同、全量测试与 Trellis 门禁;单独提交但不连接生产。 ## 3. Phase 2:生产迁移(另行明确批准) - [ ] 只读冻结活动 project、构建、当前 env、PGDATA/storage、4 个 service/timer;确认系统管理员与公司负责人均可取用 `preserve_original` 封存项,只记录完成状态。 - [ ] root 原子复制到同步树外目标,校验键集合、owner/mode/非 symlink;不输出值或文件内容。 - [ ] 重装 4 个 units,运行 Compose config、新 init 配置预检并切换 server;未获批准不启用 worker/minio profile。 - [ ] 验证 migration status、`/ready`、external/runtime smoke、普通登录、企微入口、automatic backup daily/watchdog、4 个 timer 和构建身份。 - [ ] 验收全部通过后按精确旧路径删除旧副本;再次证明旧路径不存在,活动容器和 units 只引用新路径。 - [ ] 任一验证失败时,在旧副本删除前回滚 unit/Compose 引用;记录失败尝试,不美化为一次成功。 ## 4. 后续独立任务 - [ ] 建立 `FIELD_ENCRYPTION_KEY` 版本化与安全轮换任务:带 key id 的新密文格式、keyring、惰性/批量重加密、全字段覆盖、审计与旧键删除门禁。 - [ ] 约 18 个孤儿 E2E 继续作为独立测试治理任务,不与密钥恢复混做。