@remnic/core 10.0.83 → 10.0.84

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.
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  ExtractionDrain,
3
3
  TurnIngestionCoordinator
4
- } from "./chunk-AYTDCMEL.js";
4
+ } from "./chunk-HLKUZW42.js";
5
5
  import {
6
6
  headerConnector,
7
7
  renderExtractionConversation,
@@ -440,4 +440,4 @@ export {
440
440
  ClaimBufferStorage,
441
441
  BufferDrainRunner
442
442
  };
443
- //# sourceMappingURL=chunk-SVCHO337.js.map
443
+ //# sourceMappingURL=chunk-3JPTUCD7.js.map
@@ -1,3 +1,6 @@
1
+ import {
2
+ compareStrings
3
+ } from "./chunk-ULM7JCDH.js";
1
4
  import {
2
5
  entityMentionEpoch
3
6
  } from "./chunk-7CT3AI52.js";
@@ -88,11 +91,6 @@ function throwIfMentionAborted(signal) {
88
91
  const reason = signal.reason;
89
92
  throw reason instanceof Error ? reason : new Error("entity mention rebuild aborted");
90
93
  }
91
- function compareStrings(left, right) {
92
- if (left < right) return -1;
93
- if (left > right) return 1;
94
- return 0;
95
- }
96
94
  function deduped(values) {
97
95
  const seen = /* @__PURE__ */ new Set();
98
96
  const out = [];
@@ -327,4 +325,4 @@ export {
327
325
  settleEntityMentionIndex,
328
326
  resolveEntityMentionIndex
329
327
  };
330
- //# sourceMappingURL=chunk-S57QBPTA.js.map
328
+ //# sourceMappingURL=chunk-DPPLNZ3A.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/entity-mention-index-cache.ts"],"sourcesContent":["import path from \"node:path\";\nimport { mkdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { raceAbort } from \"./abort-error.js\";\nimport { entityMentionEpoch } from \"./entity-mention-epoch.js\";\nimport { log } from \"./logger.js\";\nimport { compareStrings } from \"./eval-trajectory-contracts.js\";\n\n/**\n * In-memory entity mention index.\n *\n * Scope (namespaces, dirs, secure-store key, alias map, native revision) is\n * the cache key. Mention epoch and entity-file mutation are identity inside\n * the slot, not part of the key:\n *\n * - metadata-only corpus bumps do not move the epoch, so the next recall hits\n * - entity-file changes rebuild from entity files before the recall returns,\n * reusing memory snippets (no fact scan). A new entity is visible on that\n * recall; its memory snippets arrive with the next full reconcile. A new\n * canonical id schedules that reconcile. Callers share one scan. One\n * caller's abort stops that caller waiting and leaves the scan running\n * for the others\n * - memory create/edit/delete moves the epoch. The recall serves the last\n * index immediately and one background reconcile runs, plus at most one\n * follow-up if that scan overlaps a later write. A recall during either\n * scan does not grant another follow-up. Further rescans wait for the\n * next recall. After writes quiesce and `settleEntityMentionIndex`\n * finishes, the index matches a full rebuild\n * - secure-store key, alias map, and native revision stay in the key, so a\n * change is a miss and awaits a full rebuild. A locked store never reads\n * another key's plaintext. Evicting that older scope also stops its scan\n * from publishing the persisted index\n * - a persisted index is readable per storage root. A process-wide cache\n * clear blocks every root until that root's own post-clear build publishes.\n * One root publishing does not reopen another root's file\n */\n\nconst MAX_SLOTS = 32;\nconst SETTLE_ROUNDS = 8;\n\nexport type EntityMentionIdentity = {\n mentionEpoch: string;\n entityMutation: string;\n};\n\ntype ScopedStorage = {\n dir: string;\n hotCacheKeyId?(): string;\n entityAliases?: Readonly<Record<string, string>> | null;\n getEntityMutationVersion?(): number;\n};\n\ntype Slot = {\n scopeKey: string;\n index: unknown;\n identity: EntityMentionIdentity;\n token: number;\n rebuild: Promise<void> | null;\n entityJob: Promise<void> | null;\n again: boolean;\n followUps: number;\n currentIdentity: () => EntityMentionIdentity;\n buildFull: (abortSignal?: AbortSignal) => Promise<unknown>;\n};\n\nconst slots = new Map<string, Slot>();\nconst rebuildsByScope = new Map<string, number>();\nconst GENERATION_STRIDE = 1_000_000_000;\nlet clearEpoch = 0;\nconst localGenerationByDir = new Map<string, number>();\nconst publishedGenerationByDir = new Map<string, number>();\nconst persistTailByDir = new Map<string, Promise<void>>();\n\nfunction resolveMentionDir(dir: string): string {\n return path.resolve(dir);\n}\n\nexport function entityMentionCacheGeneration(dir: string): number {\n const resolved = resolveMentionDir(dir);\n return clearEpoch * GENERATION_STRIDE + (localGenerationByDir.get(resolved) ?? 0);\n}\n\nexport function entityMentionPersistedIndexReadable(dir: string): boolean {\n const resolved = resolveMentionDir(dir);\n const local = localGenerationByDir.get(resolved) ?? 0;\n if (clearEpoch === 0 && local === 0) return true;\n return publishedGenerationByDir.get(resolved) === entityMentionCacheGeneration(resolved);\n}\n\nfunction dirsInScope(scopeKey: string): string[] {\n const nsEnd = scopeKey.indexOf(\"\\u001e\");\n const storageEnd = nsEnd === -1 ? -1 : scopeKey.indexOf(\"\\u001e\", nsEnd + 1);\n if (nsEnd === -1 || storageEnd === -1) return [];\n return scopeKey\n .slice(nsEnd + 1, storageEnd)\n .split(\"\\u001f\")\n .map((part) => part.split(\"\\u001d\")[0] ?? \"\")\n .filter((dir) => dir.length > 0)\n .map((dir) => resolveMentionDir(dir));\n}\n\nfunction persistedMentionIndexFiles(scopeKey: string): string[] {\n return dirsInScope(scopeKey).map((dir) => path.join(dir, \"state\", \"entity-mention-index.json\"));\n}\n\nfunction bumpScopeDirs(scopeKey: string): void {\n for (const dir of dirsInScope(scopeKey)) {\n localGenerationByDir.set(dir, (localGenerationByDir.get(dir) ?? 0) + 1);\n }\n}\n\nfunction captureDirGenerations(scopeKey: string): Map<string, number> {\n const captured = new Map<string, number>();\n for (const dir of dirsInScope(scopeKey)) captured.set(dir, entityMentionCacheGeneration(dir));\n return captured;\n}\n\nfunction generationsCurrent(captured: Map<string, number>): boolean {\n for (const [dir, generation] of captured) {\n if (entityMentionCacheGeneration(dir) !== generation) return false;\n }\n return true;\n}\n\nfunction publishDirGenerations(captured: Map<string, number>): void {\n for (const [dir, generation] of captured) {\n if (entityMentionCacheGeneration(dir) === generation) publishedGenerationByDir.set(dir, generation);\n }\n}\n\nexport async function writePersistedEntityMentionIndex(\n dir: string,\n generation: number,\n content: string,\n): Promise<void> {\n const resolved = resolveMentionDir(dir);\n const previous = persistTailByDir.get(resolved) ?? Promise.resolve();\n const run = previous.catch(() => undefined).then(async () => {\n if (entityMentionCacheGeneration(resolved) !== generation) return;\n const file = path.join(resolved, \"state\", \"entity-mention-index.json\");\n await mkdir(path.dirname(file), { recursive: true });\n const current = await readFile(file, \"utf-8\").catch(() => \"\");\n if (current === content) return;\n if (entityMentionCacheGeneration(resolved) !== generation) return;\n await writeFile(file, content, \"utf-8\");\n });\n persistTailByDir.set(resolved, run.then(() => undefined, () => undefined));\n await run;\n}\n\nfunction discardPersistedMentionIndex(scopeKey: string): void {\n for (const file of persistedMentionIndexFiles(scopeKey)) {\n void rm(file, { force: true }).catch(() => undefined);\n }\n}\n\nfunction throwIfMentionAborted(signal?: AbortSignal): void {\n if (!signal?.aborted) return;\n const reason = signal.reason;\n throw reason instanceof Error ? reason : new Error(\"entity mention rebuild aborted\");\n}\n\nfunction deduped(values: readonly string[]): string[] {\n const seen = new Set<string>();\n const out: string[] = [];\n for (const value of values) {\n const trimmed = value.trim();\n if (trimmed.length === 0 || seen.has(trimmed)) continue;\n seen.add(trimmed);\n out.push(trimmed);\n }\n return out;\n}\n\nfunction sameIdentity(left: EntityMentionIdentity, right: EntityMentionIdentity): boolean {\n return left.mentionEpoch === right.mentionEpoch && left.entityMutation === right.entityMutation;\n}\n\nfunction noteRebuild(scopeKey: string): void {\n rebuildsByScope.set(scopeKey, (rebuildsByScope.get(scopeKey) ?? 0) + 1);\n}\n\nfunction scopeFamily(scopeKey: string): string {\n const nsEnd = scopeKey.indexOf(\"\\u001e\");\n const storageEnd = nsEnd === -1 ? -1 : scopeKey.indexOf(\"\\u001e\", nsEnd + 1);\n const namespaceKey = nsEnd === -1 ? scopeKey : scopeKey.slice(0, nsEnd);\n const storageKey = nsEnd === -1 || storageEnd === -1 ? \"\" : scopeKey.slice(nsEnd + 1, storageEnd);\n const dirs = storageKey\n .split(\"\\u001f\")\n .map((part) => part.split(\"\\u001d\")[0] ?? \"\")\n .join(\"\\u001f\");\n return `${namespaceKey}\\u001e${dirs}`;\n}\n\nfunction forgetScope(scopeKey: string, bumpPersisted = false): void {\n const slot = slots.get(scopeKey);\n if (slot) {\n slot.token += 1;\n slot.again = false;\n }\n if (bumpPersisted) bumpScopeDirs(scopeKey);\n slots.delete(scopeKey);\n rebuildsByScope.delete(scopeKey);\n}\n\nfunction evictOldest(scopeKey: string): void {\n if (slots.size < MAX_SLOTS || slots.has(scopeKey)) return;\n const oldest = slots.keys().next().value;\n if (typeof oldest === \"string\") forgetScope(oldest);\n}\n\nfunction evictSameFamily(scopeKey: string): void {\n const family = scopeFamily(scopeKey);\n for (const key of [...slots.keys()]) {\n if (key !== scopeKey && scopeFamily(key) === family) forgetScope(key, true);\n }\n}\n\nfunction wantsSnippetReconcile(index: unknown): boolean {\n return (\n !!index &&\n typeof index === \"object\" &&\n (index as { pendingSnippetReconcile?: boolean }).pendingSnippetReconcile === true\n );\n}\n\nfunction armRebuild(slot: Slot): void {\n // A recall that arrives while a scan is already running must not grant\n // another follow-up. The chain stops after the one already armed.\n if (!slot.rebuild) slot.followUps = 1;\n startRebuild(slot);\n}\n\nfunction startRebuild(slot: Slot): void {\n // A recall that arrives during a scan is not a write. The follow-up is\n // armed only when the scan's end identity differs from the identity it\n // started with. Setting `again` here made every concurrent recall pay a\n // second full corpus scan after a stable rebuild.\n if (slot.rebuild) return;\n const token = slot.token;\n const captured = captureDirGenerations(slot.scopeKey);\n noteRebuild(slot.scopeKey);\n const started = slot.currentIdentity();\n slot.again = false;\n const handle: { pending: Promise<void> | null } = { pending: null };\n handle.pending = slot\n .buildFull(undefined)\n .then((index) => {\n if (slot.token !== token || !generationsCurrent(captured)) return;\n publishDirGenerations(captured);\n const ended = slot.currentIdentity();\n slot.index = index;\n if (sameIdentity(started, ended)) {\n slot.identity = ended;\n return;\n }\n // Scan overlapped later writes. Keep the start identity so the next\n // recall stays stale and exactly one follow-up reconcile runs.\n slot.identity = started;\n slot.again = true;\n })\n .catch((err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n log.warn(`entity mention index rebuild failed: ${message}`);\n })\n .finally(() => {\n if (slot.rebuild === handle.pending) slot.rebuild = null;\n // One automatic follow-up per caller-started rebuild. A store that keeps\n // changing during every scan waits for the next recall (or settle) instead\n // of chaining full scans with nobody waiting.\n if (!slot.again || slot.followUps <= 0) return;\n slot.again = false;\n slot.followUps -= 1;\n startRebuild(slot);\n });\n slot.rebuild = handle.pending;\n}\n\nexport function entityMentionScopeKey(\n namespaces: readonly string[] | undefined,\n storages: readonly ScopedStorage[],\n nativeRevision: string,\n): string {\n const namespaceKey = deduped(namespaces ?? []).join(\"\\u001f\");\n const storageKey = storages\n .map((storage) => {\n const aliases = Object.entries(storage.entityAliases ?? {}).sort(([left], [right]) =>\n compareStrings(left, right),\n );\n return `${path.resolve(storage.dir)}\\u001d${storage.hotCacheKeyId?.() ?? \"\"}\\u001d${JSON.stringify(aliases)}`;\n })\n .join(\"\\u001f\");\n return `${namespaceKey}\\u001e${storageKey}\\u001e${nativeRevision}`;\n}\n\nexport function entityMentionIdentity(storages: readonly ScopedStorage[]): EntityMentionIdentity {\n return {\n mentionEpoch: storages.map((storage) => String(entityMentionEpoch.current(storage.dir))).join(\"\\u001f\"),\n entityMutation: storages.map((storage) => String(storage.getEntityMutationVersion?.() ?? 0)).join(\"\\u001f\"),\n };\n}\n\nexport function entityMentionFullRebuildsStarted(scopeKey: string): number {\n return rebuildsByScope.get(scopeKey) ?? 0;\n}\n\nexport function entityMentionIndexScopeKeys(): string[] {\n return [...slots.keys()];\n}\n\nexport function dropEntityMentionIndexCache(scopeKey?: string): void {\n if (scopeKey === undefined) {\n clearEpoch += 1;\n for (const key of [...slots.keys()]) {\n discardPersistedMentionIndex(key);\n forgetScope(key);\n }\n return;\n }\n discardPersistedMentionIndex(scopeKey);\n forgetScope(scopeKey, true);\n}\n\nexport async function settleEntityMentionIndex(scopeKey?: string): Promise<void> {\n const matches = (slot: Slot) => scopeKey === undefined || slot.scopeKey === scopeKey;\n for (let round = 0; round < SETTLE_ROUNDS; round += 1) {\n for (const slot of slots.values()) {\n if (!matches(slot)) continue;\n if (!slot.rebuild && slot.again) {\n slot.again = false;\n startRebuild(slot);\n }\n }\n const pending = [...slots.values()].filter((slot) => matches(slot) && slot.rebuild).map((slot) => slot.rebuild!);\n if (pending.length === 0) return;\n await Promise.all(pending);\n }\n}\n\nexport async function resolveEntityMentionIndex<T>(options: {\n scopeKey: string;\n currentIdentity: () => EntityMentionIdentity;\n buildFull: (abortSignal?: AbortSignal) => Promise<T>;\n rebuildEntities: (previous: T, abortSignal?: AbortSignal) => Promise<T>;\n abortSignal?: AbortSignal;\n}): Promise<T> {\n const live = options.currentIdentity();\n const existing = slots.get(options.scopeKey);\n if (!existing) {\n evictSameFamily(options.scopeKey);\n evictOldest(options.scopeKey);\n noteRebuild(options.scopeKey);\n const captured = captureDirGenerations(options.scopeKey);\n const started = options.currentIdentity();\n const index = await options.buildFull(options.abortSignal);\n // A clear or family eviction during this first scan must not publish it.\n if (!generationsCurrent(captured)) return index;\n publishDirGenerations(captured);\n const ended = options.currentIdentity();\n evictSameFamily(options.scopeKey);\n evictOldest(options.scopeKey);\n const slot: Slot = {\n scopeKey: options.scopeKey,\n index,\n identity: sameIdentity(started, ended) ? ended : started,\n token: 0,\n rebuild: null,\n entityJob: null,\n again: false,\n followUps: 0,\n currentIdentity: options.currentIdentity,\n buildFull: options.buildFull,\n };\n slots.set(options.scopeKey, slot);\n if (!sameIdentity(started, ended)) armRebuild(slot);\n return index;\n }\n existing.currentIdentity = options.currentIdentity;\n existing.buildFull = options.buildFull;\n while (existing.identity.entityMutation !== options.currentIdentity().entityMutation) {\n throwIfMentionAborted(options.abortSignal);\n const pending = existing.entityJob;\n if (pending) {\n await raceAbort(pending, options.abortSignal, \"entity mention rebuild aborted\");\n continue;\n }\n const liveNow = options.currentIdentity();\n const epochBefore = existing.identity.mentionEpoch;\n const mutationBefore = liveNow.entityMutation;\n let release = (): void => {};\n const gate = new Promise<void>((resolve) => {\n release = resolve;\n });\n existing.entityJob = gate;\n existing.token += 1;\n existing.again = false;\n const token = existing.token;\n const captured = captureDirGenerations(existing.scopeKey);\n // Shared scan. This caller's abort stops its wait and leaves the scan\n // running. Publish when the scan settles, even if this caller has left.\n // A family eviction bumps the token and the root generation; this scan\n // must not install its result or start a follow-up that would republish.\n const scan = options.rebuildEntities(existing.index as T, undefined);\n void scan\n .then(\n (rebuilt) => {\n if (existing.token !== token || !generationsCurrent(captured)) return;\n const now = options.currentIdentity();\n existing.index = rebuilt;\n const epochStable = epochBefore === liveNow.mentionEpoch && epochBefore === now.mentionEpoch;\n const mutationStable = mutationBefore === now.entityMutation;\n existing.identity = {\n entityMutation: mutationStable ? now.entityMutation : mutationBefore,\n mentionEpoch: epochStable ? now.mentionEpoch : epochBefore,\n };\n if (existing.identity.mentionEpoch !== now.mentionEpoch || wantsSnippetReconcile(rebuilt)) {\n armRebuild(existing);\n }\n },\n () => {},\n )\n .finally(() => {\n if (existing.entityJob === gate) existing.entityJob = null;\n release();\n });\n const rebuilt = await raceAbort(scan, options.abortSignal, \"entity mention rebuild aborted\");\n throwIfMentionAborted(options.abortSignal);\n return rebuilt;\n }\n if (existing.identity.mentionEpoch !== live.mentionEpoch) {\n armRebuild(existing);\n return existing.index as T;\n }\n return existing.index as T;\n}\n\nentityMentionEpoch.registerReset(() => {\n dropEntityMentionIndexCache();\n});\n"],"mappings":"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","names":["rebuilt"]}
@@ -210,7 +210,7 @@ import {
210
210
  buildEntityRecallSection,
211
211
  entityRecentTranscriptLookbackHours,
212
212
  readRecentEntityTranscriptEntries
213
- } from "./chunk-DD6OIFDG.js";
213
+ } from "./chunk-K3B72DKJ.js";
214
214
  import {
215
215
  planEpisodeWindowsWithFallback
216
216
  } from "./chunk-T3GIETKV.js";
@@ -32226,4 +32226,4 @@ export {
32226
32226
  qmdStartupCollectionChecksWithTimeout,
32227
32227
  Orchestrator
32228
32228
  };
32229
- //# sourceMappingURL=chunk-AYTDCMEL.js.map
32229
+ //# sourceMappingURL=chunk-HLKUZW42.js.map
@@ -5,7 +5,7 @@ import {
5
5
  entityMentionScopeKey,
6
6
  resolveEntityMentionIndex,
7
7
  writePersistedEntityMentionIndex
8
- } from "./chunk-S57QBPTA.js";
8
+ } from "./chunk-DPPLNZ3A.js";
9
9
  import {
10
10
  buildOriginStructuredSections,
11
11
  sanitizeOriginatedFacts
@@ -927,4 +927,4 @@ export {
927
927
  entityIndexVersion,
928
928
  entityRecentTranscriptLookbackHours
929
929
  };
930
- //# sourceMappingURL=chunk-DD6OIFDG.js.map
930
+ //# sourceMappingURL=chunk-K3B72DKJ.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"entity-mention-index-cache.d.ts","sourceRoot":"","sources":["../src/entity-mention-index-cache.ts"],"names":[],"mappings":"AAsCA,MAAM,MAAM,qBAAqB,GAAG;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,CAAC,IAAI,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC;IACxD,wBAAwB,CAAC,IAAI,MAAM,CAAC;CACrC,CAAC;AA2BF,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGhE;AAED,wBAAgB,mCAAmC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAKxE;AA2CD,wBAAsB,gCAAgC,CACpD,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAcf;AAwID,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EACzC,QAAQ,EAAE,SAAS,aAAa,EAAE,EAClC,cAAc,EAAE,MAAM,GACrB,MAAM,CAWR;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,GAAG,qBAAqB,CAK/F;AAED,wBAAgB,gCAAgC,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEzE;AAED,wBAAgB,2BAA2B,IAAI,MAAM,EAAE,CAEtD;AAED,wBAAgB,2BAA2B,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAWnE;AAED,wBAAsB,wBAAwB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAc/E;AAED,wBAAsB,yBAAyB,CAAC,CAAC,EAAE,OAAO,EAAE;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,qBAAqB,CAAC;IAC7C,SAAS,EAAE,CAAC,WAAW,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IACrD,eAAe,EAAE,CAAC,QAAQ,EAAE,CAAC,EAAE,WAAW,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IACxE,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,GAAG,OAAO,CAAC,CAAC,CAAC,CAyFb"}
1
+ {"version":3,"file":"entity-mention-index-cache.d.ts","sourceRoot":"","sources":["../src/entity-mention-index-cache.ts"],"names":[],"mappings":"AAuCA,MAAM,MAAM,qBAAqB,GAAG;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,CAAC,IAAI,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC;IACxD,wBAAwB,CAAC,IAAI,MAAM,CAAC;CACrC,CAAC;AA2BF,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGhE;AAED,wBAAgB,mCAAmC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAKxE;AA2CD,wBAAsB,gCAAgC,CACpD,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAcf;AAkID,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EACzC,QAAQ,EAAE,SAAS,aAAa,EAAE,EAClC,cAAc,EAAE,MAAM,GACrB,MAAM,CAWR;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,GAAG,qBAAqB,CAK/F;AAED,wBAAgB,gCAAgC,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEzE;AAED,wBAAgB,2BAA2B,IAAI,MAAM,EAAE,CAEtD;AAED,wBAAgB,2BAA2B,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAWnE;AAED,wBAAsB,wBAAwB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAc/E;AAED,wBAAsB,yBAAyB,CAAC,CAAC,EAAE,OAAO,EAAE;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,qBAAqB,CAAC;IAC7C,SAAS,EAAE,CAAC,WAAW,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IACrD,eAAe,EAAE,CAAC,QAAQ,EAAE,CAAC,EAAE,WAAW,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IACxE,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,GAAG,OAAO,CAAC,CAAC,CAAC,CAyFb"}
@@ -9,7 +9,8 @@ import {
9
9
  resolveEntityMentionIndex,
10
10
  settleEntityMentionIndex,
11
11
  writePersistedEntityMentionIndex
12
- } from "./chunk-S57QBPTA.js";
12
+ } from "./chunk-DPPLNZ3A.js";
13
+ import "./chunk-ULM7JCDH.js";
13
14
  import "./chunk-7CT3AI52.js";
14
15
  import "./chunk-R2MBW2S4.js";
15
16
  import "./chunk-3WCASNQZ.js";
@@ -3,8 +3,9 @@ import {
3
3
  entityIndexVersion,
4
4
  entityRecentTranscriptLookbackHours,
5
5
  readRecentEntityTranscriptEntries
6
- } from "./chunk-DD6OIFDG.js";
7
- import "./chunk-S57QBPTA.js";
6
+ } from "./chunk-K3B72DKJ.js";
7
+ import "./chunk-DPPLNZ3A.js";
8
+ import "./chunk-ULM7JCDH.js";
8
9
  import "./chunk-GKUA4MGB.js";
9
10
  import "./chunk-WJ6S54ES.js";
10
11
  import "./chunk-SVH57F5Z.js";
package/dist/index.js CHANGED
@@ -181,7 +181,7 @@ import {
181
181
  writeManifest,
182
182
  writeMeetingEpisodeMemory,
183
183
  writeTimelineState
184
- } from "./chunk-AYTDCMEL.js";
184
+ } from "./chunk-HLKUZW42.js";
185
185
  import {
186
186
  WEARABLE_SOURCE_PREFIX,
187
187
  buildExtractionTurns,
@@ -473,18 +473,6 @@ import {
473
473
  validateEvalTrajectoryReport,
474
474
  writeEvalTrajectoryReport
475
475
  } from "./chunk-PIITB2YZ.js";
476
- import {
477
- DEFAULT_EVAL_TRAJECTORY_MAX_FUTURE_SKEW_MS,
478
- DEFAULT_EVAL_TRAJECTORY_MAX_ROWS,
479
- DEFAULT_EVAL_TRAJECTORY_OUTCOME_WINDOW_MS,
480
- DEFAULT_EVAL_TRAJECTORY_REPORT_MAX_AGE_MS,
481
- DEFAULT_EVAL_TRAJECTORY_WEIGHTS,
482
- EVAL_TRAJECTORY_PROMOTION_THRESHOLDS,
483
- EVAL_TRAJECTORY_REPORT_SCHEMA_VERSION,
484
- MAX_EVAL_TRAJECTORY_ROWS_LIMIT,
485
- resolveEvalTrajectoryRunConfig,
486
- serializeEvalTrajectoryReport
487
- } from "./chunk-ULM7JCDH.js";
488
476
  import {
489
477
  buildEventOrderRecallSection
490
478
  } from "./chunk-H7BZBSP6.js";
@@ -498,8 +486,20 @@ import {
498
486
  } from "./chunk-DGFU5MSX.js";
499
487
  import {
500
488
  buildEntityRecallSection
501
- } from "./chunk-DD6OIFDG.js";
502
- import "./chunk-S57QBPTA.js";
489
+ } from "./chunk-K3B72DKJ.js";
490
+ import "./chunk-DPPLNZ3A.js";
491
+ import {
492
+ DEFAULT_EVAL_TRAJECTORY_MAX_FUTURE_SKEW_MS,
493
+ DEFAULT_EVAL_TRAJECTORY_MAX_ROWS,
494
+ DEFAULT_EVAL_TRAJECTORY_OUTCOME_WINDOW_MS,
495
+ DEFAULT_EVAL_TRAJECTORY_REPORT_MAX_AGE_MS,
496
+ DEFAULT_EVAL_TRAJECTORY_WEIGHTS,
497
+ EVAL_TRAJECTORY_PROMOTION_THRESHOLDS,
498
+ EVAL_TRAJECTORY_REPORT_SCHEMA_VERSION,
499
+ MAX_EVAL_TRAJECTORY_ROWS_LIMIT,
500
+ resolveEvalTrajectoryRunConfig,
501
+ serializeEvalTrajectoryReport
502
+ } from "./chunk-ULM7JCDH.js";
503
503
  import "./chunk-GKUA4MGB.js";
504
504
  import "./chunk-WJ6S54ES.js";
505
505
  import "./chunk-SVH57F5Z.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  BufferDrainRunner
3
- } from "../chunk-SVCHO337.js";
4
- import "../chunk-AYTDCMEL.js";
3
+ } from "../chunk-3JPTUCD7.js";
4
+ import "../chunk-HLKUZW42.js";
5
5
  import "../chunk-KFLD7ZZG.js";
6
6
  import "../chunk-QZSIDSB2.js";
7
7
  import "../chunk-5PHOU5QI.js";
@@ -95,14 +95,14 @@ import "../chunk-YVVQUAOO.js";
95
95
  import "../chunk-VL35ZFSZ.js";
96
96
  import "../chunk-W2UOAATB.js";
97
97
  import "../chunk-PIITB2YZ.js";
98
- import "../chunk-ULM7JCDH.js";
99
98
  import "../chunk-H7BZBSP6.js";
100
99
  import "../chunk-LUPVCGYK.js";
101
100
  import "../chunk-BUYVPUEM.js";
102
101
  import "../chunk-IAIPNEHD.js";
103
102
  import "../chunk-DGFU5MSX.js";
104
- import "../chunk-DD6OIFDG.js";
105
- import "../chunk-S57QBPTA.js";
103
+ import "../chunk-K3B72DKJ.js";
104
+ import "../chunk-DPPLNZ3A.js";
105
+ import "../chunk-ULM7JCDH.js";
106
106
  import "../chunk-GKUA4MGB.js";
107
107
  import "../chunk-WJ6S54ES.js";
108
108
  import "../chunk-SVH57F5Z.js";
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  BufferDrainRunner,
3
3
  ClaimBufferStorage
4
- } from "../chunk-SVCHO337.js";
5
- import "../chunk-AYTDCMEL.js";
4
+ } from "../chunk-3JPTUCD7.js";
5
+ import "../chunk-HLKUZW42.js";
6
6
  import "../chunk-KFLD7ZZG.js";
7
7
  import "../chunk-QZSIDSB2.js";
8
8
  import "../chunk-5PHOU5QI.js";
@@ -96,14 +96,14 @@ import "../chunk-YVVQUAOO.js";
96
96
  import "../chunk-VL35ZFSZ.js";
97
97
  import "../chunk-W2UOAATB.js";
98
98
  import "../chunk-PIITB2YZ.js";
99
- import "../chunk-ULM7JCDH.js";
100
99
  import "../chunk-H7BZBSP6.js";
101
100
  import "../chunk-LUPVCGYK.js";
102
101
  import "../chunk-BUYVPUEM.js";
103
102
  import "../chunk-IAIPNEHD.js";
104
103
  import "../chunk-DGFU5MSX.js";
105
- import "../chunk-DD6OIFDG.js";
106
- import "../chunk-S57QBPTA.js";
104
+ import "../chunk-K3B72DKJ.js";
105
+ import "../chunk-DPPLNZ3A.js";
106
+ import "../chunk-ULM7JCDH.js";
107
107
  import "../chunk-GKUA4MGB.js";
108
108
  import "../chunk-WJ6S54ES.js";
109
109
  import "../chunk-SVH57F5Z.js";
@@ -4,7 +4,7 @@ import {
4
4
  graphPathRelativeToStorage,
5
5
  mergeGraphExpandedResults,
6
6
  qmdStartupCollectionChecksWithTimeout
7
- } from "./chunk-AYTDCMEL.js";
7
+ } from "./chunk-HLKUZW42.js";
8
8
  import "./chunk-KFLD7ZZG.js";
9
9
  import "./chunk-QZSIDSB2.js";
10
10
  import {
@@ -100,14 +100,14 @@ import "./chunk-YVVQUAOO.js";
100
100
  import "./chunk-VL35ZFSZ.js";
101
101
  import "./chunk-W2UOAATB.js";
102
102
  import "./chunk-PIITB2YZ.js";
103
- import "./chunk-ULM7JCDH.js";
104
103
  import "./chunk-H7BZBSP6.js";
105
104
  import "./chunk-LUPVCGYK.js";
106
105
  import "./chunk-BUYVPUEM.js";
107
106
  import "./chunk-IAIPNEHD.js";
108
107
  import "./chunk-DGFU5MSX.js";
109
- import "./chunk-DD6OIFDG.js";
110
- import "./chunk-S57QBPTA.js";
108
+ import "./chunk-K3B72DKJ.js";
109
+ import "./chunk-DPPLNZ3A.js";
110
+ import "./chunk-ULM7JCDH.js";
111
111
  import "./chunk-GKUA4MGB.js";
112
112
  import "./chunk-WJ6S54ES.js";
113
113
  import "./chunk-SVH57F5Z.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remnic/core",
3
- "version": "10.0.83",
3
+ "version": "10.0.84",
4
4
  "description": "Framework-agnostic Remnic memory engine — orchestrator, storage, extraction, search, trust zones",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -3386,7 +3386,7 @@
3386
3386
  "core"
3387
3387
  ],
3388
3388
  "peerDependencies": {
3389
- "@remnic/coding-graph": "^10.0.83"
3389
+ "@remnic/coding-graph": "^10.0.84"
3390
3390
  },
3391
3391
  "peerDependenciesMeta": {
3392
3392
  "@remnic/coding-graph": {
@@ -0,0 +1,45 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+
4
+ import { correctionMcpTools } from "./access-mcp-correction-tools.js";
5
+
6
+ test("correctionMcpTools exposes plan and apply with closed schemas", () => {
7
+ assert.equal(correctionMcpTools.length, 2);
8
+ const names = correctionMcpTools.map((tool) => tool.name);
9
+ assert.deepEqual(names, ["engram.memory_correct_plan", "engram.memory_correct_apply"]);
10
+
11
+ for (const tool of correctionMcpTools) {
12
+ assert.equal(tool.inputSchema.type, "object");
13
+ assert.equal(tool.inputSchema.additionalProperties, false);
14
+ assert.ok(tool.description && tool.description.length > 20);
15
+ }
16
+ });
17
+
18
+ test("memory_correct_plan requires text and advertises duplicateOf", () => {
19
+ const plan = correctionMcpTools.find((tool) => tool.name === "engram.memory_correct_plan");
20
+ assert.ok(plan);
21
+ assert.deepEqual(plan.inputSchema.required, ["text"]);
22
+ // SAFETY: the memory_correct_plan schema declares these properties; the assertions below read only them.
23
+ const props = plan.inputSchema.properties as Record<string, { type?: string; items?: { type?: string } }>;
24
+ assert.equal(props.text?.type, "string");
25
+ assert.equal(props.duplicateOf?.type, "string");
26
+ assert.equal(props.targetIds?.type, "array");
27
+ assert.equal(props.targetIds?.items?.type, "string");
28
+ assert.equal(props.sessionKey?.type, "string");
29
+ assert.equal(props.namespace?.type, "string");
30
+ assert.match(plan.description, /duplicateOf/);
31
+ assert.match(plan.description, /memory_correct_apply/);
32
+ });
33
+
34
+ test("memory_correct_apply requires planId and advertises confirm", () => {
35
+ const apply = correctionMcpTools.find((tool) => tool.name === "engram.memory_correct_apply");
36
+ assert.ok(apply);
37
+ assert.deepEqual(apply.inputSchema.required, ["planId"]);
38
+ // SAFETY: the memory_correct_apply schema declares these properties; the assertions below read only them.
39
+ const props = apply.inputSchema.properties as Record<string, { type?: string }>;
40
+ assert.equal(props.planId?.type, "string");
41
+ assert.equal(props.confirm?.type, "boolean");
42
+ assert.equal(props.sessionKey?.type, "string");
43
+ assert.equal(props.namespace?.type, "string");
44
+ assert.match(apply.description, /confirm:\s*true/i);
45
+ });
@@ -0,0 +1,237 @@
1
+ import assert from "node:assert/strict";
2
+ import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ import test from "node:test";
6
+
7
+ import type { MemoryFile } from "../types.js";
8
+ import { rememberRawFrontmatter } from "../storage/memory-frontmatter-metadata.js";
9
+ import {
10
+ CORRECTION_FILE_BYTE_LIMIT,
11
+ WEEKLY_CORRECTION_READ_LIMIT,
12
+ WEEKLY_CORRECTION_SCAN_LIMIT,
13
+ buildActionFailurePatterns,
14
+ capWeeklyPatternDetails,
15
+ isoWeekStartMs,
16
+ provenanceVisibleInStoreRecall,
17
+ readFeedbackEntriesForWeekFile,
18
+ readWeeklyCorrections,
19
+ type WeeklyActionEvent,
20
+ type WeeklyEvidenceStorage,
21
+ } from "./weekly-evidence.js";
22
+ import { isoWeekId } from "./iso-week.js";
23
+
24
+ test("isoWeekStartMs returns Monday UTC for valid ids and null otherwise", () => {
25
+ const start = isoWeekStartMs("2026-W01");
26
+ assert.ok(start !== null);
27
+ assert.equal(new Date(start).toISOString(), "2025-12-29T00:00:00.000Z");
28
+ assert.equal(isoWeekId(new Date(start)), "2026-W01");
29
+
30
+ const w02 = isoWeekStartMs("2026-W02");
31
+ assert.ok(w02 !== null);
32
+ assert.equal(w02 - start!, 7 * 86_400_000);
33
+
34
+ assert.equal(isoWeekStartMs("2026-W1"), null);
35
+ assert.equal(isoWeekStartMs("2026-W00"), null);
36
+ assert.equal(isoWeekStartMs("not-a-week"), null);
37
+ assert.equal(isoWeekStartMs("2026-W54"), null);
38
+ // 2026 has 53 weeks only if the calendar emits it; W53 that does not land is null.
39
+ const w53 = isoWeekStartMs("2015-W53");
40
+ assert.ok(w53 !== null);
41
+ assert.equal(isoWeekId(new Date(w53)), "2015-W53");
42
+ assert.equal(isoWeekStartMs("2016-W53"), null);
43
+ });
44
+
45
+ test("readFeedbackEntriesForWeekFile filters by ISO week and skips bad lines", async () => {
46
+ const root = await mkdtemp(path.join(os.tmpdir(), "remnic-weekly-feedback-"));
47
+ try {
48
+ const inbox = path.join(root, "feedback.jsonl");
49
+ const inWeek = "2026-01-02T12:00:00.000Z"; // 2026-W01
50
+ const otherWeek = "2026-01-08T12:00:00.000Z"; // 2026-W02
51
+ await writeFile(
52
+ inbox,
53
+ [
54
+ JSON.stringify({
55
+ agent: "alpha",
56
+ decision: "approved",
57
+ reason: "looks good",
58
+ date: inWeek,
59
+ }),
60
+ "not-json",
61
+ JSON.stringify({ agent: "", decision: "approved", reason: "x", date: inWeek }),
62
+ JSON.stringify({
63
+ agent: "beta",
64
+ decision: "rejected",
65
+ reason: "no",
66
+ date: otherWeek,
67
+ }),
68
+ JSON.stringify({
69
+ agent: "gamma",
70
+ decision: "approved_with_feedback",
71
+ reason: "tweak",
72
+ date: "2025-12-30T08:00:00.000Z",
73
+ }),
74
+ "",
75
+ ].join("\n"),
76
+ "utf8",
77
+ );
78
+
79
+ const entries = await readFeedbackEntriesForWeekFile(inbox, "2026-W01");
80
+ assert.equal(entries.length, 2);
81
+ assert.deepEqual(
82
+ entries.map((row) => row.entry.agent).sort(),
83
+ ["alpha", "gamma"],
84
+ );
85
+ assert.equal(entries.find((row) => row.entry.agent === "alpha")?.sourceLine, 1);
86
+ assert.equal(entries.find((row) => row.entry.agent === "gamma")?.sourceLine, 5);
87
+
88
+ assert.deepEqual(await readFeedbackEntriesForWeekFile(path.join(root, "missing.jsonl"), "2026-W01"), []);
89
+ } finally {
90
+ await rm(root, { recursive: true, force: true });
91
+ }
92
+ });
93
+
94
+ test("buildActionFailurePatterns keeps failures, skips, and policy decisions", () => {
95
+ const events: WeeklyActionEvent[] = [
96
+ {
97
+ line: 1,
98
+ action: "forget",
99
+ outcome: "failed",
100
+ policyDecision: null,
101
+ namespace: "default",
102
+ reason: "locked",
103
+ ledgerLabel: "memory-actions.jsonl",
104
+ actionId: "a1",
105
+ },
106
+ {
107
+ line: 2,
108
+ action: "promote",
109
+ outcome: "applied",
110
+ policyDecision: null,
111
+ namespace: "default",
112
+ reason: null,
113
+ ledgerLabel: "memory-actions.jsonl",
114
+ actionId: "a2",
115
+ },
116
+ {
117
+ line: 3,
118
+ action: "edit",
119
+ outcome: "applied",
120
+ policyDecision: "deny",
121
+ namespace: "ns1",
122
+ reason: " blocked by policy ",
123
+ ledgerLabel: "namespaces/ns1/state/memory-actions.jsonl",
124
+ actionId: "a3",
125
+ },
126
+ {
127
+ line: 4,
128
+ action: "merge",
129
+ outcome: "skipped",
130
+ policyDecision: null,
131
+ namespace: "default",
132
+ reason: null,
133
+ ledgerLabel: "memory-actions.jsonl",
134
+ actionId: "a4",
135
+ },
136
+ ];
137
+
138
+ const patterns = buildActionFailurePatterns(events);
139
+ assert.equal(patterns.length, 3);
140
+ assert.match(patterns[0]!.pattern, /memory-action\/default: forget failed - locked/);
141
+ assert.equal(patterns[0]!.provenance, "memory-actions.jsonl:*");
142
+ assert.match(patterns[1]!.pattern, /memory-action\/ns1: edit applied\/deny - blocked by policy/);
143
+ assert.match(patterns[2]!.pattern, /memory-action\/default: merge skipped$/);
144
+ });
145
+
146
+ test("readWeeklyCorrections skips files over the byte cap and keeps in-week active ones", async () => {
147
+ const root = await mkdtemp(path.join(os.tmpdir(), "remnic-weekly-corr-"));
148
+ try {
149
+ const correctionsDir = path.join(root, "corrections");
150
+ await mkdir(correctionsDir, { recursive: true });
151
+
152
+ const inWeekMs = Date.parse("2026-01-02T15:00:00.000Z");
153
+ const smallName = `correction-${inWeekMs}.md`;
154
+ const largeName = `correction-${inWeekMs + 1000}.md`;
155
+ const smallBody = `---
156
+ id: corr-small
157
+ category: correction
158
+ status: active
159
+ created: 2026-01-02T15:00:00.000Z
160
+ ---
161
+
162
+ Fix the pricing table.
163
+ `;
164
+ await writeFile(path.join(correctionsDir, smallName), smallBody, "utf8");
165
+ await writeFile(
166
+ path.join(correctionsDir, largeName),
167
+ `${"x".repeat(CORRECTION_FILE_BYTE_LIMIT + 1)}`,
168
+ "utf8",
169
+ );
170
+
171
+ // SAFETY: rememberRawFrontmatter reads only path, content and frontmatter; this literal sets all three.
172
+ const smallMemory = rememberRawFrontmatter(
173
+ {
174
+ path: path.join(correctionsDir, smallName),
175
+ content: "Fix the pricing table.",
176
+ frontmatter: {
177
+ id: "corr-small",
178
+ category: "correction",
179
+ status: "active",
180
+ created: "2026-01-02T15:00:00.000Z",
181
+ },
182
+ } as MemoryFile,
183
+ smallBody,
184
+ );
185
+ const byPath = new Map<string, MemoryFile>([[path.join(correctionsDir, smallName), smallMemory]]);
186
+
187
+ const storage: WeeklyEvidenceStorage = {
188
+ async readMemoryByPath(filePath) {
189
+ return byPath.get(filePath) ?? null;
190
+ },
191
+ async readMemoryActionEventRows() {
192
+ return [];
193
+ },
194
+ };
195
+
196
+ const evidence = await readWeeklyCorrections({
197
+ storage,
198
+ memoryDir: root,
199
+ weekId: "2026-W01",
200
+ });
201
+ assert.equal(evidence.length, 1);
202
+ assert.equal(evidence[0]!.id, "corr-small");
203
+ assert.equal(evidence[0]!.note, "Fix the pricing table.");
204
+ assert.equal(evidence[0]!.provenance, `corrections/${smallName}`);
205
+
206
+ assert.ok(CORRECTION_FILE_BYTE_LIMIT === 256 * 1024);
207
+ assert.ok(WEEKLY_CORRECTION_READ_LIMIT === 500);
208
+ assert.ok(WEEKLY_CORRECTION_SCAN_LIMIT === 2000);
209
+ } finally {
210
+ await rm(root, { recursive: true, force: true });
211
+ }
212
+ });
213
+
214
+ test("provenanceVisibleInStoreRecall and capWeeklyPatternDetails prefer visible actions", () => {
215
+ assert.equal(provenanceVisibleInStoreRecall(["facts/a.md"]), true);
216
+ assert.equal(provenanceVisibleInStoreRecall(["namespaces/other/x.md"]), false);
217
+ assert.equal(provenanceVisibleInStoreRecall(["namespaces/home/x.md"], "namespaces/home/"), true);
218
+ assert.equal(provenanceVisibleInStoreRecall([]), true);
219
+
220
+ const details = [
221
+ { pattern: "foreign", provenance: ["namespaces/other/a.md"] as const },
222
+ { pattern: "action-a", provenance: ["memory-actions.jsonl:*"] as const },
223
+ { pattern: "corr", provenance: ["corrections/c.md"] as const },
224
+ { pattern: "action-b", provenance: ["memory-actions.jsonl:*"] as const },
225
+ { pattern: "overflow", provenance: ["facts/x.md"] as const },
226
+ ];
227
+ const capped = capWeeklyPatternDetails(
228
+ details,
229
+ (pattern) => (pattern.startsWith("action") ? "action" : "correction"),
230
+ null,
231
+ 3,
232
+ );
233
+ assert.deepEqual(
234
+ capped.map((row) => row.pattern),
235
+ ["action-a", "action-b", "corr"],
236
+ );
237
+ });
@@ -3,6 +3,7 @@ import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
3
3
  import { raceAbort } from "./abort-error.js";
4
4
  import { entityMentionEpoch } from "./entity-mention-epoch.js";
5
5
  import { log } from "./logger.js";
6
+ import { compareStrings } from "./eval-trajectory-contracts.js";
6
7
 
7
8
  /**
8
9
  * In-memory entity mention index.
@@ -158,12 +159,6 @@ function throwIfMentionAborted(signal?: AbortSignal): void {
158
159
  throw reason instanceof Error ? reason : new Error("entity mention rebuild aborted");
159
160
  }
160
161
 
161
- function compareStrings(left: string, right: string): number {
162
- if (left < right) return -1;
163
- if (left > right) return 1;
164
- return 0;
165
- }
166
-
167
162
  function deduped(values: readonly string[]): string[] {
168
163
  const seen = new Set<string>();
169
164
  const out: string[] = [];