Persistence schema policy and review
持久化 schema 策略与审阅
Structural fingerprints identify changed persistence types, but a fingerprint alone cannot explain a shared change or distinguish a declared reader promise from an assumption about runtime behavior. Names derived from union positions and traversal paths also change when unrelated siblings are added, obscuring the fields a reviewer needs to inspect.
English
Problem
Structural fingerprints identify changed persistence types, but a fingerprint alone cannot explain a shared change or distinguish a declared reader promise from an assumption about runtime behavior. Names derived from union positions and traversal paths also change when unrelated siblings are added, obscuring the fields a reviewer needs to inspect.
Decision
Inventory format 2 records supported compatibility metadata with the affected property. The metadata names its binding, policy version, literal discriminator, unknown-kind preservation promise, and qualified attribution kinds. Policy-bearing graphs use a separate fingerprint domain; graphs without a bound policy retain format-1 normalization and fingerprints. Inventory versions describe schema tooling, independently of Session format versions.
The extractor accepts explicit source bindings only at the core-owned source declaration and requires a literal user or developer role at each use. Producer annotations qualify complete wire-kind groups. The classifier permits a qualified new attribution kind only when both saved schemas carry matching promises. Existing kinds remain subject to structural comparison; removals, retroactive qualification, reserved identities, and unrelated breaking changes retain strict classification. Runtime owners establish and test the promised preservation behavior before activating a binding.
An optional property with no JSON value is normally omitted from the extracted graph. @persistenceReserved explicitly retains such a property as optional never when a reader forbids its name. A later JSON-valued definition then changes an existing type instead of appearing as an additive optional field. The marker accepts only one argument-free annotation on an optional never or undefined property and rejects a mapped use that makes the property required or gives it a JSON value.
Current inventories retain authored names and source locations as descriptive metadata. Structural digests identify types and provide catalog anchors. Catalogs group source alternatives by literal kind and retain every form alternative, required field, index signature, and link to its complete definition. Bounded array labels describe their elements instead of inheriting the first event that reached the array. Historical references retain their frozen rendering.
The read-only persistence-review command accepts explicit before and after inventories. It matches unchanged schemas by digest and changed alternatives only when literal discriminators identify them uniquely. Ambiguous alternatives remain separate additions and removals. Shared structural evidence lists every affected root, while a separate section preserves the authoritative classifier diagnostics. The history mechanism continues to own acknowledgement and version requirements.
Alternatives considered
Ignore all source changes. A source can carry replay or validation meaning. Explicit, fingerprinted opt-ins constrain the supported exception and leave other changes visible.
Use traversal paths as type identities. Union positions and first-owner paths describe one walk through a graph. Unrelated insertions and shared references can change them without changing the persisted type.
Infer renames from similar fields. Several alternatives can have the same discriminator or similar structure. Keeping ambiguous additions and removals avoids presenting an unsupported correspondence as fact.
Replace compatibility checks with a readable diff. Review explanations group evidence for a human reader. They cannot relax the classifier or replace the in-tree acknowledgement history.
Retain every optional-never property. Unmarked optional-never properties already normalize away in recorded schemas. Changing that rule would alter unrelated fingerprints and historical normalization; explicit reservations retain only the reader-owned prohibition.
Consequences
Declared compatibility promises participate in fingerprints and remain available when comparing historical snapshots. The tooling does not infer or enforce runtime preservation; the owner of an activated binding supplies that behavior. Ordinary comments, labels, and source locations remain outside structural identity.
Complete nested schema graphs remain stored in each inventory. Stable labels and grouped review output reduce presentation noise without changing that storage encoding or rewriting frozen historical records. The cookbook describes the review command and acknowledgement workflow.
中文
问题
结构指纹能标识变化的持久化类型,但单凭指纹无法解释共享变更,也无法区分已声明的读取承诺与对运行时行为的假设。由联合类型位置和遍历路径生成的名称还会因无关分支新增而变化,遮蔽审阅者需要检查的字段。
决策
Inventory format 2 在受影响属性上记录受支持的兼容性元数据。元数据包含绑定、策略版本、字面量判别字段、未知 kind 保留承诺和符合条件的归属 kind。带策略的图使用独立指纹域;没有绑定策略的图保留 format-1 规范化和指纹。Inventory 版本描述 schema 工具,独立于 Session 格式版本。
提取器仅接受核心拥有的 source 声明上的显式绑定,并要求每个使用位置具有 user 或 developer 字面量角色。生产者标记对完整 wire-kind 分组赋予资格。仅当双方保存的 schema 携带匹配承诺时,分类器才允许新增符合条件的归属 kind。已有 kind 仍须进行结构比较;删除、追认资格、保留标识和无关破坏性变更继续采用严格分类。运行时所有者在激活绑定前实现并验证承诺的保留行为。
没有 JSON 值的可选属性通常从提取图中省略。当读取器禁止某个属性名时,@persistenceReserved 将该属性显式保留为可选 never。后续允许 JSON 值的定义因此属于已有类型变更,而非新增可选字段。标记仅接受可选 never 或 undefined 属性上的单个无参数注解,并拒绝将属性变为必选或允许 JSON 值的映射类型使用。
当前 inventory 将人工声明名称和源码位置保留为描述性元数据。结构摘要标识类型并提供目录锚点。目录按字面量 kind 对消息源分支分组,并保留每个 form 分支、必需字段、索引签名及指向完整定义的链接。有界数组标签描述元素,不继承最先到达该数组的事件名称。历史参考保留冻结的渲染方式。
只读 persistence-review 命令接受显式的变更前后 inventory。它按摘要匹配未变 schema,仅当字面量判别字段唯一标识分支时才匹配变化分支。有歧义的分支保留为独立新增与删除。共享结构证据列出每个受影响根,独立章节保留权威分类器诊断。历史机制继续负责确认和版本要求。
考虑过的替代方案
忽略所有 source 变更。 消息源可能承载回放或校验语义。显式且纳入指纹的选择加入约束受支持的例外,并使其他变更保持可见。
将遍历路径用作类型身份。 联合类型位置和首个引用者路径描述的是一次图遍历。无关插入和共享引用可能改变它们,而持久化类型并未改变。
从相似字段推断重命名。 多个分支可能具有相同判别值或相似结构。保留有歧义的新增与删除,避免将缺乏依据的对应关系呈现为事实。
用可读 diff 取代兼容性检查。 审阅说明为读者归并证据,不能放宽分类器,也不能取代目录内的确认历史。
保留每个 optional-never 属性。 未标记的 optional-never 属性在已记录 schema 中已经被规范化省略。改变该规则会影响无关指纹和历史规范化;显式保留仅记录读取器拥有的禁止规则。
影响
声明的兼容性承诺参与指纹,并在比较历史快照时保持可用。工具不会推断或强制运行时保留行为;激活绑定的所有者提供该行为。普通注释、标签和源码位置仍处于结构身份之外。
每份 inventory 继续存储完整嵌套 schema 图。稳定标签和分组审阅输出减少展示噪音,不改变存储编码,也不重写冻结历史记录。实操手册介绍审阅命令和确认流程。