@equationalapplications/core-llm-wiki 7.7.6 → 7.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.
- package/README.md +85 -0
- package/dist/{chunk-PBUZLSOM.mjs → chunk-M76CF2Q6.mjs} +1193 -189
- package/dist/chunk-M76CF2Q6.mjs.map +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1837 -289
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +575 -32
- package/dist/index.mjs.map +1 -1
- package/dist/{testing-BIFNLUva.d.mts → testing-CWZaXKLj.d.mts} +560 -4
- package/dist/{testing-BIFNLUva.d.ts → testing-CWZaXKLj.d.ts} +560 -4
- package/dist/testing.d.mts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +1142 -201
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +1 -1
- package/package.json +2 -2
- package/dist/chunk-PBUZLSOM.mjs.map +0 -1
|
@@ -214,6 +214,10 @@ interface HealResult {
|
|
|
214
214
|
remaining: number;
|
|
215
215
|
/** Heal candidates inside the recheck cooldown. */
|
|
216
216
|
deferred: number;
|
|
217
|
+
/** Present when a token budget stopped the pass early (spec §10.5). Unattempted candidates stay eligible. */
|
|
218
|
+
budgetStop?: {
|
|
219
|
+
requiredEstimate: number;
|
|
220
|
+
};
|
|
217
221
|
}
|
|
218
222
|
/**
|
|
219
223
|
* Opt-in evidence check for LLM-authored facts (spec §6). Default off: 7.x
|
|
@@ -232,6 +236,19 @@ interface GroundingConfig {
|
|
|
232
236
|
/** Characters retained per quote. Default 300. */
|
|
233
237
|
maxEvidenceChars?: number;
|
|
234
238
|
}
|
|
239
|
+
interface LibrarianGateConfig {
|
|
240
|
+
/** Neighbours fetched per candidate. Default 5. */
|
|
241
|
+
k?: number;
|
|
242
|
+
/** Cosine at or above which (with title Jaccard ≥ FUZZY_THRESHOLD) a candidate is a duplicate. Default 0.89 (calibrated against the 30 supersession scenarios). */
|
|
243
|
+
dupThreshold?: number;
|
|
244
|
+
/** Best-neighbour cosine below which a candidate is novel. Default 0.30 (calibrated against the 30 supersession scenarios). */
|
|
245
|
+
novelThreshold?: number;
|
|
246
|
+
}
|
|
247
|
+
/** `'legacy'` is the 7.x add-only librarian. `'ops'` is the spec §5.1 / §5.3 dispatcher. */
|
|
248
|
+
interface LibrarianConfig {
|
|
249
|
+
strategy?: 'legacy' | 'ops';
|
|
250
|
+
gate?: LibrarianGateConfig;
|
|
251
|
+
}
|
|
235
252
|
interface WikiConfig {
|
|
236
253
|
/**
|
|
237
254
|
* Prefix applied to every SQL table/index/trigger name. Must match
|
|
@@ -245,6 +262,12 @@ interface WikiConfig {
|
|
|
245
262
|
maxFtsResults?: number;
|
|
246
263
|
pruneEventsAfter?: number;
|
|
247
264
|
pruneRetainSoftDeletedFor?: number;
|
|
265
|
+
/**
|
|
266
|
+
* Days after `valid_to` before `runPrune` soft-deletes an expired or
|
|
267
|
+
* superseded fact (the soft-delete retention then hard-deletes it).
|
|
268
|
+
* Default null = keep history forever.
|
|
269
|
+
*/
|
|
270
|
+
pruneSupersededAfter?: number | null;
|
|
248
271
|
autoLibrarianThreshold?: number;
|
|
249
272
|
autoHealThreshold?: number;
|
|
250
273
|
orphanAfterDays?: number | null;
|
|
@@ -305,6 +328,21 @@ interface WikiConfig {
|
|
|
305
328
|
excludeDrafts?: boolean;
|
|
306
329
|
/** Evidence check for LLM-authored facts (spec §6). Default off. */
|
|
307
330
|
grounding?: GroundingConfig;
|
|
331
|
+
/** Emit an `llm_usage` diagnostic after every LLM text call. Default false. */
|
|
332
|
+
reportLlmUsage?: boolean;
|
|
333
|
+
/** Librarian strategy selection (spec 2026-09-29 §5.1). Default `{ strategy: 'legacy' }`. */
|
|
334
|
+
librarian?: LibrarianConfig;
|
|
335
|
+
/**
|
|
336
|
+
* `'auto'` (default): write() starts librarian/heal in the background when
|
|
337
|
+
* thresholds are crossed. `'deferred'`: write() only records the event; the
|
|
338
|
+
* host runs `runPendingMaintenance()` (spec 2026-09-29 §6). Pair with
|
|
339
|
+
* `librarian: { strategy: 'ops' }`: the legacy strategy reads only the
|
|
340
|
+
* newest 50 events per pass and advances the watermark past them, so a
|
|
341
|
+
* deferred backlog larger than that is never extracted.
|
|
342
|
+
*/
|
|
343
|
+
maintenance?: 'auto' | 'deferred';
|
|
344
|
+
/** `'auto'` mode only: also trigger the librarian when pending event text reaches ~this many tokens (chars/4). */
|
|
345
|
+
autoLibrarianTokenThreshold?: number;
|
|
308
346
|
}
|
|
309
347
|
interface ReadOptions {
|
|
310
348
|
maxResults?: number;
|
|
@@ -351,6 +389,18 @@ interface ReadOptions {
|
|
|
351
389
|
* Resolves call → `WikiConfig.excludeDrafts` → false.
|
|
352
390
|
*/
|
|
353
391
|
excludeDrafts?: boolean;
|
|
392
|
+
/**
|
|
393
|
+
* Valid-time snapshot (epoch ms): return facts live at this instant using
|
|
394
|
+
* current knowledge (spec §4.2). Omitted ⇒ current facts only.
|
|
395
|
+
* Throws `WikiInvalidReadOptions('asOf', …)` when not a finite number >= 0.
|
|
396
|
+
*/
|
|
397
|
+
asOf?: number;
|
|
398
|
+
/**
|
|
399
|
+
* Pack facts into roughly this many tokens (chars/4 estimate), most valuable
|
|
400
|
+
* per token first; the top fact is always kept (truncated if needed).
|
|
401
|
+
* Tasks and events are not affected. Spec 2026-09-29 §7.1.
|
|
402
|
+
*/
|
|
403
|
+
tokenBudget?: number;
|
|
354
404
|
}
|
|
355
405
|
interface WikiFact {
|
|
356
406
|
id: string;
|
|
@@ -425,6 +475,14 @@ interface WikiFact {
|
|
|
425
475
|
* `mapRowToFact` / `mapRowToTask`.
|
|
426
476
|
*/
|
|
427
477
|
trustTier?: 'unverified' | 'machine-confirmed' | 'human-reviewed';
|
|
478
|
+
/** Epoch ms the fact became true in the world. Absent ⇒ since `created_at`. */
|
|
479
|
+
valid_from?: number | null;
|
|
480
|
+
/** Epoch ms the fact stopped being true (exclusive). Absent ⇒ open-ended. */
|
|
481
|
+
valid_to?: number | null;
|
|
482
|
+
/** Id of the fact that replaced this one. Audit / `history()` only; reads never filter on it. */
|
|
483
|
+
superseded_by?: string | null;
|
|
484
|
+
/** Epoch ms the supersession was recorded (transaction time). Audit only. */
|
|
485
|
+
superseded_at?: number | null;
|
|
428
486
|
}
|
|
429
487
|
interface WikiTask {
|
|
430
488
|
id: string;
|
|
@@ -467,6 +525,8 @@ interface WikiEvent {
|
|
|
467
525
|
summary: string;
|
|
468
526
|
related_entry_id?: string | null;
|
|
469
527
|
created_at: number;
|
|
528
|
+
/** Real-world time of the event (epoch ms). `created_at` stays ingestion time and remains the ordering key. */
|
|
529
|
+
occurred_at?: number | null;
|
|
470
530
|
}
|
|
471
531
|
interface WikiEdge {
|
|
472
532
|
id: string;
|
|
@@ -499,6 +559,10 @@ interface GraphTraversalOptions {
|
|
|
499
559
|
* Resolves call → `WikiConfig.excludeDrafts` → false.
|
|
500
560
|
*/
|
|
501
561
|
excludeDrafts?: boolean;
|
|
562
|
+
/** Valid-time snapshot for traversal (epoch ms); an edge is walkable only when both endpoints are live at this instant. Omitted ⇒ now. */
|
|
563
|
+
asOf?: number;
|
|
564
|
+
/** Pack nodes (anchor first, then BFS order) into roughly this many tokens; edges to dropped nodes are removed. */
|
|
565
|
+
tokenBudget?: number;
|
|
502
566
|
}
|
|
503
567
|
interface GraphNeighborhood {
|
|
504
568
|
/** Anchor node first, then discovered neighbors ordered by depth ASC, then updated_at DESC. */
|
|
@@ -538,6 +602,22 @@ interface LLMProvider {
|
|
|
538
602
|
systemPrompt: string;
|
|
539
603
|
userPrompt: string;
|
|
540
604
|
}) => Promise<string>;
|
|
605
|
+
/**
|
|
606
|
+
* Optional. When present, core calls this instead of `generateText` and
|
|
607
|
+
* meters the reported usage (spec 2026-09-29 §6.3). Called with the provider
|
|
608
|
+
* as `this`. Omit `usage` (or return malformed numbers) to fall back to the
|
|
609
|
+
* chars/4 estimate.
|
|
610
|
+
*/
|
|
611
|
+
generateTextWithUsage?: (params: {
|
|
612
|
+
systemPrompt: string;
|
|
613
|
+
userPrompt: string;
|
|
614
|
+
}) => Promise<{
|
|
615
|
+
text: string;
|
|
616
|
+
usage?: {
|
|
617
|
+
inputTokens: number;
|
|
618
|
+
outputTokens: number;
|
|
619
|
+
};
|
|
620
|
+
}>;
|
|
541
621
|
/**
|
|
542
622
|
* Optional. When provided, enables semantic similarity search in `read()`.
|
|
543
623
|
* Must return a stable-dimension float array for any input text.
|
|
@@ -672,9 +752,9 @@ type WikiDiagnosticSeverity = 'info' | 'warn' | 'error';
|
|
|
672
752
|
* Closed for this release series, but new codes are added in minor versions:
|
|
673
753
|
* hosts must tolerate codes they do not recognize.
|
|
674
754
|
*/
|
|
675
|
-
type WikiDiagnosticCode = 'ingest_chunk_failed' | 'fact_rejected' | 'task_rejected' | 'fact_deduplicated' | 'edge_dropped' | 'embedding_failed' | 'hook_failed' | 'background_job_failed' | 'heal_skipped' | 'grounding_missing' | 'grounding_failed' | 'classification_low_confidence' | 'classification_invalid';
|
|
755
|
+
type WikiDiagnosticCode = 'ingest_chunk_failed' | 'fact_rejected' | 'task_rejected' | 'fact_deduplicated' | 'edge_dropped' | 'embedding_failed' | 'hook_failed' | 'background_job_failed' | 'heal_skipped' | 'grounding_missing' | 'grounding_failed' | 'classification_low_confidence' | 'classification_invalid' | 'llm_usage' | 'librarian_gate' | 'librarian_op_rejected' | 'contradicts_document' | 'resolve_failed' | 'read_budget' | 'event_retention_held';
|
|
676
756
|
/** The service run that emitted the diagnostic. */
|
|
677
|
-
type WikiDiagnosticOperation = 'ingest' | 'upsertGraph' | 'librarian' | 'heal' | 'ontologyBackfill' | 'reembed' | 'importDump' | 'write';
|
|
757
|
+
type WikiDiagnosticOperation = 'ingest' | 'upsertGraph' | 'librarian' | 'heal' | 'ontologyBackfill' | 'reembed' | 'importDump' | 'write' | 'supersede' | 'read' | 'prune';
|
|
678
758
|
/** `'auto'` when a write threshold started the run (auto-librarian / auto-heal); `'call'` when the host did. */
|
|
679
759
|
type WikiDiagnosticTrigger = 'call' | 'auto';
|
|
680
760
|
/** Identifiers only — never titles, bodies, quotes, LLM output, provider messages, or hashes of content. */
|
|
@@ -695,6 +775,24 @@ interface WikiDiagnosticDetail {
|
|
|
695
775
|
chunkIndexes?: number[];
|
|
696
776
|
/** Aggregated emissions only. */
|
|
697
777
|
count?: number;
|
|
778
|
+
/** `llm_usage` only. */
|
|
779
|
+
inputTokens?: number;
|
|
780
|
+
/** `llm_usage` only. */
|
|
781
|
+
outputTokens?: number;
|
|
782
|
+
/** `llm_usage` only: true when a figure is the chars/4 estimate. */
|
|
783
|
+
estimated?: boolean;
|
|
784
|
+
/** librarian_gate only. */
|
|
785
|
+
gateNoop?: number;
|
|
786
|
+
/** librarian_gate only. */
|
|
787
|
+
gateAdd?: number;
|
|
788
|
+
/** librarian_gate only. */
|
|
789
|
+
gateAmbiguous?: number;
|
|
790
|
+
/** read_budget only. */
|
|
791
|
+
candidates?: number;
|
|
792
|
+
/** read_budget only. */
|
|
793
|
+
packed?: number;
|
|
794
|
+
/** read_budget only. */
|
|
795
|
+
tokensUsed?: number;
|
|
698
796
|
}
|
|
699
797
|
interface WikiDiagnostic {
|
|
700
798
|
code: WikiDiagnosticCode;
|
|
@@ -818,6 +916,8 @@ interface FormatContextOptions {
|
|
|
818
916
|
includeTags?: boolean;
|
|
819
917
|
includeEntityIds?: boolean;
|
|
820
918
|
includeFactScores?: boolean;
|
|
919
|
+
/** Title + body only; overrides every include* flag. Default false. */
|
|
920
|
+
compact?: boolean;
|
|
821
921
|
factWeights?: {
|
|
822
922
|
confidence?: number;
|
|
823
923
|
accessCount?: number;
|
|
@@ -1050,6 +1150,22 @@ declare class WikiDraftNotFound extends Error {
|
|
|
1050
1150
|
readonly code: "WIKI_DRAFT_NOT_FOUND";
|
|
1051
1151
|
constructor();
|
|
1052
1152
|
}
|
|
1153
|
+
type WikiSupersedeReason = 'not_found' | 'already_superseded' | 'immutable_target' | 'cycle' | 'cross_entity';
|
|
1154
|
+
/** Thrown by `supersede()` (spec §4.3). Contextless like {@link WikiDraftNotFound}. */
|
|
1155
|
+
declare class WikiSupersedeError extends Error {
|
|
1156
|
+
readonly code: "WIKI_SUPERSEDE_REJECTED";
|
|
1157
|
+
readonly reason: WikiSupersedeReason;
|
|
1158
|
+
constructor(reason: WikiSupersedeReason);
|
|
1159
|
+
}
|
|
1160
|
+
/** A new fact to create as the replacement, or the id of an existing fact. */
|
|
1161
|
+
type SupersedeReplacement = string | {
|
|
1162
|
+
title: string;
|
|
1163
|
+
body: string;
|
|
1164
|
+
tags?: string[];
|
|
1165
|
+
confidence?: WikiFact['confidence'];
|
|
1166
|
+
source_type?: 'user_stated' | 'user_confirmed' | 'librarian_inferred';
|
|
1167
|
+
valid_from?: number;
|
|
1168
|
+
};
|
|
1053
1169
|
/** One page of `listDrafts`. `nextCursor` is opaque; pass it back unchanged. */
|
|
1054
1170
|
interface DraftPage {
|
|
1055
1171
|
facts: WikiFact[];
|
|
@@ -1092,6 +1208,62 @@ interface WikiInstructions {
|
|
|
1092
1208
|
heal: string;
|
|
1093
1209
|
ontologyBackfill: string;
|
|
1094
1210
|
}
|
|
1211
|
+
type MaintenanceJob = 'librarian' | 'heal' | 'reembed';
|
|
1212
|
+
interface PendingMaintenance {
|
|
1213
|
+
entityId: string;
|
|
1214
|
+
/** Events after the librarian watermark. */
|
|
1215
|
+
pendingEvents: number;
|
|
1216
|
+
/** ceil(sum of pending event summary chars / 4). */
|
|
1217
|
+
pendingTokensEstimate: number;
|
|
1218
|
+
/** Same rule as auto-heal: events since the heal checkpoint >= autoHealThreshold. */
|
|
1219
|
+
healDue: boolean;
|
|
1220
|
+
/**
|
|
1221
|
+
* Non-deleted facts (superseded history rows included, matching what
|
|
1222
|
+
* `runReembed` sweeps) with no stored embedding that are still retryable.
|
|
1223
|
+
* Always false without `embed`.
|
|
1224
|
+
*/
|
|
1225
|
+
reembedPending: boolean;
|
|
1226
|
+
}
|
|
1227
|
+
interface RunPendingMaintenanceOptions {
|
|
1228
|
+
/** Default: every entity with pending work. */
|
|
1229
|
+
entityIds?: string[];
|
|
1230
|
+
/** generateText tokens (provider-reported or chars/4). Omitted = unbounded. */
|
|
1231
|
+
tokenBudget?: number;
|
|
1232
|
+
/** Wall-clock milliseconds from the call. Checked between units; a unit in flight is never interrupted. */
|
|
1233
|
+
deadlineMs?: number;
|
|
1234
|
+
/** Default all three. */
|
|
1235
|
+
jobs?: MaintenanceJob[];
|
|
1236
|
+
}
|
|
1237
|
+
type MaintenanceStopReason = {
|
|
1238
|
+
reason: 'complete';
|
|
1239
|
+
} | {
|
|
1240
|
+
reason: 'deadline';
|
|
1241
|
+
} | {
|
|
1242
|
+
reason: 'budget_exhausted';
|
|
1243
|
+
} | {
|
|
1244
|
+
reason: 'budget_too_small';
|
|
1245
|
+
job: 'librarian' | 'heal';
|
|
1246
|
+
entityId: string;
|
|
1247
|
+
requiredEstimate: number;
|
|
1248
|
+
};
|
|
1249
|
+
interface EntityMaintenanceReport {
|
|
1250
|
+
entityId: string;
|
|
1251
|
+
librarianPasses: number;
|
|
1252
|
+
factsWritten: number;
|
|
1253
|
+
healPasses: number;
|
|
1254
|
+
reembedded: boolean;
|
|
1255
|
+
/** Set when a lock was held elsewhere; nothing ran for that job. */
|
|
1256
|
+
busy?: MaintenanceJob[];
|
|
1257
|
+
}
|
|
1258
|
+
interface RunPendingMaintenanceResult {
|
|
1259
|
+
perEntity: EntityMaintenanceReport[];
|
|
1260
|
+
tokensUsed: number;
|
|
1261
|
+
/** True when any usage figure was a chars/4 estimate. */
|
|
1262
|
+
estimated: boolean;
|
|
1263
|
+
/** null when no tokenBudget was given. */
|
|
1264
|
+
remaining: number | null;
|
|
1265
|
+
stoppedReason: MaintenanceStopReason;
|
|
1266
|
+
}
|
|
1095
1267
|
|
|
1096
1268
|
interface WikiOutboxEvent<T = unknown> {
|
|
1097
1269
|
id: string;
|
|
@@ -1147,6 +1319,36 @@ declare class OutboxRepository extends BaseRepository {
|
|
|
1147
1319
|
acknowledge(ids: string[]): Promise<void>;
|
|
1148
1320
|
}
|
|
1149
1321
|
|
|
1322
|
+
/**
|
|
1323
|
+
* Single definition of fact liveness (spec 2026-09-29 §4.2). Every read path
|
|
1324
|
+
* uses these so SQL and JS can never disagree.
|
|
1325
|
+
*
|
|
1326
|
+
* - 'asOf' — valid time using current knowledge: live at T when
|
|
1327
|
+
* COALESCE(valid_from, created_at) <= T < valid_to (valid_to NULL = open).
|
|
1328
|
+
* - 'current' — live now per the row's own validity columns. A row with both
|
|
1329
|
+
* columns NULL is always current; created_at is deliberately ignored so
|
|
1330
|
+
* existing rows (and fixtures with arbitrary created_at) stay current.
|
|
1331
|
+
*/
|
|
1332
|
+
type LiveMode = 'current' | 'asOf';
|
|
1333
|
+
|
|
1334
|
+
/** Subset of temporal columns that {@link EntryRepository.setTemporal} may write (spec 2026-09-29 §4.3). */
|
|
1335
|
+
type TemporalFields = {
|
|
1336
|
+
valid_from?: number | null;
|
|
1337
|
+
valid_to?: number | null;
|
|
1338
|
+
superseded_by?: string | null;
|
|
1339
|
+
superseded_at?: number | null;
|
|
1340
|
+
};
|
|
1341
|
+
/** Lightweight projection used by TemporalService for supersession chain walks. */
|
|
1342
|
+
type TemporalRow = {
|
|
1343
|
+
id: string;
|
|
1344
|
+
entity_id: string;
|
|
1345
|
+
source_type: WikiFact['source_type'];
|
|
1346
|
+
deleted_at: number | null;
|
|
1347
|
+
created_at: number;
|
|
1348
|
+
valid_from: number | null;
|
|
1349
|
+
valid_to: number | null;
|
|
1350
|
+
superseded_by: string | null;
|
|
1351
|
+
};
|
|
1150
1352
|
type EntryRowMetadata = {
|
|
1151
1353
|
id: string;
|
|
1152
1354
|
entity_id: string;
|
|
@@ -1370,6 +1572,23 @@ declare class EntryRepository extends BaseRepository {
|
|
|
1370
1572
|
* Used by MaintenanceService.doRunHeal().
|
|
1371
1573
|
*/
|
|
1372
1574
|
softDeleteByIds(ids: string[], entityId: string, tx: SQLiteAdapter): Promise<void>;
|
|
1575
|
+
/** Spec §4: write any subset of the four temporal columns. Absent key = untouched; null = clear. */
|
|
1576
|
+
setTemporal(id: string, entityId: string, fields: TemporalFields, tx: SQLiteAdapter, opts?: {
|
|
1577
|
+
outbox?: boolean;
|
|
1578
|
+
}): Promise<number>;
|
|
1579
|
+
findTemporalRow(id: string, tx?: SQLiteAdapter): Promise<TemporalRow | null>;
|
|
1580
|
+
/**
|
|
1581
|
+
* Ids of non-deleted facts NOT live at `t` (spec §4.2). In 'current' mode a
|
|
1582
|
+
* row with both validity columns NULL is always live, so the query is
|
|
1583
|
+
* restricted to rows that carry a validity column — served by the partial
|
|
1584
|
+
* entries_temporal_idx.
|
|
1585
|
+
*/
|
|
1586
|
+
findNonLiveIdsByEntityIds(entityIds: readonly string[], mode: LiveMode, t: number, tx?: SQLiteAdapter): Promise<Set<string>>;
|
|
1587
|
+
findSupersessionChainIds(entityId: string, factId: string, maxDepth: number, tx?: SQLiteAdapter): Promise<{
|
|
1588
|
+
predecessors: string[];
|
|
1589
|
+
successors: string[];
|
|
1590
|
+
}>;
|
|
1591
|
+
findExpiredIds(entityId: string, cutoff: number, tx?: SQLiteAdapter): Promise<string[]>;
|
|
1373
1592
|
/**
|
|
1374
1593
|
* Bulk soft-delete all entries for an entity.
|
|
1375
1594
|
* Stages DELETE outbox entries for each row in the same transaction.
|
|
@@ -1503,6 +1722,10 @@ declare class EntryRepository extends BaseRepository {
|
|
|
1503
1722
|
getLegacyMigrationSQL(): string;
|
|
1504
1723
|
findRecentByEntityIds(entityIds: readonly string[], limit: number, tx?: SQLiteAdapter, opts?: {
|
|
1505
1724
|
excludeDrafts?: boolean;
|
|
1725
|
+
live?: {
|
|
1726
|
+
mode: LiveMode;
|
|
1727
|
+
t: number;
|
|
1728
|
+
};
|
|
1506
1729
|
}): Promise<WikiFact[]>;
|
|
1507
1730
|
/** IDs of live draft facts for the given entities (spec §5.1). Callers pass ≤ 100 entity ids. */
|
|
1508
1731
|
findDraftIdsByEntityIds(entityIds: readonly string[], tx?: SQLiteAdapter): Promise<Set<string>>;
|
|
@@ -1577,6 +1800,13 @@ declare class EntryRepository extends BaseRepository {
|
|
|
1577
1800
|
id: string;
|
|
1578
1801
|
title: string;
|
|
1579
1802
|
}>>;
|
|
1803
|
+
/**
|
|
1804
|
+
* Count of live facts for `entityId` with no stored embedding that are still
|
|
1805
|
+
* retryable (`embedding_attempts < maxAttempts`). Backs the deferred
|
|
1806
|
+
* maintenance pending report's `reembedPending` flag and the reembed job's
|
|
1807
|
+
* entity selection (PR-C 2026-09-29).
|
|
1808
|
+
*/
|
|
1809
|
+
countReembedPending(entityId: string, maxAttempts: number, tx?: SQLiteAdapter): Promise<number>;
|
|
1580
1810
|
}
|
|
1581
1811
|
|
|
1582
1812
|
/**
|
|
@@ -1622,6 +1852,15 @@ declare class SourceRefIndexRepository extends BaseRepository {
|
|
|
1622
1852
|
findActiveByEntityAndHash(entityId: string, sourceHash: string, tx?: SQLiteAdapter): Promise<string | null>;
|
|
1623
1853
|
}
|
|
1624
1854
|
|
|
1855
|
+
/**
|
|
1856
|
+
* The op-based librarian's high-water mark on the `events` table. Stored
|
|
1857
|
+
* alongside `memory_checkpoint` / `heal_checkpoint` so an entity's
|
|
1858
|
+
* maintenance state stays in one row. See spec 2026-09-29 §4.1.
|
|
1859
|
+
*/
|
|
1860
|
+
type LibrarianWatermark = {
|
|
1861
|
+
at: number;
|
|
1862
|
+
id: string;
|
|
1863
|
+
};
|
|
1625
1864
|
declare class MetadataRepository extends BaseRepository {
|
|
1626
1865
|
getCheckpoint(entityId: string, tx: SQLiteAdapter): Promise<{
|
|
1627
1866
|
memory?: number;
|
|
@@ -1632,6 +1871,17 @@ declare class MetadataRepository extends BaseRepository {
|
|
|
1632
1871
|
heal?: number;
|
|
1633
1872
|
}, tx: SQLiteAdapter): Promise<void>;
|
|
1634
1873
|
deleteCheckpoint(entityId: string, tx: SQLiteAdapter): Promise<void>;
|
|
1874
|
+
/**
|
|
1875
|
+
* Read the op-based librarian's high-water mark. Returns `null` when the
|
|
1876
|
+
* entity has never had its watermark set.
|
|
1877
|
+
*/
|
|
1878
|
+
getLibrarianWatermark(entityId: string, tx: SQLiteAdapter): Promise<LibrarianWatermark | null>;
|
|
1879
|
+
/**
|
|
1880
|
+
* Write the op-based librarian's high-water mark. Uses `ON CONFLICT`
|
|
1881
|
+
* `DO UPDATE` so existing `memory_checkpoint` / `heal_checkpoint` rows
|
|
1882
|
+
* are preserved verbatim.
|
|
1883
|
+
*/
|
|
1884
|
+
setLibrarianWatermark(entityId: string, wm: LibrarianWatermark, tx: SQLiteAdapter): Promise<void>;
|
|
1635
1885
|
getMeta(key: string, tx?: SQLiteAdapter): Promise<string | null>;
|
|
1636
1886
|
setMeta(key: string, value: string, tx: SQLiteAdapter): Promise<void>;
|
|
1637
1887
|
deleteMeta(key: string, tx?: SQLiteAdapter): Promise<void>;
|
|
@@ -1987,6 +2237,11 @@ interface NeighborhoodQueryOptions {
|
|
|
1987
2237
|
* intentionally start from a draft. Default false (drafts visible).
|
|
1988
2238
|
*/
|
|
1989
2239
|
excludeDrafts?: boolean;
|
|
2240
|
+
/** Liveness gate for discovered nodes: 'current' (live now) or 'asOf' (valid time T). Always supplied by GraphTraversalService. */
|
|
2241
|
+
live: {
|
|
2242
|
+
mode: LiveMode;
|
|
2243
|
+
t: number;
|
|
2244
|
+
};
|
|
1990
2245
|
}
|
|
1991
2246
|
declare class EdgeRepository extends BaseRepository {
|
|
1992
2247
|
/**
|
|
@@ -2077,6 +2332,40 @@ declare class EmbeddingService {
|
|
|
2077
2332
|
body: string;
|
|
2078
2333
|
tags: string | string[];
|
|
2079
2334
|
}, ctx?: EmbedDiagnosticContext): Promise<EmbedFactResult>;
|
|
2335
|
+
/**
|
|
2336
|
+
* Compute half: build the embed text, call embed(), validate the result,
|
|
2337
|
+
* mark any embed-time failure, and return the validated Float32 vector.
|
|
2338
|
+
*
|
|
2339
|
+
* Failure kinds: `no_provider`, `invalid_vector`, `float32_overflow`,
|
|
2340
|
+
* `provider_error`. All embed-time failures are marked via `markFailure`;
|
|
2341
|
+
* `no_provider` deliberately does not mark (spec §2.4).
|
|
2342
|
+
*
|
|
2343
|
+
* Storage errors are NOT possible here — that is `storeFactVector`'s domain.
|
|
2344
|
+
*/
|
|
2345
|
+
embedTextForFact(fact: {
|
|
2346
|
+
id: string;
|
|
2347
|
+
entity_id: string;
|
|
2348
|
+
title: string;
|
|
2349
|
+
body: string;
|
|
2350
|
+
tags: string | string[];
|
|
2351
|
+
}, ctx?: EmbedDiagnosticContext, opts?: {
|
|
2352
|
+
markFailures?: boolean;
|
|
2353
|
+
}): Promise<{
|
|
2354
|
+
ok: true;
|
|
2355
|
+
vector: Float32Array;
|
|
2356
|
+
} | {
|
|
2357
|
+
ok: false;
|
|
2358
|
+
kind: EmbedFailureKind;
|
|
2359
|
+
}>;
|
|
2360
|
+
/**
|
|
2361
|
+
* Storage half: persist the computed vector to the entry row, then fire the
|
|
2362
|
+
* `onEmbeddingPersisted` hook. Failure kinds: `storage_error` only — embed
|
|
2363
|
+
* failures do not originate here, so they cannot be marked as such (spec §3.2, D3).
|
|
2364
|
+
*/
|
|
2365
|
+
storeFactVector(fact: {
|
|
2366
|
+
id: string;
|
|
2367
|
+
entity_id: string;
|
|
2368
|
+
}, float32Vector: Float32Array, ctx?: EmbedDiagnosticContext): Promise<EmbedFactResult>;
|
|
2080
2369
|
private reportEmbed;
|
|
2081
2370
|
/** For callers that invoke `notifyEmbeddingPersisted` directly and catch its failure. */
|
|
2082
2371
|
reportHookFailed(ctx: EmbedDiagnosticContext, entityId: string, factId: string): void;
|
|
@@ -2161,6 +2450,12 @@ interface GroundingTrust {
|
|
|
2161
2450
|
last_verified_by?: string;
|
|
2162
2451
|
}
|
|
2163
2452
|
|
|
2453
|
+
type LabeledEvent = {
|
|
2454
|
+
label: string;
|
|
2455
|
+
event: WikiEvent;
|
|
2456
|
+
at: number;
|
|
2457
|
+
};
|
|
2458
|
+
|
|
2164
2459
|
declare class PromptService {
|
|
2165
2460
|
private globalOverrides?;
|
|
2166
2461
|
private grounding;
|
|
@@ -2216,6 +2511,28 @@ declare class PromptService {
|
|
|
2216
2511
|
systemPrompt: string;
|
|
2217
2512
|
userPrompt: string;
|
|
2218
2513
|
};
|
|
2514
|
+
/** Ops extract (spec §5.2): events only — no existing facts. */
|
|
2515
|
+
buildOpsExtractPrompt(events: LabeledEvent[], ontologyContext?: OntologyPromptContext | null): {
|
|
2516
|
+
systemPrompt: string;
|
|
2517
|
+
userPrompt: string;
|
|
2518
|
+
groundingCorpus?: string[];
|
|
2519
|
+
};
|
|
2520
|
+
/** Ops resolve (spec §5.4): only each item's own neighbours. */
|
|
2521
|
+
buildOpsResolvePrompt(items: Array<{
|
|
2522
|
+
item: number;
|
|
2523
|
+
candidate: {
|
|
2524
|
+
title: string;
|
|
2525
|
+
body: string;
|
|
2526
|
+
};
|
|
2527
|
+
existing: Array<{
|
|
2528
|
+
ref: string;
|
|
2529
|
+
title: string;
|
|
2530
|
+
body: string;
|
|
2531
|
+
}>;
|
|
2532
|
+
}>): {
|
|
2533
|
+
systemPrompt: string;
|
|
2534
|
+
userPrompt: string;
|
|
2535
|
+
};
|
|
2219
2536
|
/**
|
|
2220
2537
|
* The system prompt each writer would send, without hydrating data (spec
|
|
2221
2538
|
* §8.3). `buildSystemPrompt` with no variables hydrates only ontology
|
|
@@ -2456,6 +2773,22 @@ declare class EventRepository extends BaseRepository {
|
|
|
2456
2773
|
prune(entityId: string, cutoff: number): Promise<{
|
|
2457
2774
|
changes: number;
|
|
2458
2775
|
}>;
|
|
2776
|
+
/**
|
|
2777
|
+
* Watermark-guarded prune (spec 2026-09-29 competitive-memory §6): delete
|
|
2778
|
+
* events at or before `cutoff` **and** at-or-before the librarian watermark.
|
|
2779
|
+
* Events the librarian has not processed yet are retention-held, never
|
|
2780
|
+
* deleted. `wm = null` (no watermark yet) deletes nothing.
|
|
2781
|
+
* Used by runPrune under the deferred/ops strategies.
|
|
2782
|
+
*/
|
|
2783
|
+
pruneThrough(entityId: string, cutoff: number, wm: LibrarianWatermark | null): Promise<{
|
|
2784
|
+
changes: number;
|
|
2785
|
+
}>;
|
|
2786
|
+
/**
|
|
2787
|
+
* Count events at or before `cutoff` that are after the watermark — the
|
|
2788
|
+
* retention-held tail `pruneThrough` left in place. `wm = null` counts all
|
|
2789
|
+
* events at or before `cutoff` (every one of them is held back).
|
|
2790
|
+
*/
|
|
2791
|
+
countHeldBack(entityId: string, cutoff: number, wm: LibrarianWatermark | null): Promise<number>;
|
|
2459
2792
|
/**
|
|
2460
2793
|
* Return the total number of events stored for an entity.
|
|
2461
2794
|
* `tx` is optional — pass an active transaction handle for atomic reads.
|
|
@@ -2466,6 +2799,105 @@ declare class EventRepository extends BaseRepository {
|
|
|
2466
2799
|
* When limit is provided, fetches newest-first then reverses to preserve chronological order.
|
|
2467
2800
|
*/
|
|
2468
2801
|
getByEntityId(entityId: string, limit?: number): Promise<WikiEvent[]>;
|
|
2802
|
+
/**
|
|
2803
|
+
* Return events for `entityId` strictly after the watermark `(at, id)` in
|
|
2804
|
+
* chronological (ASC, id-ASC tie-break) order. Pass `wm = null` to read
|
|
2805
|
+
* from the beginning of the entity's event log. `limit` caps the result.
|
|
2806
|
+
*
|
|
2807
|
+
* Used by the op-based librarian (PR-B) to enumerate its unprocessed tail.
|
|
2808
|
+
*/
|
|
2809
|
+
getAfter(entityId: string, wm: LibrarianWatermark | null, limit?: number): Promise<WikiEvent[]>;
|
|
2810
|
+
/**
|
|
2811
|
+
* Count of events for `entityId` strictly after the watermark. Used as
|
|
2812
|
+
* the op-based librarian's bounded batch size and by the deferred-maintenance
|
|
2813
|
+
* pending report. Pass `wm = null` to count the entity's whole event log
|
|
2814
|
+
* (no watermark yet) — mirrors `getAfter` / `sumSummaryCharsAfter`.
|
|
2815
|
+
*/
|
|
2816
|
+
countAfter(entityId: string, wm: LibrarianWatermark | null): Promise<number>;
|
|
2817
|
+
/**
|
|
2818
|
+
* Return the event at a given chronological offset for `entityId` (0-based,
|
|
2819
|
+
* oldest first). Used by MaintenanceService.seedLibrarianWatermark to anchor
|
|
2820
|
+
* the watermark on a real row when a legacy DB first migrates to the
|
|
2821
|
+
* op-based librarian. The offset is clamped and truncated to defend against
|
|
2822
|
+
* hostile or fractional callers.
|
|
2823
|
+
*/
|
|
2824
|
+
getAtOffset(entityId: string, offset: number, tx?: SQLiteAdapter): Promise<WikiEvent | null>;
|
|
2825
|
+
/**
|
|
2826
|
+
* Sum of `summary` lengths (in characters) for events for `entityId`
|
|
2827
|
+
* strictly after the watermark. Pass `wm = null` to sum the entity's whole
|
|
2828
|
+
* event log (no watermark yet). Used by the op-based librarian's token
|
|
2829
|
+
* budget estimator (PR-B) and by the auto-trigger's pending-size check
|
|
2830
|
+
* (PR-C). SQLite's `LENGTH` returns character count for UTF-8 text input.
|
|
2831
|
+
*/
|
|
2832
|
+
sumSummaryCharsAfter(entityId: string, wm: LibrarianWatermark | null, tx?: SQLiteAdapter): Promise<number>;
|
|
2833
|
+
}
|
|
2834
|
+
|
|
2835
|
+
interface UsageRecord {
|
|
2836
|
+
inputTokens: number;
|
|
2837
|
+
outputTokens: number;
|
|
2838
|
+
/** True when either figure came from estimateTokens rather than the provider. */
|
|
2839
|
+
estimated: boolean;
|
|
2840
|
+
}
|
|
2841
|
+
/** One budget shared by every LLM call in a maintenance run. */
|
|
2842
|
+
declare class UsageMeter {
|
|
2843
|
+
readonly budget: number | undefined;
|
|
2844
|
+
used: number;
|
|
2845
|
+
estimated: boolean;
|
|
2846
|
+
constructor(budget?: number);
|
|
2847
|
+
get remaining(): number;
|
|
2848
|
+
fits(estimate: number): boolean;
|
|
2849
|
+
record(r: UsageRecord): void;
|
|
2850
|
+
}
|
|
2851
|
+
|
|
2852
|
+
/**
|
|
2853
|
+
* Librarian strategy seam (spec 2026-09-29 §5.1).
|
|
2854
|
+
*
|
|
2855
|
+
* The seam lets PR-B (ops librarian) plug in without `MaintenanceService`
|
|
2856
|
+
* editing the body. The verbatim legacy move lives in `legacy.ts`; the
|
|
2857
|
+
* dispatcher in `index.ts` is the only place that knows which strategies
|
|
2858
|
+
* exist. New strategies register there.
|
|
2859
|
+
*
|
|
2860
|
+
* `LibrarianStrategy` is the contract every implementation satisfies. The
|
|
2861
|
+
* pass is identified by its `(entityId, trigger, promptOverride?, meter?)`
|
|
2862
|
+
* context; the strategy returns what it processed so the caller can
|
|
2863
|
+
* advance checkpoints / watermarks.
|
|
2864
|
+
*/
|
|
2865
|
+
|
|
2866
|
+
/** Per-pass inputs the caller decides; the strategy cannot derive these. */
|
|
2867
|
+
interface LibrarianContext {
|
|
2868
|
+
entityId: string;
|
|
2869
|
+
trigger: WikiDiagnosticTrigger;
|
|
2870
|
+
promptOverride?: string;
|
|
2871
|
+
/** Optional meter (Phase C budgeted maintenance). Legacy honors it:
|
|
2872
|
+
* `callLlm` pre-flights the prompt estimate against it, usage is recorded
|
|
2873
|
+
* on every call, and the pass returns `budgetStop` when the budget is
|
|
2874
|
+
* exhausted (see `librarianBudget.test.ts`). */
|
|
2875
|
+
meter?: UsageMeter;
|
|
2876
|
+
}
|
|
2877
|
+
/**
|
|
2878
|
+
* Position in the event log a pass read through: the event's `created_at`
|
|
2879
|
+
* (epoch ms) and its id. Callers advance checkpoints / watermarks with it.
|
|
2880
|
+
*/
|
|
2881
|
+
interface EventCursor {
|
|
2882
|
+
at: number;
|
|
2883
|
+
id: string;
|
|
2884
|
+
}
|
|
2885
|
+
/**
|
|
2886
|
+
* What the strategy did. The shape is intentionally narrow: callers (lock
|
|
2887
|
+
* wrapper, deferred scheduler) only need to know whether work happened and
|
|
2888
|
+
* whether a budget error truncated it. PR-B adds its own watermark
|
|
2889
|
+
* semantics; the legacy `processedThrough` is an {@link EventCursor} for the
|
|
2890
|
+
* newest event the pass read (or null when there were no events).
|
|
2891
|
+
*/
|
|
2892
|
+
interface LibrarianResult {
|
|
2893
|
+
/** Newest event the pass processed (epoch ms + id), or `null` if the event log was empty. */
|
|
2894
|
+
processedThrough: EventCursor | null;
|
|
2895
|
+
/** Number of facts actually written (excludes deduped, rejected, failed-validation). */
|
|
2896
|
+
factsWritten: number;
|
|
2897
|
+
/** Set only when `callLlm` raised `WikiBudgetExhausted`. */
|
|
2898
|
+
budgetStop?: {
|
|
2899
|
+
requiredEstimate: number;
|
|
2900
|
+
};
|
|
2469
2901
|
}
|
|
2470
2902
|
|
|
2471
2903
|
declare const ONTOLOGY_BACKFILL_BATCH_SIZE = 25;
|
|
@@ -2574,6 +3006,39 @@ declare class MaintenanceService {
|
|
|
2574
3006
|
private forgetDryRun;
|
|
2575
3007
|
/** Core librarian pass (locks handled by {@link runLibrarian}). Package-internal orchestration hook. */
|
|
2576
3008
|
doRunLibrarian(entityId: string, promptOverride?: string, trigger?: WikiDiagnosticTrigger): Promise<void>;
|
|
3009
|
+
/**
|
|
3010
|
+
* Seam between the lock wrapper and the strategy dispatcher (spec 2026-09-29
|
|
3011
|
+
* §5.1). Builds the strategy deps from `this` and dispatches via
|
|
3012
|
+
* `runLibrarianStrategy` so PR-B can plug in `ops/` without touching this
|
|
3013
|
+
* class. Returns the strategy's `LibrarianResult` so deferred/budgeted
|
|
3014
|
+
* schedulers (PR-C) can advance watermarks; the existing void-returning
|
|
3015
|
+
* `doRunLibrarian` discards it.
|
|
3016
|
+
*
|
|
3017
|
+
* Spec §10.3: one place advances the watermark, for every strategy, only
|
|
3018
|
+
* after the pass resolved (its transaction committed) and never backwards.
|
|
3019
|
+
* A budget-stopped pass wrote nothing and must not move the watermark.
|
|
3020
|
+
*/
|
|
3021
|
+
runLibrarianPass(ctx: LibrarianContext): Promise<LibrarianResult>;
|
|
3022
|
+
/**
|
|
3023
|
+
* Strategy deps shared between legacy and ops librarians (spec §5.1). The
|
|
3024
|
+
* ops strategy (PR-B Task 8) reads/anchors the watermark through these two
|
|
3025
|
+
* hooks so the dispatcher itself never reaches into the metadata table —
|
|
3026
|
+
* the watermark invariant (one place advances, never backwards) lives here.
|
|
3027
|
+
*/
|
|
3028
|
+
private librarianDeps;
|
|
3029
|
+
/**
|
|
3030
|
+
* Persist `next` as the entity's librarian watermark when it is strictly
|
|
3031
|
+
* newer than the stored value, under the (created_at, id) ordering used by
|
|
3032
|
+
* the op-based librarian (spec §10.3). Never moves backwards.
|
|
3033
|
+
*/
|
|
3034
|
+
private advanceLibrarianWatermark;
|
|
3035
|
+
/**
|
|
3036
|
+
* Spec §10.3: first ops pass on a legacy DB starts after what the count
|
|
3037
|
+
* checkpoint already covered. No-op when a watermark already exists or the
|
|
3038
|
+
* memory checkpoint is 0; otherwise anchor the watermark to the event at
|
|
3039
|
+
* offset `min(memory_checkpoint, totalEvents) - 1`.
|
|
3040
|
+
*/
|
|
3041
|
+
seedLibrarianWatermark(entityId: string): Promise<void>;
|
|
2577
3042
|
/**
|
|
2578
3043
|
* Core heal pass (locks handled by {@link runHeal}). Package-internal orchestration hook.
|
|
2579
3044
|
*
|
|
@@ -2586,6 +3051,7 @@ declare class MaintenanceService {
|
|
|
2586
3051
|
batchSize?: number;
|
|
2587
3052
|
bodyTruncationChars?: number;
|
|
2588
3053
|
trigger?: WikiDiagnosticTrigger;
|
|
3054
|
+
meter?: UsageMeter;
|
|
2589
3055
|
}): Promise<HealResult>;
|
|
2590
3056
|
/** Core ontology backfill pass (locks handled by {@link runOntologyBackfill}). Package-internal orchestration hook. */
|
|
2591
3057
|
doRunOntologyBackfill(entityId: string, options?: {
|
|
@@ -2632,6 +3098,43 @@ declare class MaintenanceService {
|
|
|
2632
3098
|
private _sanitizeRankerError;
|
|
2633
3099
|
}
|
|
2634
3100
|
|
|
3101
|
+
/**
|
|
3102
|
+
* Read-side report for the deferred maintenance mode: which entities have
|
|
3103
|
+
* pending work (librarian events behind the watermark, heal backlog, unembedded
|
|
3104
|
+
* facts) without running anything. `run` executes the work (PR-C task 4).
|
|
3105
|
+
*/
|
|
3106
|
+
declare class MaintenanceScheduler {
|
|
3107
|
+
private db;
|
|
3108
|
+
private options;
|
|
3109
|
+
private maintenanceService;
|
|
3110
|
+
private metadataRepo;
|
|
3111
|
+
private eventRepo;
|
|
3112
|
+
private entryRepo;
|
|
3113
|
+
private jobManager;
|
|
3114
|
+
constructor(db: SQLiteAdapter, options: WikiOptions, maintenanceService: MaintenanceService, metadataRepo: MetadataRepository, eventRepo: EventRepository, entryRepo: EntryRepository, jobManager: JobManager);
|
|
3115
|
+
/**
|
|
3116
|
+
* Entities with **any** pending work only, sorted by `pendingEvents` desc
|
|
3117
|
+
* then `entityId` asc. Token estimate is ceil(pending summary chars / 4),
|
|
3118
|
+
* matching the auto-trigger's estimator (PR-B).
|
|
3119
|
+
*/
|
|
3120
|
+
getPending(entityIds?: string[]): Promise<PendingMaintenance[]>;
|
|
3121
|
+
/**
|
|
3122
|
+
* Execute pending maintenance (spec §6.2): fair-share rounds of at most one
|
|
3123
|
+
* unit per entity (librarian batch, else heal batch, else reembed), entities
|
|
3124
|
+
* ordered by `getPending` (pendingEvents desc, id asc). Holds the same
|
|
3125
|
+
* per-entity `JobManager` locks a manual run would; a busy entity is skipped
|
|
3126
|
+
* and reported, never thrown. Nothing is still running when this resolves.
|
|
3127
|
+
*
|
|
3128
|
+
* Stop precedence (spec §10 items 3-6): `deadline` > `budget_exhausted` >
|
|
3129
|
+
* `budget_too_small` > `complete`. `budget_too_small` means a job's smallest
|
|
3130
|
+
* unit needs more than the WHOLE budget — that job is skipped this run and
|
|
3131
|
+
* the run continues; `budget_exhausted` means a unit needs more than what
|
|
3132
|
+
* REMAINS — the run stops. The token budget meters `generateText` calls
|
|
3133
|
+
* only; embeddings are never metered.
|
|
3134
|
+
*/
|
|
3135
|
+
run(opts?: RunPendingMaintenanceOptions): Promise<RunPendingMaintenanceResult>;
|
|
3136
|
+
}
|
|
3137
|
+
|
|
2635
3138
|
declare class ImportExportService {
|
|
2636
3139
|
private db;
|
|
2637
3140
|
private entryRepo;
|
|
@@ -2676,7 +3179,7 @@ declare class RetrievalService {
|
|
|
2676
3179
|
* Stable tie-break sort: score desc → access_count desc → updated_at desc → id asc.
|
|
2677
3180
|
*/
|
|
2678
3181
|
private _tieBreakSort;
|
|
2679
|
-
private
|
|
3182
|
+
private _withoutIds;
|
|
2680
3183
|
/**
|
|
2681
3184
|
* Comparator for score + deterministic tie-break fields.
|
|
2682
3185
|
* Negative return means "a ranks ahead of b" for descending score order.
|
|
@@ -2705,6 +3208,10 @@ declare class WriteService {
|
|
|
2705
3208
|
private jobManager;
|
|
2706
3209
|
private maintenanceService;
|
|
2707
3210
|
constructor(db: SQLiteAdapter, options: WikiOptions, entryRepo: EntryRepository, eventRepo: EventRepository, metadataRepo: MetadataRepository, jobManager: JobManager, maintenanceService: MaintenanceService);
|
|
3211
|
+
private inflight;
|
|
3212
|
+
private track;
|
|
3213
|
+
/** Await every background job this instance started (spec §6.2). Loops because a finishing job can start another. */
|
|
3214
|
+
drain(): Promise<void>;
|
|
2708
3215
|
write(entityId: string, event: Omit<WikiEvent, 'id' | 'entity_id' | 'created_at'>): Promise<void>;
|
|
2709
3216
|
private runLibrarianThenMaybeHeal;
|
|
2710
3217
|
/**
|
|
@@ -2728,17 +3235,41 @@ declare class GraphTraversalService {
|
|
|
2728
3235
|
traverseGraph(entityId: string, options: GraphTraversalOptions): Promise<GraphNeighborhood>;
|
|
2729
3236
|
}
|
|
2730
3237
|
|
|
3238
|
+
/** Supersession and history (spec 2026-09-29 §4.3). */
|
|
3239
|
+
declare class TemporalService {
|
|
3240
|
+
private db;
|
|
3241
|
+
private options;
|
|
3242
|
+
private entryRepo;
|
|
3243
|
+
private searchService;
|
|
3244
|
+
private embeddingService;
|
|
3245
|
+
constructor(db: SQLiteAdapter, options: WikiOptions, entryRepo: EntryRepository, searchService: SearchService, embeddingService: EmbeddingService);
|
|
3246
|
+
/**
|
|
3247
|
+
* Link `oldId` → `newId` inside the caller's transaction. `newId` must
|
|
3248
|
+
* already exist. Throws WikiSupersedeError on any rule violation; the
|
|
3249
|
+
* caller's transaction then rolls back.
|
|
3250
|
+
*/
|
|
3251
|
+
supersedeInTx(tx: SQLiteAdapter, entityId: string, oldId: string, newId: string, t: number, now: number): Promise<void>;
|
|
3252
|
+
supersede(entityId: string, oldId: string, replacement: SupersedeReplacement, options?: {
|
|
3253
|
+
validFrom?: number;
|
|
3254
|
+
}): Promise<{
|
|
3255
|
+
newId: string;
|
|
3256
|
+
}>;
|
|
3257
|
+
history(entityId: string, factId: string): Promise<WikiFact[]>;
|
|
3258
|
+
}
|
|
3259
|
+
|
|
2731
3260
|
/** Typed escape hatch for tests — not part of the supported consumer API. */
|
|
2732
3261
|
interface WikiMemoryTestAccess {
|
|
2733
3262
|
embeddingService: EmbeddingService;
|
|
2734
3263
|
importExportService: ImportExportService;
|
|
2735
3264
|
ingestionService: IngestionService;
|
|
2736
3265
|
maintenanceService: MaintenanceService;
|
|
3266
|
+
maintenanceScheduler: MaintenanceScheduler;
|
|
2737
3267
|
retrievalService: RetrievalService;
|
|
2738
3268
|
searchService: SearchService;
|
|
2739
3269
|
writeService: WriteService;
|
|
2740
3270
|
promptService: PromptService;
|
|
2741
3271
|
graphTraversalService: GraphTraversalService;
|
|
3272
|
+
temporalService: TemporalService;
|
|
2742
3273
|
entryRepo: EntryRepository;
|
|
2743
3274
|
sourceRefIndexRepo: SourceRefIndexRepository;
|
|
2744
3275
|
metadataRepo: MetadataRepository;
|
|
@@ -2761,6 +3292,7 @@ declare class WikiMemory {
|
|
|
2761
3292
|
private jobManager;
|
|
2762
3293
|
private ingestionService;
|
|
2763
3294
|
private maintenanceService;
|
|
3295
|
+
private maintenanceScheduler;
|
|
2764
3296
|
private importExportService;
|
|
2765
3297
|
private retrievalService;
|
|
2766
3298
|
private writeService;
|
|
@@ -2769,6 +3301,7 @@ declare class WikiMemory {
|
|
|
2769
3301
|
private graphTraversalService;
|
|
2770
3302
|
private lintRepo;
|
|
2771
3303
|
private lintService;
|
|
3304
|
+
private temporalService;
|
|
2772
3305
|
private readonly okfTrustWrites;
|
|
2773
3306
|
constructor(db: SQLiteAdapter, options: WikiOptions);
|
|
2774
3307
|
/**
|
|
@@ -2884,6 +3417,17 @@ declare class WikiMemory {
|
|
|
2884
3417
|
traverseGraph(entityId: string, options: GraphTraversalOptions): Promise<GraphNeighborhood>;
|
|
2885
3418
|
getMemoryBundle(entityId: string): Promise<MemoryBundle>;
|
|
2886
3419
|
write(entityId: string, event: Omit<WikiEvent, 'id' | 'entity_id' | 'created_at'>): Promise<void>;
|
|
3420
|
+
/** Await auto-mode background librarian/heal jobs started by write(). No-op in 'deferred' mode. */
|
|
3421
|
+
drain(): Promise<void>;
|
|
3422
|
+
/**
|
|
3423
|
+
* Report which entities have pending maintenance work (librarian events
|
|
3424
|
+
* behind the watermark, heal backlog, unembedded facts) without running
|
|
3425
|
+
* anything. Entities with no pending work are omitted; sorted by
|
|
3426
|
+
* `pendingEvents` desc then `entityId` asc.
|
|
3427
|
+
*/
|
|
3428
|
+
getPendingMaintenance(entityIds?: string[]): Promise<PendingMaintenance[]>;
|
|
3429
|
+
/** Run pending librarian/heal/reembed work under an optional token budget and deadline (spec §6.2). Nothing runs after it resolves. */
|
|
3430
|
+
runPendingMaintenance(options?: RunPendingMaintenanceOptions): Promise<RunPendingMaintenanceResult>;
|
|
2887
3431
|
/**
|
|
2888
3432
|
* @param options.promptOverride - Applies only to this manual call. Does NOT affect
|
|
2889
3433
|
* WriteService-triggered auto-runs. For persistent prompt customization across auto-runs,
|
|
@@ -2963,6 +3507,18 @@ declare class WikiMemory {
|
|
|
2963
3507
|
};
|
|
2964
3508
|
metadataReset?: boolean;
|
|
2965
3509
|
}>;
|
|
3510
|
+
/**
|
|
3511
|
+
* End `oldId`'s validity and link it to its replacement (spec §4.3). One
|
|
3512
|
+
* transaction. Throws `WikiSupersedeError` for missing, foreign, already
|
|
3513
|
+
* superseded, immutable-document, or cyclic targets.
|
|
3514
|
+
*/
|
|
3515
|
+
supersede(entityId: string, oldId: string, replacement: SupersedeReplacement, options?: {
|
|
3516
|
+
validFrom?: number;
|
|
3517
|
+
}): Promise<{
|
|
3518
|
+
newId: string;
|
|
3519
|
+
}>;
|
|
3520
|
+
/** The supersession chain containing `factId`, oldest first. [] when unknown. */
|
|
3521
|
+
history(entityId: string, factId: string): Promise<WikiFact[]>;
|
|
2966
3522
|
/**
|
|
2967
3523
|
* Full and partial ingestion both reject foreign-owned generated fact IDs with
|
|
2968
3524
|
* `WikiGraphNodeOwnershipConflict`. Such collisions are unexpected. Ingestion
|
|
@@ -3154,4 +3710,4 @@ declare class WikiMemory {
|
|
|
3154
3710
|
setGeneratedByTask(taskId: string, entityId: string, actor: string): Promise<void>;
|
|
3155
3711
|
}
|
|
3156
3712
|
|
|
3157
|
-
export { type
|
|
3713
|
+
export { type ReembedResult as $, ONTOLOGY_BACKFILL_RECHECK_MS as A, type OntologyBackfillResult as B, type ChunkFailure as C, type DegradedRecord as D, type EmbedFactResult as E, type FormatContextOptions as F, type GraphNeighborhood as G, HEAL_BATCH_SIZE as H, type IngestDocumentResult as I, type OntologyConfig as J, type OntologyEdgeType as K, type LLMProvider as L, type MemoryBundle as M, type OntologyManifest as N, ONTOLOGY_BACKFILL_BATCH_SIZE as O, type OntologyMode as P, type OntologyNodeType as Q, type ReadOptions as R, type SQLiteAdapter as S, type OntologyPromptContext as T, type OntologyUpdates as U, type PendingMaintenance as V, type WikiOptions as W, type PendingSourceStatus as X, type PromptOverrides as Y, PromptService as Z, PrunePartialFailureError as _, type MemoryDump as a, type RunPendingMaintenanceOptions as a0, type RunPendingMaintenanceResult as a1, type SupersedeReplacement as a2, type VectorRanker as a3, type VectorRankerFallback as a4, type VectorRankerRankArgs as a5, type VectorRankerSemanticResult as a6, WikiBusyError as a7, type WikiBusyOperation as a8, type WikiCheckpoint as a9, validateManifest as aA, EmbeddingService as aB, ImportExportService as aC, IngestionService as aD, JobManager as aE, MaintenanceService as aF, RetrievalService as aG, SearchService as aH, WriteService as aI, type WikiConfig as aa, type WikiDiagnostic as ab, type WikiDiagnosticCode as ac, type WikiDiagnosticDetail as ad, type WikiDiagnosticOperation as ae, type WikiDiagnosticSeverity as af, type WikiDiagnosticTrigger as ag, WikiDraftNotFound as ah, WikiDuplicateHashError as ai, type WikiEdge as aj, type WikiEvent as ak, type WikiFact as al, WikiGraphNodeOwnershipConflict as am, WikiIngestEmptyError as an, type WikiInstructions as ao, WikiInvalidReadOptions as ap, type WikiLintReport as aq, type WikiMemoryTestAccess as ar, type WikiOutboxEvent as as, WikiParseError as at, WikiSourceRefHashCollision as au, WikiStrictOntologyViolation as av, WikiSupersedeError as aw, type WikiSupersedeReason as ax, type WikiTask as ay, WikiTransactionError as az, type FormattedMemoryDump as b, WikiMemory as c, type ClassifierAnswer as d, type ClassifierQuestion as e, type ClassifyRequest as f, type ClassifyResponse as g, type DraftPage as h, type EmbedFailureKind as i, type EmbeddingMarkerKind as j, type EntityMaintenanceReport as k, type EntityStatus as l, type ExtractedFact as m, type ExtractedFactEdge as n, type ExtractedFactWithOntology as o, type ExtractedTask as p, type GraphTraversalOptions as q, type GroundingConfig as r, HEAL_RECHECK_MS as s, HOOK_TIMEOUT_MARKER as t, type HealResult as u, type LibrarianConfig as v, type LibrarianGateConfig as w, type MaintenanceJob as x, type MaintenanceStopReason as y, ONTOLOGY_BACKFILL_MAX_PROMPT_CHARS as z };
|