@avantf/dsh-mem 0.6.4 → 0.8.0

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.
Files changed (150) hide show
  1. package/README.md +19 -10
  2. package/lib/client.js +1665 -3466
  3. package/lib/dsh-build.json +6 -5
  4. package/lib/engine/graph-recall/in-memory.d.ts +93 -0
  5. package/lib/engine/graph-recall/index.d.ts +22 -0
  6. package/lib/engine/graph-recall/traverse.d.ts +119 -0
  7. package/lib/engine/graph-recall/types.d.ts +188 -0
  8. package/lib/engine/mem/config/config_files.d.ts +1 -1
  9. package/lib/engine/mem/config/loader.d.ts +2 -3
  10. package/lib/engine/mem/config/paths.d.ts +2 -13
  11. package/lib/engine/mem/db/dao/contradictions.d.ts +4 -22
  12. package/lib/engine/mem/db/dao/entities.d.ts +80 -7
  13. package/lib/engine/mem/db/dao/fact_sources.d.ts +3 -13
  14. package/lib/engine/mem/db/dao/facts.d.ts +311 -56
  15. package/lib/engine/mem/db/dao/triples.d.ts +1 -26
  16. package/lib/engine/mem/db/graph.d.ts +249 -0
  17. package/lib/engine/mem/db/journal_notes.d.ts +35 -0
  18. package/lib/engine/mem/db/migrations.d.ts +9 -0
  19. package/lib/engine/mem/db/port.d.ts +22 -3
  20. package/lib/engine/mem/db/schema.d.ts +119 -0
  21. package/lib/engine/mem/db/tokenizer.d.ts +9 -0
  22. package/lib/engine/mem/dbdrivers/fake/driver.d.ts +75 -0
  23. package/lib/engine/mem/dbdrivers/fake/index.d.ts +7 -0
  24. package/lib/engine/mem/dbdrivers/fake/surface.d.ts +34 -0
  25. package/lib/engine/mem/dbdrivers/fake/transport.d.ts +61 -0
  26. package/lib/engine/mem/dbdrivers/sqlite/connection.d.ts +14 -0
  27. package/lib/engine/mem/dbdrivers/sqlite/contradictions.d.ts +35 -0
  28. package/lib/engine/mem/dbdrivers/sqlite/dao/index.d.ts +16 -0
  29. package/lib/engine/mem/dbdrivers/sqlite/driver.d.ts +54 -0
  30. package/lib/engine/mem/dbdrivers/sqlite/facts.d.ts +117 -0
  31. package/lib/engine/mem/dbdrivers/sqlite/index.d.ts +6 -0
  32. package/lib/engine/mem/dbdrivers/sqlite/migrations.d.ts +15 -0
  33. package/lib/engine/mem/dbdrivers/sqlite/relations.d.ts +62 -0
  34. package/lib/engine/mem/dbdrivers/sqlite/search.d.ts +56 -0
  35. package/lib/engine/mem/dbdrivers/sqlite/sources.d.ts +37 -0
  36. package/lib/engine/mem/defaults.d.ts +3 -4
  37. package/lib/engine/mem/dispatch.d.ts +7 -32
  38. package/lib/engine/mem/entities/extract.d.ts +44 -47
  39. package/lib/engine/mem/eval/derived_runner.d.ts +6 -1
  40. package/lib/engine/mem/eval/relation_gold.d.ts +251 -0
  41. package/lib/engine/mem/eval/write_metrics.d.ts +1 -1
  42. package/lib/engine/mem/facts_io.d.ts +328 -0
  43. package/lib/engine/mem/index.d.ts +10 -2
  44. package/lib/engine/mem/interfaces/capabilities.d.ts +30 -0
  45. package/lib/engine/mem/interfaces/common.d.ts +11 -0
  46. package/lib/engine/mem/interfaces/errors.d.ts +65 -0
  47. package/lib/engine/mem/interfaces/index.d.ts +18 -0
  48. package/lib/engine/mem/interfaces/migrations.d.ts +21 -0
  49. package/lib/engine/mem/interfaces/repositories.d.ts +471 -0
  50. package/lib/engine/mem/interfaces/search_index.d.ts +113 -0
  51. package/lib/engine/mem/interfaces/storage_backend.d.ts +84 -0
  52. package/lib/engine/mem/interfaces/storage_driver.d.ts +43 -0
  53. package/lib/engine/mem/interfaces/version.d.ts +34 -0
  54. package/lib/engine/mem/lifecycle/contradiction.d.ts +2 -2
  55. package/lib/engine/mem/maintenance_paths.d.ts +41 -0
  56. package/lib/engine/mem/modelBootstrap.d.ts +1 -1
  57. package/lib/engine/mem/relations/confidence.d.ts +39 -0
  58. package/lib/engine/mem/relations/extract.d.ts +128 -0
  59. package/lib/engine/mem/relations/index.d.ts +32 -0
  60. package/lib/engine/mem/relations/name-quality.d.ts +78 -0
  61. package/lib/engine/mem/relations/normalize.d.ts +275 -0
  62. package/lib/engine/mem/relations/patterns.d.ts +67 -0
  63. package/lib/engine/mem/relations/statement.d.ts +88 -0
  64. package/lib/engine/mem/relations/types.d.ts +79 -0
  65. package/lib/engine/mem/runtime.d.ts +117 -90
  66. package/lib/engine/mem/storage/create.d.ts +42 -0
  67. package/lib/engine/mem/storage/errors.d.ts +65 -0
  68. package/lib/engine/mem/storage/index.d.ts +15 -0
  69. package/lib/engine/mem/storage/ports.d.ts +472 -0
  70. package/lib/engine/mem/storage/registry.d.ts +37 -0
  71. package/lib/engine/mem/storage/sqlite.d.ts +28 -0
  72. package/lib/engine/mem/store/common.d.ts +1 -1
  73. package/lib/engine/mem/store/entity_leg.d.ts +59 -2
  74. package/lib/engine/mem/store/entity_sweep.d.ts +4 -3
  75. package/lib/engine/mem/store/explicit_relations.d.ts +52 -0
  76. package/lib/engine/mem/store/facts_restore.d.ts +124 -0
  77. package/lib/engine/mem/store/floors.d.ts +4 -1
  78. package/lib/engine/mem/store/graph_reader.d.ts +146 -0
  79. package/lib/engine/mem/store/hybrid.d.ts +50 -13
  80. package/lib/engine/mem/store/kinds.d.ts +47 -0
  81. package/lib/engine/mem/store/legs.d.ts +24 -29
  82. package/lib/engine/mem/store/lexical.d.ts +36 -45
  83. package/lib/engine/mem/store/memory.d.ts +486 -82
  84. package/lib/engine/mem/store/recall_policy.d.ts +49 -0
  85. package/lib/engine/mem/store/relation_backfill.d.ts +210 -0
  86. package/lib/engine/mem/store/relation_planner.d.ts +191 -0
  87. package/lib/engine/mem/store/secret_guard.d.ts +0 -1
  88. package/lib/engine/mem/store/self_query.d.ts +4 -2
  89. package/lib/engine/mem/store/time_filter.d.ts +121 -0
  90. package/lib/engine/mem/store/titles.d.ts +52 -0
  91. package/lib/engine/mem/store/vector_repair.d.ts +44 -54
  92. package/lib/engine/mem-contract/config.d.ts +44 -38
  93. package/lib/engine/mem-contract/text.d.ts +1 -1
  94. package/lib/engine/mem-contract/tools.d.ts +184 -117
  95. package/lib/engine/mem-contract/types.d.ts +364 -288
  96. package/lib/index.js +13898 -11500
  97. package/lib/interface-version.json +1 -1
  98. package/lib/types/client/index.d.ts +2 -2
  99. package/lib/types/client/index.d.ts.map +1 -1
  100. package/lib/types/client/paging.d.ts +3 -12
  101. package/lib/types/client/paging.d.ts.map +1 -1
  102. package/lib/types/client/summarize.d.ts.map +1 -1
  103. package/lib/types/command.d.ts +61 -0
  104. package/lib/types/command.d.ts.map +1 -0
  105. package/lib/types/envinit-bootstrap.d.ts +1 -1
  106. package/lib/types/envinit.d.ts +2 -6
  107. package/lib/types/envinit.d.ts.map +1 -1
  108. package/lib/types/hints.d.ts +28 -24
  109. package/lib/types/hints.d.ts.map +1 -1
  110. package/lib/types/index.d.ts +21 -40
  111. package/lib/types/index.d.ts.map +1 -1
  112. package/lib/types/inject.d.ts +3 -2
  113. package/lib/types/inject.d.ts.map +1 -1
  114. package/lib/types/interface_gate.d.ts +9 -9
  115. package/lib/types/prompt.d.ts +17 -41
  116. package/lib/types/prompt.d.ts.map +1 -1
  117. package/lib/types/provision.d.ts +3 -0
  118. package/lib/types/provision.d.ts.map +1 -1
  119. package/lib/types/remote.d.ts +23 -9
  120. package/lib/types/remote.d.ts.map +1 -1
  121. package/lib/types/render.d.ts +3 -3
  122. package/lib/types/tool_schema.d.ts +4 -0
  123. package/lib/types/tool_schema.d.ts.map +1 -1
  124. package/lib/types/vectorMigration.d.ts +5 -7
  125. package/lib/types/vectorMigration.d.ts.map +1 -1
  126. package/package.json +16 -15
  127. package/lib/engine/mem/config/domains.d.ts +0 -20
  128. package/lib/engine/mem/db/dao/chunks.d.ts +0 -231
  129. package/lib/engine/mem/db/dao/documents.d.ts +0 -51
  130. package/lib/engine/mem/db/hash.d.ts +0 -2
  131. package/lib/engine/mem/db/knowledge.d.ts +0 -17
  132. package/lib/engine/mem/eval/index.d.ts +0 -4
  133. package/lib/engine/mem/git.d.ts +0 -73
  134. package/lib/engine/mem/router.d.ts +0 -51
  135. package/lib/engine/mem/store/doc_files.d.ts +0 -125
  136. package/lib/engine/mem/store/document_text.d.ts +0 -47
  137. package/lib/engine/mem/store/ingest_guard.d.ts +0 -25
  138. package/lib/engine/mem/store/knowledge.d.ts +0 -598
  139. package/lib/engine/mem/store/source_picker.d.ts +0 -43
  140. package/lib/engine/mem-retrieval/adapters/local_reranker.d.ts +0 -52
  141. package/lib/engine/mem-retrieval/adapters/none_reranker.d.ts +0 -10
  142. package/lib/engine/mem-retrieval/rerank.d.ts +0 -13
  143. package/lib/types/client/domains.d.ts +0 -53
  144. package/lib/types/client/domains.d.ts.map +0 -1
  145. package/lib/types/client/ingest.d.ts +0 -24
  146. package/lib/types/client/ingest.d.ts.map +0 -1
  147. package/lib/types/open.d.ts +0 -77
  148. package/lib/types/open.d.ts.map +0 -1
  149. package/lib/types/reconcile.d.ts +0 -64
  150. package/lib/types/reconcile.d.ts.map +0 -1
@@ -0,0 +1,328 @@
1
+ import { EXPORT_STATUSES, type ExportStatus, type MemoryKind, type RememberRequest } from '../mem-contract/index.js';
2
+ /**
3
+ * The runtime slice these flows actually touch.
4
+ *
5
+ * Narrow on purpose: export reads two config fields, import/merge also call the store's `add` path.
6
+ * Keeping the parameter structural (rather than the whole `AvantfRuntime`) is what lets the admin
7
+ * dispatcher — an object literal whose `closed` getter is attached only at return time — pass
8
+ * itself in without a cast, and it documents that these flows cannot reach any other store face.
9
+ */
10
+ export interface FactsIoRuntime {
11
+ config: {
12
+ home: string;
13
+ memory: {
14
+ db: {
15
+ path: string;
16
+ };
17
+ };
18
+ };
19
+ remember(req: RememberRequest): Promise<unknown>;
20
+ }
21
+ /** The document's discriminator. A file without it is not an export of this tool. */
22
+ export declare const FACTS_EXPORT_FORMAT = "avantf-mem-facts";
23
+ /**
24
+ * The version THIS build writes: 5 (v4's `title` plus the note-only `relations`).
25
+ *
26
+ * Versions are additive by design: v2/v3/v4/v5 each add OPTIONAL fields, so an older document is the
27
+ * same shape minus the new keys. A version outside {@link FACTS_EXPORT_VERSIONS} must be refused,
28
+ * never guessed at.
29
+ */
30
+ export declare const FACTS_EXPORT_VERSION = 5;
31
+ /**
32
+ * A version this build can READ. v1–v4 documents are what users already have on disk, and a v5
33
+ * document adds only the OPTIONAL `relations` field — so all five parse into the same type.
34
+ */
35
+ export declare const FACTS_EXPORT_VERSIONS: readonly [1, 2, 3, 4, 5];
36
+ /** The version literal, so a parsed document can say which field set it came from. */
37
+ export type FactsExportVersion = (typeof FACTS_EXPORT_VERSIONS)[number];
38
+ /**
39
+ * `--status` values accepted by `export` (the whole DB, or one status).
40
+ *
41
+ * Re-exported from the contract, where the admin action and the CLI flag read the same set. The
42
+ * engine's public face keeps the name its callers already import.
43
+ */
44
+ export { EXPORT_STATUSES, type ExportStatus };
45
+ /** One `fact_sources` row, copied verbatim. */
46
+ export interface ExportedFactSource {
47
+ kind: string;
48
+ ref: string;
49
+ }
50
+ /**
51
+ * One fact, as it stands in the source database.
52
+ *
53
+ * Every field is part of the documented format even when v1 import ignores it — the point of the
54
+ * document is that a later restore does not have to invent what was never written down.
55
+ */
56
+ export interface ExportedFact {
57
+ /** Source-local row id. For reports/debugging ONLY; content is the identity. */
58
+ source_id: number;
59
+ content: string;
60
+ /** The memory layer (v3). ABSENT on a v1/v2 document, which carries `category` instead. */
61
+ kind?: MemoryKind;
62
+ /**
63
+ * v4: the journal title (JOURNAL_TITLE_SEARCH §7). ABSENT on a v1/v2/v3 document — those rows had
64
+ * no title column at all, and an import restores them as NULL rather than inventing one.
65
+ */
66
+ title?: string | null;
67
+ /** The old free-form label, kept for audit only; `null` when the row predates the migration. */
68
+ legacy_category?: string | null;
69
+ /**
70
+ * v1/v2 ONLY: the old free-form category. Read (and mapped) for backward compatibility, never
71
+ * written by this build — an export from a v10 source database still carries it, and a v1/v2
72
+ * document on disk is exactly that shape.
73
+ */
74
+ category?: string;
75
+ status: string;
76
+ created_at: string | null;
77
+ updated_at: string | null;
78
+ ttl_days: number;
79
+ pinned: boolean;
80
+ pinned_at: string | null;
81
+ trust_score: number;
82
+ assert_count: number;
83
+ helpful_count: number;
84
+ last_reinforced_at: string | null;
85
+ sources: ExportedFactSource[];
86
+ valid_from: string | null;
87
+ valid_to: string | null;
88
+ supersedes_source_id: number | null;
89
+ /** `null` for an active row; the archive bookkeeping for an archived one. */
90
+ archive: {
91
+ at: string | null;
92
+ reason: string | null;
93
+ } | null;
94
+ /** Active-day clock at the last trust settle — the decay baseline. v1 had no such column. */
95
+ settle_clock?: number | null;
96
+ /** Reinforcement events inside the current 24h window. */
97
+ bonus_count?: number | null;
98
+ /** Calendar start of that window. */
99
+ bonus_window_at?: string | null;
100
+ /** How many times this fact was RETURNED by a retrieval leg (local usage stat, still stored). */
101
+ retrieval_count?: number | null;
102
+ last_retrieved_at?: string | null;
103
+ /** Mirror bookkeeping (a fact copied between libraries); informational, restored verbatim. */
104
+ mirror_source?: string | null;
105
+ mirror_target?: string | null;
106
+ /**
107
+ * The DERIVED-STATE stamps. Exported for completeness/diagnostics, but restore deliberately does
108
+ * not trust them: it stamps `entities_version = 0` (so the entity sweep rebuilds) and
109
+ * `conflict_checked = 1` (no corpus-wide conflict re-scan after a rebuild).
110
+ */
111
+ entities_version?: number | null;
112
+ conflict_checked?: number | null;
113
+ /**
114
+ * v5: the relations the CALLER stated on this note (`edges.source = 'explicit'`), in insertion
115
+ * order. ABSENT on a v1–v4 document (those rows were written before the field existed) and on
116
+ * every `journal` row — a journal refuses relations by contract, so the key there would assert a
117
+ * relation set a journal cannot have.
118
+ *
119
+ * These are NOT the extracted (`svo`) edges: those are re-derived from `content`, while an
120
+ * explicit relation is the one graph fact the text does not contain. That is why it travels.
121
+ */
122
+ relations?: ExportedRelation[];
123
+ }
124
+ /** One caller-stated relation inside an export document (v5). */
125
+ export interface ExportedRelation {
126
+ subject: string;
127
+ predicate: string;
128
+ object: string;
129
+ }
130
+ /** The single JSON document `export` writes (and `import`/`restore` read). */
131
+ export interface FactsExportDocument {
132
+ format: typeof FACTS_EXPORT_FORMAT;
133
+ /** The version the document was WRITTEN as (1, 2 or 3); this build writes 3. */
134
+ version: FactsExportVersion;
135
+ exported_at: string;
136
+ source: {
137
+ data_home: string;
138
+ db: string;
139
+ /** The SOURCE database's whole-DB status counts, independent of `--status`. */
140
+ counts: {
141
+ active: number;
142
+ archived: number;
143
+ };
144
+ };
145
+ facts: ExportedFact[];
146
+ }
147
+ /** How v1 import may treat the provenance embedded in the document. */
148
+ export interface ImportOptions {
149
+ /** Plan only: no write, and the report gets `would_import`. */
150
+ dryRun?: boolean;
151
+ /** Fallback provenance when the document has none (the CLI passes `import:<file>`). */
152
+ sourceRef?: string;
153
+ /**
154
+ * Use `sources[0].ref` when present (the default, and the import contract).
155
+ *
156
+ * `merge` turns this OFF: its documented provenance is `merge:<absolute source path>` for every
157
+ * imported row, so a merge must not start attributing rows to whatever the other host recorded.
158
+ */
159
+ preferEmbeddedSources?: boolean;
160
+ }
161
+ /** One row the store refused; the rest of the import continues. */
162
+ export interface ImportFailure {
163
+ /** The document's `source_id`, or `null` when the row was too malformed to have one. */
164
+ source_id: number | null;
165
+ error: string;
166
+ }
167
+ /** Source id → target id for one fact this invocation actually CREATED. */
168
+ export interface ImportNewId {
169
+ source_id: number | null;
170
+ new_fact_id: number;
171
+ }
172
+ /**
173
+ * Counts of values v1 could not carry, over the facts this invocation imported (or, for a dry run,
174
+ * planned to import). `1` per fact that actually carried the value; `0` when there was nothing to
175
+ * lose. See the module doc for why these are losses rather than silent successes.
176
+ */
177
+ export interface MetadataDropped {
178
+ timestamps: number;
179
+ trust: number;
180
+ assert_count: number;
181
+ helpful_count: number;
182
+ pinned: number;
183
+ supersedes: number;
184
+ }
185
+ /** The single JSON object `import` prints (`file` is added by the CLI, which knows the argument). */
186
+ export interface ImportReport {
187
+ /** The input form this run detected: an export document. */
188
+ mode: 'json';
189
+ version: number;
190
+ total: number;
191
+ imported: number;
192
+ /** Present on `--dry-run` only; the number of facts that WOULD be written. */
193
+ would_import?: number;
194
+ skipped_existing: number;
195
+ skipped_archived: number;
196
+ failed: ImportFailure[];
197
+ new_ids: ImportNewId[];
198
+ metadata_dropped: MetadataDropped;
199
+ }
200
+ /** The db→db variant's report. Field names kept from the original `merge` output. */
201
+ export interface MergeReport {
202
+ /** The input form this run detected: a SQLite source database. */
203
+ mode: 'db';
204
+ source: string;
205
+ source_active: number;
206
+ added: number;
207
+ would_add: number;
208
+ skipped_existing: number;
209
+ skipped_archived: number;
210
+ failed: {
211
+ source_fact_id: number | null;
212
+ error: string;
213
+ }[];
214
+ new_ids: {
215
+ source_fact_id: number | null;
216
+ new_fact_id: number;
217
+ }[];
218
+ }
219
+ export interface MergeOptions {
220
+ /** Provenance for rows without an embedded source; default `merge:<absolute source path>`. */
221
+ sourceRef?: string;
222
+ /** Plan only: no model warmup, no write, `added` stays 0. */
223
+ dryRun?: boolean;
224
+ }
225
+ /**
226
+ * Export THIS runtime's memory facts. Read-only: the store's own connection is never asked to write
227
+ * (and this command needs no embedding model — the rows are already there).
228
+ */
229
+ export declare function exportFacts(rt: FactsIoRuntime, options?: {
230
+ status?: ExportStatus;
231
+ }): FactsExportDocument;
232
+ /**
233
+ * The compression containers `export` can write. `none` is plain minified JSON (the format's
234
+ * canonical text, and what stdout always carries).
235
+ */
236
+ export type FactsExportCodec = 'brotli' | 'gzip' | 'none';
237
+ /**
238
+ * The one serialization. MINIFIED by default: the document is a machine artifact that gets
239
+ * compressed, and indentation only makes the uncompressed fallback bigger. `pretty` exists for
240
+ * debugging (a human reading a diff), never as the default — and it is the ONLY mode that appends
241
+ * the trailing newline that used to be unconditional.
242
+ */
243
+ export declare function serializeFactsExport(doc: FactsExportDocument, options?: {
244
+ pretty?: boolean;
245
+ }): string;
246
+ /**
247
+ * Serialize + compress in one step. gzip uses level 9; brotli uses quality 11 and tells the encoder
248
+ * the input size, which is the smallest output either library produces for a one-shot export.
249
+ *
250
+ * `codec` defaults to `none` so a caller that says nothing gets the canonical minified JSON.
251
+ */
252
+ export declare function encodeFactsExport(doc: FactsExportDocument, options?: {
253
+ codec?: FactsExportCodec;
254
+ pretty?: boolean;
255
+ }): Buffer;
256
+ /** The document an encoded file carries, plus the container it actually turned out to be. */
257
+ export interface DecodedFactsExport {
258
+ doc: FactsExportDocument;
259
+ codec: FactsExportCodec;
260
+ }
261
+ /**
262
+ * Whether these bytes are a SQLite database, decided by the FILE HEADER.
263
+ *
264
+ * `mem_admin import` takes either an export document or another host's `memory.db`, and the only
265
+ * honest discriminator is the content: the export containers (plain / gzip / brotli) never start with
266
+ * the SQLite header, and a `.db` file renamed to `.json` still is one. Kept here, beside
267
+ * {@link decodeFactsExport}, so both content sniffers live together.
268
+ */
269
+ export declare function isSqliteDatabase(bytes: Buffer): boolean;
270
+ /**
271
+ * The same check for a PATH, reading only the 16-byte header.
272
+ *
273
+ * A `memory.db` can be hundreds of MiB; deciding which flow to take must not read it into memory
274
+ * first. The JSON path still reads the whole document (it has to decode it), but the db path hands the
275
+ * path straight to the read-only opener.
276
+ */
277
+ export declare function isSqliteDatabaseFile(path: string): boolean;
278
+ /**
279
+ * Decode one export file from its BYTES. The file name is deliberately not an input: gzip has a
280
+ * magic header, brotli does not, and a pre-compression export is plain JSON — so the only reliable
281
+ * discriminator is the content itself (a brotli file renamed to `.json` still imports, and a plain
282
+ * JSON file renamed to `.json.br` does too).
283
+ *
284
+ * Order, and why: gzip magic → gunzip (a corrupt gzip is refused as gzip, not silently "JSON");
285
+ * otherwise UTF-8 JSON (the backward-compatible path for every old pretty file); only when JSON
286
+ * parsing fails, brotli (its decoder rejects non-brotli input, so this cannot shadow a JSON
287
+ * document). A document that IS JSON but has the wrong format/version throws its own error right
288
+ * away — {@link parseFactsExport} is the format gate, not a fallback.
289
+ */
290
+ export declare function decodeFactsExport(bytes: Buffer): DecodedFactsExport;
291
+ /**
292
+ * Resolve the container for a file export: an explicit flag wins, then the extension (`.br` /
293
+ * `.gz`), then plain minified JSON. Shared by the CLI and `/mem` so the two surfaces cannot
294
+ * disagree about what `--out backup.json.gz` means.
295
+ */
296
+ export declare function codecForExportPath(path: string, explicit?: FactsExportCodec): FactsExportCodec;
297
+ /**
298
+ * Parse and validate an export document TEXT (the stdin entry point). Top-level format errors are
299
+ * FATAL (the caller must write nothing); a malformed individual fact is NOT — {@link importFacts}
300
+ * collects it in `failed` and keeps going. Restore is STRICTER by construction: it validates every
301
+ * row before opening its transaction, because skipping a row would produce a different history.
302
+ */
303
+ export declare function parseFactsExport(text: string): FactsExportDocument;
304
+ /**
305
+ * Import one export document into `rt`'s memory store.
306
+ *
307
+ * Order of decisions per fact: archived → skipped_archived (v1 never revives); content already in
308
+ * the target (or planned by an earlier row of this same document) → skipped_existing; otherwise the
309
+ * store's add path runs. A row the store refuses is collected in `failed` and the loop continues.
310
+ *
311
+ * A v5 row's `relations` travel through that same add path, so the imported fact gets its declared
312
+ * relations as `source: 'explicit'` edges (normalized, name-gated, four-tuple deduped against the
313
+ * extracted ones). Two consequences worth knowing: a row that is SKIPPED as already-present keeps
314
+ * the target's own relation set (this is a content union, not a merge of graphs), and a `journal`
315
+ * row carrying relations is refused per row with {@link RELATIONS_NEED_NOTE} — that combination is
316
+ * unrepresentable, so it must be reported rather than silently stripped.
317
+ */
318
+ export declare function importFacts(rt: FactsIoRuntime, doc: FactsExportDocument, options?: ImportOptions): Promise<ImportReport>;
319
+ /**
320
+ * `merge` — the db→document→import form of the same union.
321
+ *
322
+ * The source is another host's file: opened read-only, never migrated, never written. The document is
323
+ * built in memory and handed to {@link importFacts}, so merge and `import` share one per-fact add
324
+ * path (and one failure-collection rule). Its provenance stays `merge:<absolute source path>` even
325
+ * when the source rows carry their own sources — that is the documented merge contract and the
326
+ * reason {@link ImportOptions.preferEmbeddedSources} can be turned off.
327
+ */
328
+ export declare function mergeDb(rt: FactsIoRuntime, dbPath: string, options?: MergeOptions): Promise<MergeReport>;
@@ -19,11 +19,19 @@ export * from './modelBootstrap.js';
19
19
  export * from './dispatch.js';
20
20
  export * from './trustHeartbeat.js';
21
21
  export * from './runtime.js';
22
+ export * from './storage/index.js';
23
+ export * from './interfaces/index.js';
24
+ export { isSqliteStorageBackend, sqliteDriver, SqliteStorageBackend, SQLITE_CAPABILITIES } from './dbdrivers/sqlite/index.js';
25
+ export { FAKE_CAPABILITIES, FakeStorageBackend, fakeDriver, isFakeStorageBackend, MockRemoteTransport, type MockRemoteTurnaround, type StorageTransport, type TransportRequestRecord, } from './dbdrivers/fake/index.js';
22
26
  export * from './store/memory.js';
23
- export * from './store/knowledge.js';
27
+ export { normalizeWrite } from './store/common.js';
28
+ export * from './facts_io.js';
29
+ export * from './maintenance_paths.js';
30
+ export * from './store/facts_restore.js';
24
31
  export * from './store/vector_repair.js';
25
32
  export * from './store/hybrid.js';
26
- export * from './store/source_picker.js';
27
33
  export * from './store/lexical.js';
28
34
  export * from './store/floors.js';
29
35
  export { registerSemanticBackend, registerVectorStore, type SemanticBackend, type VectorStore, } from '../mem-retrieval/index.js';
36
+ export * from './store/relation_backfill.js';
37
+ export { extractRelationCandidates, normalizeRelation, evaluateRelation, type RelationCandidate, type RelationEvaluation, type RelationExtractor, } from './relations/index.js';
@@ -0,0 +1,30 @@
1
+ /**
2
+ * What a storage driver DECLARES it can do (docs/DB_DRIVER_LAYOUT.md §二).
3
+ *
4
+ * Capabilities are how the HAL stays honest about optional behaviour without a second interface per
5
+ * driver: a backend that cannot do full-text search says so once, here, instead of the store probing
6
+ * it with a query that fails. Adding a flag is a MINOR contract change (an old driver that does not
7
+ * know the flag simply does not declare it; the host must tolerate unknown flags).
8
+ *
9
+ * @module interfaces/capabilities
10
+ */
11
+ export interface StorageCapabilities {
12
+ /** Async unit-of-work transactions (`LifecycleService.transaction`). */
13
+ transactions: boolean;
14
+ /** Content full-text search (`SearchIndex.searchContent`). */
15
+ fullText: boolean;
16
+ /** Title search (`SearchIndex.searchTitles` + the exact-title face). */
17
+ titles: boolean;
18
+ /** The relation graph (entities / triples / edges / graph reader). */
19
+ relations: boolean;
20
+ /**
21
+ * Persisted vector BLOBS (`facts.semantic_vector` / `hrr_vector`) and their inventory reads. The
22
+ * live vector INDEX is a retrieval concern resolved above the storage layer; this flag is about
23
+ * storing and reading the rows a driver owns.
24
+ */
25
+ vectors: boolean;
26
+ /** The backend applies its own schema migrations on open (`MigrationRunner`). */
27
+ migrations: boolean;
28
+ /** The contract is async (always `true` for contract major 1 — see `interfaces/version.ts`). */
29
+ async: true;
30
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * The storage HAL's async shape (DB-2).
3
+ *
4
+ * Every port method that touches stored state returns this: the in-process SQLite driver fulfils the
5
+ * contract by returning a plain value (it has no I/O to wait for), while a remote driver returns a
6
+ * promise. Callers ALWAYS `await`, so no store, no retrieval leg and no lifecycle caller has to know
7
+ * which kind of driver it holds — and a new driver never rewrites a call site.
8
+ *
9
+ * @module interfaces/common
10
+ */
11
+ export type Awaitable<T> = T | Promise<T>;
@@ -0,0 +1,65 @@
1
+ /**
2
+ * The storage error boundary (DB-3).
3
+ *
4
+ * SQLite reports failures as a driver error object with a numeric `errcode`; PostgreSQL has SQLSTATE,
5
+ * an HTTP backend has status codes, and none of those belong above the port. The store has exactly
6
+ * three things it can usefully do with a failed read/write: retry (the backend is temporarily
7
+ * unavailable), report a conflict (a uniqueness/constraint rule refused the write), or fail (anything
8
+ * else). This module names those three, and `db/sqlite.ts` — the one place that sees a driver error —
9
+ * maps into them.
10
+ *
11
+ * WHAT THIS IS NOT: a replacement for the domain refusals. `TITLE_IMMUTABLE`, `RELATIONS_NEED_NOTE`
12
+ * and the other `Error`s the store throws are decisions about the caller's request, not backend
13
+ * failures; they stay plain and unchanged. Only errors that come out of the database layer are
14
+ * classified here.
15
+ *
16
+ * The messages are preserved verbatim (the classification is metadata), so every existing caller and
17
+ * test that asserts on a driver message keeps working.
18
+ *
19
+ * @module interfaces/errors
20
+ */
21
+ /** What a caller can do about a failed storage operation. */
22
+ export type StorageFailureKind = 'unavailable' | 'constraint' | 'corrupt' | 'unknown';
23
+ /** A database-layer failure, classified so the boundary does not leak a driver's error shape. */
24
+ export declare class StorageError extends Error {
25
+ readonly kind: StorageFailureKind;
26
+ constructor(message: string, kind: StorageFailureKind, options?: {
27
+ code?: string | number;
28
+ cause?: unknown;
29
+ });
30
+ /** The driver's own code, kept for a log line — never branched on above the adapter. */
31
+ readonly code?: string | number;
32
+ /** Whether the same call may succeed if repeated later (a lock timeout, a restarting server). */
33
+ get retryable(): boolean;
34
+ }
35
+ /** The backend is temporarily unable to serve (SQLite: `SQLITE_BUSY`/`SQLITE_LOCKED`). */
36
+ export declare class StorageUnavailableError extends StorageError {
37
+ constructor(message: string, options?: {
38
+ code?: string | number;
39
+ cause?: unknown;
40
+ });
41
+ }
42
+ /** The backend refused the write because of one of its integrity rules. */
43
+ export declare class StorageConstraintError extends StorageError {
44
+ constructor(message: string, options?: {
45
+ code?: string | number;
46
+ cause?: unknown;
47
+ });
48
+ }
49
+ /** The stored data cannot be read (SQLite: `SQLITE_CORRUPT`/`SQLITE_NOTADB`). */
50
+ export declare class StorageCorruptError extends StorageError {
51
+ constructor(message: string, options?: {
52
+ code?: string | number;
53
+ cause?: unknown;
54
+ });
55
+ }
56
+ /** Whether a caught value is already one of ours (a second mapping must not wrap it again). */
57
+ export declare function isStorageError(error: unknown): error is StorageError;
58
+ /**
59
+ * Classify a driver failure into the storage vocabulary.
60
+ *
61
+ * Takes `unknown` because that is what a `catch` binds; anything already classified is returned
62
+ * untouched (mapping is idempotent), and a non-error value becomes a generic `StorageError` carrying
63
+ * its string form, so callers never have to re-check.
64
+ */
65
+ export declare function mapStorageError(error: unknown): StorageError;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The storage HAL contract (docs/DB_DRIVER_LAYOUT.md).
3
+ *
4
+ * Nothing in this directory may import `dbdrivers/`, `db/dao` or `node:sqlite`: these files are the
5
+ * vocabulary a driver implements and the store consumes, and they have to stay loadable in a host
6
+ * that has no SQLite at all.
7
+ *
8
+ * @module interfaces
9
+ */
10
+ export * from './common.js';
11
+ export * from './version.js';
12
+ export * from './capabilities.js';
13
+ export * from './migrations.js';
14
+ export * from './repositories.js';
15
+ export * from './search_index.js';
16
+ export * from './errors.js';
17
+ export * from './storage_backend.js';
18
+ export * from './storage_driver.js';
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Schema migration state, as the HAL sees it (DB-3).
3
+ *
4
+ * A driver keeps its own schema state (SQLite's `PRAGMA user_version`, a remote backend's version
5
+ * table or a service endpoint). The host needs two things from it and nothing more: what this open
6
+ * applied, and a way to RE-READ the current version without applying anything (the hook the
7
+ * migration/import tooling needs).
8
+ *
9
+ * @module interfaces/migrations
10
+ */
11
+ import type { Awaitable } from './common.js';
12
+ export interface MigrationRunner {
13
+ /** The version the backend reported before this open. */
14
+ readonly from: number;
15
+ /** The version this build brings (or brought) the backend to. */
16
+ readonly to: number;
17
+ /** The steps this open actually applied, in order (empty = the backend was already current). */
18
+ readonly applied: readonly number[];
19
+ /** Re-read the backend's current schema version, applying nothing. */
20
+ current(): Awaitable<number>;
21
+ }