/** * Memory Knowledge Graph — K7 index rebuild/repair (kgRebuildIndex, with * resume and validation against the reference reads) and the graph * integrity check. Split out of memory-kg.ts, which re-exports the public * symbols. */ import type { KgIndexStatus } from './memory-kg-index.js'; import type { KgScope } from './memory-kg-model.js'; export interface KgRebuildResult { success: boolean; status: KgIndexStatus; validation?: { sampledEntities: number; sampledOrigins: number; full: boolean; }; error?: string; } /** (Re)build a scope's derived index from canonical data — nodes, then * edges, then rules, that fixed order, resuming from the last checkpointed * `{phase, offset}` rather than restarting when a prior call was * interrupted mid-build. Every write here (`addToAdj`/`addToOriginIndex`) * is idempotent, so a page reprocessed after an interruption cannot * duplicate an entry. * * A concurrent ingest/rollback during the build is safe, not just tolerated: * the dual-write hooks run whenever state is not `absent`/`failed`, so a * write made mid-build is captured whether or not the scan has reached that * row yet — at worst twice, which idempotency absorbs for free. The one * residual race (a row deleted between the scan reading it and the scan's * own write landing) can leave a dangling ref in the index; it is never * observable as wrong data, because every indexed READ * (`kgIndexedEdgesByEndpoint`/`kgIndexedByOrigin`) returns `null` — and the * caller falls back to the exhaustive scan — the instant it cannot resolve * a ref it holds. This is the backend's real capability (single-row CAS, * no cross-row transaction), used honestly rather than claiming atomicity * it cannot provide. * * Ends in `validating`: samples up to `VALIDATE_SAMPLE` of the entities and * origins the scan actually saw, and re-reads them through the just-built * index, comparing against a FRESH, independent reference read * (`kgReferenceEdges`/`collectByOrigin`) — not the in-memory data the build * itself computed, which would only prove the build agrees with itself. A * write that silently failed, or a concurrent change the dual-write hooks * missed, is exactly what this catches before the index is ever trusted. */ export declare function kgRebuildIndex(options?: { scope?: KgScope; dbPath?: string; }): Promise; export interface KgIntegrityResult { success: boolean; edges: number; /** Edges naming an endpoint that does not exist. Retrieval is node-seeded, * so such an edge is a fact unreachable through either of the things it is * about — it can only be found by a check like this one. */ dangling: { key: string; missing: string[]; }[]; /** True when the edge scan did not cover the namespace: absence of a dangling * edge here is then not evidence that there is none. */ truncated?: boolean; error?: string; } /** Verify that every edge's endpoints exist. * * `kgIngest` now creates missing endpoints before writing an edge and * `kgRollback` removes edges whose endpoints it deleted, so a healthy graph * reports nothing. This exists for graphs written before either rule, and as * the check that says so rather than assuming it. */ export declare function kgIntegrityCheck(options?: { dbPath?: string; scope?: KgScope; /** Dangling edges to report before stopping (default 100). */ limit?: number; }): Promise; //# sourceMappingURL=memory-kg-rebuild.d.ts.map