@amalgm/shell 0.1.125 → 0.1.127

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,111 +2,325 @@
2
2
  * The registry graph as this machine holds it.
3
3
  *
4
4
  * The authority stores the graph as a small head naming each root's immutable
5
- * pages, so this machine holds the same shape: the head, and the records of
6
- * every root that head names, grouped exactly as the head pages them. A
7
- * publication rebuilds only the roots it walked — every other root carries its
8
- * page list forward untouched, never re-serialized, re-hashed, or re-journaled.
5
+ * pages, and this machine holds exactly that: the head, plus the records of
6
+ * only the roots the current operation acts on. Nothing ever materializes the
7
+ * whole account — an Add reads its boundary root and the core root, a Register
8
+ * reads the roots it rebuilds, and every other root stays as page identities.
9
+ *
10
+ * Two page laws make root-scoped reading exact and cheap:
11
+ * - A root's pages are one contiguous uuid-sorted slice, so any single uuid
12
+ * is found (or proven absent) by binary-searching pages — log(pages) page
13
+ * reads, each proven against its declared identity and dropped after use.
14
+ * - Set-membership questions sweep pages one at a time, so their transient
15
+ * memory is O(page), never O(graph).
9
16
  *
10
17
  * A resource whose authority snapshot is still records-shaped (a login's
11
18
  * initial publication, before any head has committed) is held with a null
12
- * head. Its first head commit must page every root at once, which is exactly
13
- * what the authority demands of a commit over a records base.
19
+ * head and every record in memory — such graphs are one machine's first
20
+ * publication and small by construction. Its first head commit must page
21
+ * every root at once, which is exactly what the authority demands of a
22
+ * commit over a records base.
14
23
  */
15
- import { assembleRootRecords, graphHeadChecksum, graphHeadFromRootPages, graphHeadReplacement, pagesForRoot, parseGraphHead, parseSnapshot, recordsByRoot, snapshotFromRecords, stableJson, ENTITY_CLOUD_SCHEMA_VERSION, GRAPH_HEAD_KIND, } from "@amalgm/live";
24
+ import { graphHeadChecksum, graphHeadFromRootPages, graphHeadReplacement, pagesForRoot, parseGraphHead, parseGraphPage, parseSnapshot, proveRootPagination, recordsByRoot, snapshotFromRecords, stableJson, ENTITY_CLOUD_SCHEMA_VERSION, GRAPH_HEAD_KIND, } from "@amalgm/live";
25
+ /** How many pages a root materialization fetches ahead of its in-order
26
+ * proof. Bounds transient page bytes at PAGE_PREFETCH page budgets. */
27
+ const PAGE_PREFETCH = 4;
28
+ function rawUuid(row) {
29
+ return String(row?.uuid ?? "");
30
+ }
16
31
  export class RegistryGraph {
17
32
  /** The committed head, or null while the authority still holds a
18
33
  * records-shaped snapshot. */
19
34
  head;
20
- rootRecords;
21
- flat = null;
22
- rootIndex = null;
23
- constructor(head, rootRecords) {
35
+ roots;
36
+ readPage;
37
+ sha256Hex;
38
+ constructor(head, roots, readPage, sha256Hex) {
24
39
  this.head = head;
25
- this.rootRecords = rootRecords;
40
+ this.roots = roots;
41
+ this.readPage = readPage;
42
+ this.sha256Hex = sha256Hex;
43
+ }
44
+ /** Hold a records-shaped snapshot fully materialized: it is a first
45
+ * publication's own graph and carries no page identities to defer to. */
46
+ static fromRecords(records, sha256Hex) {
47
+ const roots = new Map();
48
+ for (const [rootId, group] of recordsByRoot(records)) {
49
+ roots.set(rootId, {
50
+ pages: [],
51
+ records: group,
52
+ rootRecord: group.find((record) => record.uuid === rootId) ?? null,
53
+ loading: null,
54
+ });
55
+ }
56
+ const reader = () => {
57
+ throw new Error("a records-shaped graph has no pages to read");
58
+ };
59
+ return new RegistryGraph(null, roots, reader, sha256Hex);
26
60
  }
27
- /** Hold a records-shaped snapshot as the same per-root groups a head would
28
- * name, so every reader above this class is shape-blind. */
29
- static fromRecords(records) {
30
- return new RegistryGraph(null, recordsByRoot(records));
61
+ /** Hold a committed head lazily: every root starts as page identities and
62
+ * materializes only when an operation reads it. */
63
+ static fromHead(head, readPage, sha256Hex) {
64
+ const roots = new Map();
65
+ for (const root of head.roots) {
66
+ roots.set(root.rootId, {
67
+ pages: root.pages,
68
+ records: null,
69
+ rootRecord: null,
70
+ loading: null,
71
+ });
72
+ }
73
+ return new RegistryGraph(head, roots, readPage, sha256Hex);
31
74
  }
32
75
  rootIds() {
33
- return [...this.rootRecords.keys()];
76
+ return [...this.roots.keys()];
34
77
  }
35
- recordsFor(rootId) {
36
- return this.rootRecords.get(rootId.toLowerCase()) ?? [];
78
+ /** The records of one root as this machine has already materialized them,
79
+ * or null when that root is still page identities. */
80
+ loadedRecords(rootId) {
81
+ return this.roots.get(rootId.toLowerCase())?.records ?? null;
37
82
  }
38
- /** Every record of every root, uuid-sorted. Only whole-graph readers pay
39
- * for this — a publication never calls it. */
40
- records() {
41
- this.flat ??= snapshotFromRecords([...this.rootRecords.values()].flat()).records;
42
- return this.flat;
83
+ /** Materialize one root: every page proven and parsed in order with a
84
+ * bounded prefetch, bytes dropped as they are consumed, then the root's
85
+ * complete subtree and canonical-pagination proof. An absent root answers
86
+ * empty rather than faulting — reading a root that is not there is how
87
+ * callers learn it is not there. */
88
+ async recordsFor(rootId) {
89
+ const state = this.roots.get(rootId.toLowerCase());
90
+ if (!state)
91
+ return [];
92
+ if (state.records)
93
+ return state.records;
94
+ state.loading ??= (async () => {
95
+ const assembled = [];
96
+ await this.scanPages(state.pages, (rows) => {
97
+ assembled.push(...rows);
98
+ });
99
+ const records = proveRootPagination(rootId.toLowerCase(), assembled, state.pages, this.sha256Hex);
100
+ state.records = records;
101
+ state.rootRecord = records.find((record) => record.uuid === rootId.toLowerCase()) ?? null;
102
+ return records;
103
+ })();
104
+ try {
105
+ return await state.loading;
106
+ }
107
+ catch (error) {
108
+ state.loading = null;
109
+ throw error;
110
+ }
43
111
  }
44
- /** The whole graph in the records shape the cold install and workspace
45
- * selection paths read. Normalization already happened per root, so this
46
- * only names the shape. */
47
- snapshot() {
48
- return {
49
- schemaVersion: ENTITY_CLOUD_SCHEMA_VERSION,
50
- kind: "amalgm-entity-registry",
51
- records: this.records(),
52
- };
112
+ /** One root's own record — the discovery unit. Found by binary search over
113
+ * the root's uuid-sorted pages without materializing the root; each probed
114
+ * page is proven against its identity and dropped. */
115
+ async rootRecord(rootId) {
116
+ const normalized = rootId.toLowerCase();
117
+ const state = this.roots.get(normalized);
118
+ if (!state)
119
+ throw new Error(`cloud graph has no root ${normalized}`);
120
+ if (state.rootRecord)
121
+ return state.rootRecord;
122
+ if (state.records) {
123
+ throw new Error(`cloud graph root ${normalized} does not hold its own record`);
124
+ }
125
+ const found = await this.findInPages(state.pages, normalized);
126
+ if (!found)
127
+ throw new Error(`cloud graph root ${normalized} does not hold its own record`);
128
+ state.rootRecord = found;
129
+ return found;
130
+ }
131
+ /** Every root's own record, for discovery over the whole account — which
132
+ * root is the core, which roots are workspaces — at log(pages) page reads
133
+ * per root instead of materializing anything. */
134
+ async rootRecords() {
135
+ return Promise.all([...this.roots.keys()].map((rootId) => this.rootRecord(rootId)));
53
136
  }
54
- /** Which root a record descends from, or null when the graph does not hold
55
- * it. The index is built once, and only for callers that need it. */
56
- rootOf(uuid) {
57
- if (!this.rootIndex) {
58
- const index = new Map();
59
- for (const [rootId, records] of this.rootRecords) {
60
- for (const record of records)
61
- index.set(record.uuid, rootId);
137
+ /** Which root holds this uuid, or null when the graph does not. A uuid that
138
+ * names a root is answered directly; anything else binary-searches each
139
+ * root's pages, materialized roots answered from memory. */
140
+ async locate(uuid) {
141
+ const normalized = uuid.toLowerCase();
142
+ if (this.roots.has(normalized))
143
+ return normalized;
144
+ const lazy = [];
145
+ for (const [rootId, state] of this.roots) {
146
+ if (state.records) {
147
+ if (state.records.some((record) => record.uuid === normalized))
148
+ return rootId;
149
+ }
150
+ else {
151
+ lazy.push([rootId, state]);
62
152
  }
63
- this.rootIndex = index;
64
153
  }
65
- return this.rootIndex.get(uuid) ?? null;
154
+ for (const [rootId, state] of lazy) {
155
+ if (await this.findInPages(state.pages, normalized))
156
+ return rootId;
157
+ }
158
+ return null;
159
+ }
160
+ /** Which root holds each of these uuids. Materialized roots answer from
161
+ * memory; the rest are swept page-at-a-time with transient parses, so one
162
+ * miss-heavy question — a publication merge asking about thousands of
163
+ * fresh uuids — costs one bounded pass, not one probe per uuid. */
164
+ async membership(uuids) {
165
+ const found = new Map();
166
+ const lazy = [];
167
+ for (const [rootId, state] of this.roots) {
168
+ if (uuids.has(rootId))
169
+ found.set(rootId, rootId);
170
+ if (state.records) {
171
+ for (const record of state.records) {
172
+ if (uuids.has(record.uuid))
173
+ found.set(record.uuid, rootId);
174
+ }
175
+ }
176
+ else {
177
+ lazy.push([rootId, state]);
178
+ }
179
+ }
180
+ for (const [rootId, state] of lazy) {
181
+ if (found.size === uuids.size)
182
+ break;
183
+ await this.scanPages(state.pages, (rows) => {
184
+ for (const row of rows) {
185
+ const uuid = rawUuid(row);
186
+ if (uuids.has(uuid))
187
+ found.set(uuid, rootId);
188
+ }
189
+ return found.size === uuids.size;
190
+ });
191
+ }
192
+ return found;
66
193
  }
67
194
  /** The checksum the authority holds for this graph right now. */
68
- checksum(sha256Hex) {
69
- return this.head === null
70
- ? sha256Hex(stableJson(snapshotFromRecords(this.records())))
71
- : graphHeadChecksum(this.head, sha256Hex);
195
+ checksum() {
196
+ if (this.head !== null)
197
+ return graphHeadChecksum(this.head, this.sha256Hex);
198
+ return this.sha256Hex(stableJson(this.recordsShapedSnapshot()));
199
+ }
200
+ /** The records shape of a headless graph — a first publication's own small
201
+ * snapshot. A committed head never flattens: readers are root-scoped. */
202
+ recordsShapedSnapshot() {
203
+ if (this.head !== null) {
204
+ throw new Error("a committed graph head is never flattened to records");
205
+ }
206
+ const records = [];
207
+ for (const state of this.roots.values())
208
+ records.push(...(state.records ?? []));
209
+ return {
210
+ schemaVersion: ENTITY_CLOUD_SCHEMA_VERSION,
211
+ kind: "amalgm-entity-registry",
212
+ records: snapshotFromRecords(records).records,
213
+ };
72
214
  }
73
215
  /** Publish a new graph in which `rebuilt` roots carry the given records and
74
- * every other root carries its committed pages forward. A root mapped to an
216
+ * every other root carries its committed pages — and any records this
217
+ * machine already materialized for them — forward. A root mapped to an
75
218
  * empty record list is dropped from the graph. */
76
- rebuild(rebuilt, sha256Hex) {
219
+ rebuild(rebuilt) {
77
220
  const replaced = new Map([...rebuilt].map(([rootId, records]) => [rootId.toLowerCase(), records]));
78
221
  if (this.head === null) {
79
222
  // The authority's base carries no page identities, so it can prove
80
223
  // nothing about a root this commit leaves alone. Paging every root is
81
224
  // the only lawful first head.
82
- for (const rootId of this.rootRecords.keys()) {
225
+ for (const rootId of this.roots.keys()) {
83
226
  if (!replaced.has(rootId)) {
84
227
  throw new Error(`the first graph head must page every root, and ${rootId} is missing`);
85
228
  }
86
229
  }
87
230
  }
88
- const carried = (this.head?.roots ?? []).filter((root) => !replaced.has(root.rootId));
231
+ const nextRoots = new Map();
232
+ for (const [rootId, state] of this.roots) {
233
+ if (replaced.has(rootId))
234
+ continue;
235
+ nextRoots.set(rootId, {
236
+ pages: state.pages,
237
+ records: state.records,
238
+ rootRecord: state.rootRecord,
239
+ loading: null,
240
+ });
241
+ }
89
242
  const pages = [];
90
- const paged = [];
91
- const nextRecords = new Map(this.rootRecords);
92
243
  for (const [rootId, records] of replaced) {
93
- if (records.length === 0) {
94
- nextRecords.delete(rootId);
244
+ if (records.length === 0)
95
245
  continue;
96
- }
97
- const rootPages = pagesForRoot(rootId, records, sha256Hex);
246
+ const rootPages = pagesForRoot(rootId, records, this.sha256Hex);
98
247
  pages.push(...rootPages);
99
- paged.push({ rootId, pages: rootPages.map((page) => page.ref) });
100
- nextRecords.set(rootId, rootPages.flatMap((page) => page.records));
248
+ const paged = rootPages.flatMap((page) => page.records);
249
+ nextRoots.set(rootId, {
250
+ pages: rootPages.map((page) => page.ref),
251
+ records: paged,
252
+ rootRecord: paged.find((record) => record.uuid === rootId) ?? null,
253
+ loading: null,
254
+ });
101
255
  }
102
- const head = graphHeadFromRootPages([...carried, ...paged]);
256
+ const head = graphHeadFromRootPages([...nextRoots].map(([rootId, state]) => ({ rootId, pages: state.pages })));
103
257
  return {
104
- graph: new RegistryGraph(head, nextRecords),
258
+ graph: new RegistryGraph(head, nextRoots, this.readPage, this.sha256Hex),
105
259
  operation: graphHeadReplacement(head, [...replaced.keys()]),
106
260
  pages,
107
- checksum: graphHeadChecksum(head, sha256Hex),
261
+ checksum: graphHeadChecksum(head, this.sha256Hex),
108
262
  };
109
263
  }
264
+ /** Prove, parse, and visit pages in order, fetching a bounded window ahead
265
+ * so the network pipeline stays full while transient memory stays at a few
266
+ * page budgets. The visitor may answer true to stop the scan early. */
267
+ async scanPages(refs, visit) {
268
+ const pending = [];
269
+ let ahead = 0;
270
+ try {
271
+ for (let index = 0; index < refs.length; index += 1) {
272
+ while (ahead < refs.length && pending.length < PAGE_PREFETCH) {
273
+ pending.push(this.readPage(refs[ahead]));
274
+ ahead += 1;
275
+ }
276
+ const ref = refs[index];
277
+ const rows = parseGraphPage(ref, await pending.shift(), this.sha256Hex);
278
+ if (visit(rows, ref) === true)
279
+ return;
280
+ }
281
+ }
282
+ finally {
283
+ // A stop or a fault must strand no in-flight read unobserved.
284
+ await Promise.allSettled(pending);
285
+ }
286
+ }
287
+ /** Binary-search one root's uuid-sorted pages for a single uuid. Each
288
+ * probed page is proven and dropped; the hit is normalized through the
289
+ * canonical record law before anyone reads it. */
290
+ async findInPages(refs, uuid) {
291
+ let low = 0;
292
+ let high = refs.length - 1;
293
+ while (low <= high) {
294
+ const middle = (low + high) >> 1;
295
+ const ref = refs[middle];
296
+ const rows = parseGraphPage(ref, await this.readPage(ref), this.sha256Hex);
297
+ if (rows.length === 0)
298
+ return null;
299
+ if (uuid < rawUuid(rows[0])) {
300
+ high = middle - 1;
301
+ continue;
302
+ }
303
+ if (uuid > rawUuid(rows[rows.length - 1])) {
304
+ low = middle + 1;
305
+ continue;
306
+ }
307
+ let start = 0;
308
+ let end = rows.length - 1;
309
+ while (start <= end) {
310
+ const probe = (start + end) >> 1;
311
+ const found = rawUuid(rows[probe]);
312
+ if (found === uuid) {
313
+ return snapshotFromRecords([rows[probe]]).records[0] ?? null;
314
+ }
315
+ if (uuid < found)
316
+ end = probe - 1;
317
+ else
318
+ start = probe + 1;
319
+ }
320
+ return null;
321
+ }
322
+ return null;
323
+ }
110
324
  }
111
325
  /** Every page identity the head names — the set a publication may skip
112
326
  * uploading because the authority already holds it under this exact graph. */
@@ -118,25 +332,14 @@ export function graphPageIdentities(head) {
118
332
  }
119
333
  return identities;
120
334
  }
121
- /** Materialize the authority's stored snapshot bytes into this machine's
122
- * graph. A head is materialized by reading the pages it names; a records-shaped
123
- * snapshot is grouped in place. */
124
- export async function registryGraphFromSnapshot(bytes, readPages, sha256Hex) {
335
+ /** Hold the authority's stored snapshot bytes as this machine's graph. A head
336
+ * is held lazily — no page is read here — and a records-shaped snapshot is
337
+ * grouped in place. */
338
+ export function registryGraphFromSnapshot(bytes, readPage, sha256Hex) {
125
339
  if (!snapshotIsGraphHead(bytes)) {
126
- return RegistryGraph.fromRecords(parseSnapshot(bytes).records);
127
- }
128
- const head = parseGraphHead(bytes);
129
- const read = await readPages(head.roots.flatMap((root) => root.pages));
130
- const rootRecords = new Map();
131
- for (const root of head.roots) {
132
- rootRecords.set(root.rootId, assembleRootRecords(root.rootId, root.pages, root.pages.map((page) => {
133
- const found = read.get(page.sha256);
134
- if (!found)
135
- throw new Error(`cloud graph page ${page.sha256} was not read`);
136
- return found;
137
- }), sha256Hex));
138
- }
139
- return new RegistryGraph(head, rootRecords);
340
+ return RegistryGraph.fromRecords(parseSnapshot(bytes).records, sha256Hex);
341
+ }
342
+ return RegistryGraph.fromHead(parseGraphHead(bytes), readPage, sha256Hex);
140
343
  }
141
344
  /** Which shape the authority's snapshot bytes carry. Both shapes declare their
142
345
  * kind ahead of their payload, and no record carries a `kind` of its own, so
@@ -1 +1 @@
1
- {"version":3,"file":"registry-graph.js","sourceRoot":"","sources":["../src/registry-graph.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry-graph.js","sourceRoot":"","sources":["../src/registry-graph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Verified local cache for immutable registry graph pages.
3
+ *
4
+ * Cache bytes are disposable evidence. A page is readable or writable only
5
+ * when its size and content hash match the identity committed in the graph
6
+ * head; corrupt evidence is ignored and can never poison later retries.
7
+ */
8
+ import { type GraphPageRef, type Sha256Hex } from "@amalgm/live";
9
+ /** Return only byte-exact cached evidence. Missing, torn, or corrupt bytes
10
+ * are all a cache miss and therefore recover through the immutable source. */
11
+ export declare function readVerifiedRegistryPage(file: string, ref: GraphPageRef, sha256Hex: Sha256Hex): Buffer | null;
12
+ /** Verify before the atomic write. A corrupt authority response must never
13
+ * replace good cache evidence or become a permanent same-size cache poison. */
14
+ export declare function writeVerifiedRegistryPage(file: string, ref: GraphPageRef, bytes: Uint8Array, sha256Hex: Sha256Hex): void;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Verified local cache for immutable registry graph pages.
3
+ *
4
+ * Cache bytes are disposable evidence. A page is readable or writable only
5
+ * when its size and content hash match the identity committed in the graph
6
+ * head; corrupt evidence is ignored and can never poison later retries.
7
+ */
8
+ import { readFileSync } from "node:fs";
9
+ import { atomicWrite } from "./filesystem.js";
10
+ function pageMatches(ref, bytes, sha256Hex) {
11
+ return bytes.byteLength === ref.bytes && sha256Hex(bytes) === ref.sha256;
12
+ }
13
+ /** Return only byte-exact cached evidence. Missing, torn, or corrupt bytes
14
+ * are all a cache miss and therefore recover through the immutable source. */
15
+ export function readVerifiedRegistryPage(file, ref, sha256Hex) {
16
+ try {
17
+ const bytes = readFileSync(file);
18
+ return pageMatches(ref, bytes, sha256Hex) ? bytes : null;
19
+ }
20
+ catch {
21
+ return null;
22
+ }
23
+ }
24
+ /** Verify before the atomic write. A corrupt authority response must never
25
+ * replace good cache evidence or become a permanent same-size cache poison. */
26
+ export function writeVerifiedRegistryPage(file, ref, bytes, sha256Hex) {
27
+ if (!pageMatches(ref, bytes, sha256Hex)) {
28
+ throw new Error(`cloud graph page ${ref.sha256} does not match its bytes`);
29
+ }
30
+ atomicWrite(file, bytes);
31
+ }
32
+ //# sourceMappingURL=registry-page-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry-page-cache.js","sourceRoot":"","sources":["../src/registry-page-cache.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAIvC,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,SAAS,WAAW,CAClB,GAAiB,EACjB,KAAiB,EACjB,SAAoB;IAEpB,OAAO,KAAK,CAAC,UAAU,KAAK,GAAG,CAAC,KAAK,IAAI,SAAS,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC;AAC3E,CAAC;AAED;8EAC8E;AAC9E,MAAM,UAAU,wBAAwB,CACtC,IAAY,EACZ,GAAiB,EACjB,SAAoB;IAEpB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QACjC,OAAO,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;+EAC+E;AAC/E,MAAM,UAAU,yBAAyB,CACvC,IAAY,EACZ,GAAiB,EACjB,KAAiB,EACjB,SAAoB;IAEpB,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,oBAAoB,GAAG,CAAC,MAAM,2BAA2B,CAAC,CAAC;IAC7E,CAAC;IACD,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC3B,CAAC"}
@@ -116,6 +116,9 @@ export declare class UserGroundHost {
116
116
  private watchDirty;
117
117
  private cloudState;
118
118
  private converged;
119
+ /** Cumulative graph-page reads, reported as diffs on the stages that
120
+ * materialize roots so the ledger shows what each operation actually read. */
121
+ private readonly graphPageReads;
119
122
  private syncing;
120
123
  private recordRail;
121
124
  private recordStore;
@@ -182,14 +185,32 @@ export declare class UserGroundHost {
182
185
  private userRoot;
183
186
  private cacheDir;
184
187
  private cloudPort;
185
- /** The authority's stored snapshot as this machine's graph. A head names
186
- * immutable pages, so every page this machine already cached is a local read
187
- * and an unchanged root never crosses the network twice. */
188
+ /** The authority's stored snapshot as this machine's graph. A head is held
189
+ * lazily — no page is read until an operation asks for a root — and every
190
+ * page this machine already cached is a local read, so an unchanged root
191
+ * never crosses the network twice. */
188
192
  private materializeRegistry;
189
- /** Read graph pages by identity: cached pages come off local disk, the rest
190
- * are fetched straight from content storage and cached on the way in. Every
191
- * page is re-proven against its declared identity before it is kept. */
192
- private readGraphPages;
193
+ /** The records a lookup hands to Live: every root's own record — the
194
+ * discovery set that proves root uniqueness — plus the full records of
195
+ * exactly the roots the operation acts on. A records-shaped snapshot is a
196
+ * first publication's own small graph and travels whole, keeping its
197
+ * records-shape checksum law intact. */
198
+ private selectScope;
199
+ /** The account's core root: the one active top-level workspace named by the
200
+ * account email. Registered-boundary references live only there. */
201
+ private coreRootId;
202
+ /** Fold the committed delivery tail over a root-scoped base without losing
203
+ * a subtree the tail moved across roots. A container the folded boundary
204
+ * contains only through delivered results may still file unchanged
205
+ * descendants under the root that used to hold it, so that root's records
206
+ * join the base and the fold reruns until no probe widens it. Leaf results
207
+ * travel whole and never probe. */
208
+ private foldScopedPrefix;
209
+ /** Read one graph page by identity: cached pages come off local disk, the
210
+ * rest are fetched straight from content storage and cached on the way in.
211
+ * The graph proves every page against its declared identity as it parses,
212
+ * so this reader only guards the cache against torn copies. */
213
+ private readGraphPage;
193
214
  private localPort;
194
215
  /** Send's small-cargo fast path: the record's sealed artifact rides the
195
216
  * submit frame itself, so one round trip carries record, manifest, and