Files
weichenandCursor 03c306af68 Record the U7 release-gate specs
Why: Second-instance writes stay closed until an independent replay or an admitted CI gate, plus a second host. Those remaining steps needed a durable spec.
Evidence: Task-card evidence rows read the merged PRs, tree equality, CI runs 2783/2810/2816, and Dev main branch protection. Source SELF. Drills were not run.
Impact: Docs and the task card only. Checklist grades stay SELF or not started. The collaboration proposal body stays r2.3.
Refs: docs/release-multi-instance.md
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-13 03:06:05 +00:00

102 lines
4.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# U7 独立重放规格(未执行)
状态:规格。本文件不记录一次已经完成的重放,也不改变
[放行检查单](release-multi-instance.md) 的证据等级。第二实例写流量保持关闭。
2026-10-12 已决定不做容量重放。本规格只覆盖 C5、C4 和 A6,以及对象存储回落。
## 固定对象
从干净检出开始,物化子模块后再跑命令。默认对象是 Dev
`3fb8210f6495a78e70a67af3661bdfe9c00fb9de`,其 gitlink 为:
| 组件 | SHA |
|---|---|
| Backend | `dc736e339d01c59e658abc63c81909059bd6ea02` |
| Documents | `05c13a42b14d70f878cc8a51c543e018a7f7a663` |
合入提交与对应 PR head 在本地 `git rev-parse ^{tree}` 上同树。核验输出在任务卡
`.task/feature-u7-release-roadmap.md` 的证据表,来源 SELF。若重放日 main 已前进,
重放者改用新的完整 SHA,并重新读出 backend 与 documents 的 gitlink,写进重放记录。
## 重放者
重放者是另一个人,或另一台由该人操作的机器。先跑完命令并写出结论,再打开作者收据。
作者保全目录 `u7-k4-retest-preserved-20261013` 与其中的 `task-finish.txt` 属于作者证据。
同一账号下另开一个 agent 会话、或切换角色,不能记成 REPLAY。
`policy/platform-admission.md` 已写明不能把切换 Agent 角色当独立账号。
重放者身份未指定前,本规格不启动。
## 环境
- 只使用名称前缀 `u7drill` 或 `u7bk` 的实例,端口落在 18980–18999。
- 启动前确认环境里没有 `BLOBSTORE_S3_ENDPOINT`。演练脚本本身不设置该变量。
应用把 `NewS3FromEnv` 返回的空 `*S3` 放进 `blobstore.Store` 接口,
`blobstore.IsNil` 把它当成未配置,工件写入 `--artifacts` 目录。
- 已构造的对象存储由 `TestFinishOpenKeepsConfiguredBlobStore` 覆盖,重放时一并跑该测试。
本次不要求另起一台对象存储。
- `tests/ops/lib.sh` 的资源门禁要求数据目录所在盘可用空间至少 100GiB,且 1 分钟负载不超过 16。
不满足时脚本会停,不能改门禁来换一次通过。
## 最小重放集
按这个顺序执行。每条用 `CMD="<命令>" make evidence` 写入重放者自己的任务卡。
工具写入的来源标签仍是 SELF;审阅记录里另行声明 REPLAY,并写明重放者、主机、命令和对象 SHA。
1. `tests/ops/self_check.sh`
2. `tests/ops/run_backup_drill.sh`
3. `tests/ops/run_fault_drill.sh --fault all`
4. 用隔离的 PostgreSQL 跑 `make test-multi-instance`(见
`tests/integration/multi-instance/README.md`)。这套库使用文档中的示例端口时,
不要占用演练的 18980–18999。
5. 在 `modules/backend` 执行:
```bash
go test -count=1 -timeout 15m ./internal/blobstore/ ./internal/store/ \
-run 'TestIsNil|TestNewS3FromEnvFallback|TestFinishOpenTypedNilS3UsesLocalArtifacts|TestFinishOpenKeepsConfiguredBlobStore|TestOpenPostgresTypedNilS3UsesLocalArtifacts'
```
`TestOpenPostgresTypedNilS3UsesLocalArtifacts` 需要真实 PostgreSQL。没有 DSN 时该项记
NOT_RUN,其余四项仍要跑。
## 判据
C5 以 `tests/ops/run_backup_drill.sh` 写出的 `verdict.json` 为准:
| 项 | 通过条件 |
|---|---|
| K1 | 归档成功且 `failed_count` 为 0,基础备份与逻辑备份清单校验通过 |
| K2 | RPO 在 0 到 300 秒之间 |
| K3 | 恢复后登录、项目、会话均为 200,且 RTO 不超过 3600 秒 |
| K4 | 工件 `checked > 0`、`missing = 0`、`mismatch = 0`,跨用户访问项目和工件均为拒绝 |
| K5 | `dup_seq = 0`、`seq_gap_convs = 0`,恢复后的行数落在备份点与故障点之间 |
| K6 | 逻辑恢复的行数与备份点一致 |
| K7 | 备份文件权限收紧,结果目录无凭据泄漏 |
C4 以故障脚本的 F1–F5 与 Redis 轨 G1–G3 为准。G4 降级不可见、G5 启动时 Redis 不通则拒绝,
沿用检查单里的「发现」,不把它们改成产品失败。
A6 以 `make test-multi-instance` 退出码 0 为准。
K4 还要看应用日志里没有 `blobstore.(*S3).Put` 的空指针 panic,并且工件文件出现在该次
`--artifacts` 目录。脚本只在拿不到工件 id 时才写 `finding-upload.txt`;那个文件里的
panic 句子是脚本自带的说明,重放时以应用日志和 `artifacts-verify.json` 为准。
与 2026-10-13 SELF 目录 `backup-20261013-013354` 对照时,比较的是上述判据。
RPO、RTO 的秒数可以不同。判据不一致则阻塞,并按失实登记。
## 重放记录模板
重放完成后把记录放到 Documents 的 `docs/records/`,并回写检查单的 C4、C5、A6 证据等级。
那一步另需授权。记录至少包含:
- 重放者与主机(人,或人操作的另一台机器)
- 开始前读取的 Dev、Backend、Documents 完整 SHA
- 每条命令、退出码、结果目录名
- `verdict.json` 里的 K1–K7、`rpo_s`、`rto_s`
- C4 的 F1–F5 与 G1–G5
- A6 退出码
- 五项单测的通过或 NOT_RUN
- 来源声明:审阅记录为 REPLAY;`make evidence` 行仍为 SELF