/** * Memory Knowledge Graph — the name index and merge index, and entity * resolution through them (same-name candidates without name-only * identity). Split out of memory-kg.ts, which re-exports the public * symbols. */ import type { KgNamespaces } from './memory-kg-model.js'; import type { FailureLog } from './memory-kg-scan.js'; /** An entity the name index knows about. */ export interface KgNameCandidate { id: string; /** Identity-bearing type bucket; '' for an entity asserted without a type. */ type: string; } /** @returns the indexed entities, or null when the backend could not be read. * * The null is load-bearing: an unreadable index looks exactly like an empty * one, and treating a read failure as "no entities with this name" would make * the next write REPLACE the row with a single entry, erasing every other * same-name entity from the index. A later generic assertion would then see one * candidate and adopt it — a silent wrong merge caused by a read hiccup. */ export declare function readNameIndex(name: string, ns: KgNamespaces, dbPath: string | undefined): Promise; /** Persist (or clear) the index row for one name. * * The index is a HINT, not a source of truth: it is written after the entity * write lands, and a row that goes stale — pointing at an entity a rollback * removed — self-heals, because resolving onto a missing id makes the next * ingest create that entity fresh with an empty claim ledger, which is exactly * what a new entity is. Nothing reads the index to decide what the graph * contains; `kgStats`, `kgSearch` and `kgRollback` all read the claim * namespaces. */ export declare function writeNameIndex(name: string, entities: KgNameCandidate[], ns: KgNamespaces, dbPath: string | undefined, failures: FailureLog): Promise; /** What resolving a name against the index produced. */ interface ResolvedEntity { id: string; /** Same-name entities this assertion did NOT merge with. Reported, never * merged away — "Alex the person" and "Alex the service" are candidates for * a human or a consolidation pass to judge, not a merge the graph may do on * its own. */ candidates: KgNameCandidate[]; /** Index content to persist for this name, or null when it is already * correct. Written only after the entity write lands, so a refused write * never leaves the index pointing at an entity that does not exist. */ index: KgNameCandidate[] | null; } /** * Resolve (type, name) to the entity that should carry the assertion. * * Identity is the (type, name) tuple, so distinct types are distinct entities. * The one thing name-only identity got right — a generic label must not fork an * entity away from its typed self — is preserved here instead of in the key: * * - exact type-bucket match → that entity * - generic assertion, exactly one same-name entity → adopt it * - typed assertion, exactly one same-name entity and it is untyped → adopt it * and promote its type (its ID does not change, so references stay valid) * - anything else → a new entity, with the alternatives as candidates * * @returns null when the name index could not be read — the caller must refuse * the assertion rather than resolve it against an index it could not see. */ export declare function resolveEntity(name: string, type: string, ns: KgNamespaces, dbPath: string | undefined): Promise; export {}; //# sourceMappingURL=memory-kg-names.d.ts.map