@aionis/substrate 0.1.4 → 0.1.6

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 (44) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +101 -10
  3. package/dist/candidate-index.d.ts +25 -0
  4. package/dist/candidate-index.d.ts.map +1 -0
  5. package/dist/candidate-index.js +217 -0
  6. package/dist/candidate-index.js.map +1 -0
  7. package/dist/embedding-projection.d.ts +16 -0
  8. package/dist/embedding-projection.d.ts.map +1 -0
  9. package/dist/embedding-projection.js +101 -0
  10. package/dist/embedding-projection.js.map +1 -0
  11. package/dist/file-substrate.d.ts +3 -0
  12. package/dist/file-substrate.d.ts.map +1 -1
  13. package/dist/file-substrate.js +47 -1
  14. package/dist/file-substrate.js.map +1 -1
  15. package/dist/index.d.ts +3 -0
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +3 -0
  18. package/dist/index.js.map +1 -1
  19. package/dist/search.d.ts +11 -2
  20. package/dist/search.d.ts.map +1 -1
  21. package/dist/search.js +78 -7
  22. package/dist/search.js.map +1 -1
  23. package/dist/sqlite-substrate.d.ts +3 -0
  24. package/dist/sqlite-substrate.d.ts.map +1 -1
  25. package/dist/sqlite-substrate.js +61 -6
  26. package/dist/sqlite-substrate.js.map +1 -1
  27. package/dist/types.d.ts +3 -0
  28. package/dist/types.d.ts.map +1 -1
  29. package/dist/zvec-candidate-index.d.ts +42 -0
  30. package/dist/zvec-candidate-index.d.ts.map +1 -0
  31. package/dist/zvec-candidate-index.js +463 -0
  32. package/dist/zvec-candidate-index.js.map +1 -0
  33. package/docs/ADAPTER_CONTRACT.md +12 -2
  34. package/docs/API_USAGE.md +135 -0
  35. package/docs/CLI.md +21 -1
  36. package/docs/PRODUCT_CONTRACT.md +136 -0
  37. package/docs/RUNTIME_DUAL_WRITE_EXPERIMENT.md +14 -0
  38. package/docs/RUNTIME_ZVEC_CANDIDATE_INDEX.md +80 -0
  39. package/docs/STORE_CONTRACT.md +15 -0
  40. package/docs/V0_2_ROADMAP.md +12 -1
  41. package/docs/ZVEC_PROVIDER_EMBEDDING_EVAL.md +216 -0
  42. package/docs/ZVEC_SCALE_MAINTENANCE.md +89 -0
  43. package/examples/live-sidecar/index.mjs +189 -0
  44. package/package.json +16 -1
@@ -0,0 +1,463 @@
1
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
2
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
3
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
4
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
5
+ });
6
+ }
7
+ return path;
8
+ };
9
+ import { createHash } from "node:crypto";
10
+ import { existsSync, mkdirSync, readdirSync, renameSync, rmSync } from "node:fs";
11
+ import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
12
+ import { dirname, join } from "node:path";
13
+ const ZVEC_PACKAGE = "@zvec/zvec";
14
+ const DEFAULT_COLLECTION_NAME = "aionis_substrate_candidates_v1";
15
+ const DEFAULT_VECTOR_FIELD = "embedding";
16
+ const MANIFEST_FILE = "manifest.json";
17
+ function assertStatus(status, operation) {
18
+ const statuses = Array.isArray(status) ? status : [status];
19
+ const failed = statuses.find((item) => !item.ok);
20
+ if (failed)
21
+ throw new Error(`Zvec candidate index ${operation} failed: ${failed.code} ${failed.message}`);
22
+ }
23
+ function normalizeVector(value, label) {
24
+ if (value === null || value === undefined)
25
+ return null;
26
+ if (!Array.isArray(value) || value.length === 0)
27
+ throw new Error(`${label} vector must be a non-empty number array`);
28
+ const out = value.map((item, index) => {
29
+ if (!Number.isFinite(item))
30
+ throw new Error(`${label} vector contains a non-finite value at index ${index}`);
31
+ return Number(item);
32
+ });
33
+ return out;
34
+ }
35
+ function metadataVector(node) {
36
+ const metadata = node.metadata ?? {};
37
+ const candidates = [
38
+ metadata.embedding,
39
+ metadata.embedding_vector,
40
+ metadata.vector,
41
+ metadata.query_vector,
42
+ ];
43
+ for (const candidate of candidates) {
44
+ if (!Array.isArray(candidate))
45
+ continue;
46
+ if (candidate.every((item) => typeof item === "number" && Number.isFinite(item)))
47
+ return [...candidate];
48
+ }
49
+ return null;
50
+ }
51
+ function vectorHash(vector) {
52
+ const hash = createHash("sha256");
53
+ for (const value of vector)
54
+ hash.update(String(value)).update("\0");
55
+ return hash.digest("hex");
56
+ }
57
+ function stableMetadataText(metadata) {
58
+ if (!metadata)
59
+ return "";
60
+ return Object.entries(metadata)
61
+ .filter(([, value]) => typeof value === "string" || typeof value === "number" || typeof value === "boolean")
62
+ .sort(([a], [b]) => a.localeCompare(b))
63
+ .map(([key, value]) => `${key}:${String(value)}`)
64
+ .join(" ");
65
+ }
66
+ function nodeFingerprint(node, vector, embeddingModel) {
67
+ return JSON.stringify({
68
+ id: node.id,
69
+ scope: node.scope,
70
+ kind: node.kind,
71
+ title: node.title ?? null,
72
+ summary: node.summary,
73
+ lifecycle: node.lifecycle,
74
+ authority: node.authority,
75
+ confidence: node.confidence,
76
+ targetFiles: node.targetFiles ?? [],
77
+ payloadRef: node.payloadRef ?? null,
78
+ agentId: node.agentId ?? null,
79
+ teamId: node.teamId ?? null,
80
+ metadata: stableMetadataText(node.metadata),
81
+ updatedAt: node.updatedAt,
82
+ embeddingModel,
83
+ vectorHash: vectorHash(vector),
84
+ });
85
+ }
86
+ function docIdFor(scope, memoryId, embeddingModel) {
87
+ return createHash("sha256")
88
+ .update(scope)
89
+ .update("\0")
90
+ .update(memoryId)
91
+ .update("\0")
92
+ .update(embeddingModel)
93
+ .digest("hex");
94
+ }
95
+ function manifestKey(scope, memoryId, embeddingModel) {
96
+ return `${scope}\u0000${memoryId}\u0000${embeddingModel}`;
97
+ }
98
+ function dimensionDirName(dimension) {
99
+ return `dim-${dimension}`;
100
+ }
101
+ function parseDimensionDirName(value) {
102
+ const match = /^dim-(\d+)$/.exec(value);
103
+ if (!match)
104
+ return null;
105
+ const dimension = Number(match[1]);
106
+ return Number.isInteger(dimension) && dimension > 0 ? dimension : null;
107
+ }
108
+ function stringLiteral(value) {
109
+ return `'${value.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
110
+ }
111
+ function filterExpression(input, embeddingModel) {
112
+ const clauses = [
113
+ `scope = ${stringLiteral(input.scope)}`,
114
+ `embedding_model = ${stringLiteral(embeddingModel)}`,
115
+ ];
116
+ if (input.kinds?.length)
117
+ clauses.push(`kind in (${input.kinds.map(stringLiteral).join(", ")})`);
118
+ if (input.lifecycle?.length)
119
+ clauses.push(`lifecycle in (${input.lifecycle.map(stringLiteral).join(", ")})`);
120
+ if (input.authority?.length)
121
+ clauses.push(`authority in (${input.authority.map(stringLiteral).join(", ")})`);
122
+ if (input.agentId !== undefined)
123
+ clauses.push(`agent_id = ${input.agentId === null ? "''" : stringLiteral(input.agentId)}`);
124
+ if (input.teamId !== undefined)
125
+ clauses.push(`team_id = ${input.teamId === null ? "''" : stringLiteral(input.teamId)}`);
126
+ return clauses.join(" AND ");
127
+ }
128
+ function normalizeScore(rawScore) {
129
+ if (!Number.isFinite(rawScore))
130
+ return 0;
131
+ return Math.max(-1, Math.min(1, 1 - rawScore));
132
+ }
133
+ async function loadZvecModule() {
134
+ try {
135
+ return await import(__rewriteRelativeImportExtension(ZVEC_PACKAGE));
136
+ }
137
+ catch (err) {
138
+ const message = err instanceof Error ? err.message : String(err);
139
+ throw new Error(`Zvec candidate index requires optional dependency ${ZVEC_PACKAGE}. Install it with npm install ${ZVEC_PACKAGE}@0.5.0. Cause: ${message}`);
140
+ }
141
+ }
142
+ function createSchema(zvec, collectionName, vectorField, dimension) {
143
+ return new zvec.ZVecCollectionSchema({
144
+ name: collectionName,
145
+ vectors: {
146
+ name: vectorField,
147
+ dataType: zvec.ZVecDataType.VECTOR_FP32,
148
+ dimension,
149
+ indexParams: {
150
+ indexType: zvec.ZVecIndexType.FLAT,
151
+ metricType: zvec.ZVecMetricType.COSINE,
152
+ },
153
+ },
154
+ fields: [
155
+ { name: "memory_id", dataType: zvec.ZVecDataType.STRING, indexParams: { indexType: zvec.ZVecIndexType.INVERT } },
156
+ { name: "scope", dataType: zvec.ZVecDataType.STRING, indexParams: { indexType: zvec.ZVecIndexType.INVERT } },
157
+ { name: "embedding_model", dataType: zvec.ZVecDataType.STRING, indexParams: { indexType: zvec.ZVecIndexType.INVERT } },
158
+ { name: "kind", dataType: zvec.ZVecDataType.STRING, indexParams: { indexType: zvec.ZVecIndexType.INVERT } },
159
+ { name: "lifecycle", dataType: zvec.ZVecDataType.STRING, indexParams: { indexType: zvec.ZVecIndexType.INVERT } },
160
+ { name: "authority", dataType: zvec.ZVecDataType.STRING, indexParams: { indexType: zvec.ZVecIndexType.INVERT } },
161
+ { name: "agent_id", dataType: zvec.ZVecDataType.STRING, nullable: true, indexParams: { indexType: zvec.ZVecIndexType.INVERT } },
162
+ { name: "team_id", dataType: zvec.ZVecDataType.STRING, nullable: true, indexParams: { indexType: zvec.ZVecIndexType.INVERT } },
163
+ { name: "updated_at", dataType: zvec.ZVecDataType.STRING, indexParams: { indexType: zvec.ZVecIndexType.INVERT } },
164
+ ],
165
+ });
166
+ }
167
+ function recordToDoc(node, vector, embeddingModel) {
168
+ const fields = {
169
+ memory_id: node.id,
170
+ scope: node.scope,
171
+ embedding_model: embeddingModel,
172
+ kind: node.kind,
173
+ lifecycle: node.lifecycle,
174
+ authority: node.authority,
175
+ updated_at: node.updatedAt,
176
+ };
177
+ if (node.agentId)
178
+ fields.agent_id = node.agentId;
179
+ if (node.teamId)
180
+ fields.team_id = node.teamId;
181
+ return {
182
+ id: docIdFor(node.scope, node.id, embeddingModel),
183
+ vectors: { [DEFAULT_VECTOR_FIELD]: vector },
184
+ fields,
185
+ };
186
+ }
187
+ async function readManifest(path) {
188
+ try {
189
+ const parsed = JSON.parse(await readFile(path, "utf8"));
190
+ const entries = Array.isArray(parsed.entries) ? parsed.entries : [];
191
+ return new Map(entries.map((entry) => [manifestKey(entry.scope, entry.memoryId, entry.embeddingModel), entry]));
192
+ }
193
+ catch (err) {
194
+ if (err.code === "ENOENT")
195
+ return new Map();
196
+ throw err;
197
+ }
198
+ }
199
+ async function writeManifest(path, entries) {
200
+ const payload = {
201
+ version: 1,
202
+ entries: Array.from(entries.values()).sort((a, b) => a.scope.localeCompare(b.scope) ||
203
+ a.memoryId.localeCompare(b.memoryId) ||
204
+ a.embeddingModel.localeCompare(b.embeddingModel)),
205
+ };
206
+ const tempPath = `${path}.tmp-${process.pid}-${Date.now()}`;
207
+ await mkdir(dirname(path), { recursive: true });
208
+ await writeFile(tempPath, `${JSON.stringify(payload, null, 2)}\n`, "utf8");
209
+ await rename(tempPath, path);
210
+ }
211
+ export class ZvecCandidateIndex {
212
+ zvecPromise = null;
213
+ collections = new Map();
214
+ manifest = null;
215
+ options;
216
+ path;
217
+ manifestPath;
218
+ collectionName;
219
+ vectorField;
220
+ embeddingModel;
221
+ manifestDirty = false;
222
+ constructor(options) {
223
+ this.options = options;
224
+ if (!options.path.trim())
225
+ throw new Error("Zvec candidate index path is required");
226
+ this.path = options.path;
227
+ this.manifestPath = join(options.path, MANIFEST_FILE);
228
+ this.collectionName = options.collectionName ?? DEFAULT_COLLECTION_NAME;
229
+ this.vectorField = options.vectorField ?? DEFAULT_VECTOR_FIELD;
230
+ this.embeddingModel = options.embeddingModel ?? "default";
231
+ mkdirSync(options.path, { recursive: true });
232
+ }
233
+ async zvec() {
234
+ this.zvecPromise ??= loadZvecModule();
235
+ return this.zvecPromise;
236
+ }
237
+ async loadManifest() {
238
+ this.manifest ??= await readManifest(this.manifestPath);
239
+ return this.manifest;
240
+ }
241
+ async saveManifest() {
242
+ await writeManifest(this.manifestPath, await this.loadManifest());
243
+ this.manifestDirty = false;
244
+ }
245
+ markManifestDirty() {
246
+ this.manifestDirty = true;
247
+ }
248
+ async flushManifest() {
249
+ if (!this.manifestDirty)
250
+ return;
251
+ await this.saveManifest();
252
+ }
253
+ async collectionForDimension(dimension) {
254
+ if (!Number.isInteger(dimension) || dimension <= 0)
255
+ throw new Error(`invalid Zvec vector dimension: ${dimension}`);
256
+ const existing = this.collections.get(dimension);
257
+ if (existing)
258
+ return existing.collection;
259
+ const zvec = await this.zvec();
260
+ const collectionPath = join(this.path, dimensionDirName(dimension));
261
+ const collection = existsSync(collectionPath)
262
+ ? zvec.ZVecOpen(collectionPath)
263
+ : zvec.ZVecCreateAndOpen(collectionPath, createSchema(zvec, this.collectionName, this.vectorField, dimension));
264
+ this.collections.set(dimension, { dimension, collection });
265
+ return collection;
266
+ }
267
+ async nodeVector(node) {
268
+ const raw = this.options.vectorForNode
269
+ ? await this.options.vectorForNode(node)
270
+ : metadataVector(node);
271
+ return normalizeVector(raw, `node ${node.id}`);
272
+ }
273
+ async queryVector(input) {
274
+ const raw = this.options.vectorForQuery
275
+ ? await this.options.vectorForQuery(input)
276
+ : input.queryVector;
277
+ return normalizeVector(raw, "query");
278
+ }
279
+ async upsertNode(node) {
280
+ const vector = await this.nodeVector(node);
281
+ if (!vector) {
282
+ await this.deleteNode(node.scope, node.id);
283
+ return;
284
+ }
285
+ const embeddingModel = node.metadata?.embedding_model && typeof node.metadata.embedding_model === "string"
286
+ ? node.metadata.embedding_model
287
+ : this.embeddingModel;
288
+ const collection = await this.collectionForDimension(vector.length);
289
+ assertStatus(collection.upsertSync({
290
+ ...recordToDoc(node, vector, embeddingModel),
291
+ vectors: { [this.vectorField]: vector },
292
+ }), "upsert");
293
+ const manifest = await this.loadManifest();
294
+ manifest.set(manifestKey(node.scope, node.id, embeddingModel), {
295
+ scope: node.scope,
296
+ memoryId: node.id,
297
+ docId: docIdFor(node.scope, node.id, embeddingModel),
298
+ dimension: vector.length,
299
+ embeddingModel,
300
+ fingerprint: nodeFingerprint(node, vector, embeddingModel),
301
+ });
302
+ this.markManifestDirty();
303
+ }
304
+ async deleteNode(scope, id) {
305
+ const manifest = await this.loadManifest();
306
+ const entries = Array.from(manifest.entries()).filter(([, entry]) => entry.scope === scope && entry.memoryId === id);
307
+ if (entries.length > 0) {
308
+ for (const [key, entry] of entries) {
309
+ const collection = await this.collectionForDimension(entry.dimension);
310
+ assertStatus(collection.deleteSync(entry.docId), "delete");
311
+ manifest.delete(key);
312
+ }
313
+ this.markManifestDirty();
314
+ return;
315
+ }
316
+ for (const dimension of this.knownDimensions()) {
317
+ const collection = await this.collectionForDimension(dimension);
318
+ assertStatus(collection.deleteByFilterSync(`scope = ${stringLiteral(scope)} AND memory_id = ${stringLiteral(id)}`), "delete");
319
+ }
320
+ }
321
+ async search(input) {
322
+ const vector = await this.queryVector(input);
323
+ if (!vector)
324
+ return null;
325
+ const embeddingModel = input.embeddingModel ?? this.embeddingModel;
326
+ const collection = await this.collectionForDimension(vector.length);
327
+ const rows = collection.querySync({
328
+ fieldName: this.vectorField,
329
+ vector,
330
+ topk: input.limit ?? 50,
331
+ filter: filterExpression(input, embeddingModel),
332
+ includeVector: false,
333
+ outputFields: ["memory_id"],
334
+ });
335
+ return rows
336
+ .map((row) => {
337
+ const memoryId = typeof row.fields.memory_id === "string" ? row.fields.memory_id : row.id;
338
+ const reasons = [{
339
+ code: "zvec_candidate_index_match",
340
+ detail: `Zvec candidate score=${normalizeScore(row.score).toFixed(6)}`,
341
+ }];
342
+ return {
343
+ scope: input.scope,
344
+ memoryId,
345
+ score: normalizeScore(row.score),
346
+ reasons,
347
+ };
348
+ })
349
+ .sort((a, b) => b.score - a.score || a.memoryId.localeCompare(b.memoryId));
350
+ }
351
+ async rebuild(nodes) {
352
+ const buffered = [];
353
+ for (const node of nodes) {
354
+ const vector = await this.nodeVector(node);
355
+ if (!vector)
356
+ continue;
357
+ const embeddingModel = node.metadata?.embedding_model && typeof node.metadata.embedding_model === "string"
358
+ ? node.metadata.embedding_model
359
+ : this.embeddingModel;
360
+ buffered.push({ node, vector, embeddingModel });
361
+ }
362
+ const tmpPath = `${this.path}.rebuild-${process.pid}-${Date.now()}`;
363
+ rmSync(tmpPath, { recursive: true, force: true });
364
+ const next = new ZvecCandidateIndex({
365
+ ...this.options,
366
+ path: tmpPath,
367
+ collectionName: this.collectionName,
368
+ vectorField: this.vectorField,
369
+ embeddingModel: this.embeddingModel,
370
+ });
371
+ try {
372
+ for (const item of buffered)
373
+ await next.upsertNode(item.node);
374
+ const nextManifest = await next.loadManifest();
375
+ await next.close();
376
+ await this.close();
377
+ rmSync(this.path, { recursive: true, force: true });
378
+ renameSync(tmpPath, this.path);
379
+ mkdirSync(this.path, { recursive: true });
380
+ this.manifest = new Map(nextManifest);
381
+ this.manifestDirty = false;
382
+ return await this.verify(nodes);
383
+ }
384
+ catch (err) {
385
+ await next.close().catch(() => undefined);
386
+ rmSync(tmpPath, { recursive: true, force: true });
387
+ throw err;
388
+ }
389
+ }
390
+ async verify(nodes) {
391
+ const manifest = await this.loadManifest();
392
+ const expected = new Map();
393
+ for (const node of nodes) {
394
+ const vector = await this.nodeVector(node);
395
+ if (!vector)
396
+ continue;
397
+ const embeddingModel = node.metadata?.embedding_model && typeof node.metadata.embedding_model === "string"
398
+ ? node.metadata.embedding_model
399
+ : this.embeddingModel;
400
+ expected.set(manifestKey(node.scope, node.id, embeddingModel), {
401
+ node,
402
+ vector,
403
+ embeddingModel,
404
+ fingerprint: nodeFingerprint(node, vector, embeddingModel),
405
+ });
406
+ }
407
+ const missingNodeIds = [];
408
+ const orphanNodeIds = [];
409
+ const staleNodeIds = [];
410
+ for (const [key, expectedEntry] of expected) {
411
+ const actual = manifest.get(key);
412
+ if (!actual) {
413
+ missingNodeIds.push(expectedEntry.node.id);
414
+ continue;
415
+ }
416
+ if (actual.fingerprint !== expectedEntry.fingerprint)
417
+ staleNodeIds.push(expectedEntry.node.id);
418
+ const collection = await this.collectionForDimension(actual.dimension);
419
+ const fetched = collection.fetchSync({ ids: actual.docId, outputFields: ["memory_id"], includeVector: false });
420
+ if (!fetched[actual.docId] && !missingNodeIds.includes(expectedEntry.node.id)) {
421
+ missingNodeIds.push(expectedEntry.node.id);
422
+ }
423
+ }
424
+ for (const [key, actual] of manifest) {
425
+ if (!expected.has(key))
426
+ orphanNodeIds.push(actual.memoryId);
427
+ }
428
+ missingNodeIds.sort();
429
+ orphanNodeIds.sort();
430
+ staleNodeIds.sort();
431
+ return {
432
+ ok: missingNodeIds.length === 0 && orphanNodeIds.length === 0 && staleNodeIds.length === 0,
433
+ sourceCount: expected.size,
434
+ indexedCount: manifest.size,
435
+ missingNodeIds,
436
+ orphanNodeIds,
437
+ staleNodeIds,
438
+ };
439
+ }
440
+ async close() {
441
+ await this.flushManifest();
442
+ for (const { collection } of this.collections.values())
443
+ collection.closeSync();
444
+ this.collections.clear();
445
+ }
446
+ knownDimensions() {
447
+ const dimensions = new Set(this.collections.keys());
448
+ if (existsSync(this.path)) {
449
+ for (const entry of readdirSync(this.path, { withFileTypes: true })) {
450
+ if (!entry.isDirectory())
451
+ continue;
452
+ const dimension = parseDimensionDirName(entry.name);
453
+ if (dimension)
454
+ dimensions.add(dimension);
455
+ }
456
+ }
457
+ return Array.from(dimensions).sort((a, b) => a - b);
458
+ }
459
+ }
460
+ export function createZvecCandidateIndex(options) {
461
+ return new ZvecCandidateIndex(options);
462
+ }
463
+ //# sourceMappingURL=zvec-candidate-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zvec-candidate-index.js","sourceRoot":"","sources":["../src/zvec-candidate-index.ts"],"names":[],"mappings":"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"}
@@ -100,7 +100,17 @@ Given the same durable node state, adapters must return the same `searchNodes` i
100
100
 
101
101
  Search is read-only. It must not append `memory.decision.recorded`, lifecycle events, or any other event.
102
102
 
103
- Search is not a vector index and not the full Runtime admission policy. It is a deterministic substrate query for locating candidate memory nodes before higher-level governance decides whether they can affect an Agent turn.
103
+ Search is a deterministic substrate query for locating candidate memory nodes before higher-level governance decides whether they can affect an Agent turn. Vector candidate indexes can narrow the search window, while final node loading and scoring stay inside the adapter's canonical Substrate path.
104
+
105
+ When a candidate index is configured, both adapters must preserve the same final `searchNodes` ids, scores, and reason-code semantics. The index is allowed to preselect candidate ids, but the adapter must reload canonical nodes from the truth store before returning results.
106
+
107
+ Candidate index synchronization requirements:
108
+
109
+ - open-time rebuild is enabled by default;
110
+ - `putNode` write-through updates the index after the durable node mutation succeeds;
111
+ - `transitionLifecycle` write-through updates the index after the durable lifecycle mutation succeeds;
112
+ - `verify(nodes)` must expose missing, orphan, and stale entries so operators can rebuild instead of trusting silent drift.
113
+ - Zvec-backed indexes may require `queryVector`; if no usable query vector is supplied, the adapter must fall back to canonical deterministic search instead of returning an empty result set.
104
114
 
105
115
  ### 8. Context Preview and Decision Receipt Side Effect
106
116
 
@@ -167,7 +177,7 @@ The test suite currently checks:
167
177
  The adapter contract does not define:
168
178
 
169
179
  - vector similarity search;
170
- - embedding storage/indexing;
180
+ - embedding model management or embedding provider calls;
171
181
  - full Aionis Runtime admission policy;
172
182
  - SaaS tenancy;
173
183
  - external Agent orchestration.
package/docs/API_USAGE.md CHANGED
@@ -137,6 +137,141 @@ It supports structured filters for kind, lifecycle, authority, target files, own
137
137
 
138
138
  It is not vector search, semantic adjudication, or admission policy. Use `compileContext` when the Agent needs governed prompt surfaces.
139
139
 
140
+ ## Optional Candidate Index
141
+
142
+ Use a candidate index when the store needs a database-like lookup boundary before final Substrate scoring:
143
+
144
+ ```ts
145
+ import { createMemoryCandidateIndex, openSqliteAionisSubstrate } from "@aionis/substrate";
146
+
147
+ const candidateIndex = createMemoryCandidateIndex();
148
+ const store = await openSqliteAionisSubstrate({
149
+ path: "./substrate.sqlite",
150
+ candidateIndex,
151
+ });
152
+
153
+ await store.putNode({
154
+ id: "route-current",
155
+ scope: "repo-a",
156
+ kind: "procedure",
157
+ summary: "Use src/runtime.ts after verifier passed.",
158
+ lifecycle: "active",
159
+ authority: "trusted",
160
+ confidence: 0.95,
161
+ targetFiles: ["src/runtime.ts"],
162
+ });
163
+
164
+ const health = await candidateIndex.verify(await store.listNodes("repo-a"));
165
+ const results = await store.searchNodes({
166
+ scope: "repo-a",
167
+ query: "runtime verifier",
168
+ limit: 10,
169
+ });
170
+ ```
171
+
172
+ The index is optional. When configured, it receives write-through node updates and is rebuilt on open unless `rebuildCandidateIndexOnOpen: false` is set. Search still reloads canonical nodes from the store and applies Substrate scoring/filtering; the index only supplies candidate ids.
173
+
174
+ ### Zvec Candidate Index
175
+
176
+ Install Zvec only when local vector preselection is needed:
177
+
178
+ ```bash
179
+ npm install @aionis/substrate @zvec/zvec
180
+ ```
181
+
182
+ ```ts
183
+ import { createZvecCandidateIndex, openSqliteAionisSubstrate } from "@aionis/substrate";
184
+
185
+ const candidateIndex = createZvecCandidateIndex({
186
+ path: "./substrate.zvec",
187
+ embeddingModel: "text-embedding-3-small",
188
+ });
189
+
190
+ const store = await openSqliteAionisSubstrate({
191
+ path: "./substrate.sqlite",
192
+ candidateIndex,
193
+ });
194
+
195
+ await store.putNode({
196
+ id: "route-current",
197
+ scope: "repo-a",
198
+ kind: "procedure",
199
+ summary: "Use src/runtime.ts after verifier passed.",
200
+ lifecycle: "active",
201
+ authority: "trusted",
202
+ confidence: 0.95,
203
+ targetFiles: ["src/runtime.ts"],
204
+ metadata: {
205
+ embedding_model: "text-embedding-3-small",
206
+ embedding: [0.12, 0.34, 0.56],
207
+ },
208
+ });
209
+
210
+ const results = await store.searchNodes({
211
+ scope: "repo-a",
212
+ queryVector: [0.11, 0.35, 0.55],
213
+ embeddingModel: "text-embedding-3-small",
214
+ candidateLimit: 20,
215
+ limit: 10,
216
+ });
217
+ ```
218
+
219
+ `createZvecCandidateIndex` is a candidate-index adapter. File/SQLite remain the truth store, and queries without `queryVector` fall back to deterministic Substrate search.
220
+
221
+ ### Embedding Projection
222
+
223
+ Substrate does not call embedding providers by itself, but it exposes a stable
224
+ projection contract for hosts that want to generate vectors consistently:
225
+
226
+ ```ts
227
+ import {
228
+ buildAionisEmbeddingDocument,
229
+ buildAionisEmbeddingQuery,
230
+ createZvecCandidateIndex,
231
+ openSqliteAionisSubstrate,
232
+ } from "@aionis/substrate";
233
+
234
+ const memory = {
235
+ id: "route-current",
236
+ scope: "repo-a",
237
+ kind: "procedure" as const,
238
+ summary: "Use src/runtime.ts after verifier passed.",
239
+ lifecycle: "active" as const,
240
+ authority: "trusted" as const,
241
+ confidence: 0.95,
242
+ targetFiles: ["src/runtime.ts"],
243
+ };
244
+
245
+ const documentText = buildAionisEmbeddingDocument(memory);
246
+ const documentVector = await embedAsDocument(documentText);
247
+
248
+ const candidateIndex = createZvecCandidateIndex({
249
+ path: "./substrate.zvec",
250
+ embeddingModel: "text-embedding-v4",
251
+ vectorForQuery: async (input) => {
252
+ if (!input.query) return null;
253
+ return await embedAsQuery(buildAionisEmbeddingQuery(input.query));
254
+ },
255
+ });
256
+
257
+ const store = await openSqliteAionisSubstrate({
258
+ path: "./substrate.sqlite",
259
+ candidateIndex,
260
+ });
261
+
262
+ await store.putNode({
263
+ ...memory,
264
+ metadata: {
265
+ embedding_model: "text-embedding-v4",
266
+ embedding: documentVector,
267
+ },
268
+ });
269
+ ```
270
+
271
+ Use the same projection version for writes and searches. The structured
272
+ projection labels memory documents and retrieval queries separately, which is
273
+ useful for providers that distinguish document and query embeddings.
274
+
140
275
  ## Preview Context
141
276
 
142
277
  ```ts