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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
//! Internal schema versioning for the `__manifest` Lance dataset.
//!
//! ## Why this exists
//!
//! The on-disk shape of `__manifest` evolves alongside the engine. This module
//! is the *single* place where on-disk shape is reconciled with what the binary
//! expects:
//!
//! - One constant `INTERNAL_MANIFEST_SCHEMA_VERSION` declares the shape this
//! binary writes.
//! - One stamp `omnigraph:internal_schema_version` in the manifest dataset's
//! schema-level metadata records the on-disk shape.
//! - One guard `refuse_if_stamp_unsupported` rejects any graph this binary
//! cannot serve — in either direction — with a clear, actionable error.
//!
//! ## Single-version contract (strand + export/import)
//!
//! This binary reads exactly ONE internal-schema version (`MIN_SUPPORTED ==
//! CURRENT`). There is no in-place migration: a graph stamped below CURRENT is
//! refused on open with a "rebuild via `omnigraph export` + `init`/`load`"
//! message, not silently upgraded. This is the deliberate pre-release contract —
//! storage-format changes are a cutover, not a rolling in-place migration (see
//! `docs/user/operations/upgrade.md` and the versioning policy in `docs/dev`).
//! `stamp_current_version` stamps fresh graphs at CURRENT, so newly initialized
//! graphs always pass.
//!
//! ## If an in-place migration is ever needed
//!
//! The stamp + `refuse_if_stamp_unsupported` are the seam a future migration
//! would plug into: re-introduce a dispatcher that walks the stamp forward and
//! lower `MIN_SUPPORTED` below CURRENT for exactly the versions it can upgrade.
//! Until a concrete graph demands it, that machinery is unearned complexity and
//! is deliberately absent. A future converter is best shaped as a standalone
//! one-shot tool, not a framework baked into the open path.
//!
//! ## Forward-version protection
//!
//! A stamp *higher* than this binary's version triggers a clear "upgrade
//! omnigraph first" error. An old binary cannot clobber a newer schema by
//! silently treating "unknown stamp" as "missing stamp".
use Dataset;
use crate;
/// Current internal schema version this binary expects to find on disk.
///
/// History:
/// - v1 — implicit (pre-stamp). `__manifest.object_id` carried no
/// `lance-schema:unenforced-primary-key` annotation.
/// - v2 — `__manifest.object_id` carries the unenforced-PK annotation,
/// engaging Lance's bloom-filter conflict resolver at commit time.
/// - v3 — one-time sweep of legacy `__run__<id>` staging branches left on the
/// `__manifest` dataset by the pre-v0.4.0 Run state machine.
/// - v4 — RFC-013 Phase 7 folds graph lineage into `__manifest` as
/// `graph_commit`/`graph_head` rows written in the publish CAS (no
/// `_graph_commits.lance`).
///
/// v1–v3 graphs are not served by this binary (see `MIN_SUPPORTED`); the history
/// is kept for provenance and to document what each stamp value meant.
pub const INTERNAL_MANIFEST_SCHEMA_VERSION: u32 = 4;
/// The oldest on-disk internal-schema stamp this binary will open. With no
/// in-place migration, this equals `INTERNAL_MANIFEST_SCHEMA_VERSION`: a graph
/// stamped below it is refused (`refuse_if_stamp_unsupported`) with a
/// rebuild-via-export/import message rather than silently upgraded.
///
/// Lowering this below CURRENT only makes sense alongside a re-introduced
/// migration dispatcher that can actually walk those versions forward (see the
/// module doc).
pub const MIN_SUPPORTED_INTERNAL_SCHEMA_VERSION: u32 = INTERNAL_MANIFEST_SCHEMA_VERSION;
const INTERNAL_SCHEMA_VERSION_KEY: &str = "omnigraph:internal_schema_version";
/// Read the on-disk stamp from `__manifest`'s schema-level metadata.
/// Absent ⇒ v1 (pre-stamp world), which is below `MIN_SUPPORTED` and so refused.
pub
/// Stamp a freshly-initialized manifest with the current internal schema
/// version. Idempotent — safe to call on an already-stamped dataset.
pub async
/// Refuse to open a manifest whose stamp this binary cannot serve — in either
/// direction — with a clear, actionable path. Shared by every open path (the
/// read-write open guard, the read-only open guard, and the publisher), so a new
/// stamp-reading caller gets the floor and the ceiling together and cannot
/// half-enforce.
///
/// - `stamp > CURRENT`: the graph was written by a newer binary — upgrade omnigraph.
/// - `stamp < MIN_SUPPORTED`: the graph was made by an older omnigraph whose
/// storage format this binary does not read — rebuild it via export/import.
pub
async
/// Test-only: force the on-disk internal-schema stamp to `version`. The minimal
/// seam used to synthesize a sub-CURRENT graph and assert the open path refuses
/// it. Its only caller is the in-source refusal test, so it is `cfg(test)`-only.
pub async