Files
Jyotisha/docs/tasks/TASK-beta-safety-net-fix-20261015.md
T

3.2 KiB
Raw Blame History

TASK · 内测安全网修复单(issue #75,产品选 A)

  • 日期:2026-10-15
  • 原任务书:docs/tasks/TASK-beta-safety-net-20261014.md
  • 被验 SHA:53d8df257ddef8918034acef36df0b4b7daade2c(codex/beta-safety-net-20261014)
  • 执行方:Grok,同一分支续做(先 merge 最新 origin/staging,不改写已推历史)
  • 决策记录:产品负责人 2026-10-15 在 issue #75 选 A——授权新增定时工作流 .gitea/workflows/backup-production-daily.yml(每天北京时间 04:00 自动连生产做加密备份),但每日备份不得改动「当前恢复点」记录。恢复点仍只由产品负责人手动点「Create production recovery」创建。仍不改已有四个生产工作流的语义;仍不点任何生产按钮。

1. 问题

deploy/run-production-recovery.sh 无论由谁调用,结尾都会无条件写 $DEPLOY_PATH/.state/recovery-baseline.env(RECOVERY_REFERENCE、RECOVERY_SHA256、RECOVERY_FORMAT=2 等)。发布、迁移、回退都读这份文件当「当前恢复点」。每日备份复用这个脚本,于是每天 04:00 都会把它换成当天的自动备份——产品负责人上线前手动建的恢复点,隔一夜就被替换。

2. 修法要求

  1. 每日备份不写 recovery-baseline.env:RECOVERY_BASENAME_PREFIX=production-daily 时(或新增一个明确的模式参数,二选一,写进 PROGRESS),脚本仍完整执行「导出 → 加密 → 还原核对(含 #74 的表权限、列权限、属主三项比对)→ 写 *-restore-verify.json」,但跳过写 recovery-baseline.env,并在输出里打印 baseline_updated=false。手动恢复点路径行为不变,打印 baseline_updated=true。
  2. 每日备份的核对结果单独记录:在 $DEPLOY_PATH/.state/ 下另写一个 daily-backup-latest.env(只含文件名、sha256、校验时间、格式版本,不含数据、不含密钥),供告警 / 运维查看;发布、迁移、回退工作流不得读取它。
  3. 合同测试(tests/test_beta_safety_net.py 或 frontend/tests/staging-backend-workflows.test.ts):
    • 每日模式下 recovery-baseline.env 不被创建或修改(用临时目录 + 假 docker 跑脚本,断言文件 mtime / 内容不变);
    • 手动模式下仍会写,且含 RECOVERY_FORMAT=2;
    • 三个读取恢复点的生产工作流 / 脚本不引用 daily-backup-latest.env。
  4. runbook 与 deploy/README.md:写清「每日备份只做存档与核对,不是发布用的恢复点;上线前仍要手动点 Create production recovery」。
  5. 清理脚本只删 production-daily-* 前缀的文件(原任务书已要求)——再确认不会删 production-pre-migration-* 手动恢复点。

3. 验收

  • Claude 会对本单做完整验收(上一轮在发现定时工作流后就停下等拍板,其余部分尚未逐行验):逐行看新工作流与各脚本、跑 tests/test_beta_safety_net.py、Python 全量、前端全量、docker compose config。
  • 交回前本机跑:python -m pytest tests/test_beta_safety_net.py tests/test_repo_privacy_markers.py -q、npx tsx --test tests/runtime-sources-no-test-imports.test.ts tests/staging-backend-workflows.test.ts。

4. 让步顺序

无。