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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
//! The one JSONL line: what a shared memory carries between machines (#5902).
//!
//! Why: the export file is a wire format two independently-built binaries read
//! and write, so its shape and its version live in one place rather than being
//! implied by whatever the exporter happened to serialize.
//! What: [`SHARE_FORMAT_VERSION`], [`SharedMemoryRecord`], and the verification
//! a reader owes before trusting a line.
//! Test: `record_round_trips_through_json`, `verify_rejects_a_forged_digest`,
//! `verify_rejects_an_unknown_format_version` in `share::tests`.
use ;
use ;
use crate;
use crate;
/// Version of the JSONL record shape.
///
/// Why: separate from [`CONTENT_HASH_VERSION`] because the two change for
/// different reasons. Adding a field to the record is compatible and does not
/// touch identity; changing the normalization re-mints every id. A reader that
/// conflated them could not tell "I do not understand this field layout" from "I
/// cannot reproduce these digests".
/// What: `1`. A record declaring a higher version is refused rather than
/// best-effort parsed — see [`SharedMemoryRecord::verify`].
pub const SHARE_FORMAT_VERSION: u32 = 1;
/// One exported memory: its content-addressed identity plus the metadata an
/// importer needs to place it.
///
/// 🔴 MEMORIES ONLY — no derived data, by owner decision. No embedding vector,
/// no HNSW/usearch index state, no BM25 data. Anything rebuildable from the
/// bodies stays out, and stays out as an ABSENT FIELD rather than an optional
/// empty one: an empty field invites a later change to populate it without
/// re-opening this decision.
///
/// Why: an embedding is a lossy but real encoding of its source text, and these
/// files are committed to a PUBLIC repository. Excluding derived data makes what
/// gets published exactly the memory bodies we already intend to publish, with no
/// second channel carrying the same content in a form nobody inspects.
/// `trusty-agents`' `ExportRecord` does carry a vector, on the reasoning that the
/// receiver can insert without a model load; that trade is refused here. Three
/// supporting reasons: a 384-dimension `f32` array serializes to roughly 4–6 KB of
/// JSON, an order of magnitude larger than the body it describes, which makes a
/// committed file's diff unreadable and its history heavy; the receiving machine's
/// embedder, dimension, or model revision need not match the sender's, so an
/// imported vector can be silently wrong in a way no assertion here could catch;
/// and re-embedding on import is cheap against a warm process-wide embedder. The
/// accepted cost is that import depends on the embedder — see
/// [`super::import::import_palace_records`] for how that failure is handled.
///
/// Why no author, machine, or session field: the palace has none to export.
/// `Palace`, `Wing`, `Room`, and `Drawer` carry no provenance of any kind; the
/// only provenance in the model is `Triple.provenance`, a free-form optional
/// string on KG edges. Inventing one here would be a new concept smuggled in
/// through a file format.
///
/// What: the digest, the verbatim body, tags, `created_at`, the drawer type tag,
/// the room label, and importance. The room is the LABEL, not the `room_id`:
/// room ids are UUIDv5 over `(wing_id, lowercased label)` (ADR-0027), so both
/// machines mint the same id from the same label, and the label survives a
/// palace that has not seen that room yet.
/// Test: `record_round_trips_through_json`, `export_then_import_preserves_metadata`.
/// Why a record could not be trusted.
///
/// Why this is an error and not a warning: an import that accepted a line whose
/// declared digest does not match its body would store a memory under an
/// identity no other machine can reproduce, which breaks convergence silently
/// and permanently. Refusing the line is recoverable; accepting it is not.
/// Test: `verify_rejects_a_forged_digest`, `verify_rejects_an_unknown_format_version`,
/// `import_skips_a_bad_line_and_keeps_the_rest`.