Files
gplan-2/design/dev/architecture/adr-0005-save-contract-and-schema-versioning.md
T

105 lines
5.6 KiB
Markdown
Raw 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.
# ADR-0005: 存档契约与版本化(Save Contract & Schema Versioning)
## Status
Accepted(2026-09-12,solo 模式用户授权代决;轻量契约 ADR——实现归 D3 Alpha,本 ADR 只锁契约使 Foundation 层 TR 覆盖闭合)
## Date
2026-09-12
## Engine Compatibility
| Field | Value |
|-------|-------|
| **Engine** | Godot 4.7.2-stable |
| **Domain** | Core(数据/序列化契约) |
| **Knowledge Risk** | LOW(契约层; FileAccess/JSON 基线稳定) |
| **References Consulted** | `docs/engine-reference/godot/`(四文件);D2 GDD Rule 8 / EC9 / RNG 生命周期 |
| **Post-Cutoff APIs Used** | None |
| **Verification Required** | None(D3 实现期按契约验证) |
## ADR Dependencies
| Field | Value |
|-------|-------|
| **Depends On** | None |
| **Enables** | D3 存档序列化(Alpha)——契约先行,实现期免重议 |
| **Blocks** | None |
| **Ordering Note** | 清零 Foundation 层 TR 覆盖缺口(requirements-traceability.md 的最后两条 pending) |
## Context
### Problem Statement
Technical Setup → Pre-Production 门要求"Foundation 层需求 ADR 覆盖零缺口"。63 条 TR 基线中 Foundation 层尚有两条无 ADR 承载:TR-d2-010(SCHEMA_VERSION 版本化)与 TR-gc-002(RNG 快照存续契约)。两者的契约在 D2 GDD 已定但散落,未 ADR 化——本 ADR 收拢,D3 Alpha 实现时照契约执行。
### Constraints
- MVP 无元进度存档(C4/D3 归 Alpha)——本 ADR 不引入任何 MVP 实现
- RNG 快照语义已被 D2 GDD(RNG 生命周期)与 B1 GDD(回放切点)锁定——本 ADR 只做契约归集,不改语义
### Requirements
- 版本不匹配拒绝读取(高版本拒读,D2 EC9)
- 续玩/复盘可从快照精确恢复随机序列
- 快照切点与在飞流实例的互斥有明确归属
## Decision
**1. 版本化契约**:`SCHEMA_VERSION` 常量归 D2(既定);存档文件携带该版本号;**比较逻辑归 D3**(D2 EC9 既有分工)——存档版本 > 当前 SCHEMA_VERSION → 拒绝读取 + 明确错误信息;低版本存档的迁移策略归 D3 Alpha 设计时定(候选:拒读 / 迁移器——届时另议,非本 ADR 范围)。
**2. RNG 快照契约(从 D2/B1 GDD 收拢为 ADR 登记)**:
- 快照内容 = `master_seed` + 各封闭流 scope 计数器 + 意图序列 + 窗口选择序列
- **切点规则**:快照切出必须发生在 scope 事件边界之外(无在飞 `open_stream` 实例时);运行期 scope 事件边界 = board install(A1 取号 / B4 取号)——B1 编排保证无在飞实例跨界(消费侧遵守义务,B1 GDD 回放切点条款)
- 违反后果:续玩/复盘与实况分叉(D2 AC-15 语义失效)——该前提由 D3 消费侧遵守,B1 侧编排义务已在位
**3. 存档内容归属预告(D3 Alpha 实现的输入清单,非本 ADR 决策)**:冒险结构(C2 域)、关卡进度(C1 域)、HP/库存(B1/B4 关卡域)、钥石/天赋(C4 MetaTable)、RAP 不持久(战斗域清零)。D3 GDD 立项时按此清单展开。
### Architecture Diagram
(不适用——契约 ADR;数据流见 architecture.md §Data Flow 3)
### Key Interfaces
- D3 → D2:读取 `SCHEMA_VERSION`(比较方向:存档版本 ≤ 当前才可读)
- D3 → RngService:只读计数器接口(D2 已暴露)+ `set_master_seed`(仅 C2 调用——D3 只读快照、恢复时经 C2 重放接线)
## Alternatives Considered
### Alternative 1: 不立 ADR,依赖 D2/D3 GDD 散落条款
- **Cons**: gate 的 Foundation 零缺口检查失败;契约散落三处(D2 EC9 / D2 RNG 生命周期 / B1 回放切点),D3 实现时需跨三文档拼装。
- **Rejection Reason**: 收拢成本一次会话内,收益是门检查全绿 + D3 立项输入就绪。
### Alternative 2: 现在就设计存档格式(JSON vs 二进制 vs Resource)
- **Cons**: C4/D3 未设计,过早——MVP 无存档需求牵引。
- **Rejection Reason**: 违背"schema 先行、数值回填"的项目节奏;格式决策留给 D3 GDD。
## Consequences
### Positive
- Foundation 层 TR 覆盖零缺口(门检查全绿)
- D3 立项时的硬输入就绪(版本比较方向、快照内容、切点规则、内容归属清单)
### Negative
- 无(纯收拢,零新约束)
### Risks
- D3 Alpha 实现时偏离切点规则 → 缓解:本 ADR + D2 AC-15 / B1 AC-34 双侧断言承载
## GDD Requirements Addressed
| GDD System | Requirement | How This ADR Addresses It |
|------------|-------------|--------------------------|
| d2-data-config.md | Rule 8 版本化;EC9 高版本拒读;RNG 快照生命周期 | 契约收拢 + 版本比较归属(D3)成文 |
| b1-settlement.md | 回放切点契约(快照语义 = seed + 计数器 + 两类输入序列) | 切点规则 ADR 化(无在飞实例时切出,scope 边界 = board install) |
| game-concept.md | 存档/冒险/关卡术语层级(C4/D3 Alpha 范围) | 存档内容归属预告清单 |
## Performance Implications
- **CPU / Memory / Load Time / Network**: 无(MVP 零实现;Alpha 期存档体积预期 < 1MB 量级)
## Migration Plan
无迁移(MVP 零实现)。D3 GDD 立项(Alpha 期)以本 ADR 为硬输入。
## Validation Criteria
- D3 实现后:同快照恢复 → 随机序列逐位一致(D2 AC-15 / B1 AC-34 形态)
- 版本不匹配路径拒绝读取且错误信息含两侧版本号
- tests/integration/ 收录存档往返测试(D3 落地时)
## Related Decisions
- ADR-0001(回放输入序列的载体)、ADR-0004(集成测试载体)
- docs/architecture/requirements-traceability.md(TR-d2-010 / TR-gc-002 覆盖闭合)