@remnic/core 9.3.714 → 9.3.715

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.
@@ -7,7 +7,7 @@ import { RebuildMemoryLifecycleLedgerResult } from './maintenance/rebuild-memory
7
7
  import { RebuildObservationsResult } from './maintenance/rebuild-observations.js';
8
8
  import { ArchiveObservationsResult } from './maintenance/archive-observations.js';
9
9
  import { Writable, Readable } from 'node:stream';
10
- import { O as Orchestrator } from './orchestrator-iVZWi8aW.js';
10
+ import { O as Orchestrator } from './orchestrator-BOaVstFG.js';
11
11
  import { ReplayRunSummary } from './replay/runner.js';
12
12
  import { ReplaySource, ReplayTurn } from './replay/types.js';
13
13
  import { b as BulkImportResult } from './types-gb_SNtjR.js';
@@ -16,7 +16,7 @@ import { WorkProjectStatus, WorkTaskStatus, WorkTaskPriority } from './work/type
16
16
  import { RoutePatternType } from './routing/engine.js';
17
17
  import { TailscaleSyncOptions } from './network/tailscale.js';
18
18
  import { DashboardStatus } from './dashboard-runtime.js';
19
- import { g as EngramAccessService } from './access-service-lddjZoRh.js';
19
+ import { g as EngramAccessService } from './access-service-GgnA--CE.js';
20
20
  import { ResolveSecretRefFn } from './resolve-auth-token.js';
21
21
  import { CompatRunner, CompatReport } from './compat/types.js';
22
22
  import { EvalBaselineDeltaReport, EvalBaselineSnapshot, EvalCiGateReport, EvalBenchmarkPackSummary, EvalHarnessStatus, EvalStoredBaselineCiGateReport } from './evals.js';
package/dist/cli.d.ts CHANGED
@@ -7,7 +7,7 @@ import './maintenance/rebuild-memory-lifecycle-ledger.js';
7
7
  import './maintenance/rebuild-observations.js';
8
8
  import './maintenance/archive-observations.js';
9
9
  import 'node:stream';
10
- import './orchestrator-iVZWi8aW.js';
10
+ import './orchestrator-BOaVstFG.js';
11
11
  import './replay/runner.js';
12
12
  import './replay/types.js';
13
13
  import './types-gb_SNtjR.js';
@@ -16,7 +16,7 @@ import './work/types.js';
16
16
  import './routing/engine.js';
17
17
  import './network/tailscale.js';
18
18
  import './dashboard-runtime.js';
19
- import './access-service-lddjZoRh.js';
19
+ import './access-service-GgnA--CE.js';
20
20
  import './resolve-auth-token.js';
21
21
  import './compat/types.js';
22
22
  import './evals.js';
@@ -38,7 +38,7 @@ import './trust-zones.js';
38
38
  import './session-integrity.js';
39
39
  import './recall-state.js';
40
40
  import './policy-runtime.js';
41
- export { A as AccessHttpServeCliCommandOptions, a as ArchiveObservationsCliCommandOptions, B as BulkImportCliCommandOptions, C as CliApi, b as CliCommand, c as CliProgram, d as CompatCliCommandOptions, e as ConnectorsRunCliOutputOptions, f as ConversationIndexHealthCliOrchestrator, D as DashboardStartCliCommandOptions, g as DedupeCandidate, E as ExactDedupePlan, G as GraphHealthCliCommandOptions, M as MemoryActionAuditCliCommandOptions, h as MemoryActionAuditCliNamespaceSummary, i as MemoryActionAuditCliReport, j as MemoryGovernanceCliCommandOptions, k as MemoryGovernanceReportCliCommandOptions, l as MemoryGovernanceRestoreCliCommandOptions, m as MemoryReviewDispositionCliCommandOptions, n as MemoryTimelineCliCommandOptions, o as MigrateCliOrchestrator, q as MigrateCliReport, s as MigrateObservationsCliCommandOptions, P as PolicyDiffCliReport, t as PolicyDiffEntry, u as PolicyRollbackCliReport, v as PolicyStatusCliReport, w as PolicyTuningCliOrchestrator, R as RebuildMemoryLifecycleLedgerCliCommandOptions, x as RebuildMemoryProjectionCliCommandOptions, y as RebuildObservationsCliCommandOptions, z as RepairMemoryProjectionCliCommandOptions, F as ReplayCliCommandOptions, H as ReplayCliOrchestrator, I as RouteCliCommandOptions, S as SessionIntegrityCliCommandOptions, J as SessionRepairCliCommandOptions, T as TailscaleStatusCliCommandOptions, K as TailscaleSyncCliCommandOptions, L as TierMigrationCliOrchestrator, N as TrainingExportCliCommandOptions, V as VerifyMemoryProjectionCliCommandOptions, W as WebDavServeCliCommandOptions, O as WorkProjectCliCommandOptions, Q as WorkTaskCliCommandOptions, U as emitConnectorsRunCliResult, X as filterNormalMemorySearchResults, Y as hasDestructivePurgeFailures, Z as isNormalRetrievalVisibleMemory, _ as listMemoryMarkdownFilePaths, $ as parseDurationToMs, a0 as parseStrictCliDate, a1 as planAggressiveDuplicateDeletions, a2 as planExactDuplicateDeletions, a3 as registerCli, a4 as resolveAccessPrincipalOverride, a5 as resolveMemoryDirForNamespace, a6 as runAbstractionNodeStatusCliCommand, a7 as runAccessHttpServeCliCommand, a8 as runAccessHttpStatusCliCommand, a9 as runAccessHttpStopCliCommand, aa as runAccessMcpServeCliCommand, ab as runArchiveObservationsCliCommand, ac as runBenchmarkBaselineReportCliCommand, ad as runBenchmarkBaselineSnapshotCliCommand, ae as runBenchmarkCiGateCliCommand, af as runBenchmarkImportCliCommand, ag as runBenchmarkStatusCliCommand, ah as runBenchmarkStoredBaselineCiGateCliCommand, ai as runBenchmarkValidateCliCommand, r as runBulkImportCliCommand, aj as runCausalTrajectoryStatusCliCommand, ak as runCommitmentLifecycleCliCommand, al as runCommitmentRecordCliCommand, am as runCommitmentSetStateCliCommand, an as runCommitmentStatusCliCommand, ao as runCompatCliCommand, ap as runCompoundingPromoteCliCommand, aq as runConversationIndexHealthCliCommand, ar as runConversationIndexInspectCliCommand, as as runConversationIndexRebuildCliCommand, at as runCueAnchorStatusCliCommand, au as runDashboardStartCliCommand, av as runDashboardStatusCliCommand, aw as runDashboardStopCliCommand, ax as runGraphHealthCliCommand, ay as runHarmonicSearchCliCommand, az as runMemoryActionAuditCliCommand, aA as runMemoryGovernanceCliCommand, aB as runMemoryGovernanceReportCliCommand, aC as runMemoryGovernanceRestoreCliCommand, aD as runMemoryReviewDispositionCliCommand, aE as runMemoryTimelineCliCommand, aF as runMigrateNormalizeFrontmatterCliCommand, aG as runMigrateObservationsCliCommand, aH as runMigrateRechunkCliCommand, aI as runMigrateReextractCliCommand, aJ as runMigrateRescoreImportanceCliCommand, aK as runObjectiveStateStatusCliCommand, aL as runPolicyDiffCliCommand, aM as runPolicyRollbackCliCommand, aN as runPolicyStatusCliCommand, aO as runRebuildMemoryLifecycleLedgerCliCommand, aP as runRebuildMemoryProjectionCliCommand, aQ as runRebuildObservationsCliCommand, aR as runRepairMemoryProjectionCliCommand, aS as runReplayCliCommand, aT as runResumeBundleBuildCliCommand, aU as runResumeBundleRecordCliCommand, aV as runResumeBundleStatusCliCommand, aW as runRouteCliCommand, aX as runSemanticRulePromoteCliCommand, aY as runSemanticRuleVerifyCliCommand, aZ as runSessionCheckCliCommand, a_ as runSessionRepairCliCommand, a$ as runTailscaleStatusCliCommand, b0 as runTailscaleSyncCliCommand, b1 as runTierMigrateCliCommand, b2 as runTierStatusCliCommand, b3 as runTrainingExportCliCommand, b4 as runTrustZoneDemoSeedCliCommand, b5 as runTrustZonePromoteCliCommand, b6 as runTrustZoneStatusCliCommand, b7 as runUtilityLearningCliCommand, b8 as runUtilityLearningStatusCliCommand, b9 as runUtilityTelemetryRecordCliCommand, ba as runUtilityTelemetryStatusCliCommand, bb as runVerifiedRecallSearchCliCommand, bc as runVerifyMemoryProjectionCliCommand, bd as runWebDavServeCliCommand, be as runWebDavStopCliCommand, bf as runWorkProductRecallSearchCliCommand, bg as runWorkProductRecordCliCommand, bh as runWorkProductStatusCliCommand, bi as runWorkProjectCliCommand, bj as runWorkTaskCliCommand } from './cli-iAiVkbYJ.js';
41
+ export { A as AccessHttpServeCliCommandOptions, a as ArchiveObservationsCliCommandOptions, B as BulkImportCliCommandOptions, C as CliApi, b as CliCommand, c as CliProgram, d as CompatCliCommandOptions, e as ConnectorsRunCliOutputOptions, f as ConversationIndexHealthCliOrchestrator, D as DashboardStartCliCommandOptions, g as DedupeCandidate, E as ExactDedupePlan, G as GraphHealthCliCommandOptions, M as MemoryActionAuditCliCommandOptions, h as MemoryActionAuditCliNamespaceSummary, i as MemoryActionAuditCliReport, j as MemoryGovernanceCliCommandOptions, k as MemoryGovernanceReportCliCommandOptions, l as MemoryGovernanceRestoreCliCommandOptions, m as MemoryReviewDispositionCliCommandOptions, n as MemoryTimelineCliCommandOptions, o as MigrateCliOrchestrator, q as MigrateCliReport, s as MigrateObservationsCliCommandOptions, P as PolicyDiffCliReport, t as PolicyDiffEntry, u as PolicyRollbackCliReport, v as PolicyStatusCliReport, w as PolicyTuningCliOrchestrator, R as RebuildMemoryLifecycleLedgerCliCommandOptions, x as RebuildMemoryProjectionCliCommandOptions, y as RebuildObservationsCliCommandOptions, z as RepairMemoryProjectionCliCommandOptions, F as ReplayCliCommandOptions, H as ReplayCliOrchestrator, I as RouteCliCommandOptions, S as SessionIntegrityCliCommandOptions, J as SessionRepairCliCommandOptions, T as TailscaleStatusCliCommandOptions, K as TailscaleSyncCliCommandOptions, L as TierMigrationCliOrchestrator, N as TrainingExportCliCommandOptions, V as VerifyMemoryProjectionCliCommandOptions, W as WebDavServeCliCommandOptions, O as WorkProjectCliCommandOptions, Q as WorkTaskCliCommandOptions, U as emitConnectorsRunCliResult, X as filterNormalMemorySearchResults, Y as hasDestructivePurgeFailures, Z as isNormalRetrievalVisibleMemory, _ as listMemoryMarkdownFilePaths, $ as parseDurationToMs, a0 as parseStrictCliDate, a1 as planAggressiveDuplicateDeletions, a2 as planExactDuplicateDeletions, a3 as registerCli, a4 as resolveAccessPrincipalOverride, a5 as resolveMemoryDirForNamespace, a6 as runAbstractionNodeStatusCliCommand, a7 as runAccessHttpServeCliCommand, a8 as runAccessHttpStatusCliCommand, a9 as runAccessHttpStopCliCommand, aa as runAccessMcpServeCliCommand, ab as runArchiveObservationsCliCommand, ac as runBenchmarkBaselineReportCliCommand, ad as runBenchmarkBaselineSnapshotCliCommand, ae as runBenchmarkCiGateCliCommand, af as runBenchmarkImportCliCommand, ag as runBenchmarkStatusCliCommand, ah as runBenchmarkStoredBaselineCiGateCliCommand, ai as runBenchmarkValidateCliCommand, r as runBulkImportCliCommand, aj as runCausalTrajectoryStatusCliCommand, ak as runCommitmentLifecycleCliCommand, al as runCommitmentRecordCliCommand, am as runCommitmentSetStateCliCommand, an as runCommitmentStatusCliCommand, ao as runCompatCliCommand, ap as runCompoundingPromoteCliCommand, aq as runConversationIndexHealthCliCommand, ar as runConversationIndexInspectCliCommand, as as runConversationIndexRebuildCliCommand, at as runCueAnchorStatusCliCommand, au as runDashboardStartCliCommand, av as runDashboardStatusCliCommand, aw as runDashboardStopCliCommand, ax as runGraphHealthCliCommand, ay as runHarmonicSearchCliCommand, az as runMemoryActionAuditCliCommand, aA as runMemoryGovernanceCliCommand, aB as runMemoryGovernanceReportCliCommand, aC as runMemoryGovernanceRestoreCliCommand, aD as runMemoryReviewDispositionCliCommand, aE as runMemoryTimelineCliCommand, aF as runMigrateNormalizeFrontmatterCliCommand, aG as runMigrateObservationsCliCommand, aH as runMigrateRechunkCliCommand, aI as runMigrateReextractCliCommand, aJ as runMigrateRescoreImportanceCliCommand, aK as runObjectiveStateStatusCliCommand, aL as runPolicyDiffCliCommand, aM as runPolicyRollbackCliCommand, aN as runPolicyStatusCliCommand, aO as runRebuildMemoryLifecycleLedgerCliCommand, aP as runRebuildMemoryProjectionCliCommand, aQ as runRebuildObservationsCliCommand, aR as runRepairMemoryProjectionCliCommand, aS as runReplayCliCommand, aT as runResumeBundleBuildCliCommand, aU as runResumeBundleRecordCliCommand, aV as runResumeBundleStatusCliCommand, aW as runRouteCliCommand, aX as runSemanticRulePromoteCliCommand, aY as runSemanticRuleVerifyCliCommand, aZ as runSessionCheckCliCommand, a_ as runSessionRepairCliCommand, a$ as runTailscaleStatusCliCommand, b0 as runTailscaleSyncCliCommand, b1 as runTierMigrateCliCommand, b2 as runTierStatusCliCommand, b3 as runTrainingExportCliCommand, b4 as runTrustZoneDemoSeedCliCommand, b5 as runTrustZonePromoteCliCommand, b6 as runTrustZoneStatusCliCommand, b7 as runUtilityLearningCliCommand, b8 as runUtilityLearningStatusCliCommand, b9 as runUtilityTelemetryRecordCliCommand, ba as runUtilityTelemetryStatusCliCommand, bb as runVerifiedRecallSearchCliCommand, bc as runVerifyMemoryProjectionCliCommand, bd as runWebDavServeCliCommand, be as runWebDavStopCliCommand, bf as runWorkProductRecallSearchCliCommand, bg as runWorkProductRecordCliCommand, bh as runWorkProductStatusCliCommand, bi as runWorkProjectCliCommand, bj as runWorkTaskCliCommand } from './cli-Do1YtfnH.js';
42
42
  import './connectors-cli-2iaQ5tX2.js';
43
43
  import './storage.js';
44
44
  import './page-versioning.js';
@@ -1,4 +1,4 @@
1
- import { O as Orchestrator } from './orchestrator-iVZWi8aW.js';
1
+ import { O as Orchestrator } from './orchestrator-BOaVstFG.js';
2
2
  import { M as MemoryCategory, P as PluginConfig } from './types-D9dwzU_x.js';
3
3
  import './briefing.js';
4
4
  import './storage.js';
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  export { PluginEntryResolverOptions, resolvePluginEntry } from './plugin-entry-resolver.js';
2
2
  export { isOpenaiApiKeyDisabled, parseConfig, resolveEnvVars } from './config.js';
3
3
  export { MigrationOptions, MigrationResult, RollbackResult, migrateFromEngram, rollbackFromEngramMigration } from './migrate/from-engram.js';
4
- import { S as SpeakerRegistry, W as WearablesService } from './orchestrator-iVZWi8aW.js';
5
- export { D as DEFAULT_SELF_NAME, O as Orchestrator, R as ResolvedSpeaker, a as SpeakerOverride, b as WEARABLE_SOURCE_PREFIX, c as WearableDayTranscriptView, d as WearableMemoryGenDeps, e as WearableMemoryGenResult, f as WearableMemorySearchResult, g as WearableMemoryWriter, h as WearableSearchBackend, i as WearableStorageIo, j as WearableSyncDeps, k as WearableSyncOptions, l as WearableTranscriptSearchResult, m as WearablesServiceDeps, n as buildExtractionTurns, o as dateInTimezone, p as defaultTimezone, q as defaultWorkspaceDir, r as distinctSpeakerLabels, s as emptySpeakerRegistry, t as generateWearableMemories, u as importNativeMemories, v as loadSpeakerRegistry, w as locateTranscriptPath, x as memoryStatusForMode, y as resolveSpeaker, z as resolveSyncDates, A as sanitizeSessionKeyForFilename, B as saveSpeakerRegistry, C as speakerRegistryKey, E as speakersFilePath, F as syncWearableSource, H as wearableDayTag, J as wearableSourceLabel, K as writeDailyDigestMemory } from './orchestrator-iVZWi8aW.js';
4
+ import { S as SpeakerRegistry, W as WearablesService } from './orchestrator-BOaVstFG.js';
5
+ export { D as DEFAULT_SELF_NAME, O as Orchestrator, R as ResolvedSpeaker, a as SpeakerOverride, b as WEARABLE_SOURCE_PREFIX, c as WearableDayTranscriptView, d as WearableMemoryGenDeps, e as WearableMemoryGenResult, f as WearableMemorySearchResult, g as WearableMemoryWriter, h as WearableSearchBackend, i as WearableStorageIo, j as WearableSyncDeps, k as WearableSyncOptions, l as WearableTranscriptSearchResult, m as WearablesServiceDeps, n as buildExtractionTurns, o as dateInTimezone, p as defaultTimezone, q as defaultWorkspaceDir, r as distinctSpeakerLabels, s as emptySpeakerRegistry, t as generateWearableMemories, u as importNativeMemories, v as loadSpeakerRegistry, w as locateTranscriptPath, x as memoryStatusForMode, y as resolveSpeaker, z as resolveSyncDates, A as sanitizeSessionKeyForFilename, B as saveSpeakerRegistry, C as speakerRegistryKey, E as speakersFilePath, F as syncWearableSource, H as wearableDayTag, J as wearableSourceLabel, K as writeDailyDigestMemory } from './orchestrator-BOaVstFG.js';
6
6
  export { normalizeProjectionPreview, normalizeProjectionTags } from './memory-projection-format.js';
7
7
  export { ModelCapabilities, ModelRegistry } from './model-registry.js';
8
8
  export { ACTIVE_STATUSES, ContradictionFilter, ContradictionJudgeBatchResult, ContradictionJudgeInput, ContradictionJudgeResult, ContradictionListResult, ContradictionVerdict, ResolutionResult, ResolutionVerb, ScanDependencies, ScanResult, computePairId, executeResolution, isCoolingDown, isValidResolutionVerb, judgeContradictionPairs, listPairs, readPair, resolvePair, runContradictionScan, writePair, writePairs } from './contradiction/index.js';
@@ -24,7 +24,7 @@ import { aG as CodingContext, aR as CodingModeConfig, P as PluginConfig, M as Me
24
24
  export { J as AgentAccessAuthToken, r as BriefingActiveThread, aU as BriefingConfig, p as BriefingFocus, o as BriefingFollowup, aV as BriefingOpenCommitment, t as BriefingRecentEntity, s as BriefingResult, n as BriefingSections, aW as BriefingWindow, z as BufferSurpriseEvent, q as CalendarEvent, C as CalendarSource, aX as CodexCompatConfig, aJ as ConsolidationObservation, a6 as ContinuityImprovementLoop, aY as DEFAULT_RECALL_DISCLOSURE, E as EntityFile, $ as EntityStructuredSection, aZ as ExtractedFact, G as GatewayConfig, ac as MemoryActionEligibilityContext, a_ as MemoryActionEligibilitySource, U as MemoryActionType, g as MemoryFile, k as MemoryFrontmatter, a$ as MemoryObservation, b0 as MemoryScope, b1 as RECALL_DISCLOSURE_LEVELS, i as RecallDisclosure, D as SecretRef, b2 as WearableAuthCheck, b3 as WearableFetchOptions, b4 as WearableFetchPage, az as WearableMemoryMode, ay as WearableNativeMemory, b5 as WearableNativeMemoryPage, aD as WearableSourceStatus, aC as WearableSyncSummary, b6 as WearableTranscriptSegment, b7 as isRecallDisclosure } from './types-D9dwzU_x.js';
25
25
  export { JudgeBatchResult, JudgeCandidate, JudgeVerdict, JudgeVerdictKind, clearVerdictCache, createVerdictCache, getVerdictKind, isDurableVerdict, isValidCachedVerdict, judgeFactDurability, normalizeCachedVerdict, verdictCacheSize } from './extraction-judge.js';
26
26
  export { hasBroadGraphIntent, inferIntentFromText, intentCompatibilityScore, isTaskInitiationIntent, planRecallMode } from './intent.js';
27
- export { i as EngramAccessInputError, g as EngramAccessService, P as ProcedureStatsConfigSnapshot, j as ProcedureStatsRecent, k as ProcedureStatsReport, l as ProcedureStatusCounts, m as computeProcedureStats, n as formatProcedureStatsText } from './access-service-lddjZoRh.js';
27
+ export { i as EngramAccessInputError, g as EngramAccessService, P as ProcedureStatsConfigSnapshot, j as ProcedureStatsRecent, k as ProcedureStatsReport, l as ProcedureStatusCounts, m as computeProcedureStats, n as formatProcedureStatsText } from './access-service-GgnA--CE.js';
28
28
  export { FILTER_LABELS as DIRECT_ANSWER_FILTER_LABELS, DirectAnswerCandidate, DirectAnswerConfig, DirectAnswerInput, DirectAnswerReason, DirectAnswerResult, isDirectAnswerEligible } from './direct-answer.js';
29
29
  export { MemoryTier, TierRoutingPolicy, TierTransitionDecision, computeTierValueScore, decideTierTransition } from './tier-routing.js';
30
30
  export { ApplyReasoningTraceBoostOptions, BoostableResult, DEFAULT_REASONING_TRACE_BOOST, applyReasoningTraceBoost, isReasoningTracePath, looksLikeProblemSolvingQuery } from './reasoning-trace-recall.js';
@@ -79,7 +79,7 @@ export { EnrichmentAuditEntry, EnrichmentCandidate, EnrichmentCostTier, Enrichme
79
79
  export { d as BulkImportError, B as BulkImportOptions, b as BulkImportResult, a as BulkImportSource, e as BulkImportSourceAdapter, f as ImportSourceRole, I as ImportTurn, g as ImportTurnValidationIssue, i as isImportRole, p as parseIsoTimestamp, v as validateImportTurn } from './types-gb_SNtjR.js';
80
80
  export { clearBulkImportSources, getBulkImportSource, listBulkImportSources, registerBulkImportSource } from './bulk-import/index.js';
81
81
  export { a as ProcessBatchContext, P as ProcessBatchFn, b as ProcessBatchResult, f as formatBatchTranscript, r as resolveBulkImportContext, c as runBulkImportPipeline, v as validateBatchSize } from './pipeline-DmqtvION.js';
82
- export { B as BulkImportCliCommandOptions, p as parseStrictCliDate, r as runBulkImportCliCommand } from './cli-iAiVkbYJ.js';
82
+ export { B as BulkImportCliCommandOptions, p as parseStrictCliDate, r as runBulkImportCliCommand } from './cli-Do1YtfnH.js';
83
83
  export { DEFAULT_IMPORT_BATCH_SIZE, ImportProgress, ImportedMemory, ImporterAdapter, ImporterParseOptions, ImporterTransformOptions, ImporterWriteResult, ImporterWriteTarget, RunImportOptions, RunImporterResult, defaultWriteMemoriesToOrchestrator, importedMemoryToTurn, runImporter, validateImportBatchSize, validateImportRateLimit } from './importers/index.js';
84
84
  export { FallbackLlmClient, FallbackLlmOptions, FallbackLlmResponse, FallbackLlmRuntimeContext } from './fallback-llm.js';
85
85
  export { ComputeMemoryWorthInput, MemoryWorthResult, computeMemoryWorth } from './memory-worth.js';
package/dist/index.js CHANGED
@@ -189,7 +189,7 @@ import {
189
189
  saveTaxonomy,
190
190
  validateSlug,
191
191
  validateTaxonomy
192
- } from "./chunk-FXZKXW7C.js";
192
+ } from "./chunk-YUJL27ET.js";
193
193
  import {
194
194
  WEARABLE_SOURCE_PREFIX,
195
195
  buildExtractionTurns,
@@ -1,4 +1,4 @@
1
- import { h as EngramAccessRecallResponse } from './access-service-lddjZoRh.js';
1
+ import { h as EngramAccessRecallResponse } from './access-service-GgnA--CE.js';
2
2
  import { ActionConfidenceRequest } from './access-schema.js';
3
3
  import { RecallXraySnapshot } from './recall-xray.js';
4
4
  import { ActionConfidenceResult } from './action-confidence.js';
@@ -22,7 +22,7 @@ import './memory-provenance.js';
22
22
  import './user-model.js';
23
23
  import './recall-audit-anomaly.js';
24
24
  import './recall-audit.js';
25
- import './orchestrator-iVZWi8aW.js';
25
+ import './orchestrator-BOaVstFG.js';
26
26
  import './briefing.js';
27
27
  import './buffer.js';
28
28
  import './extraction-faithfulness.js';
@@ -969,6 +969,11 @@ declare class Orchestrator {
969
969
  * callers already destructure `persistedIds` by position.
970
970
  */
971
971
  private lastPersistExtractionDeferredCount;
972
+ /**
973
+ * Side-channel (#1635): pending_review persisted ids from the last
974
+ * persistExtraction; runExtraction excludes them from the thread episode set.
975
+ */
976
+ private lastPersistExtractionPendingReviewIds;
972
977
  private readonly _fastGatewayLlm;
973
978
  get fastGatewayLlm(): FallbackLlmClient | null;
974
979
  /**
@@ -1757,6 +1762,12 @@ declare class Orchestrator {
1757
1762
  */
1758
1763
  requestQmdMaintenanceForTool(reason: string): void;
1759
1764
  private persistExtraction;
1765
+ /**
1766
+ * Append persisted ids to the thread episode set, excluding pending_review
1767
+ * fact ids (#1635) so they don't re-seed predecessor edges. Fail-open like
1768
+ * the raw appendEpisodeIds call it replaces.
1769
+ */
1770
+ private appendPersistedThreadEpisodes;
1760
1771
  private indexPersistedMemory;
1761
1772
  /**
1762
1773
  * Build a graph edge for a persisted memory (v8.2).
@@ -9,7 +9,7 @@ import './local-llm.js';
9
9
  import './fallback-llm.js';
10
10
  import './orchestration/maintenance.js';
11
11
  import './live-connectors-runner.js';
12
- export { L as BulkImportBatchIngestResult, M as BulkImportBatchPartialFailureError, N as GraphRecallRankedResult, Q as GraphRecallShadowComparison, G as GraphRecallSnapshot, I as IntentDebugSnapshot, O as Orchestrator, T as QmdRecallSnapshot, U as RecallInvocationOptions, V as RecallModeDecision, X as appendMemoryToGraphContext, Y as blendGraphExpandedRecallScore, Z as buildCompressionGuidelinesMarkdown, _ as buildMemoryPathById, $ as computeArtifactCandidateFetchLimit, a0 as computeArtifactRecallLimit, a1 as computeQmdHybridFetchLimit, a2 as dedupeEntitySynthesisEvidenceEntries, q as defaultWorkspaceDir, a3 as deriveTopicsFromExtraction, a4 as filterRecallCandidates, a5 as formatCompressionGuidelinesForRecall, a6 as graphPathRelativeToStorage, a7 as hasIdentityRecoveryIntent, a8 as isArtifactMemoryPath, a9 as lifecycleRecallScoreAdjustment, aa as mergeArtifactRecallCandidates, ab as mergeGraphExpandedResults, ac as resolveEffectiveIdentityInjectionMode, ad as resolveEffectiveRecallMode, ae as resolvePersistedMemoryRelativePath, af as resolveRecallModeDecision, ag as resolveRecallModeDecisionAsync, ah as resolveRecentThreadMemoryPaths, A as sanitizeSessionKeyForFilename, ai as shouldFilterLifecycleRecallCandidate, aj as summarizeGraphShadowComparison } from './orchestrator-iVZWi8aW.js';
12
+ export { L as BulkImportBatchIngestResult, M as BulkImportBatchPartialFailureError, N as GraphRecallRankedResult, Q as GraphRecallShadowComparison, G as GraphRecallSnapshot, I as IntentDebugSnapshot, O as Orchestrator, T as QmdRecallSnapshot, U as RecallInvocationOptions, V as RecallModeDecision, X as appendMemoryToGraphContext, Y as blendGraphExpandedRecallScore, Z as buildCompressionGuidelinesMarkdown, _ as buildMemoryPathById, $ as computeArtifactCandidateFetchLimit, a0 as computeArtifactRecallLimit, a1 as computeQmdHybridFetchLimit, a2 as dedupeEntitySynthesisEvidenceEntries, q as defaultWorkspaceDir, a3 as deriveTopicsFromExtraction, a4 as filterRecallCandidates, a5 as formatCompressionGuidelinesForRecall, a6 as graphPathRelativeToStorage, a7 as hasIdentityRecoveryIntent, a8 as isArtifactMemoryPath, a9 as lifecycleRecallScoreAdjustment, aa as mergeArtifactRecallCandidates, ab as mergeGraphExpandedResults, ac as resolveEffectiveIdentityInjectionMode, ad as resolveEffectiveRecallMode, ae as resolvePersistedMemoryRelativePath, af as resolveRecallModeDecision, ag as resolveRecallModeDecisionAsync, ah as resolveRecentThreadMemoryPaths, A as sanitizeSessionKeyForFilename, ai as shouldFilterLifecycleRecallCandidate, aj as summarizeGraphShadowComparison } from './orchestrator-BOaVstFG.js';
13
13
  import './model-registry.js';
14
14
  import './relevance.js';
15
15
  import './negative.js';
@@ -28,7 +28,7 @@ import {
28
28
  sanitizeSessionKeyForFilename,
29
29
  shouldFilterLifecycleRecallCandidate,
30
30
  summarizeGraphShadowComparison
31
- } from "./chunk-FXZKXW7C.js";
31
+ } from "./chunk-YUJL27ET.js";
32
32
  import "./chunk-DGTDRIUO.js";
33
33
  import "./chunk-O62P2LFL.js";
34
34
  import "./chunk-7HYPN2GC.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remnic/core",
3
- "version": "9.3.714",
3
+ "version": "9.3.715",
4
4
  "description": "Framework-agnostic Remnic memory engine — orchestrator, storage, extraction, search, trust zones",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -2966,7 +2966,7 @@
2966
2966
  "core"
2967
2967
  ],
2968
2968
  "peerDependencies": {
2969
- "@remnic/coding-graph": "^9.3.714"
2969
+ "@remnic/coding-graph": "^9.3.715"
2970
2970
  },
2971
2971
  "peerDependenciesMeta": {
2972
2972
  "@remnic/coding-graph": {
@@ -25,6 +25,7 @@ import { Orchestrator } from "./orchestrator.js";
25
25
  import { readEdges } from "./graph.js";
26
26
  import type { ExtractionResult, PluginConfig } from "./types.js";
27
27
  import type { LocalLlmClient } from "./local-llm.js";
28
+ import type { BufferTurn, ConversationThread } from "./types.js";
28
29
 
29
30
  /**
30
31
  * Stub local LLM whose `chatCompletion` only answers faithfulness-gate calls
@@ -42,15 +43,20 @@ function faithfulnessStubLocalLlm(
42
43
  ) => {
43
44
  if (options.operation !== "extraction-faithfulness") return null;
44
45
  const userMsg = messages.find((m) => m.role === "user");
45
- // The prompt emits `FACT: "<text>"` fact text never contains a raw
46
- // double-quote, so capture up to the closing quote.
47
- const match = userMsg?.content.match(/FACT: "([^"]*)"/);
48
- const factContent = match ? (match[1] ?? "") : "";
49
- const verdict = verdictForFactContent(factContent);
46
+ // The batch prompt emits one `FACT: "<text>"` line per fact, each
47
+ // followed by `Respond with the JSON array entry for index <i>`. The
48
+ // gate maps verdicts back to facts by that index, so return one entry
49
+ // per fact in prompt order. (Single-fact callers still get one entry.)
50
+ const factMatches = [...(userMsg?.content ?? "").matchAll(/FACT: "([^"]*)"/g)];
51
+ const entries = factMatches.map((m, i) => ({
52
+ index: i,
53
+ verdict: verdictForFactContent(m[1] ?? ""),
54
+ rationale: "stub verdict",
55
+ }));
50
56
  return {
51
- content: JSON.stringify([
52
- { index: 0, verdict, rationale: "stub verdict" },
53
- ]),
57
+ content: JSON.stringify(
58
+ entries.length > 0 ? entries : [{ index: 0, verdict: "entailed" as const, rationale: "stub" }],
59
+ ),
54
60
  };
55
61
  },
56
62
  } as unknown as LocalLlmClient;
@@ -250,3 +256,203 @@ test("pending_review fact gets no graph edge; an active fact with the same entit
250
256
  await rm(memoryDir, { recursive: true, force: true });
251
257
  }
252
258
  });
259
+
260
+
261
+ /**
262
+ * Thread-enabled harness for issue #1635: time + causal graph ON (so
263
+ * thread-predecessor edges are built), faithfulness gate in enforce mode.
264
+ * Entity graph is left OFF to isolate the thread-episode predecessor
265
+ * mechanism (entity-sibling edges are a separate, out-of-scope path).
266
+ */
267
+ async function makeThreadHarness(): Promise<OrchHarness> {
268
+ const memoryDir = await mkdtemp(
269
+ path.join(os.tmpdir(), "remnic-faithfulness-thread-"),
270
+ );
271
+ const config: PluginConfig = parseConfig({
272
+ openaiApiKey: "sk-test",
273
+ memoryDir,
274
+ workspaceDir: path.join(memoryDir, "workspace"),
275
+ multiGraphMemoryEnabled: true,
276
+ entityGraphEnabled: false,
277
+ timeGraphEnabled: true,
278
+ causalGraphEnabled: true,
279
+ extractionFaithfulnessGate: "enforce",
280
+ extractionFaithfulnessContextChars: 400,
281
+ extractionFaithfulnessTimeoutMs: 2000,
282
+ extractionJudgeEnabled: false,
283
+ temporalSupersessionEnabled: false,
284
+ contradictionDetectionEnabled: false,
285
+ chunkingEnabled: false,
286
+ embeddingFallbackEnabled: false,
287
+ qmdEnabled: false,
288
+ extractionMinChars: 0,
289
+ extractionMinImportanceLevel: "trivial",
290
+ inlineSourceAttributionEnabled: false,
291
+ });
292
+ const orchestrator = new Orchestrator(config);
293
+ return { orchestrator, memoryDir };
294
+ }
295
+
296
+ /** ExtractionResult with two facts (order preserved by the persist loop). */
297
+ function twoFactResult(
298
+ contentA: string,
299
+ entityRefA: string,
300
+ contentB: string,
301
+ entityRefB: string,
302
+ ): ExtractionResult {
303
+ return {
304
+ facts: [
305
+ { content: contentA, category: "fact", tags: [], confidence: 0.9, entityRef: entityRefA },
306
+ { content: contentB, category: "fact", tags: [], confidence: 0.9, entityRef: entityRefB },
307
+ ],
308
+ entities: [],
309
+ relationships: [],
310
+ questions: [],
311
+ profileUpdates: [],
312
+ } as unknown as ExtractionResult;
313
+ }
314
+
315
+ interface StorageLike {
316
+ ensureDirectories: () => Promise<void>;
317
+ dir: string;
318
+ readAllMemories: () => Promise<
319
+ Array<{ path: string; frontmatter: { id: string; status?: string } }>
320
+ >;
321
+ }
322
+
323
+ interface PersistExtractionSig {
324
+ (
325
+ r: ExtractionResult,
326
+ s: unknown,
327
+ t: string | null,
328
+ ctx: unknown,
329
+ bn: unknown,
330
+ plan: unknown,
331
+ src: string,
332
+ ): Promise<string[]>;
333
+ }
334
+
335
+ test("pending_review id must NOT enter persisted thread episodes across a cross-flush (#1635)", async () => {
336
+ const { orchestrator, memoryDir } = await makeThreadHarness();
337
+ try {
338
+ // fact content containing "closed permanently" → unsupported → pending_review.
339
+ (orchestrator as unknown as { localLlm: LocalLlmClient }).localLlm =
340
+ faithfulnessStubLocalLlm((c) =>
341
+ c.includes("closed permanently") ? "unsupported" : "entailed",
342
+ );
343
+
344
+ const getStorage = orchestrator as unknown as {
345
+ getStorage: (ns: string) => Promise<StorageLike>;
346
+ };
347
+ const storage = await getStorage.getStorage("default");
348
+ await storage.ensureDirectories();
349
+
350
+ // Establish a real thread (mirrors runExtraction's processTurn step) so
351
+ // appendEpisodeIds has a thread file to write episode ids into.
352
+ const threading = orchestrator as unknown as {
353
+ threading: {
354
+ processTurn: (turn: BufferTurn, ids: string[]) => Promise<string>;
355
+ loadThread: (id: string) => Promise<ConversationThread | null>;
356
+ };
357
+ };
358
+ const seedTurn: BufferTurn = {
359
+ role: "user",
360
+ content: "Tell me about the widget factory.",
361
+ timestamp: "2026-07-06T10:00:00.000Z",
362
+ sessionKey: "agent:test:main",
363
+ };
364
+ const threadId = await threading.threading.processTurn(seedTurn, []);
365
+ assert.ok(threadId, "thread established via processTurn");
366
+
367
+ const persist = orchestrator as unknown as {
368
+ persistExtraction: PersistExtractionSig;
369
+ appendPersistedThreadEpisodes: (
370
+ threadId: string,
371
+ persistedIds: string[],
372
+ ) => Promise<void>;
373
+ };
374
+
375
+ const sourceText =
376
+ "The widget factory reopened this quarter after being closed permanently last year.";
377
+
378
+ // --- Flush 1: an active fact + a pending_review fact, same thread ---
379
+ const flush1 = await persist.persistExtraction(
380
+ twoFactResult(
381
+ "The widget factory reopened this quarter.", "wf-active",
382
+ "The widget factory closed permanently last year.", "wf-pending",
383
+ ),
384
+ storage,
385
+ threadId,
386
+ { sessionKey: "agent:test:main", principal: "test" },
387
+ undefined,
388
+ null,
389
+ sourceText,
390
+ );
391
+ const [activeId1, pendingId] = flush1;
392
+ assert.ok(activeId1, "flush1 active fact persisted");
393
+ assert.ok(pendingId, "flush1 pending_review fact persisted");
394
+
395
+ // runExtraction's append step (the real helper; filters pending_review).
396
+ await persist.appendPersistedThreadEpisodes(threadId, flush1);
397
+
398
+ // PART (a): the thread FILE must hold the active id but NOT the pending id.
399
+ const threadAfter1 = await threading.threading.loadThread(threadId);
400
+ assert.ok(threadAfter1, "thread file readable after flush 1");
401
+ assert.ok(
402
+ threadAfter1!.episodeIds.includes(activeId1),
403
+ "active fact id is in persisted thread episodes",
404
+ );
405
+ assert.ok(
406
+ !threadAfter1!.episodeIds.includes(pendingId),
407
+ "pending_review id must NOT enter persisted thread episodes (#1635)",
408
+ );
409
+
410
+ // The pending fact IS durable (with status pending_review) — proves the
411
+ // gate routed it correctly; the guard is about its absence from the thread.
412
+ const memsAfter1 = await storage.readAllMemories();
413
+ const pendingMem = memsAfter1.find((m) => m.frontmatter.id === pendingId);
414
+ assert.ok(pendingMem, "pending_review fact is durable");
415
+ assert.equal(
416
+ pendingMem!.frontmatter.status,
417
+ "pending_review",
418
+ "unsupported fact is pending_review under enforce",
419
+ );
420
+
421
+ // --- Flush 2: an active fact in the SAME thread ---
422
+ const flush2 = await persist.persistExtraction(
423
+ factResult("The widget factory hired ten new engineers.", "wf-active"),
424
+ storage,
425
+ threadId,
426
+ { sessionKey: "agent:test:main", principal: "test" },
427
+ undefined,
428
+ null,
429
+ sourceText,
430
+ );
431
+ const activeId2 = flush2[0];
432
+ assert.ok(activeId2, "flush2 active fact persisted");
433
+ await persist.appendPersistedThreadEpisodes(threadId, flush2);
434
+
435
+ // PART (a)+(b): no predecessor edge may reference the pending fact. Under
436
+ // the bug, flush 1 would have appended pendingId to the thread file, flush
437
+ // 2's loadThread would re-seed it into threadEpisodeIdsForGraph, and the
438
+ // active fact2 would build a time/causal predecessor edge to it.
439
+ const pendingPath = path.relative(memoryDir, pendingMem!.path);
440
+ for (const gtype of ["time", "causal"] as const) {
441
+ const edges = await readEdges(memoryDir, gtype);
442
+ assert.ok(
443
+ !edges.some((e) => e.from === pendingPath || e.to === pendingPath),
444
+ `no ${gtype} edge references the pending_review fact path (${pendingPath}); got ${edges.length} edges`,
445
+ );
446
+ }
447
+
448
+ // Control: the graph + threading are wired — the active fact2 builds a
449
+ // time predecessor edge to the active fact1 (which IS in the thread file).
450
+ const timeEdges = await readEdges(memoryDir, "time");
451
+ assert.ok(
452
+ timeEdges.length > 0,
453
+ "active fact2 builds a time predecessor edge (control: graph+threading wired)",
454
+ );
455
+ } finally {
456
+ await rm(memoryDir, { recursive: true, force: true });
457
+ }
458
+ });
@@ -1731,8 +1731,16 @@ export function resolveRecentThreadMemoryPaths(options: {
1731
1731
  buildMemoryPathById(options.allMemsForGraph, options.storageDir);
1732
1732
  if (pathById.size === 0) return [];
1733
1733
 
1734
+ // #1635 (defensive): skip pending_review ids from legacy episode sets.
1735
+ const pendingReviewIds = new Set<string>(
1736
+ (options.allMemsForGraph ?? [])
1737
+ .filter((m) => m.frontmatter.status === "pending_review" && m.frontmatter.id)
1738
+ .map((m) => m.frontmatter.id as string),
1739
+ );
1740
+
1734
1741
  return options.threadEpisodeIds
1735
1742
  .filter((id) => id !== options.currentMemoryId)
1743
+ .filter((id) => !pendingReviewIds.has(id))
1736
1744
  .slice(-maxRecent)
1737
1745
  .map((id) => pathById.get(id))
1738
1746
  .filter((p): p is string => typeof p === "string" && p.length > 0);
@@ -1858,6 +1866,11 @@ export class Orchestrator {
1858
1866
  * callers already destructure `persistedIds` by position.
1859
1867
  */
1860
1868
  private lastPersistExtractionDeferredCount: number = 0;
1869
+ /**
1870
+ * Side-channel (#1635): pending_review persisted ids from the last
1871
+ * persistExtraction; runExtraction excludes them from the thread episode set.
1872
+ */
1873
+ private lastPersistExtractionPendingReviewIds: string[] = [];
1861
1874
  private readonly _fastGatewayLlm: FallbackLlmClient | null;
1862
1875
 
1863
1876
  get fastGatewayLlm(): FallbackLlmClient | null {
@@ -13461,23 +13474,16 @@ export class Orchestrator {
13461
13474
  }
13462
13475
 
13463
13476
  // Batch-append persisted IDs so non-fact memories (entities/questions) are
13464
- // always attached to the thread.
13477
+ // always attached to the thread. The helper excludes pending_review ids (#1635).
13465
13478
  if (
13466
13479
  this.config.threadingEnabled &&
13467
13480
  threadIdForExtraction &&
13468
13481
  persistedIds.length > 0
13469
13482
  ) {
13470
- try {
13471
- await this.threading.appendEpisodeIds(
13472
- threadIdForExtraction,
13473
- persistedIds,
13474
- );
13475
- } catch (err) {
13476
- log.warn(
13477
- "[threading] appendEpisodeIds failed after persistence (non-fatal)",
13478
- err,
13479
- );
13480
- }
13483
+ await this.appendPersistedThreadEpisodes(
13484
+ threadIdForExtraction,
13485
+ persistedIds,
13486
+ );
13481
13487
  }
13482
13488
 
13483
13489
  // Thread title update for the already-established thread context.
@@ -13831,9 +13837,11 @@ export class Orchestrator {
13831
13837
  // to avoid a maintenance hazard where the two guard paths could diverge.
13832
13838
  return attachCitation(content, citationContext, citationTemplate);
13833
13839
  };
13840
+ const persistedIds: string[] = [];
13834
13841
  const supersessionOrderingAt = (validAt?: string): string =>
13835
13842
  validAt && validAt.length > 0 ? validAt : new Date().toISOString();
13836
- const persistedIds: string[] = [];
13843
+ // #1635: pending_review persisted ids, excluded from the thread episode set below.
13844
+ const pendingReviewPersistedIds: string[] = [];
13837
13845
  const persistedIdsByStorage = new Map<
13838
13846
  string,
13839
13847
  { storage: StorageManager; ids: string[] }
@@ -13841,11 +13849,18 @@ export class Orchestrator {
13841
13849
  const trackPersistedId = (
13842
13850
  targetStorage: StorageManager,
13843
13851
  id: string,
13844
- options: { includeReturnedIds?: boolean } = {},
13852
+ options: {
13853
+ includeReturnedIds?: boolean;
13854
+ /** #1635: keep this id out of the persisted thread episode set. */
13855
+ pendingReview?: boolean;
13856
+ } = {},
13845
13857
  ): void => {
13846
13858
  if (options.includeReturnedIds !== false) {
13847
13859
  persistedIds.push(id);
13848
13860
  }
13861
+ if (options.pendingReview) {
13862
+ pendingReviewPersistedIds.push(id);
13863
+ }
13849
13864
  const key = targetStorage.dir;
13850
13865
  const existing = persistedIdsByStorage.get(key);
13851
13866
  if (existing) {
@@ -15347,7 +15362,9 @@ export class Orchestrator {
15347
15362
  log.debug(
15348
15363
  `chunked memory ${parentId} into ${chunkResult.chunks.length} chunks`,
15349
15364
  );
15350
- trackPersistedId(targetStorage, parentId);
15365
+ trackPersistedId(targetStorage, parentId, {
15366
+ pendingReview: faithfulnessEnforceStatus === "pending_review",
15367
+ });
15351
15368
  // #1576 (cursor Medium): keep pending_review ids out of threadEpisodeIdsForGraph — else later active facts build thread-predecessor edges to an unfaithful memory.
15352
15369
  if (
15353
15370
  faithfulnessEnforceStatus !== "pending_review" &&
@@ -15633,8 +15650,9 @@ export class Orchestrator {
15633
15650
  source: "extraction",
15634
15651
  }),
15635
15652
  );
15636
- trackPersistedId(targetStorage, memoryId);
15637
- // #1576 (cursor Medium): same thread-episode guard on the non-chunked path.
15653
+ trackPersistedId(targetStorage, memoryId, {
15654
+ pendingReview: faithfulnessEnforceStatus === "pending_review",
15655
+ });
15638
15656
  if (
15639
15657
  faithfulnessEnforceStatus !== "pending_review" &&
15640
15658
  threadEpisodeIdsForGraph &&
@@ -15944,9 +15962,35 @@ export class Orchestrator {
15944
15962
  log.debug(`temporal-index update error (non-fatal): ${err}`),
15945
15963
  );
15946
15964
 
15965
+ // #1635: surface pending_review ids so the thread episode set excludes them.
15966
+ this.lastPersistExtractionPendingReviewIds = pendingReviewPersistedIds;
15947
15967
  // Return the persisted fact IDs for threading
15948
15968
  return persistedIds;
15949
15969
  }
15970
+ /**
15971
+ * Append persisted ids to the thread episode set, excluding pending_review
15972
+ * fact ids (#1635) so they don't re-seed predecessor edges. Fail-open like
15973
+ * the raw appendEpisodeIds call it replaces.
15974
+ */
15975
+ private async appendPersistedThreadEpisodes(
15976
+ threadId: string,
15977
+ persistedIds: string[],
15978
+ ): Promise<void> {
15979
+ const pendingReviewIds = this.lastPersistExtractionPendingReviewIds ?? [];
15980
+ const episodeIds =
15981
+ pendingReviewIds.length > 0
15982
+ ? persistedIds.filter((id) => !pendingReviewIds.includes(id))
15983
+ : persistedIds;
15984
+ if (episodeIds.length === 0) return;
15985
+ try {
15986
+ await this.threading.appendEpisodeIds(threadId, episodeIds);
15987
+ } catch (err) {
15988
+ log.warn(
15989
+ "[threading] appendEpisodeIds failed after persistence (non-fatal)",
15990
+ err,
15991
+ );
15992
+ }
15993
+ }
15950
15994
 
15951
15995
  private async indexPersistedMemory(
15952
15996
  storage: StorageManager,