1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2024-present, fjall-rs
// Copyright (c) 2026-present, Structured World Foundation
/// Block / SST disk format version.
///
/// This enum tracks the on-disk layout of Blocks and SST files: block
/// header layout, filter wire format, range-tombstone encoding, ECC
/// trailer geometry. It is the version persisted in the manifest's
/// `format_version` section and gated at `Tree::open`.
///
/// ## Relationship to the manifest layout version
///
/// `FormatVersion` and [`crate::manifest_blocks::MANIFEST_LAYOUT_VERSION_V1`]
/// evolve at **independent cadences**:
///
/// | Concept | Type | Tracks |
/// |---------|------|--------|
/// | `FormatVersion` | This enum (V1..V5) | Block / SST on-disk layout |
/// | `manifest_layout_version` | `u8` in manifest Footer Block | Manifest file structure (footer fields, TOC encoding, head-mirror geometry) |
///
/// A block format bump does NOT force a manifest layout bump and
/// vice versa. The CURRENT pointer's canonical digest binds the
/// manifest layout version (so a manifest-only break is detected
/// at recovery), and the manifest's `format_version` section binds
/// this enum (so a block-format-only break is detected at
/// `Tree::open`).
///
/// ## Amendment policy
///
/// Once a value is **published to crates.io** (any released binary
/// writes that value to disk), **any** subsequent change to the
/// on-disk bytes under that value is a breaking change that MUST
/// bump to a new variant. This applies regardless of whether the
/// change is otherwise additive: a reader running the old code is
/// not free to interpret unknown bytes.
///
/// The amendment window is the **pre-release period**: while a
/// `FormatVersion` is being actively developed and no published
/// binary writes it, the on-disk bytes under that version MAY be
/// amended in place (no enum bump required). The release that
/// crystallises the variant ends this window.
///
/// Same rule applies to `manifest_layout_version` independently:
/// pre-publication amendments are free; post-publication changes
/// require a new layout-version constant.
///
/// **Practical checklist for any PR that touches on-disk bytes:**
///
/// 1. Identify which layer the change touches (Block/SST → this
/// enum; manifest framing → `manifest_layout_version`).
/// 2. If that layer's current value has shipped to crates.io,
/// add a new variant / constant instead of amending in place.
/// 3. The OTHER layer's value stays unless its layer also changed.
/// ## Supported versions
///
/// **V5 is the ONLY supported on-disk format.** The engine neither reads
/// nor migrates pre-V5 layouts: there are no legacy decode paths, no
/// upgrade tooling, and no backward-compat variations anywhere in the
/// codebase. Discriminants 1–4 are reserved history — opening a tree that
/// carries one fails with [`crate::Error::InvalidVersion`] at the manifest
/// gate. The same single-format rule applies to every subsidiary format
/// (blob frames, manifest layout): each has exactly one readable shape,
/// the one the current writer emits.
///
/// The retired discriminants are reserved as NUMBERS, not as names: this enum
/// carries no `V1`–`V4` variants. Keeping them as deprecated stubs would add
/// four public names that no file can ever decode into and that exist only to
/// keep a downstream exhaustive `match` compiling — a compatibility shim for a
/// layout the engine deliberately cannot read. A caller matching on this enum
/// should be matching what the writer emits, and that is one shape.
///
/// Adopting a pre-V5 database is a CONVERSION, not a compatibility mode: the
/// offline migration tool (#580) owns every legacy decoder and rewrites the
/// tree into V5. Recovery, salvage, patrol scrub and verify stay V5-only by
/// construction, so no legacy shape is ever reachable from the live engine.