Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LutgzyJqNhPpZy1nFsJtN3
3.2 KiB
3.2 KiB
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. 修法要求
- 每日备份不写
recovery-baseline.env:RECOVERY_BASENAME_PREFIX=production-daily时(或新增一个明确的模式参数,二选一,写进 PROGRESS),脚本仍完整执行「导出 → 加密 → 还原核对(含 #74 的表权限、列权限、属主三项比对)→ 写*-restore-verify.json」,但跳过写recovery-baseline.env,并在输出里打印baseline_updated=false。手动恢复点路径行为不变,打印baseline_updated=true。 - 每日备份的核对结果单独记录:在
$DEPLOY_PATH/.state/下另写一个daily-backup-latest.env(只含文件名、sha256、校验时间、格式版本,不含数据、不含密钥),供告警 / 运维查看;发布、迁移、回退工作流不得读取它。 - 合同测试(
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。
- 每日模式下
- runbook 与
deploy/README.md:写清「每日备份只做存档与核对,不是发布用的恢复点;上线前仍要手动点 Create production recovery」。 - 清理脚本只删
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. 让步顺序
无。