@remnic/core 9.3.657 → 9.3.658
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/dist/access-cli.js +12 -12
- package/dist/access-http.js +6 -6
- package/dist/access-mcp.js +5 -5
- package/dist/access-service.js +4 -4
- package/dist/briefing.d.ts +1 -1
- package/dist/briefing.js +2 -2
- package/dist/causal-consolidation.js +3 -3
- package/dist/{chunk-YEZHZCUO.js → chunk-2VCTTEJM.js} +3 -3
- package/dist/{chunk-DR67OK4E.js → chunk-3R6OP33G.js} +3 -3
- package/dist/{chunk-JSVFEHLL.js → chunk-46RXRASB.js} +2 -2
- package/dist/{chunk-NXCK7DO7.js → chunk-4PLOQDBB.js} +54 -18
- package/dist/chunk-4PLOQDBB.js.map +1 -0
- package/dist/{chunk-54XF2FY7.js → chunk-5PFIMBJJ.js} +12 -12
- package/dist/{chunk-4UL7VPTD.js → chunk-6M4LYWA2.js} +4 -4
- package/dist/{chunk-DIBWFCLA.js → chunk-7KSPKZIQ.js} +3 -3
- package/dist/{chunk-RDW5G6DO.js → chunk-7VWDC7AD.js} +10 -11
- package/dist/chunk-7VWDC7AD.js.map +1 -0
- package/dist/{chunk-SWDHVH2P.js → chunk-BKRIAXTU.js} +2 -2
- package/dist/{chunk-WWMHAMAY.js → chunk-BNUAOLDK.js} +2 -2
- package/dist/{chunk-GCYFUTUC.js → chunk-FIS5RT6K.js} +2 -2
- package/dist/{chunk-IOZ5WBWD.js → chunk-G2VVBWFU.js} +7 -5
- package/dist/chunk-G2VVBWFU.js.map +1 -0
- package/dist/{chunk-GSHW5VVD.js → chunk-GGL7R2L2.js} +4 -4
- package/dist/{chunk-WIKMCJUR.js → chunk-JI3LQFJH.js} +2 -2
- package/dist/{chunk-Z6UDTNY6.js → chunk-KI6QM5AV.js} +6 -6
- package/dist/chunk-KI6QM5AV.js.map +1 -0
- package/dist/{chunk-2BD7DG37.js → chunk-MBZAESQ3.js} +2 -2
- package/dist/{chunk-VAEAGTEQ.js → chunk-QFKRE7AU.js} +3 -3
- package/dist/{chunk-AGJKWOKV.js → chunk-RVT6U6PV.js} +2 -2
- package/dist/{chunk-TFFZUFEP.js → chunk-VJYFXDCZ.js} +2 -2
- package/dist/{chunk-QZRKNA5F.js → chunk-ZCMO46YY.js} +2 -2
- package/dist/cli.js +15 -15
- package/dist/compounding/engine.js +2 -2
- package/dist/connectors/codex-materialize-runner.js +2 -2
- package/dist/connectors/index.js +2 -2
- package/dist/entity-retrieval.js +2 -2
- package/dist/index.js +20 -20
- package/dist/maintenance/memory-governance.js +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +2 -2
- package/dist/maintenance/rebuild-memory-projection.js +3 -3
- package/dist/namespaces/migrate.js +3 -3
- package/dist/namespaces/storage.js +2 -2
- package/dist/operator-toolkit.js +5 -5
- package/dist/orchestrator.js +10 -10
- package/dist/semantic-consolidation.js +3 -3
- package/dist/semantic-rule-promotion.js +2 -2
- package/dist/semantic-rule-verifier.js +2 -2
- package/dist/storage.d.ts +27 -5
- package/dist/storage.js +1 -1
- package/dist/verified-recall.js +2 -2
- package/package.json +1 -1
- package/src/briefing.ts +8 -4
- package/src/entity-retrieval.ts +8 -3
- package/src/orchestrator.ts +1 -2
- package/src/storage.ts +79 -26
- package/dist/chunk-IOZ5WBWD.js.map +0 -1
- package/dist/chunk-NXCK7DO7.js.map +0 -1
- package/dist/chunk-RDW5G6DO.js.map +0 -1
- package/dist/chunk-Z6UDTNY6.js.map +0 -1
- /package/dist/{chunk-YEZHZCUO.js.map → chunk-2VCTTEJM.js.map} +0 -0
- /package/dist/{chunk-DR67OK4E.js.map → chunk-3R6OP33G.js.map} +0 -0
- /package/dist/{chunk-JSVFEHLL.js.map → chunk-46RXRASB.js.map} +0 -0
- /package/dist/{chunk-54XF2FY7.js.map → chunk-5PFIMBJJ.js.map} +0 -0
- /package/dist/{chunk-4UL7VPTD.js.map → chunk-6M4LYWA2.js.map} +0 -0
- /package/dist/{chunk-DIBWFCLA.js.map → chunk-7KSPKZIQ.js.map} +0 -0
- /package/dist/{chunk-SWDHVH2P.js.map → chunk-BKRIAXTU.js.map} +0 -0
- /package/dist/{chunk-WWMHAMAY.js.map → chunk-BNUAOLDK.js.map} +0 -0
- /package/dist/{chunk-GCYFUTUC.js.map → chunk-FIS5RT6K.js.map} +0 -0
- /package/dist/{chunk-GSHW5VVD.js.map → chunk-GGL7R2L2.js.map} +0 -0
- /package/dist/{chunk-WIKMCJUR.js.map → chunk-JI3LQFJH.js.map} +0 -0
- /package/dist/{chunk-2BD7DG37.js.map → chunk-MBZAESQ3.js.map} +0 -0
- /package/dist/{chunk-VAEAGTEQ.js.map → chunk-QFKRE7AU.js.map} +0 -0
- /package/dist/{chunk-AGJKWOKV.js.map → chunk-RVT6U6PV.js.map} +0 -0
- /package/dist/{chunk-TFFZUFEP.js.map → chunk-VJYFXDCZ.js.map} +0 -0
- /package/dist/{chunk-QZRKNA5F.js.map → chunk-ZCMO46YY.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/orchestrator.ts","../src/procedural/procedure-recall.ts","../src/maintenance/pattern-reinforcement.ts","../src/dedup/semantic.ts","../src/taxonomy/default-taxonomy.ts","../src/taxonomy/resolver-doc-generator.ts","../src/taxonomy/taxonomy-loader.ts","../src/wearables/registry.ts","../src/wearables/service.ts","../src/namespaces/catalog.ts","../src/maintenance/namespace-planner.ts"],"sourcesContent":["import { log } from \"./logger.js\";\nimport {\n buildChainFollowupGenerator,\n type BriefingFollowupGenerator,\n} from \"./briefing.js\";\nimport path from \"node:path\";\nimport os from \"node:os\";\nimport { createHash, randomBytes } from \"node:crypto\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport {\n mkdir,\n readdir,\n readFile,\n stat,\n unlink,\n writeFile,\n} from \"node:fs/promises\";\nimport { formatDaySummaryMemories } from \"./day-summary.js\";\nimport { resolveHomeDir } from \"./runtime/env.js\";\nimport { migrateFromEngram } from \"./migrate/from-engram.js\";\nimport { SmartBuffer } from \"./buffer.js\";\nimport { chunkContent, type ChunkingConfig } from \"./chunking.js\";\nimport { semanticChunkContent, type SemanticChunkResult } from \"./semantic-chunking.js\";\nimport { ExtractionEngine } from \"./extraction.js\";\nimport { isAboveImportanceThreshold, scoreImportance } from \"./importance.js\";\nimport {\n judgeFactDurability,\n createVerdictCache,\n createDeferCountMap,\n getVerdictKind,\n validateProcedureExtraction,\n type JudgeBatchResult,\n type JudgeCandidate,\n type JudgeVerdict,\n} from \"./extraction-judge.js\";\nimport {\n EXTRACTION_JUDGE_VERDICT_CATEGORY,\n recordJudgeVerdict,\n} from \"./extraction-judge-telemetry.js\";\nimport { recordJudgeTrainingPair } from \"./extraction-judge-training.js\";\nimport { buildProcedurePersistBody } from \"./procedural/procedure-types.js\";\nimport { buildProcedureRecallSection } from \"./procedural/procedure-recall.js\";\nimport {\n attachCitation,\n type CitationContext,\n hasCitationForTemplate,\n stripCitationForTemplate,\n} from \"./source-attribution.js\";\n// stripCitation (default-format only) is intentionally NOT used on the\n// legacy archive path — replaced by skip-with-warning (Finding 2 — Urgw).\n// stripCitationForTemplate IS used for pre-tagged dedup canonicalization.\nimport { findUnresolvedEntityRefs } from \"./reconstruct.js\";\nimport type {\n SearchBackend,\n SearchExecutionOptions,\n SearchQueryOptions,\n} from \"./search/port.js\";\nimport {\n createSearchBackend,\n createConversationIndexRuntime,\n} from \"./search/factory.js\";\nimport { NoopSearchBackend } from \"./search/noop-backend.js\";\nimport {\n compareEntityTimestamps,\n StorageManager,\n ContentHashIndex,\n fingerprintEntityStructuredFacts,\n normalizeAttributePairs,\n parseEntityFile,\n} from \"./storage.js\";\nimport { sanitizeMemoryContent } from \"./sanitize.js\";\nimport { ThreadingManager } from \"./threading.js\";\nimport { extractTopics } from \"./topics.js\";\nimport { TranscriptManager } from \"./transcript.js\";\nimport { HourlySummarizer } from \"./summarizer.js\";\nimport { LocalLlmClient } from \"./local-llm.js\";\nimport {\n FallbackLlmClient,\n fallbackLlmRuntimeContextFromConfig,\n gatewayTaskChainOptions,\n} from \"./fallback-llm.js\";\nimport {\n ensureDaySummaryCron,\n ensureNightlyGovernanceCron,\n ensureProceduralMiningCron,\n ensureContradictionScanCron,\n ensurePatternReinforcementCron,\n ensureGraphEdgeDecayCron,\n graphEdgeDecayCadenceToCronExpr,\n} from \"./maintenance/memory-governance-cron.js\";\nimport {\n runLiveConnectorsOnce,\n type LiveConnectorsRunSummary,\n} from \"./live-connectors-runner.js\";\nimport {\n runPatternReinforcement,\n type PatternReinforcementResult,\n} from \"./maintenance/pattern-reinforcement.js\";\nimport { ModelRegistry } from \"./model-registry.js\";\nimport { applyRuntimeRetrievalPolicy, expandQuery } from \"./retrieval.js\";\nimport {\n mergeWithAgentResults,\n runDirectAgent,\n runTemporalAgent,\n shouldRunAgent,\n type ParallelSearchResult,\n} from \"./retrieval-agents.js\";\nimport { RerankCache, rerankLocalOrNoop } from \"./rerank.js\";\nimport {\n applyMemoryWorthFilter,\n buildMemoryWorthCounterMap,\n type MemoryWorthCounters,\n} from \"./memory-worth-filter.js\";\nimport { reorderRecallResultsWithMmr } from \"./recall-mmr.js\";\nimport { applyReasoningTraceBoost } from \"./reasoning-trace-recall.js\";\nimport { buildRetrievedMemoryProvenance } from \"./memory-provenance.js\";\nimport {\n applyTemporalSupersession,\n normalizeSupersessionKey,\n shouldFilterSupersededFromRecall,\n} from \"./temporal-supersession.js\";\nimport { isValidAsOf } from \"./temporal-validity.js\";\nimport { RelevanceStore } from \"./relevance.js\";\nimport { NegativeExampleStore } from \"./negative.js\";\nimport {\n LastRecallStore,\n type LastRecallBudgetSummary,\n TierMigrationStatusStore,\n clampGraphRecallExpandedEntries,\n type GraphRecallExpandedEntry,\n type LastRecallSnapshot,\n type TierMigrationCycleSummary,\n type TierMigrationStatusSnapshot,\n} from \"./recall-state.js\";\nimport {\n buildXraySnapshot,\n type RecallFilterTrace,\n type RecallXrayResult,\n type RecallXrayScoreDecomposition,\n type RecallXraySnapshot,\n type RecallXrayServedBy,\n} from \"./recall-xray.js\";\nimport {\n recordEvalShadowRecall,\n type EvalShadowRecallRecord,\n} from \"./evals.js\";\nimport { SessionObserverState } from \"./session-observer-state.js\";\nimport {\n abortError as sharedAbortError,\n isAbortError,\n throwIfAborted as sharedThrowIfAborted,\n} from \"./abort-error.js\";\nimport { CODEX_THREAD_KEY_PREFIX } from \"./codex-thread-key.js\";\nimport { isDisagreementPrompt } from \"./signal.js\";\nimport { lintWorkspaceFiles, rotateMarkdownFileToArchive } from \"./hygiene.js\";\nimport { isPathInsideStorageRoot } from \"./storage-paths.js\";\nimport { EmbeddingFallback } from \"./embedding-fallback.js\";\nimport {\n decideSemanticDedup,\n type SemanticDedupDecision,\n type SemanticDedupHit,\n} from \"./dedup/semantic.js\";\nimport { BootstrapEngine } from \"./bootstrap.js\";\nimport { parseQmdExplain } from \"./qmd.js\";\nimport {\n buildQmdRecallCacheKey,\n getCachedQmdRecall,\n setCachedQmdRecall,\n} from \"./qmd-recall-cache.js\";\nimport {\n buildEntityRecallSection,\n entityRecentTranscriptLookbackHours,\n readRecentEntityTranscriptEntries,\n} from \"./entity-retrieval.js\";\nimport { buildExplicitCueRecallSection } from \"./explicit-cue-recall.js\";\nimport {\n buildTargetedFactRecallSection,\n shouldRecallTargetedFactEvidence,\n} from \"./targeted-fact-recall.js\";\nimport {\n buildFocusedListRecallSection,\n shouldRecallFocusedListEvidence,\n} from \"./focused-list-recall.js\";\nimport {\n buildResponseGuidanceRecallSection,\n shouldRecallResponseGuidance,\n} from \"./response-guidance-recall.js\";\nimport {\n buildEventOrderRecallSection,\n shouldRecallEventOrderEvidence,\n} from \"./event-order-recall.js\";\nimport {\n hasBroadGraphIntent,\n inferIntentFromText,\n intentCompatibilityScore,\n planRecallMode,\n} from \"./intent.js\";\nimport { buildRecallQueryPolicy } from \"./recall-query-policy.js\";\nimport { parseMemoryActionEligibilityContext } from \"./schemas.js\";\nimport { evaluateMemoryActionPolicy } from \"./memory-action-policy.js\";\nimport {\n buildCompressionGuidelinesMarkdown as buildCompressionGuidelinesMarkdownV2,\n computeCompressionGuidelineCandidate,\n refineCompressionGuidelineCandidateSemantically,\n renderCompressionGuidelinesMarkdown,\n} from \"./compression-optimizer.js\";\nimport { createRecallSectionMetricRecorder } from \"./recall-qos.js\";\nimport { BoxBuilder, type BoxFrontmatter } from \"./boxes.js\";\nimport { classifyMemoryKind } from \"./himem.js\";\nimport { TmtBuilder } from \"./tmt.js\";\nimport {\n decideLifecycleTransition,\n resolveLifecycleState,\n type LifecycleSignals,\n} from \"./lifecycle.js\";\nimport { isActiveMemoryStatus } from \"./memory-lifecycle-ledger-utils.js\";\nimport {\n indexMemoriesBatch,\n clearIndexes,\n indexesExist,\n deindexMemory,\n queryByDateRangeAsync,\n queryByTagsAsync,\n isTemporalQuery,\n recencyWindowFromPrompt,\n extractTagsFromPrompt,\n resolvePromptTagPrefilterAsync,\n} from \"./temporal-index.js\";\nimport { GraphIndex } from \"./graph.js\";\nimport {\n searchCausalTrajectories,\n type CausalTrajectorySearchResult,\n} from \"./causal-trajectory.js\";\nimport {\n objectiveStateStoreOverrideForNamespace,\n searchObjectiveStateSnapshots,\n type ObjectiveStateSearchResult,\n} from \"./objective-state.js\";\nimport {\n listTrustZoneRecords,\n searchTrustZoneRecords,\n type TrustZoneSearchResult,\n} from \"./trust-zones.js\";\nimport { tryDirectAnswer, type DirectAnswerSources } from \"./direct-answer-wiring.js\";\nimport { DEFAULT_TAXONOMY } from \"./taxonomy/index.js\";\nimport {\n searchHarmonicRetrieval,\n type HarmonicRetrievalResult,\n} from \"./harmonic-retrieval.js\";\nimport {\n compareVerifiedEpisodeResults,\n searchVerifiedEpisodes,\n type VerifiedEpisodeResult,\n} from \"./verified-recall.js\";\nimport {\n compareVerifiedSemanticRuleResults,\n searchVerifiedSemanticRules,\n type VerifiedSemanticRuleResult,\n} from \"./semantic-rule-verifier.js\";\nimport { applyCommitmentLedgerLifecycle } from \"./commitment-ledger.js\";\nimport {\n searchWorkProductLedgerEntries,\n type WorkProductLedgerSearchResult,\n} from \"./work-product-ledger.js\";\nimport {\n collectNativeKnowledgeChunks,\n formatNativeKnowledgeSection,\n searchNativeKnowledge,\n} from \"./native-knowledge.js\";\nimport { normalizeReplaySessionKey, type ReplayTurn } from \"./replay/types.js\";\nimport type { ImportTurn } from \"./bulk-import/types.js\";\nimport { WearablesService } from \"./wearables/service.js\";\nimport {\n type AgentPersonaModelConfig,\n confidenceTier,\n type MemoryIntent,\n type MemorySummary,\n} from \"./types.js\";\nimport { LcmEngine } from \"./lcm/index.js\";\nimport { shouldSkipImplicitExtraction } from \"./explicit-capture.js\";\nimport {\n findSimilarClusters,\n buildConsolidationPrompt,\n parseConsolidationResponse,\n buildOperatorAwareConsolidationPrompt,\n parseOperatorAwareConsolidationResponse,\n chooseConsolidationOperator,\n buildExtensionsBlockForConsolidation,\n materializeAfterSemanticConsolidation,\n type SemanticConsolidationLlmOperator,\n type SemanticConsolidationResult,\n} from \"./semantic-consolidation.js\";\nimport { chunkTranscriptEntries } from \"./conversation-index/chunker.js\";\nimport { writeConversationChunks } from \"./conversation-index/indexer.js\";\nimport { cleanupConversationChunks } from \"./conversation-index/cleanup.js\";\nimport {\n type ConversationIndexBackend,\n type ConversationIndexBackendInspection,\n type ConversationQmdRuntime,\n} from \"./conversation-index/backend.js\";\nimport {\n NamespaceStorageRouter,\n} from \"./namespaces/storage.js\";\nimport {\n NamespaceCatalog,\n} from \"./namespaces/catalog.js\";\nimport {\n planNamespaceMaintenance,\n runNamespaceMaintenanceBatchPlan,\n type NamespaceMaintenancePlan,\n type NamespaceMaintenanceSkipReason,\n} from \"./maintenance/namespace-planner.js\";\nimport {\n namespaceIdentityFromToken,\n namespaceIdentityToken,\n normalizeNamespaceIdentity,\n} from \"./namespaces/identity.js\";\nimport {\n canReadNamespace,\n defaultNamespaceForPrincipal,\n recallNamespacesForPrincipal,\n resolvePrincipal,\n} from \"./namespaces/principal.js\";\nimport {\n expandScopeProfileReadNamespaces,\n resolveScopeProfilePlan,\n type ResolvedScopeProfilePlan,\n} from \"./namespaces/scope-profiles.js\";\nimport {\n combineNamespaces,\n lcmReadSessionIdsForNamespaces,\n resolveCodingNamespaceOverlay,\n} from \"./coding/coding-namespace.js\";\nimport type { CodingContext } from \"./types.js\";\nimport {\n NamespaceSearchRouter,\n type NamespaceSearchHealth,\n} from \"./namespaces/search.js\";\nimport { SharedContextManager } from \"./shared-context/manager.js\";\nimport {\n CompoundingEngine,\n defaultTierMigrationCycleBudget,\n} from \"./compounding/engine.js\";\nimport { parseFlexibleIsoTimestamp } from \"./utils/iso-timestamp.js\";\n// IRC preference consolidation — used by eval adapter directly;\n// orchestrator integration planned for future PR.\n// import { consolidatePreferences, buildQueryAwarePreferenceSection, synthesizePreferencesFromLcm } from \"./compounding/preference-consolidator.js\";\nimport { TierMigrationExecutor } from \"./tier-migration.js\";\nimport { decideTierTransition, type MemoryTier } from \"./tier-routing.js\";\nimport {\n isSafeRouteNamespace,\n selectRouteRule,\n type RouteRule,\n type RoutingEngineOptions,\n} from \"./routing/engine.js\";\nimport { RoutingRulesStore } from \"./routing/store.js\";\nimport {\n PolicyRuntimeManager,\n type RuntimePolicyValues,\n} from \"./policy-runtime.js\";\nimport {\n applyUtilityPromotionRuntimePolicy,\n applyUtilityRankingRuntimeDelta,\n loadUtilityRuntimeValues,\n type UtilityRuntimeValues,\n} from \"./utility-runtime.js\";\nimport {\n buildBehaviorSignalsForMemory,\n dedupeBehaviorSignalsByMemoryAndHash,\n} from \"./behavior-signals.js\";\nimport { ProfilingCollector } from \"./profiling.js\";\nimport {\n keyring,\n secureStoreDir,\n SecureStoreLockedError,\n} from \"./secure-store/index.js\";\nimport type {\n AccessTrackingEntry,\n BehaviorLoopPolicyState,\n BehaviorSignalEvent,\n BootstrapOptions,\n BootstrapResult,\n BufferTurn,\n ContinuityIncidentRecord,\n ConsolidationObservation,\n EngramTraceEvent,\n ExtractionResult,\n IdentityInjectionMode,\n LifecycleState,\n MemoryActionEvent,\n MemoryActionType,\n MemoryLink,\n MemoryFile,\n MemoryFrontmatter,\n DaySummaryResult,\n PluginConfig,\n QmdSearchResult,\n RecallPlanMode,\n RecallSectionConfig,\n RecallTierExplain,\n EntityStructuredSection,\n EntityTimelineEntry,\n} from \"./types.js\";\n\nexport interface BulkImportBatchIngestResult {\n attemptedTurnCount: number;\n extractionCount: number;\n persistedCount: number;\n durableOutputCount: number;\n skippedCount: number;\n failedCount: number;\n postPersistMetadataFailureCount: number;\n processedTurnCount: number;\n}\n\nexport class BulkImportBatchPartialFailureError extends Error {\n readonly partialResult: BulkImportBatchIngestResult;\n\n readonly originalError: unknown;\n\n constructor(\n message: string,\n partialResult: BulkImportBatchIngestResult,\n originalError: unknown,\n ) {\n super(message);\n this.name = \"BulkImportBatchPartialFailureError\";\n this.partialResult = partialResult;\n this.originalError = originalError;\n }\n}\n\ninterface ExtractionRunResult {\n status: \"completed\" | \"skipped\";\n reason?: string;\n persistedCount: number;\n durableOutputCount: number;\n postPersistMetadataFailed?: boolean;\n}\n\nexport function dedupeEntitySynthesisEvidenceEntries(\n entries: EntityTimelineEntry[],\n): EntityTimelineEntry[] {\n const dedupedEvidenceEntries: EntityTimelineEntry[] = [];\n const evidenceByFact = new Map<string, {\n newest: EntityTimelineEntry;\n oldest: EntityTimelineEntry;\n }>();\n\n for (const entry of entries) {\n const normalizedFact = entry.text.trim();\n if (!normalizedFact) continue;\n const existing = evidenceByFact.get(normalizedFact);\n if (!existing) {\n evidenceByFact.set(normalizedFact, { newest: entry, oldest: entry });\n continue;\n }\n if (compareEntityTimestamps(entry.timestamp, existing.newest.timestamp) > 0) {\n existing.newest = entry;\n }\n if (compareEntityTimestamps(entry.timestamp, existing.oldest.timestamp) < 0) {\n existing.oldest = entry;\n }\n }\n\n for (const { newest, oldest } of evidenceByFact.values()) {\n dedupedEvidenceEntries.push(newest);\n const newestKey = [\n newest.timestamp,\n newest.source ?? \"\",\n newest.sessionKey ?? \"\",\n newest.principal ?? \"\",\n newest.text,\n ].join(\"\\u0000\");\n const oldestKey = [\n oldest.timestamp,\n oldest.source ?? \"\",\n oldest.sessionKey ?? \"\",\n oldest.principal ?? \"\",\n oldest.text,\n ].join(\"\\u0000\");\n if (oldestKey !== newestKey) {\n dedupedEvidenceEntries.push(oldest);\n }\n }\n\n return dedupedEvidenceEntries;\n}\n\nfunction flattenStructuredSectionEvidence(\n sections: EntityStructuredSection[] | undefined,\n): EntityTimelineEntry[] {\n return (sections ?? []).flatMap((section) =>\n section.facts\n .map((fact) => fact.trim())\n .filter((fact) => fact.length > 0)\n .map((fact) => ({\n timestamp: \"\",\n text: fact,\n source: `section:${section.title}`,\n })),\n );\n}\n\nfunction fingerprintEntitySynthesisEvidence(entity: {\n timeline: EntityTimelineEntry[];\n structuredSections?: EntityStructuredSection[];\n}): string {\n const fingerprint = createHash(\"sha256\");\n const timelineEntries = entity.timeline\n .map((entry) => [\n entry.timestamp,\n entry.source ?? \"\",\n entry.sessionKey ?? \"\",\n entry.principal ?? \"\",\n entry.text,\n ].join(\"\\u0000\"))\n .sort();\n const timelineEntrySeparator = String.fromCharCode(1);\n const structuredFactsSeparator = String.fromCharCode(2);\n fingerprint.update(timelineEntries.join(timelineEntrySeparator));\n fingerprint.update(structuredFactsSeparator);\n fingerprint.update(fingerprintEntityStructuredFacts(entity) ?? \"\");\n return fingerprint.digest(\"hex\");\n}\n\nexport interface GraphRecallSnapshot {\n recordedAt: string;\n mode: RecallPlanMode | string;\n queryHash: string;\n queryLength: number;\n namespaces: string[];\n seedCount: number;\n expandedCount: number;\n seeds: string[];\n expanded: GraphRecallExpandedEntry[];\n status?: \"completed\" | \"skipped\" | \"aborted\";\n reason?: string;\n shadowMode?: boolean;\n queryIntent?: MemoryIntent;\n seedResults?: GraphRecallRankedResult[];\n finalResults?: GraphRecallRankedResult[];\n shadowComparison?: GraphRecallShadowComparison;\n}\n\nexport interface GraphRecallRankedResult {\n path: string;\n score: number;\n docid?: string;\n sourceLabels: string[];\n}\n\nexport interface GraphRecallShadowComparison {\n baselineCount: number;\n graphCount: number;\n overlapCount: number;\n overlapRatio: number;\n averageOverlapDelta: number;\n}\n\nexport interface IntentDebugSnapshot {\n recordedAt: string;\n promptHash: string;\n promptLength: number;\n retrievalQueryHash: string;\n retrievalQueryLength: number;\n plannerEnabled: boolean;\n plannedMode: RecallPlanMode;\n effectiveMode: RecallPlanMode;\n recallResultLimit: number;\n queryIntent: MemoryIntent;\n graphExpandedIntentDetected: boolean;\n graphDecision: {\n status: \"not_requested\" | \"skipped\" | \"completed\" | \"aborted\";\n reason?: string;\n shadowMode: boolean;\n qmdAvailable: boolean;\n graphRecallEnabled: boolean;\n multiGraphMemoryEnabled: boolean;\n };\n}\n\nexport interface QmdRecallSnapshot {\n recordedAt: string;\n queryHash: string;\n queryLength: number;\n collection?: string;\n namespaces: string[];\n fetchLimit: number;\n primaryResultCount: number;\n hybridResultCount: number;\n queryAwareSeedCount: number;\n resultCount: number;\n intentHint?: string;\n explainEnabled: boolean;\n hybridTopUpUsed: boolean;\n hybridTopUpSkippedReason?: string;\n results: QmdSearchResult[];\n}\n\nexport interface RecallModeDecision {\n plannedMode: RecallPlanMode;\n effectiveMode: RecallPlanMode;\n graphExpandedIntentDetected: boolean;\n graphReason?: string;\n /**\n * Where `plannedMode` came from (issue #1367 / Option C). `\"heuristic\"` for\n * the regex planner; `\"llm\"` when the LLM planner classified it; and\n * `\"heuristic-fallback\"` when the LLM was enabled but errored/timed out and we\n * fell back. Absent on the synchronous heuristic-only path.\n */\n plannerSource?: \"heuristic\" | \"llm\" | \"heuristic-fallback\";\n /** Short rationale from the planner (for telemetry / x-ray). */\n plannerReason?: string;\n /** Wall-clock spent in the LLM planner call, when one was made. */\n plannerLatencyMs?: number;\n /** True when the LLM planner was enabled but fell back to the heuristic. */\n plannerFallbackUsed?: boolean;\n /** Model that served the LLM classification, when one was used. */\n plannerModelUsed?: string;\n /**\n * The regex-heuristic baseline mode, captured whenever the LLM planner ran\n * (any source). Lets operators compare planned-vs-heuristic during rollout —\n * distinct from `plannedMode`, which on the LLM path is the LLM's choice.\n */\n plannerHeuristicMode?: RecallPlanMode;\n /**\n * In shadow mode, the mode the LLM *would* have chosen (recorded for\n * comparison) while `effectiveMode` stays on the heuristic decision.\n */\n shadowLlmMode?: RecallPlanMode;\n}\n\n/**\n * Map the orchestrator's internal `recallSource` strings to the\n * X-ray `servedBy` vocabulary (issue #570 PR 1). The X-ray tier\n * ladder intentionally flattens QMD / embedding / cold-fallback to\n * the `hybrid` tier because they all materialize through the same\n * hybrid BM25+vector pipeline from the caller's perspective. The\n * `recent_scan` path gets its own dedicated tier because it bypasses\n * the hybrid pipeline entirely. `none` is treated as `hybrid` on the\n * theory that a query that returned nothing still routed through the\n * hybrid pipeline — but callers should normally gate capture on\n * `recalledMemoryIds.length > 0`.\n */\nfunction mapRecallSourceToXrayServedBy(\n source:\n | \"none\"\n | \"hot_qmd\"\n | \"hot_embedding\"\n | \"cold_fallback\"\n | \"recent_scan\",\n): RecallXrayServedBy {\n // Exhaustive switch: every current union member is explicitly\n // listed so TypeScript surfaces a compile error if a new source is\n // added without a deliberate mapping. The `never`-typed fallthrough\n // keeps the function total at runtime — if the caller passes an\n // unexpected value that slipped past the type system (e.g. a JSON\n // deserialization), we still fall back to `hybrid`.\n switch (source) {\n case \"recent_scan\":\n return \"recent-scan\";\n case \"hot_qmd\":\n case \"hot_embedding\":\n case \"cold_fallback\":\n case \"none\":\n return \"hybrid\";\n }\n const _exhaustive: never = source;\n void _exhaustive;\n return \"hybrid\";\n}\n\nexport interface RecallInvocationOptions {\n namespace?: string;\n topK?: number;\n mode?: RecallPlanMode;\n abortSignal?: AbortSignal;\n /**\n * Capture a `RecallXraySnapshot` for this recall (issue #570). When\n * `true`, the orchestrator builds a snapshot from the data it has\n * already gathered and stashes it in memory, accessible via\n * `getLastXraySnapshot()`. When `false` or absent, nothing is\n * captured and recall behavior is unchanged (schema-only slice).\n */\n xrayCapture?: boolean;\n /**\n * Per-invocation override for `recallBudgetChars` (issue #570 PR 3/4).\n * Flows through `getRecallBudgetChars()` for this recall only — no\n * shared config mutation, so concurrent recalls on the same\n * orchestrator are not affected (CLAUDE.md rule 47: no shared\n * mutable state across async boundaries). Must be a non-negative\n * finite integer; non-conforming values are ignored and the\n * configured budget is used.\n */\n budgetCharsOverride?: number;\n /**\n * Per-invocation principal override (issue #570 PR 4). When set,\n * the orchestrator uses this principal for ACL / namespace checks\n * instead of `resolvePrincipal(sessionKey, config)`. This is the\n * escape hatch for access surfaces (HTTP / MCP) that have already\n * authenticated the caller upstream — threading an unmapped\n * principal through the session-key-based resolver would otherwise\n * collapse it to `\"default\"` and produce false denials in\n * namespace-enabled deployments (CLAUDE.md rule 42).\n */\n principalOverride?: string;\n /**\n * Historical recall point (issue #680). When set, the orchestrator\n * filters out memories whose `valid_at` is after this timestamp OR\n * whose `invalid_at` is at-or-before this timestamp, so callers see\n * the corpus as it existed at `asOf`. ISO 8601 string; comparisons\n * use `Date.parse()` so timezone-aware values round-trip correctly\n * (CLAUDE.md gotcha — never compare ISO strings lexicographically).\n * Invalid values must be rejected at input boundaries (CLAUDE.md\n * rule 51); the orchestrator does NOT silently fall back here.\n */\n asOf?: string;\n /**\n * Issue #681 — when `true`, bypasses `graphTraversalConfidenceFloor`\n * and includes edges below the floor in graph traversal. Useful for\n * diagnostic recall queries that need to surface results that would\n * normally be pruned by confidence decay. Default `false`.\n */\n includeLowConfidence?: boolean;\n /**\n * User-aware context scopes active for this recall. Used by X-ray\n * provenance safety checks so boundary-scoped memories are evaluated\n * against the caller's real context.\n */\n currentContextScopes?: readonly unknown[];\n}\n\ntype QueryAwarePrefilter = {\n candidatePaths: Set<string> | null;\n temporalFromDate: string | null;\n matchedTags: string[];\n expandedTags: string[];\n combination: \"none\" | \"temporal\" | \"tag\" | \"intersection\" | \"union\";\n filteredToFullSearch: boolean;\n};\n\n// Recall-specific abort helpers. Thin wrappers over the shared\n// `abort-error.ts` module so every abort in the codebase shares the\n// same `name === \"AbortError\"` classification contract (`isAbortError`\n// works uniformly). We keep the \"recall aborted\" default message for\n// back-compat with call-site logs; callers that pass an explicit\n// message (e.g. \"extraction aborted (before_extract)\") are unaffected.\nconst abortRecallError = sharedAbortError;\n\nfunction throwIfRecallAborted(\n signal?: AbortSignal,\n message = \"recall aborted\",\n): void {\n sharedThrowIfAborted(signal, message);\n}\n\nasync function raceRecallAbort<T>(\n promise: Promise<T>,\n signal?: AbortSignal,\n message = \"recall aborted\",\n): Promise<T> {\n throwIfRecallAborted(signal, message);\n if (!signal) return promise;\n\n let onAbort: (() => void) | null = null;\n const abortPromise = new Promise<T>((_resolve, reject) => {\n onAbort = () => reject(abortRecallError(message));\n signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n\n try {\n return await Promise.race([promise, abortPromise]);\n } finally {\n if (onAbort) {\n signal.removeEventListener(\"abort\", onAbort);\n }\n }\n}\n\nfunction qmdCollectionPathParts(resultPath: string): {\n collection: string;\n relativePath: string;\n} | null {\n if (!resultPath || path.isAbsolute(resultPath)) return null;\n const normalized = resultPath.replace(/\\\\/g, \"/\").replace(/^\\/+/, \"\");\n const slashIndex = normalized.indexOf(\"/\");\n if (slashIndex <= 0 || slashIndex >= normalized.length - 1) return null;\n const collection = normalized.slice(0, slashIndex);\n if (/^\\d{4}-\\d{2}-\\d{2}$/.test(collection)) return null;\n return {\n collection,\n relativePath: normalized.slice(slashIndex + 1),\n };\n}\n\nfunction qmdResultPathCandidates(\n storageDir: string,\n resultPath: string,\n): string[] {\n const candidates = new Set<string>();\n const storageRoot = path.resolve(storageDir);\n const addCandidate = (candidate: string) => {\n const resolved = path.resolve(candidate);\n if (isPathInsideStorageRoot(storageRoot, resolved)) {\n candidates.add(resolved);\n }\n };\n const addRelativeCandidates = (relativePath: string) => {\n const normalized = relativePath.replace(/\\\\/g, \"/\").replace(/^\\/+/, \"\");\n if (!normalized) return;\n addCandidate(path.join(storageRoot, normalized));\n if (/^\\d{4}-\\d{2}-\\d{2}\\//.test(normalized)) {\n addCandidate(path.join(storageRoot, \"facts\", normalized));\n }\n };\n\n if (path.isAbsolute(resultPath)) {\n addCandidate(resultPath);\n } else {\n addRelativeCandidates(resultPath);\n }\n\n return [...candidates];\n}\n\n/** Maximum age (ms) before a compaction-reset signal file is considered stale and removed. */\nconst COMPACTION_SIGNAL_MAX_AGE_MS = 60 * 60 * 1000; // 1 hour\nconst DEFAULT_QMD_STARTUP_COLLECTION_CHECK_TIMEOUT_MS = 10_000;\n\ntype DaySummaryGatherOptions = {\n timeZone?: string;\n now?: Date;\n};\n\nfunction normalizeIanaTimeZone(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n if (!trimmed) return undefined;\n try {\n Intl.DateTimeFormat(undefined, { timeZone: trimmed });\n return trimmed;\n } catch {\n return undefined;\n }\n}\n\nfunction formatDateInTimeZone(date: Date, timeZone: string): string {\n const parts = new Intl.DateTimeFormat(\"en-US\", {\n timeZone,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n }).formatToParts(date);\n const get = (type: string): string => parts.find((part) => part.type === type)?.value ?? \"\";\n return `${get(\"year\")}-${get(\"month\")}-${get(\"day\")}`;\n}\n\nfunction utcDateKey(date: Date): string {\n return date.toISOString().slice(0, 10);\n}\n\nfunction utcDateKeysAround(date: Date): string[] {\n const dayMs = 86_400_000;\n const keys = [\n utcDateKey(new Date(date.getTime() - dayMs)),\n utcDateKey(date),\n utcDateKey(new Date(date.getTime() + dayMs)),\n ];\n return keys.filter((value, index, array) => array.indexOf(value) === index);\n}\n\nfunction utcDateKeysForLocalDay(date: Date, timeZone: string): string[] {\n const targetLocalDate = formatDateInTimeZone(date, timeZone);\n const keys = new Set<string>();\n const hourMs = 3_600_000;\n const scanStart = date.getTime() - 48 * hourMs;\n const scanEnd = date.getTime() + 48 * hourMs;\n for (let ms = scanStart; ms <= scanEnd; ms += hourMs) {\n const candidate = new Date(ms);\n if (formatDateInTimeZone(candidate, timeZone) === targetLocalDate) {\n keys.add(utcDateKey(candidate));\n }\n }\n return keys.size > 0 ? [...keys].sort() : utcDateKeysAround(date);\n}\n\nfunction parseFiniteDate(value: unknown): Date | null {\n if (typeof value !== \"string\" || value.trim().length === 0) return null;\n const parsed = new Date(value);\n return Number.isFinite(parsed.getTime()) ? parsed : null;\n}\n\nfunction filterHourlySummaryMarkdownForLocalDay(\n raw: string,\n utcDate: string,\n timeZone: string,\n targetLocalDate: string,\n): string | null {\n const hourHeaderPattern = /^## ([01]\\d|2[0-3]):00[ \\t]*$/gm;\n const matches = Array.from(raw.matchAll(hourHeaderPattern));\n if (matches.length === 0) return null;\n\n const firstSectionStart = matches[0]?.index ?? 0;\n const preamble = raw.slice(0, firstSectionStart).trim();\n const sections: string[] = [];\n for (let index = 0; index < matches.length; index += 1) {\n const match = matches[index];\n const hour = match[1];\n if (!hour) continue;\n const sectionTimestamp = parseFiniteDate(`${utcDate}T${hour}:00:00.000Z`);\n if (\n !sectionTimestamp ||\n formatDateInTimeZone(sectionTimestamp, timeZone) !== targetLocalDate\n ) {\n continue;\n }\n const sectionStart = match.index ?? 0;\n const sectionEnd = matches[index + 1]?.index ?? raw.length;\n const section = raw.slice(sectionStart, sectionEnd).trim();\n if (section.length > 0) sections.push(section);\n }\n\n if (sections.length === 0) return null;\n return [preamble, ...sections]\n .filter((section) => section.length > 0)\n .join(\"\\n\\n\");\n}\n\ntype SearchCollectionState = \"present\" | \"missing\" | \"unknown\" | \"skipped\";\n\nfunction qmdStartupCollectionCheckTimeoutMs(): number {\n const raw =\n process.env.REMNIC_QMD_STARTUP_COLLECTION_CHECK_TIMEOUT_MS ??\n process.env.ENGRAM_QMD_STARTUP_COLLECTION_CHECK_TIMEOUT_MS;\n if (raw === undefined) return DEFAULT_QMD_STARTUP_COLLECTION_CHECK_TIMEOUT_MS;\n const parsed = Number(raw);\n return Number.isFinite(parsed) && parsed >= 1_000\n ? Math.floor(parsed)\n : DEFAULT_QMD_STARTUP_COLLECTION_CHECK_TIMEOUT_MS;\n}\n\nasync function qmdStartupCollectionCheckWithTimeout(\n promise: Promise<SearchCollectionState>,\n controller: AbortController,\n label: string,\n): Promise<SearchCollectionState> {\n const timeoutMs = qmdStartupCollectionCheckTimeoutMs();\n let timer: NodeJS.Timeout | undefined;\n let settled = false;\n\n const timeoutPromise = new Promise<SearchCollectionState>((resolve) => {\n timer = setTimeout(() => {\n if (settled) return;\n controller.abort();\n log.warn(\n `QMD startup collection check for ${label} timed out after ${timeoutMs}ms; keeping search enabled fail-open`,\n );\n resolve(\"unknown\");\n }, timeoutMs);\n timer.unref?.();\n });\n\n const checkedPromise = promise\n .catch((err): SearchCollectionState => {\n log.warn(\n `QMD startup collection check for ${label} failed; keeping search enabled fail-open: ${err}`,\n );\n return \"unknown\";\n })\n .finally(() => {\n settled = true;\n if (timer) clearTimeout(timer);\n });\n\n return await Promise.race([checkedPromise, timeoutPromise]);\n}\n\n/** Default workspace directory when no per-agent or config workspace is available. */\nexport function defaultWorkspaceDir(): string {\n return path.join(os.homedir(), \".openclaw\", \"workspace\");\n}\n\n/**\n * Produce a collision-resistant, filesystem-safe identifier from a session key.\n *\n * Session keys follow colon-delimited forms (e.g., `agent:gpucodebot:main`).\n * A naive replace (`:` → `_`) is lossy: different keys like `agent:alpha` and\n * `agent/alpha` would collide. Instead we append a short SHA-256 hash of the\n * original key to the human-readable sanitized prefix, guaranteeing uniqueness\n * while keeping filenames debuggable.\n *\n * Format: `<sanitized>-<12-char-hex-hash>`\n * Example: `agent:gpucodebot:main` → `agent_gpucodebot_main-a1b2c3d4e5f6`\n */\nexport function sanitizeSessionKeyForFilename(sessionKey: string): string {\n const readable = sessionKey.replace(/[^a-zA-Z0-9._-]/g, \"_\");\n const hash = createHash(\"sha256\")\n .update(sessionKey)\n .digest(\"hex\")\n .slice(0, 12);\n return `${readable}-${hash}`;\n}\n\nfunction latestSourceValidAtFromTurns(turns: readonly BufferTurn[]): string | undefined {\n let latestMs: number | null = null;\n for (const turn of turns) {\n if (turn.extractionContextOnly === true) continue;\n if (typeof turn.sourceValidAt !== \"string\") continue;\n const parsed = parseFlexibleIsoTimestamp(turn.sourceValidAt.trim());\n if (parsed === null) continue;\n if (latestMs === null || parsed > latestMs) {\n latestMs = parsed;\n }\n }\n return latestMs === null ? undefined : new Date(latestMs).toISOString();\n}\n\nfunction sourceValidAtMs(turn: BufferTurn): number | null {\n if (typeof turn.sourceValidAt !== \"string\") return null;\n return parseFlexibleIsoTimestamp(turn.sourceValidAt.trim());\n}\n\nconst SOURCE_VALID_AT_CONTEXT_TURNS = 2;\n\nfunction sourceValidAtSliceKey(turn: BufferTurn, index: number): string {\n const validAtMs = sourceValidAtMs(turn);\n return validAtMs === null ? `unknown:${index}` : String(validAtMs);\n}\n\nfunction asExtractionContextTurn(turn: BufferTurn): BufferTurn {\n return { ...turn, extractionContextOnly: true };\n}\n\nfunction asExtractionTargetTurn(turn: BufferTurn): BufferTurn {\n const { extractionContextOnly: _contextOnly, ...targetTurn } = turn;\n return targetTurn;\n}\n\nfunction sourceValidAtContextTurns(\n turns: readonly BufferTurn[],\n targetStart: number,\n targetEnd: number,\n targetValidAtMs: number | null,\n): BufferTurn[] {\n if (targetValidAtMs === null) return [];\n return turns\n .flatMap((turn, index) => {\n if (index >= targetStart && index < targetEnd) return [];\n const contextValidAtMs = sourceValidAtMs(turn);\n if (contextValidAtMs === null || contextValidAtMs > targetValidAtMs) {\n return [];\n }\n return [{ turn, index, validAtMs: contextValidAtMs }];\n })\n .sort((a, b) => {\n if (a.validAtMs < b.validAtMs) return -1;\n if (a.validAtMs > b.validAtMs) return 1;\n if (a.index === b.index) return 0;\n return a.index < b.index ? -1 : 1;\n })\n .slice(-SOURCE_VALID_AT_CONTEXT_TURNS)\n .map(({ turn }) => asExtractionContextTurn(turn));\n}\n\nfunction targetSourceValidAtSortMs(turns: readonly BufferTurn[]): number {\n let latestMs: number | null = null;\n for (const turn of turns) {\n if (turn.extractionContextOnly === true) continue;\n const validAtMs = sourceValidAtMs(turn);\n if (validAtMs === null) continue;\n if (latestMs === null || validAtMs > latestMs) {\n latestMs = validAtMs;\n }\n }\n return latestMs ?? Number.POSITIVE_INFINITY;\n}\n\nfunction sortSourceValidAtSlicesChronologically(\n slices: BufferTurn[][],\n): BufferTurn[][] {\n return slices\n .map((turns, order) => ({\n turns,\n order,\n targetValidAtMs: targetSourceValidAtSortMs(turns),\n }))\n .sort((a, b) => {\n if (a.targetValidAtMs < b.targetValidAtMs) return -1;\n if (a.targetValidAtMs > b.targetValidAtMs) return 1;\n if (a.order === b.order) return 0;\n return a.order < b.order ? -1 : 1;\n })\n .map((slice) => slice.turns);\n}\n\nfunction splitTurnsBySourceValidAt(\n turns: readonly BufferTurn[],\n options: { includeContext?: boolean } = {},\n): BufferTurn[][] {\n if (turns.length === 0) return [];\n if (!turns.some((turn) => sourceValidAtMs(turn) !== null)) {\n return [[...turns]];\n }\n\n const slices: BufferTurn[][] = [];\n let start = 0;\n while (start < turns.length) {\n const targetValidAtMs = sourceValidAtMs(turns[start]);\n const activeKey = sourceValidAtSliceKey(turns[start], start);\n let end = start + 1;\n while (\n end < turns.length &&\n sourceValidAtSliceKey(turns[end], end) === activeKey\n ) {\n end += 1;\n }\n\n const contextTurns =\n options.includeContext === false\n ? []\n : sourceValidAtContextTurns(turns, start, end, targetValidAtMs);\n slices.push([\n ...contextTurns,\n ...turns.slice(start, end).map(asExtractionTargetTurn),\n ]);\n start = end;\n }\n return sortSourceValidAtSlicesChronologically(slices);\n}\n\nexport function isArtifactMemoryPath(filePath: string): boolean {\n return /(?:^|[\\\\/])artifacts(?:[\\\\/]|$)/i.test(filePath);\n}\n\nexport function deriveTopicsFromExtraction(result: ExtractionResult): string[] {\n const topics = new Set<string>();\n for (const fact of result.facts ?? []) {\n for (const tag of fact.tags ?? []) {\n if (tag && tag.length >= 2) topics.add(tag.toLowerCase());\n }\n if (fact.entityRef) topics.add(fact.entityRef.toLowerCase());\n if (fact.category) topics.add(fact.category);\n }\n for (const entity of (result as any).entities ?? []) {\n if (typeof entity.name === \"string\" && entity.name.length >= 2) {\n topics.add(entity.name.toLowerCase());\n }\n }\n return [...topics].slice(0, 16);\n}\n\nexport function buildCompressionGuidelinesMarkdown(\n events: MemoryActionEvent[],\n generatedAtIso: string = new Date().toISOString(),\n): string {\n return buildCompressionGuidelinesMarkdownV2(events, generatedAtIso);\n}\n\nexport function formatCompressionGuidelinesForRecall(\n raw: string,\n maxLines: number = 5,\n): string | null {\n if (typeof raw !== \"string\" || raw.trim().length === 0) return null;\n const sectionMatch = raw.match(\n // End the section at `\\n## ` or end-of-string. Plain $ (not \\s*$): the\n // \\s* branch overlapped the lazy body and backtracked polynomially\n // (CodeQL js/polynomial-redos). Captured lines are trimmed/filtered below,\n // so trailing whitespace handling is unchanged.\n /## Suggested Guidelines\\s*\\n([\\s\\S]*?)(?:\\n##\\s+|$)/i,\n );\n if (!sectionMatch) return null;\n\n const lines = sectionMatch[1]\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.startsWith(\"- \"))\n .slice(0, Math.max(1, Math.floor(maxLines)));\n if (lines.length === 0) return null;\n\n return lines.join(\"\\n\");\n}\n\nexport function filterRecallCandidates(\n candidates: QmdSearchResult[],\n options: {\n namespacesEnabled: boolean;\n recallNamespaces: string[];\n resolveNamespace: (path: string) => string;\n limit: number;\n },\n): QmdSearchResult[] {\n const scopedByNamespace = options.namespacesEnabled\n ? candidates.filter((r) =>\n options.recallNamespaces.includes(options.resolveNamespace(r.path)),\n )\n : candidates;\n return scopedByNamespace\n .filter((r) => !isArtifactMemoryPath(r.path))\n .slice(0, Math.max(0, options.limit));\n}\n\nfunction applyQueryAwareCandidateFilter(\n candidates: QmdSearchResult[],\n candidatePaths: Set<string> | null,\n): QmdSearchResult[] {\n if (!candidatePaths) return candidates;\n if (candidatePaths.size === 0) return [];\n const filtered = candidates.filter((candidate) =>\n candidatePaths.has(candidate.path),\n );\n return filtered.length > 0 ? filtered : candidates;\n}\n\nfunction tokenizeRecallQuery(prompt: string): string[] {\n return prompt\n .toLowerCase()\n .split(/[^a-z0-9]+/i)\n .map((t) => t.trim())\n .filter((t) => t.length >= 3);\n}\n\nfunction hasLifecycleMetadata(frontmatter: MemoryFrontmatter): boolean {\n return (\n frontmatter.lifecycleState !== undefined ||\n frontmatter.verificationState !== undefined ||\n frontmatter.policyClass !== undefined ||\n frontmatter.lastValidatedAt !== undefined ||\n frontmatter.decayScore !== undefined ||\n frontmatter.heatScore !== undefined\n );\n}\n\nexport function shouldFilterLifecycleRecallCandidate(\n frontmatter: MemoryFrontmatter,\n options: {\n lifecyclePolicyEnabled: boolean;\n lifecycleFilterStaleEnabled: boolean;\n },\n): boolean {\n if (!options.lifecyclePolicyEnabled || !options.lifecycleFilterStaleEnabled)\n return false;\n if (!hasLifecycleMetadata(frontmatter)) return false;\n const lifecycleState = resolveLifecycleState(frontmatter);\n return lifecycleState === \"stale\" || lifecycleState === \"archived\";\n}\n\nexport function lifecycleRecallScoreAdjustment(\n frontmatter: MemoryFrontmatter,\n options: {\n lifecyclePolicyEnabled: boolean;\n },\n): number {\n if (!options.lifecyclePolicyEnabled) return 0;\n if (!hasLifecycleMetadata(frontmatter)) return 0;\n\n let delta = 0;\n const lifecycleState = resolveLifecycleState(frontmatter);\n switch (lifecycleState) {\n case \"active\":\n delta += 0.05;\n break;\n case \"validated\":\n delta += 0.03;\n break;\n case \"candidate\":\n delta -= 0.01;\n break;\n case \"stale\":\n delta -= 0.06;\n break;\n case \"archived\":\n delta -= 0.08;\n break;\n }\n if (frontmatter.verificationState === \"disputed\") {\n delta -= 0.12;\n }\n return delta;\n}\n\nexport function computeArtifactRecallLimit(\n recallMode: RecallPlanMode,\n recallResultLimit: number,\n verbatimArtifactsMaxRecall: number,\n): number {\n if (recallMode === \"no_recall\") return 0;\n if (Math.max(0, recallResultLimit) === 0) return 0;\n const base = Math.max(0, verbatimArtifactsMaxRecall);\n if (recallMode === \"minimal\") {\n return Math.min(base, Math.max(0, recallResultLimit));\n }\n return base;\n}\n\nexport function resolveEffectiveRecallMode(options: {\n plannerEnabled: boolean;\n graphRecallEnabled: boolean;\n multiGraphMemoryEnabled: boolean;\n graphExpandedIntentEnabled?: boolean;\n prompt: string;\n}): RecallPlanMode {\n return resolveRecallModeDecision(options).effectiveMode;\n}\n\ninterface RecallModeGraphOptions {\n plannerEnabled: boolean;\n graphRecallEnabled: boolean;\n multiGraphMemoryEnabled: boolean;\n graphExpandedIntentEnabled?: boolean;\n prompt: string;\n}\n\n/**\n * Apply the graph-mode overlay + gating to a planner-produced mode.\n *\n * Shared by the heuristic ({@link resolveRecallModeDecision}) and LLM\n * ({@link resolveRecallModeDecisionAsync}) paths so graph promotion and the\n * \"graph disabled → fall back to full\" gating behave identically regardless of\n * which planner produced `plannedModeRaw` (gotcha #39).\n */\nfunction finalizeRecallModeDecision(\n plannedModeRaw: RecallPlanMode,\n options: RecallModeGraphOptions,\n): RecallModeDecision {\n let plannedMode: RecallPlanMode = plannedModeRaw;\n const graphExpandedIntentDetected =\n options.plannerEnabled &&\n options.graphExpandedIntentEnabled === true &&\n hasBroadGraphIntent(options.prompt);\n if (plannedMode !== \"graph_mode\" && graphExpandedIntentDetected) {\n plannedMode = \"graph_mode\";\n }\n if (\n plannedMode === \"graph_mode\" &&\n (!options.graphRecallEnabled || !options.multiGraphMemoryEnabled)\n ) {\n return {\n plannedMode,\n effectiveMode: \"full\",\n graphExpandedIntentDetected,\n graphReason: !options.graphRecallEnabled\n ? \"graph recall disabled by config\"\n : \"multi-graph memory disabled by config\",\n };\n }\n return {\n plannedMode,\n effectiveMode: plannedMode,\n graphExpandedIntentDetected,\n };\n}\n\nexport function resolveRecallModeDecision(options: RecallModeGraphOptions): RecallModeDecision {\n const plannedMode: RecallPlanMode = options.plannerEnabled\n ? planRecallMode(options.prompt)\n : \"full\";\n return finalizeRecallModeDecision(plannedMode, options);\n}\n\n/**\n * Async recall-mode decision with optional LLM-based planning (issue #1367 /\n * Option C). Falls back to the heuristic decision when the LLM planner is\n * disabled, in shadow mode, or unavailable/failed — so this is always safe to\n * await on the recall hot path. Provider-agnostic: the LLM call routes through\n * the gateway/fallback chain.\n *\n * `recallPlannerEnabled === false` keeps the legacy \"always full\" behavior and\n * skips the LLM entirely (the planner as a whole is off).\n */\nexport async function resolveRecallModeDecisionAsync(\n options: RecallModeGraphOptions & {\n config: PluginConfig;\n hints?: string[];\n llm?: FallbackLlmClient;\n signal?: AbortSignal;\n },\n): Promise<RecallModeDecision> {\n const heuristicDecision = resolveRecallModeDecision(options);\n\n // Planner globally off, or LLM planning not opted into → heuristic only.\n if (!options.plannerEnabled || !options.config.recallPlannerLlmEnabled) {\n return heuristicDecision;\n }\n\n const { planRecallModeLLM } = await import(\"./recall-planner-llm.js\");\n const planned = await planRecallModeLLM(\n options.prompt,\n options.hints,\n options.config,\n options.llm,\n options.signal,\n );\n\n // Shadow mode: record what the LLM would have chosen but keep the heuristic\n // effective decision (safe rollout / comparison — gotcha #30).\n if (options.config.recallPlannerShadowMode) {\n return {\n ...heuristicDecision,\n plannerSource: planned.source,\n plannerReason: `shadow:${planned.reason}`,\n plannerLatencyMs: planned.latencyMs,\n plannerFallbackUsed: planned.fallbackUsed,\n plannerModelUsed: planned.modelUsed,\n plannerHeuristicMode: planned.heuristicMode,\n shadowLlmMode: planned.mode,\n };\n }\n\n const llmDecision = finalizeRecallModeDecision(planned.mode, options);\n return {\n ...llmDecision,\n plannerSource: planned.source,\n plannerReason: planned.reason,\n plannerLatencyMs: planned.latencyMs,\n plannerFallbackUsed: planned.fallbackUsed,\n plannerModelUsed: planned.modelUsed,\n plannerHeuristicMode: planned.heuristicMode,\n };\n}\n\nexport function hasIdentityRecoveryIntent(prompt: string): boolean {\n const text = typeof prompt === \"string\" ? prompt.toLowerCase() : \"\";\n if (!text) return false;\n return /\\b(identity|continuity|recover(?:y|ing|ed)?|incident|drift|restore|regress(?:ion|ed|ing)?)\\b/i.test(\n text,\n );\n}\n\nexport function resolveEffectiveIdentityInjectionMode(options: {\n configuredMode: IdentityInjectionMode;\n recallMode: RecallPlanMode;\n prompt: string;\n}): { mode: IdentityInjectionMode; shouldInject: boolean } {\n if (\n options.configuredMode === \"recovery_only\" &&\n !hasIdentityRecoveryIntent(options.prompt)\n ) {\n return { mode: \"recovery_only\", shouldInject: false };\n }\n if (options.recallMode === \"minimal\" && options.configuredMode === \"full\") {\n return { mode: \"minimal\", shouldInject: true };\n }\n return { mode: options.configuredMode, shouldInject: true };\n}\n\nexport function computeArtifactCandidateFetchLimit(\n targetCount: number,\n): number {\n const cappedTarget = Math.max(0, targetCount);\n if (cappedTarget === 0) return 0;\n const headroom = Math.max(8, cappedTarget * 4);\n return Math.min(200, cappedTarget + headroom);\n}\n\nexport function computeQmdHybridFetchLimit(\n recallFetchLimit: number,\n artifactsEnabled: boolean,\n maxArtifactRecall: number,\n): number {\n const cappedRecallLimit = Math.max(0, recallFetchLimit);\n if (cappedRecallLimit === 0) return 0;\n if (!artifactsEnabled) return cappedRecallLimit;\n // Overscan when artifacts are enabled, then filter artifact paths before\n // re-applying the recall cap to avoid artifact-dominated top-N starvation.\n const artifactHeadroom = Math.max(20, Math.max(0, maxArtifactRecall) * 8);\n return Math.min(400, cappedRecallLimit + artifactHeadroom);\n}\n\nexport function mergeGraphExpandedResults(\n primary: QmdSearchResult[],\n expanded: QmdSearchResult[],\n): QmdSearchResult[] {\n const mergedByPath = new Map<string, QmdSearchResult>();\n for (const item of [...primary, ...expanded]) {\n const prev = mergedByPath.get(item.path);\n if (!prev) {\n mergedByPath.set(item.path, item);\n continue;\n }\n const better = item.score > prev.score ? item : prev;\n const snippet = prev.snippet || item.snippet;\n mergedByPath.set(item.path, { ...better, snippet });\n }\n return Array.from(mergedByPath.values());\n}\n\nexport function graphPathRelativeToStorage(\n storageDir: string,\n candidatePath: string,\n): string | null {\n const absolutePath = path.isAbsolute(candidatePath)\n ? candidatePath\n : path.resolve(storageDir, candidatePath);\n const rel = path.relative(storageDir, absolutePath);\n if (!rel || rel === \".\") return null;\n if (rel.startsWith(\"..\")) return null;\n return rel.split(path.sep).join(\"/\");\n}\n\nfunction normalizeGraphActivationScore(score: number): number {\n const bounded = Number.isFinite(score) && score > 0 ? score : 0;\n return bounded / (1 + bounded);\n}\n\nexport function blendGraphExpandedRecallScore(options: {\n graphActivationScore: number;\n seedRecallScore: number;\n activationWeight: number;\n blendMin: number;\n blendMax: number;\n}): number {\n const graphNorm = normalizeGraphActivationScore(options.graphActivationScore);\n const seedScore = Number.isFinite(options.seedRecallScore)\n ? Math.min(1, Math.max(0, options.seedRecallScore))\n : 0;\n const weight = Math.min(1, Math.max(0, options.activationWeight));\n const rawMin = Math.min(1, Math.max(0, options.blendMin));\n const rawMax = Math.min(1, Math.max(0, options.blendMax));\n const minBound = Math.min(rawMin, rawMax);\n const maxBound = Math.max(rawMin, rawMax);\n const blended = graphNorm * weight + seedScore * (1 - weight);\n return Math.max(minBound, Math.min(maxBound, blended));\n}\n\nexport function summarizeGraphShadowComparison(\n baseline: QmdSearchResult[],\n merged: QmdSearchResult[],\n topN: number,\n): {\n baselineCount: number;\n graphCount: number;\n overlapCount: number;\n overlapRatio: number;\n averageOverlapDelta: number;\n} {\n const limit = Math.max(0, Math.floor(topN));\n const baselineTop = limit > 0 ? baseline.slice(0, limit) : [];\n const graphTop = limit > 0 ? merged.slice(0, limit) : [];\n const baselineByPath = new Map(\n baselineTop.map((item) => [item.path, item.score]),\n );\n const graphByPath = new Map(graphTop.map((item) => [item.path, item.score]));\n\n let overlapCount = 0;\n let overlapDeltaSum = 0;\n for (const [p, baselineScore] of baselineByPath.entries()) {\n const graphScore = graphByPath.get(p);\n if (typeof graphScore !== \"number\") continue;\n overlapCount += 1;\n overlapDeltaSum += graphScore - baselineScore;\n }\n\n const baselineCount = baselineTop.length;\n return {\n baselineCount,\n graphCount: graphTop.length,\n overlapCount,\n overlapRatio: baselineCount > 0 ? overlapCount / baselineCount : 0,\n averageOverlapDelta: overlapCount > 0 ? overlapDeltaSum / overlapCount : 0,\n };\n}\n\nfunction parseGraphRecallRankedResults(\n value: unknown,\n): GraphRecallRankedResult[] {\n if (!Array.isArray(value)) return [];\n const parsed: GraphRecallRankedResult[] = [];\n for (const entry of value) {\n if (!entry || typeof entry !== \"object\") continue;\n const candidate = entry as Partial<GraphRecallRankedResult>;\n if (\n typeof candidate.path !== \"string\" ||\n typeof candidate.score !== \"number\"\n )\n continue;\n parsed.push({\n path: candidate.path,\n score: candidate.score,\n docid: typeof candidate.docid === \"string\" ? candidate.docid : undefined,\n sourceLabels: Array.isArray(candidate.sourceLabels)\n ? candidate.sourceLabels.filter(\n (item): item is string => typeof item === \"string\",\n )\n : [],\n });\n }\n return parsed.slice(0, 64);\n}\n\nfunction parseMemoryIntentSnapshot(value: unknown): MemoryIntent {\n const candidate =\n value && typeof value === \"object\" ? (value as Partial<MemoryIntent>) : {};\n return {\n goal: typeof candidate.goal === \"string\" ? candidate.goal : \"unknown\",\n actionType:\n typeof candidate.actionType === \"string\"\n ? candidate.actionType\n : \"unknown\",\n entityTypes: Array.isArray(candidate.entityTypes)\n ? candidate.entityTypes.filter(\n (item): item is string => typeof item === \"string\",\n )\n : [],\n taskInitiation: candidate.taskInitiation === true,\n };\n}\n\nfunction buildQmdIntentHint(intent: MemoryIntent): string | undefined {\n const parts: string[] = [];\n if (intent.goal !== \"unknown\") {\n parts.push(`goal:${intent.goal.replace(/_/g, \" \")}`);\n }\n if (intent.actionType !== \"unknown\") {\n parts.push(`action:${intent.actionType.replace(/_/g, \" \")}`);\n }\n if (intent.entityTypes.length > 0) {\n parts.push(`entities:${intent.entityTypes.join(\",\")}`);\n }\n if (intent.taskInitiation === true) {\n parts.push(\"task_initiation\");\n }\n return parts.length > 0 ? parts.join(\" \") : undefined;\n}\n\nfunction parseQmdRecallResults(value: unknown): QmdSearchResult[] {\n if (!Array.isArray(value)) return [];\n const parsed: QmdSearchResult[] = [];\n for (const entry of value) {\n if (!entry || typeof entry !== \"object\") continue;\n const candidate = entry as Partial<QmdSearchResult>;\n if (\n typeof candidate.path !== \"string\" ||\n typeof candidate.score !== \"number\"\n )\n continue;\n parsed.push({\n docid: typeof candidate.docid === \"string\" ? candidate.docid : \"\",\n path: candidate.path,\n snippet: typeof candidate.snippet === \"string\" ? candidate.snippet : \"\",\n score: candidate.score,\n explain: parseQmdExplain(candidate.explain),\n transport:\n candidate.transport === \"daemon\" ||\n candidate.transport === \"subprocess\" ||\n candidate.transport === \"hybrid\" ||\n candidate.transport === \"scoped_prefilter\"\n ? candidate.transport\n : undefined,\n });\n }\n return parsed.slice(0, 32);\n}\n\nexport function mergeArtifactRecallCandidates(\n candidatesByNamespace: MemoryFile[][],\n limit: number,\n): MemoryFile[] {\n const cappedLimit = Math.max(0, limit);\n if (cappedLimit === 0) return [];\n\n const out: MemoryFile[] = [];\n const seen = new Set<string>();\n let offset = 0;\n while (out.length < cappedLimit) {\n let hasAnyCandidateAtOffset = false;\n for (const list of candidatesByNamespace) {\n if (offset >= list.length) continue;\n hasAnyCandidateAtOffset = true;\n const item = list[offset];\n const dedupeKey = `${item.frontmatter.id}:${item.frontmatter.sourceMemoryId ?? \"\"}:${item.content}`;\n if (seen.has(dedupeKey)) continue;\n seen.add(dedupeKey);\n out.push(item);\n if (out.length >= cappedLimit) break;\n }\n if (!hasAnyCandidateAtOffset) break;\n offset += 1;\n }\n return out;\n}\n\nexport function resolveRecentThreadMemoryPaths(options: {\n threadEpisodeIds: string[];\n currentMemoryId: string;\n allMemsForGraph: MemoryFile[] | null | undefined;\n pathById?: Map<string, string>;\n storageDir: string;\n maxRecent: number;\n}): string[] {\n const maxRecent = Math.max(0, options.maxRecent);\n if (options.threadEpisodeIds.length === 0 || maxRecent === 0) return [];\n const pathById =\n options.pathById ??\n buildMemoryPathById(options.allMemsForGraph, options.storageDir);\n if (pathById.size === 0) return [];\n\n return options.threadEpisodeIds\n .filter((id) => id !== options.currentMemoryId)\n .slice(-maxRecent)\n .map((id) => pathById.get(id))\n .filter((p): p is string => typeof p === \"string\" && p.length > 0);\n}\n\nexport function buildMemoryPathById(\n allMemsForGraph: MemoryFile[] | null | undefined,\n storageDir: string,\n): Map<string, string> {\n const pathById = new Map<string, string>();\n for (const mem of allMemsForGraph ?? []) {\n const id = mem.frontmatter.id;\n if (!id) continue;\n pathById.set(id, path.relative(storageDir, mem.path));\n }\n return pathById;\n}\n\nexport function appendMemoryToGraphContext(options: {\n allMemsForGraph: MemoryFile[] | null | undefined;\n storageDir: string;\n memoryRelPath: string;\n memoryId: string;\n category: MemoryFile[\"frontmatter\"][\"category\"];\n content: string;\n entityRef: string | undefined;\n}): void {\n if (!Array.isArray(options.allMemsForGraph)) return;\n\n const nowIso = new Date().toISOString();\n options.allMemsForGraph.push({\n path: path.join(options.storageDir, options.memoryRelPath),\n content: options.content,\n frontmatter: {\n id: options.memoryId,\n category: options.category,\n created: nowIso,\n updated: nowIso,\n source: \"extraction\",\n confidence: 0.8,\n confidenceTier: \"implied\",\n tags: [],\n entityRef: options.entityRef,\n status: \"active\",\n },\n });\n}\n\nexport function resolvePersistedMemoryRelativePath(options: {\n memoryId: string;\n pathById: Map<string, string>;\n category: string;\n}): string {\n const persisted = options.pathById.get(options.memoryId);\n if (persisted) return persisted;\n if (options.category === \"correction\") {\n return path.join(\"corrections\", `${options.memoryId}.md`);\n }\n // Pick the subtree that matches the StorageManager.writeMemory routing\n // so fallback paths (used before memoryPathById has seen the fresh\n // write) agree with where the file actually lives. Without this branch,\n // reasoning_trace graph edges point at facts/<date>/, and subsequent\n // graph expansion silently drops those nodes when readMemoryByPath\n // cannot resolve them (issue #564 PR 3 review).\n const subtree =\n options.category === \"procedure\"\n ? \"procedures\"\n : options.category === \"reasoning_trace\"\n ? \"reasoning-traces\"\n : \"facts\";\n const idParts = options.memoryId.split(\"-\");\n const maybeTimestamp = Number(idParts[1]);\n if (Number.isFinite(maybeTimestamp) && maybeTimestamp > 0) {\n const day = new Date(maybeTimestamp).toISOString().slice(0, 10);\n return path.join(subtree, day, `${options.memoryId}.md`);\n }\n return path.join(subtree, `${options.memoryId}.md`);\n}\n\nfunction qmdMaintenanceSkipReasonForError(error: unknown): NamespaceMaintenanceSkipReason | null {\n const message = error instanceof Error ? error.message : String(error);\n return /^QMD (?:update|embed) skipped by .*min-interval gate$/.test(message)\n ? \"throttled\"\n : null;\n}\n\nexport class Orchestrator {\n readonly storage: StorageManager;\n private readonly storageRouter: NamespaceStorageRouter;\n /** Rebuildable namespace catalog (issue #1499). Inert unless namespaces enabled. */\n readonly namespaceCatalog: NamespaceCatalog;\n private readonly namespaceStorageDirHints = new Map<string, Set<string>>();\n private namespaceStorageDirHintsLoaded = false;\n private readonly namespaceSearchRouter: NamespaceSearchRouter;\n qmd: SearchBackend;\n private readonly conversationQmd?: ConversationQmdRuntime;\n private readonly conversationFaiss?: ReturnType<\n typeof createConversationIndexRuntime\n >[\"faiss\"];\n private readonly conversationIndexBackend?: ConversationIndexBackend;\n readonly sharedContext?: SharedContextManager;\n readonly compounding?: CompoundingEngine;\n readonly buffer: SmartBuffer;\n readonly transcript: TranscriptManager;\n readonly sessionObserver: SessionObserverState;\n readonly summarizer: HourlySummarizer;\n readonly localLlm: LocalLlmClient;\n readonly fastLlm: LocalLlmClient;\n private readonly judgeVerdictCache: Map<string, JudgeVerdict>;\n /**\n * Per-orchestrator defer-counter map (issue #562, PR 2). Tracks how many\n * times the judge has returned `\"defer\"` for a given candidate content\n * hash so the defer cap can be enforced.\n */\n private readonly judgeDeferCounts: Map<string, number>;\n /**\n * Side-channel: number of facts deferred in the most recent\n * `persistExtraction` call (issue #562, PR 2). The caller reads this after\n * `persistExtraction` returns to decide whether to retain buffer turns for\n * the next extraction pass. Not part of the return signature because many\n * callers already destructure `persistedIds` by position.\n */\n private lastPersistExtractionDeferredCount: number = 0;\n private readonly _fastGatewayLlm: FallbackLlmClient | null;\n\n get fastGatewayLlm(): FallbackLlmClient | null {\n return this._fastGatewayLlm;\n }\n readonly modelRegistry: ModelRegistry;\n readonly relevance: RelevanceStore;\n readonly negatives: NegativeExampleStore;\n readonly lastRecall: LastRecallStore;\n readonly tierMigrationStatus: TierMigrationStatusStore;\n /**\n * In-memory X-ray snapshot from the most recent `recall()` call that\n * was invoked with `xrayCapture: true` (issue #570 PR 1). Scope is\n * per-process; later slices add CLI/HTTP/MCP surfaces that consume\n * this via the shared renderer. `null` until the first capture, and\n * NEVER overwritten by a recall that did not request capture —\n * requests without the flag leave prior captures intact so the\n * capturing caller can still read their snapshot back.\n */\n private lastXraySnapshot: RecallXraySnapshot | null = null;\n readonly embeddingFallback: EmbeddingFallback;\n private readonly conversationIndexDir: string;\n private readonly extraction: ExtractionEngine;\n readonly config: PluginConfig;\n readonly profiler: ProfilingCollector;\n private readonly threading: ThreadingManager;\n /** v8.2: Per-namespace multi-graph memory indexes (entity/time/causal edges) */\n private readonly graphIndexes = new Map<string, GraphIndex>();\n /** Per-namespace BoxBuilders, keyed by the namespace root directory path. */\n private readonly boxBuilders = new Map<string, BoxBuilder>();\n /** Temporal Memory Tree builder — builds hour/day/week/persona summary nodes. */\n private readonly tmtBuilder: TmtBuilder;\n /** Lossless Context Management engine — proactive session archive + DAG summarization. */\n readonly lcmEngine: LcmEngine | null = null;\n private readonly rerankCache = new RerankCache();\n\n /**\n * Short-TTL cache for Memory Worth counter lookups so interactive recall\n * doesn't trigger a full `readAllMemories` scan per query. Keyed by\n * namespace; the filter unions across namespaces at query time. The TTL\n * is intentionally short (seconds, not minutes) because counters are\n * mutated by `recordMemoryOutcome` asynchronously and we'd rather serve\n * a 30-second-stale worth score than a stable-but-wrong one.\n */\n private readonly memoryWorthCounterCache = new Map<\n string,\n { at: number; counters: ReadonlyMap<string, MemoryWorthCounters> }\n >();\n private static readonly MEMORY_WORTH_CACHE_TTL_MS = 30_000;\n /**\n * Per-session workspace selections keyed by sessionKey.\n * Set by the before_agent_start hook so recall() uses the correct\n * agent workspace for BOOT.md injection. Cleared after each recall.\n * Using a Map prevents concurrent sessions from overwriting each other.\n */\n private _recallWorkspaceOverrides = new Map<string, string>();\n /**\n * Per-session coding-agent context (issue #569). Populated by connectors at\n * session-start (PRs 5/6/7) via `setCodingContextForSession`. Used by both\n * the recall path and the write path so that memory routing respects the\n * project/branch scope a session is operating in (rule 42 — read + write\n * through the same namespace layer).\n */\n private readonly _codingContextBySession = new Map<string, CodingContext>();\n /**\n * Per-session peer ID registry (issue #679 PR 3/5).\n * Set by connectors / hooks via `setPeerIdForSession` so `recallInternal`\n * can inject the peer's profile into recall context when\n * `peerProfileRecallEnabled` is true. Cleared when the session ends.\n * Keyed by sessionKey so concurrent sessions don't clobber each other\n * (rule 11 — scope globals per plugin ID / session).\n */\n private readonly _peerIdBySession = new Map<string, string>();\n private routingRulesStore: RoutingRulesStore | null = null;\n private contentHashIndex: ContentHashIndex | null = null;\n private readonly contentHashIndexesByStorageDir = new Map<string, ContentHashIndex>();\n private readonly artifactSourceStatusCache = new WeakMap<\n StorageManager,\n {\n loadedAtMs: number;\n statusVersion: number;\n statuses: Map<string, \"active\" | \"superseded\" | \"archived\" | \"missing\">;\n }\n >();\n private static readonly ARTIFACT_STATUS_CACHE_TTL_MS = 60_000;\n\n // Access tracking buffer (Phase 1A)\n // Maps memoryId -> {count, lastAccessed} for batched updates\n private accessTrackingBuffer: Map<\n string,\n { count: number; lastAccessed: string }\n > = new Map();\n\n // Background serial queue for extractions (agent_end optimization)\n // Queue stores promises that resolve when extraction should run\n private extractionQueue: Array<() => Promise<void>> = [];\n private queueProcessing = false;\n private heartbeatObserverChains = new Map<string, Promise<void>>();\n private recentExtractionFingerprints = new Map<string, number>();\n private nonZeroExtractionsSinceConsolidation = 0;\n private lastConsolidationRunAtMs = 0;\n private consolidationInFlight = false;\n private readonly consolidationObservers = new Set<\n (observation: ConsolidationObservation) => Promise<void> | void\n >();\n private qmdMaintenanceTimer: NodeJS.Timeout | null = null;\n private wearablesServiceInstance: WearablesService | null = null;\n private wearablesAutoSyncHandle: { stop(): Promise<void> } | null = null;\n private qmdMaintenancePending = false;\n private qmdMaintenanceInFlight = false;\n private lastQmdEmbedAtMs = 0;\n private lastQmdEmbedAtMsByNamespace = new Map<string, number>();\n private lastQmdReprobeAtMs = 0;\n private tierMigrationInFlight = false;\n private lastTierMigrationRunAtMs = 0;\n private readonly conversationIndexLastUpdateAtMs = new Map<string, number>();\n private lastFileHygieneRunAtMs = 0;\n // Pattern-reinforcement cadence gate (issue #687 PR 2/4). Tracks the\n // last successful run so `runPatternReinforcement` can short-circuit\n // when the configured cadence has not elapsed. Keyed by namespace\n // so MCP-triggered runs in tenant A don't suppress runs in tenant B\n // (PR #730 review feedback, Codex P2). The default-tenant path\n // uses the empty-string key.\n private lastPatternReinforcementAtByNs = new Map<string, number>();\n private lastRecallFailureLogAtMs = 0;\n private lastRecallFailureAtMs = 0;\n private suppressedRecallFailures = 0;\n private readonly policyRuntime: PolicyRuntimeManager;\n private runtimePolicyValues: RuntimePolicyValues | null = null;\n private utilityRuntimeValues: UtilityRuntimeValues | null = null;\n private evalShadowWriteChain: Promise<void> = Promise.resolve();\n\n // Pending background observation-mode direct-answer annotations (#518).\n // Tracks fire-and-forget `annotateDirectAnswerTier` calls so callers (tests,\n // waitForDirectAnswerObservationIdle) can await settlement.\n private directAnswerObservationChain: Promise<void> = Promise.resolve();\n\n // Initialization gate: recall() awaits this before proceeding\n private initPromise: Promise<void> | null = null;\n private resolveInit: (() => void) | null = null;\n\n /**\n * Resolves when deferred initialization (QMD probe, warmup, caches, cron)\n * completes. CLI and http-serve callers that need `qmd.isAvailable()` to\n * reflect reality should `await orchestrator.deferredReady` after\n * `initialize()`. Gateway callers can ignore it — recall() degrades\n * gracefully when QMD isn't ready yet.\n *\n * Also resolves (without error) when `initialize()` throws before reaching\n * the deferred-init phase, so callers never hang on a permanently-pending\n * promise.\n *\n * Host adapters that need to tie deferred init to their stop() lifecycle\n * should `await orchestrator.deferredReady` before proceeding with teardown\n * to prevent background QMD/warmup/cron tasks from racing with shutdown.\n */\n deferredReady: Promise<void> = Promise.resolve();\n private resolveDeferredReady: (() => void) | null = null;\n private deferredInitAbort: AbortController | null = null;\n\n /**\n * Whether the deferred init's QMD startup sync completed successfully.\n * When false after deferredReady resolves, the server retry loop should\n * attempt startupSearchSync() even if `qmd.isAvailable()` is true —\n * availability only means probe succeeded, not that the index is current.\n */\n deferredSyncSucceeded = false;\n\n /**\n * Abort deferred initialization so background QMD sync/warmup stops\n * promptly on shutdown. Safe to call multiple times or before init.\n */\n abortDeferredInit(): void {\n if (this.deferredInitAbort) {\n this.deferredInitAbort.abort();\n this.deferredInitAbort = null;\n }\n }\n\n private async disposeSearchBackendIfNeeded(): Promise<void> {\n await (this.qmd as { dispose?: () => void | Promise<void> }).dispose?.();\n }\n\n /**\n * Stop background initialization and release runtime-owned handles.\n * Long-lived hosts should call this from their shutdown path; one-shot\n * commands should call it before returning to let Node exit naturally.\n */\n async destroy(): Promise<void> {\n this.abortDeferredInit();\n if (this.wearablesAutoSyncHandle) {\n // Aborts in-flight provider fetches and waits for the tick to\n // settle, so nothing is writing or reindexing past destroy().\n await this.wearablesAutoSyncHandle.stop();\n this.wearablesAutoSyncHandle = null;\n }\n if (this.qmdMaintenanceTimer) {\n clearTimeout(this.qmdMaintenanceTimer);\n this.qmdMaintenanceTimer = null;\n }\n this.qmdMaintenancePending = false;\n await this.namespaceSearchRouter.dispose();\n await this.disposeSearchBackendIfNeeded();\n if (this.conversationQmd && this.conversationQmd !== this.qmd) {\n await (this.conversationQmd as { dispose?: () => void | Promise<void> }).dispose?.();\n }\n }\n\n /** Set per-session workspace for the next recall() call (compaction reset). @internal */\n setRecallWorkspaceOverride(sessionKey: string, dir: string): void {\n this._recallWorkspaceOverrides.set(sessionKey, dir);\n }\n\n /** Remove a per-session workspace selection (cleanup on error or early return). @internal */\n clearRecallWorkspaceOverride(sessionKey: string): void {\n this._recallWorkspaceOverrides.delete(sessionKey);\n }\n\n resolvePrincipal(sessionKey?: string): string | undefined {\n return resolvePrincipal(sessionKey, this.config);\n }\n\n resolveSelfNamespace(sessionKey?: string): string {\n const base = defaultNamespaceForPrincipal(\n this.resolvePrincipal(sessionKey),\n this.config,\n );\n return this.applyCodingNamespaceOverlay(sessionKey, base);\n }\n\n /**\n * Effective namespace a same-session LCM/structured-history READER must use\n * to find what the access `observe` surface WROTE (#1495 thread 2).\n *\n * This MUST mirror the `observe` scope plan's write-namespace resolution, NOT\n * `resolveSelfNamespace`: when no coding overlay applies, `observe` archives\n * under `config.defaultNamespace` (an unqualified observed turn is NOT moved\n * to the principal self namespace — identical to\n * `resolveCodingScopedWriteNamespace`/`memory_store`, rule 39). Only when a\n * coding overlay actually changes the namespace does the writer (and so the\n * reader) use the overlaid `project-*` namespace. Returning the self base for\n * the no-overlay case would prefix the read key with a namespace the writer\n * never used, so the reader would miss its own evidence.\n *\n * Honours the access-surface `principalOverride` (#1505 thread 2, codex): when\n * a recall supplies an authenticated principal NOT encoded in the raw\n * `sessionKey`, `observe` archived LCM under THAT principal's base namespace.\n * Deriving the base from `resolvePrincipal(sessionKey)` alone could fall back\n * to `default`, so principal `alice` observing `sess-1` would write under\n * `alice` but READ under `default`. Threading the override here keeps the read\n * base identical to the write base.\n *\n * READ-AUTHORIZATION gate (#1505 round 3, codex P2 \"Gate LCM recall keys by\n * readable namespaces\"): the overlay LCM read key is a `<principal>-project-*`\n * sub-namespace of the principal SELF base. The normal recall namespace set\n * below only substitutes the coding overlay when the principal SELF base is\n * actually in the readable recall set (`recallNamespacesForPrincipal` — gated\n * by `defaultRecallNamespaces.includes(\"self\")` AND `canReadNamespace`). If a\n * principal can WRITE but not READ its self namespace (or `defaultRecall-\n * Namespaces` omits `self`), QMD/file recall never touches those overlay rows,\n * so neither may the LCM read key. When the self base is NOT readable, fall\n * back to the default store — exactly what an unqualified, unauthorized recall\n * resolves to — rather than injecting overlay rows the rest of recall excludes\n * (rule 42 read/write parity; rule 48 least-privilege).\n */\n private lcmReadNamespaceForSession(\n sessionKey?: string,\n principalOverride?: string,\n ): string {\n const principal =\n typeof principalOverride === \"string\" && principalOverride.length > 0\n ? principalOverride\n : this.resolvePrincipal(sessionKey);\n const base = defaultNamespaceForPrincipal(principal, this.config);\n const overlaid = this.applyCodingNamespaceOverlay(sessionKey, base);\n // No overlay → collapse to the default store so the LCM key is the raw\n // sessionKey, exactly what an unqualified observe archived under.\n if (overlaid === base) return this.config.defaultNamespace;\n // Overlay applied. Only honour it when the principal SELF base is in the\n // readable recall set (same gate the recall namespace set uses to\n // substitute the overlay). Otherwise the overlay rows are unauthorized for\n // this reader — fall back to the default store so the LCM read matches\n // what QMD/file recall would surface.\n const selfReadableInRecall = recallNamespacesForPrincipal(\n principal,\n this.config,\n ).includes(base);\n return selfReadableInRecall ? overlaid : this.config.defaultNamespace;\n }\n\n /**\n * Attach a coding-agent context to a session (issue #569). Called by the\n * Claude Code / Codex / Cursor connectors at session start after\n * `resolveGitContext(cwd)`. The context is consulted by the recall path\n * and the write path so that memories route to a project- (and optionally\n * branch-) scoped namespace.\n *\n * Pass `null` to clear.\n */\n setCodingContextForSession(sessionKey: string, codingContext: CodingContext | null): void {\n if (typeof sessionKey !== \"string\" || sessionKey.length === 0) return;\n // Defensive init — `Object.create(Orchestrator.prototype)` stubs in\n // legacy tests skip class-field initializers (rule 16 applies to test\n // teardown; we apply the same defensiveness on construction here so\n // PR 2 doesn't break those tests).\n if (!this._codingContextBySession) {\n (this as unknown as { _codingContextBySession: Map<string, CodingContext> })._codingContextBySession = new Map();\n }\n if (codingContext === null) {\n this._codingContextBySession.delete(sessionKey);\n return;\n }\n this._codingContextBySession.set(sessionKey, codingContext);\n }\n\n /**\n * Read-only accessor for the coding context attached to a session. Returns\n * `null` when none is set. Used by `remnic doctor` and by tests.\n *\n * Defensive `_codingContextBySession` lookup — legacy orchestrator-flush\n * tests use `Object.create(Orchestrator.prototype)` which does not run\n * class-field initializers, so the Map may be undefined on stubs.\n */\n getCodingContextForSession(sessionKey: string | undefined): CodingContext | null {\n if (typeof sessionKey !== \"string\" || sessionKey.length === 0) return null;\n return this._codingContextBySession?.get(sessionKey) ?? null;\n }\n\n /**\n * Shared helper used by both the recall path and the write path (rule 42).\n *\n * Given a base namespace computed from the principal, returns the overlaid\n * coding namespace when the session has a coding context AND\n * `codingMode.projectScope` is true AND `namespacesEnabled` is true.\n * Otherwise returns `baseNamespace` unchanged — CLAUDE.md #30 escape hatch.\n *\n * Principal isolation (CLAUDE.md rule 42): the overlay is COMBINED with\n * the principal-derived `baseNamespace` rather than replacing it, so two\n * principals working in the same repository do not share memories through\n * a common `project-*` namespace.\n *\n * Namespaces-disabled gate: when `namespacesEnabled` is false, the\n * storage router maps every namespace to the same `memoryDir`. Returning\n * `project-*` in that mode would create apparent route separation with\n * no actual storage isolation — a false-isolation trap. In that mode we\n * return `baseNamespace` unchanged so coding mode degrades to the existing\n * unscoped behavior.\n *\n * @internal\n */\n applyCodingNamespaceOverlay(sessionKey: string | undefined, baseNamespace: string): string {\n if (!this.config.namespacesEnabled) return baseNamespace;\n const codingContext = this.getCodingContextForSession(sessionKey);\n const overlay = resolveCodingNamespaceOverlay(codingContext, this.config.codingMode, this.config.defaultNamespace);\n if (!overlay) return baseNamespace;\n return combineNamespaces(baseNamespace, overlay.namespace);\n }\n\n /**\n * Register a peer ID for a session so recall can inject the peer's\n * profile into context (issue #679 PR 3/5). Pass `null` to clear.\n *\n * Connectors and the `before_agent_start` hook call this when the\n * session's counter-party is known. The ID is validated against\n * `PEER_ID_PATTERN` before storing.\n *\n * Fail-closed (Codex P1 review): an invalid peerId clears any\n * previously registered mapping for the session rather than silently\n * keeping stale data. This prevents a malformed metadata update from\n * mixing one peer's profile context into another session.\n *\n * Defensive init (Cursor review + rule 16): `Object.create(\n * Orchestrator.prototype)` stubs in legacy tests skip class-field\n * initializers, so `_peerIdBySession` may be undefined. Mirror the\n * same guard used by `setCodingContextForSession`.\n */\n setPeerIdForSession(sessionKey: string, peerId: string | null): void {\n if (typeof sessionKey !== \"string\" || sessionKey.length === 0) return;\n // Defensive init — mirrors setCodingContextForSession (rule 16).\n if (!this._peerIdBySession) {\n (this as unknown as { _peerIdBySession: Map<string, string> })._peerIdBySession = new Map();\n }\n if (peerId === null) {\n this._peerIdBySession.delete(sessionKey);\n return;\n }\n // Basic pattern guard — full validation lives in peers/storage.ts.\n // Invalid input is fail-closed: clear the existing mapping so stale\n // peer context can't bleed in after a bad metadata update (Codex P1).\n if (\n typeof peerId !== \"string\" ||\n peerId.length === 0 ||\n peerId.length > 64 ||\n !/^[A-Za-z0-9]+(?:[._-][A-Za-z0-9]+)*$/.test(peerId)\n ) {\n log.warn(`setPeerIdForSession: invalid peerId — clearing session mapping`);\n this._peerIdBySession.delete(sessionKey);\n return;\n }\n this._peerIdBySession.set(sessionKey, peerId);\n }\n\n /**\n * Return the peer ID registered for a session, or `null` when none\n * is set. Used by `recallInternal` to inject the peer profile section.\n * Defensive `_peerIdBySession` lookup — legacy orchestrator-flush tests\n * use `Object.create(Orchestrator.prototype)` which skips class-field\n * initializers, so the Map may be undefined on stubs.\n */\n getPeerIdForSession(sessionKey: string | undefined): string | null {\n if (typeof sessionKey !== \"string\" || sessionKey.length === 0) return null;\n return this._peerIdBySession?.get(sessionKey) ?? null;\n }\n\n /**\n * Read-side overlay: returns the list of namespaces a session should read\n * from, including any read fallbacks (branch → project, global root).\n *\n * Returns `null` when:\n * - `namespacesEnabled` is false (overlay would create false isolation)\n * - no context attached to the session\n * - `codingMode.projectScope` is false (CLAUDE.md #30 escape hatch)\n *\n * The returned `namespace` / `readFallbacks` are RAW overlay fragments\n * (e.g. `project-origin-ab12`). Callers MUST combine them with the\n * principal-derived base through `combineNamespaces()` before passing to\n * storage, so principal isolation is preserved (rule 42).\n *\n * @internal\n */\n applyCodingRecallOverlay(sessionKey: string | undefined): { namespace: string; readFallbacks: string[] } | null {\n if (!this.config.namespacesEnabled) return null;\n const codingContext = this.getCodingContextForSession(sessionKey);\n const overlay = resolveCodingNamespaceOverlay(codingContext, this.config.codingMode, this.config.defaultNamespace);\n if (!overlay) return null;\n return { namespace: overlay.namespace, readFallbacks: overlay.readFallbacks };\n }\n\n async getStorageForNamespace(namespace?: string): Promise<StorageManager> {\n const ns =\n typeof namespace === \"string\" && namespace.trim().length > 0\n ? namespace.trim()\n : this.config.defaultNamespace;\n return this.storageRouter.storageFor(ns);\n }\n\n private configuredNamespaces(): string[] {\n return Array.from(\n new Set(\n [\n this.config.defaultNamespace,\n this.config.sharedNamespace,\n ...this.config.namespacePolicies.map((policy) => policy.name),\n ]\n .map((value) => value.trim())\n .filter(Boolean),\n ),\n );\n }\n\n private rememberNamespaceStorageDirHint(namespace: string, storageDir?: string): void {\n if (!this.config.namespacesEnabled || !storageDir) return;\n const ns = normalizeNamespaceIdentity(namespace);\n if (!ns) return;\n const defaultNs = normalizeNamespaceIdentity(this.config.defaultNamespace);\n if (ns !== defaultNs && !isSafeRouteNamespace(ns)) return;\n\n if (!this.storageDirMatchesNamespaceHint(ns, storageDir)) return;\n\n const resolvedStorageDir = path.resolve(storageDir);\n let hints = this.namespaceStorageDirHints.get(resolvedStorageDir);\n if (!hints) {\n hints = new Set<string>();\n this.namespaceStorageDirHints.set(resolvedStorageDir, hints);\n }\n hints.add(ns);\n }\n\n private storageDirMatchesNamespaceHint(namespace: string, storageDir: string): boolean {\n const ns = normalizeNamespaceIdentity(namespace);\n if (!ns) return false;\n\n const resolvedStorageDir = path.resolve(storageDir);\n const resolvedMemoryDir = path.resolve(this.config.memoryDir);\n const defaultNs = normalizeNamespaceIdentity(this.config.defaultNamespace);\n if (resolvedStorageDir === resolvedMemoryDir) return ns === defaultNs;\n\n const resolvedNamespacesDir = path.join(resolvedMemoryDir, \"namespaces\");\n if (!isPathInsideStorageRoot(resolvedNamespacesDir, resolvedStorageDir)) return false;\n\n const rawRoot = path.resolve(resolvedNamespacesDir, ns);\n const tokenRoot = path.resolve(resolvedNamespacesDir, namespaceIdentityToken(ns));\n return resolvedStorageDir === rawRoot || resolvedStorageDir === tokenRoot;\n }\n\n private namespaceStorageDirHintOwnershipRank(\n record: { namespace: string },\n resolvedStorageDir: string,\n configured: Set<string>,\n ): number {\n if (resolvedStorageDir === path.resolve(this.config.memoryDir)) {\n return record.namespace === normalizeNamespaceIdentity(this.config.defaultNamespace)\n ? 0\n : 3;\n }\n\n const leaf = path.basename(resolvedStorageDir);\n const tokenOwnsRoot = namespaceIdentityToken(record.namespace) === leaf;\n if (tokenOwnsRoot && configured.has(record.namespace)) return 0;\n if (record.namespace === leaf) return 1;\n if (tokenOwnsRoot) return 2;\n return 3;\n }\n\n private preferNamespaceStorageDirHintOwner(\n current: { namespace: string; identityToken: string; storageDir: string },\n candidate: { namespace: string; identityToken: string; storageDir: string },\n resolvedStorageDir: string,\n configured: Set<string>,\n ): { namespace: string; identityToken: string; storageDir: string } {\n const currentRank = this.namespaceStorageDirHintOwnershipRank(\n current,\n resolvedStorageDir,\n configured,\n );\n const candidateRank = this.namespaceStorageDirHintOwnershipRank(\n candidate,\n resolvedStorageDir,\n configured,\n );\n if (candidateRank < currentRank) return candidate;\n if (candidateRank > currentRank) return current;\n\n const byName = candidate.namespace.localeCompare(current.namespace);\n if (byName < 0) return candidate;\n if (byName > 0) return current;\n return candidate.identityToken.localeCompare(current.identityToken) < 0\n ? candidate\n : current;\n }\n\n private loadNamespaceStorageDirHintsFromCatalog(): void {\n if (this.namespaceStorageDirHintsLoaded || !this.namespaceCatalog.enabled) return;\n this.namespaceStorageDirHintsLoaded = true;\n const catalogPath = path.join(this.config.memoryDir, \"state\", \"namespaces.jsonl\");\n if (!existsSync(catalogPath)) return;\n\n let body: string;\n try {\n body = readFileSync(catalogPath, \"utf8\");\n } catch {\n return;\n }\n\n const compactedByNamespace = new Map<\n string,\n { namespace: string; identityToken: string; storageDir: string }\n >();\n for (const line of body.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n try {\n const parsed = JSON.parse(trimmed) as unknown;\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) continue;\n const record = parsed as Record<string, unknown>;\n if (\n typeof record.namespace !== \"string\" ||\n typeof record.storageDir !== \"string\" ||\n typeof record.identityToken !== \"string\"\n ) {\n continue;\n }\n const namespace = normalizeNamespaceIdentity(record.namespace);\n if (!namespace || record.identityToken !== namespaceIdentityToken(namespace)) continue;\n compactedByNamespace.set(namespace, {\n namespace,\n identityToken: record.identityToken,\n storageDir: record.storageDir,\n });\n } catch {\n // Catalog hints are best-effort. The catalog reader still owns full recovery.\n }\n }\n\n const configured = new Set(\n this.configuredNamespaces().map((namespace) => normalizeNamespaceIdentity(namespace)),\n );\n const preferredByStorageDir = new Map<\n string,\n { namespace: string; identityToken: string; storageDir: string }\n >();\n for (const record of compactedByNamespace.values()) {\n if (!this.storageDirMatchesNamespaceHint(record.namespace, record.storageDir)) {\n continue;\n }\n const resolvedStorageDir = path.resolve(record.storageDir);\n const current = preferredByStorageDir.get(resolvedStorageDir);\n preferredByStorageDir.set(\n resolvedStorageDir,\n current\n ? this.preferNamespaceStorageDirHintOwner(\n current,\n record,\n resolvedStorageDir,\n configured,\n )\n : record,\n );\n }\n for (const record of preferredByStorageDir.values()) {\n this.rememberNamespaceStorageDirHint(record.namespace, record.storageDir);\n }\n }\n\n /**\n * Shared namespace maintenance planner (issue #1500). This extends the\n * #1499 catalog-union QMD helper into a reusable contract: configured\n * namespaces are always considered, dynamic catalog namespaces are admitted\n * only when their live router root still matches real memory data, and branch\n * namespaces are opt-in. Recurring jobs use the per-cycle budget; startup and\n * recovery discovery paths use the same safety filters without that cycle\n * budget so every live namespace is ensured/synced.\n */\n private async namespaceMaintenancePlan(jobName: string): Promise<NamespaceMaintenancePlan> {\n return planNamespaceMaintenance(this.config, {\n jobName,\n catalog: this.namespaceCatalog,\n });\n }\n\n private async maintenanceNamespaces(\n jobName = \"qmd\",\n budgetMode: \"cycle\" | \"unbounded\" = \"unbounded\",\n ): Promise<string[]> {\n const plan = await planNamespaceMaintenance(this.config, {\n jobName,\n catalog: this.namespaceCatalog,\n budgetMode,\n });\n return plan.namespaces.map((candidate) => candidate.namespace);\n }\n\n private buildConfiguredQmdSearchOptions(\n queryText: string,\n ): SearchQueryOptions | undefined {\n const intentHint = this.config.qmdIntentHintsEnabled\n ? buildQmdIntentHint(inferIntentFromText(queryText))\n : undefined;\n const explain = this.config.qmdExplainEnabled === true;\n const searchOptions: SearchQueryOptions = {};\n if (intentHint) {\n searchOptions.intent = intentHint;\n }\n if (explain) {\n searchOptions.explain = true;\n }\n return Object.keys(searchOptions).length > 0 ? searchOptions : undefined;\n }\n\n async searchAcrossNamespaces(options: {\n query: string;\n namespaces?: string[];\n maxResults?: number;\n mode?: \"search\" | \"hybrid\" | \"bm25\" | \"vector\";\n searchOptions?: SearchQueryOptions;\n execution?: SearchExecutionOptions;\n }): Promise<QmdSearchResult[]> {\n if (\n this.config.namespacesEnabled &&\n options.namespaces !== undefined &&\n options.namespaces.length === 0\n ) {\n return [];\n }\n const namespaces = this.config.namespacesEnabled\n ? Array.from(\n new Set(\n (options.namespaces?.length\n ? options.namespaces\n : this.configuredNamespaces()\n )\n .map((value) => value.trim())\n .filter(Boolean),\n ),\n )\n : [this.config.defaultNamespace];\n\n if (!this.config.namespacesEnabled) {\n switch (options.mode) {\n case \"hybrid\":\n return await this.qmd.hybridSearch(\n options.query,\n undefined,\n options.maxResults,\n options.execution,\n );\n case \"bm25\":\n return await this.qmd.bm25Search(\n options.query,\n undefined,\n options.maxResults,\n options.execution,\n );\n case \"vector\":\n return await this.qmd.vectorSearch(\n options.query,\n undefined,\n options.maxResults,\n options.execution,\n );\n default:\n return await this.qmd.search(\n options.query,\n undefined,\n options.maxResults,\n options.searchOptions,\n options.execution,\n );\n }\n }\n\n return await this.namespaceSearchRouter.searchAcrossNamespaces({\n query: options.query,\n namespaces,\n maxResults: options.maxResults,\n mode: options.mode,\n searchOptions: options.searchOptions,\n execution: options.execution,\n });\n }\n\n async searchHealthForNamespace(\n namespace: string,\n execution?: SearchExecutionOptions,\n ): Promise<NamespaceSearchHealth> {\n return await this.namespaceSearchRouter.healthForNamespace(namespace, execution);\n }\n\n private isSearchAvailableForNamespaceRouting(): boolean {\n if (this.config.namespacesEnabled) return true;\n return this.qmd.isAvailable();\n }\n\n invalidateLiveContentHashIndex(): void {\n this.contentHashIndex = null;\n this.contentHashIndexesByStorageDir.clear();\n }\n\n private async contentHashIndexForStorage(\n targetStorage: StorageManager,\n ): Promise<ContentHashIndex | null> {\n if (!this.config.factDeduplicationEnabled) return null;\n\n if (targetStorage.dir === this.storage.dir) {\n if (!this.contentHashIndex) {\n this.contentHashIndex = this.storage.createContentHashIndex();\n await this.contentHashIndex.load();\n }\n return this.contentHashIndex;\n }\n\n const cached = this.contentHashIndexesByStorageDir.get(targetStorage.dir);\n if (cached) return cached;\n\n const index = targetStorage.createContentHashIndex();\n await index.load();\n this.contentHashIndexesByStorageDir.set(targetStorage.dir, index);\n log.info(\n `content-hash dedup: loaded ${index.size} hashes for storage ${targetStorage.dir}`,\n );\n return index;\n }\n\n private async hasContentHashDedup(\n targetStorage: StorageManager,\n content: string,\n ): Promise<boolean> {\n const index = await this.contentHashIndexForStorage(targetStorage);\n return index ? index.has(content) : false;\n }\n\n private async addContentHashDedup(\n targetStorage: StorageManager,\n content: string,\n ): Promise<void> {\n const index = await this.contentHashIndexForStorage(targetStorage);\n if (!index) return;\n index.add(content);\n }\n\n private async removeContentHashForMemory(\n targetStorage: StorageManager,\n memory: MemoryFile,\n context: string,\n ): Promise<void> {\n const index = await this.contentHashIndexForStorage(targetStorage);\n if (!index) return;\n\n if (memory.frontmatter.contentHash) {\n index.removeByHash(memory.frontmatter.contentHash);\n return;\n }\n\n log.warn(\n `[${context}] removing hash for legacy memory ${memory.frontmatter.id ?? \"(unknown)\"} via content fallback - no contentHash in frontmatter`,\n );\n index.remove(memory.content);\n }\n\n private async saveContentHashIndexes(): Promise<void> {\n const indexes = new Set<ContentHashIndex>();\n if (this.contentHashIndex) indexes.add(this.contentHashIndex);\n for (const index of this.contentHashIndexesByStorageDir.values()) {\n indexes.add(index);\n }\n for (const index of indexes) {\n await index.save();\n }\n }\n\n constructor(config: PluginConfig) {\n this.config = config;\n this.profiler = new ProfilingCollector({\n enabled: config.profilingEnabled,\n storageDir: config.profilingStorageDir || path.join(config.memoryDir, \"profiling\"),\n maxTraces: config.profilingMaxTraces,\n });\n // Namespace catalog (issue #1499): downstream, rebuildable metadata index.\n // Inert unless namespacesEnabled is true. Storage resolution registers\n // namespaces via the router's onResolve hook; the touch is best-effort and\n // a catalog write failure never affects storage resolution.\n this.namespaceCatalog = new NamespaceCatalog(config);\n this.storageRouter = new NamespaceStorageRouter(config, {\n // Return the registration promise (round 6, codex P2 — NEFoX) so the\n // router's resolve-hook dedup only marks a namespace notified when the\n // catalog actually APPENDED. A dropped append (rebuild-lock timeout) or a\n // failure resolves to `false`/rejects, so the next `storageFor` retries.\n onResolve: (namespace, storageDir) => {\n this.rememberNamespaceStorageDirHint(namespace, storageDir);\n return this.namespaceCatalog.registerResolved(namespace, storageDir);\n },\n });\n this.namespaceSearchRouter = new NamespaceSearchRouter(\n config,\n this.storageRouter,\n );\n this.storage = new StorageManager(config.memoryDir, config.entitySchemas);\n // Propagate the inline-attribution template so the storage layer can strip\n // citations from legacy facts during the hash-index rebuild path.\n this.storage.citationTemplate = config.inlineSourceAttributionFormat;\n // Wire page-level versioning (issue #371)\n this.storage.setVersioningConfig({\n enabled: config.versioningEnabled,\n maxVersionsPerPage: config.versioningMaxPerPage,\n sidecarDir: config.versioningSidecarDir,\n });\n // Wire at-rest encryption (issue #690 PR 3/4).\n // If secureStoreEnabled, check whether the keyring already holds a key\n // for this memory dir (e.g. operator unlocked before daemon restart).\n if (config.secureStoreEnabled) {\n // Mark the store as required so writes throw SecureStoreLockedError\n // instead of silently falling back to plaintext when locked (P1 finding\n // from Cursor review of PR #767).\n this.storage.setSecureStoreRequired(true);\n const storeId = secureStoreDir(config.memoryDir);\n const existingKey = keyring.getKey(storeId);\n if (existingKey) {\n this.storage.setSecureStoreKey(existingKey, config.secureStoreEncryptOnWrite);\n }\n // If no key is present the store remains locked until `remnic secure-store unlock`\n // is run — reads of encrypted files will throw SecureStoreLockedError,\n // and writes will throw SecureStoreLockedError via resolveWriteKey().\n }\n this.qmd = createSearchBackend(config);\n const conversationIndexRuntime = createConversationIndexRuntime(config, {\n getQmd: () => this.conversationQmd,\n getFaiss: () => this.conversationFaiss,\n });\n this.conversationQmd = conversationIndexRuntime.qmd;\n this.conversationFaiss = conversationIndexRuntime.faiss;\n this.conversationIndexBackend = conversationIndexRuntime.backend;\n this.sharedContext = config.sharedContextEnabled\n ? new SharedContextManager(config)\n : undefined;\n this.compounding = config.compoundingEnabled\n ? new CompoundingEngine(config, this.storage)\n : undefined;\n this.buffer = new SmartBuffer(config, this.storage);\n this.transcript = new TranscriptManager(config);\n this.conversationIndexDir = path.join(\n config.memoryDir,\n \"conversation-index\",\n \"chunks\",\n );\n this.modelRegistry = new ModelRegistry(config.memoryDir);\n this.relevance = new RelevanceStore(config.memoryDir);\n this.negatives = new NegativeExampleStore(config.memoryDir);\n this.lastRecall = new LastRecallStore(config.memoryDir);\n this.tierMigrationStatus = new TierMigrationStatusStore(config.memoryDir);\n this.sessionObserver = new SessionObserverState({\n memoryDir: config.memoryDir,\n debounceMs: config.sessionObserverDebounceMs ?? 120_000,\n bands: config.sessionObserverBands ?? [],\n });\n this.embeddingFallback = new EmbeddingFallback(config);\n this.policyRuntime = new PolicyRuntimeManager(config.memoryDir, config);\n this.summarizer = new HourlySummarizer(\n config,\n config.gatewayConfig,\n this.modelRegistry,\n this.transcript,\n );\n this.judgeVerdictCache = createVerdictCache();\n this.judgeDeferCounts = createDeferCountMap();\n this.localLlm = new LocalLlmClient(config, this.modelRegistry);\n // Issue #548: the main local-LLM client is used by extraction,\n // consolidation, and other structured-output tasks that gain\n // nothing from chain-of-thought reasoning. Apply the operator's\n // configured preference (default true) so thinking-capable models\n // skip reasoning tokens and avoid the common 60s extraction\n // timeout. Operators can set `localLlmDisableThinking: false`\n // when they want thinking enabled for narrative paths.\n this.localLlm.disableThinking = config.localLlmDisableThinking;\n this.fastLlm = config.localLlmFastEnabled\n ? (() => {\n const client = new LocalLlmClient(\n {\n ...config,\n localLlmModel: config.localLlmFastModel || config.localLlmModel,\n localLlmUrl: config.localLlmFastUrl,\n localLlmTimeoutMs: config.localLlmFastTimeoutMs,\n },\n this.modelRegistry,\n );\n // Fast-tier always suppresses thinking — the contract of\n // `fastLlm` is \"low latency at all costs\" and that is\n // independent of the main-client config.\n client.disableThinking = true;\n return client;\n })()\n : this.localLlm;\n // Initialize gateway fast LLM for fast-tier ops when modelSource is \"gateway\"\n this._fastGatewayLlm = config.modelSource === \"gateway\"\n ? new FallbackLlmClient(\n config.gatewayConfig,\n fallbackLlmRuntimeContextFromConfig(config),\n )\n : null;\n if (config.modelSource === \"gateway\") {\n log.debug(\n `orchestrator: gateway model source active` +\n (config.gatewayAgentId ? ` (primary: ${config.gatewayAgentId})` : \"\") +\n (config.fastGatewayAgentId ? ` (fast: ${config.fastGatewayAgentId})` : \"\"),\n );\n }\n this.extraction = new ExtractionEngine(\n config,\n this.profiler,\n this.localLlm,\n config.gatewayConfig,\n this.modelRegistry,\n );\n this.threading = new ThreadingManager(\n path.join(config.memoryDir, \"threads\"),\n config.threadingGapMinutes,\n );\n // BoxBuilders are created per-namespace on first use in runExtraction().\n\n // Temporal Memory Tree (v8.2) — lazy build during consolidation\n this.tmtBuilder = new TmtBuilder(config.memoryDir, {\n temporalMemoryTreeEnabled: config.temporalMemoryTreeEnabled,\n tmtHourlyMinMemories: config.tmtHourlyMinMemories,\n tmtSummaryMaxTokens: config.tmtSummaryMaxTokens,\n });\n\n // Lossless Context Management (LCM) — proactive session archive + DAG summarization\n if (config.lcmEnabled) {\n const summarizeFn = async (\n text: string,\n targetTokens: number,\n aggressive: boolean,\n ) => {\n const instructionText = aggressive\n ? `Compress the following into bullet points. One bullet per distinct fact or decision. Maximum ${targetTokens} tokens total. No prose.`\n : `Compress the following conversation segment into a dense summary. Preserve: decisions made, code artifacts mentioned, errors encountered, open questions, and any commitments or next-steps. Omit: pleasantries, restatements, and anything the agent would not need to recall later. Output a single paragraph, maximum ${targetTokens} tokens.`;\n try {\n const messages = [\n { role: \"system\" as const, content: instructionText },\n { role: \"user\" as const, content: text.slice(0, 12000) },\n ];\n const result = this.config.modelSource === \"gateway\" && this._fastGatewayLlm\n ? await this._fastGatewayLlm.chatCompletion(messages, {\n maxTokens: targetTokens * 2,\n timeoutMs: this.config.localLlmFastTimeoutMs,\n // LCM is latency-sensitive. A configured fast persona is the\n // explicit fast-tier route; otherwise use taskModelChain so LCM\n // avoids falling to an expensive gateway default. Issue #1473.\n ...(this.config.fastGatewayAgentId\n ? { agentId: this.config.fastGatewayAgentId }\n : gatewayTaskChainOptions(this.config)),\n })\n : await this.localLlm.chatCompletion(messages, {\n maxTokens: targetTokens * 2,\n operation: \"lcm-summarize\",\n priority: \"background\",\n });\n return result?.content ?? null;\n } catch {\n return null;\n }\n };\n this.lcmEngine = new LcmEngine(config, summarizeFn);\n }\n\n // Create init gate — recall() will await this before proceeding\n this.initPromise = new Promise<void>((resolve) => {\n this.resolveInit = resolve;\n });\n\n // deferredReady is NOT created here — the property initializer provides a\n // safe default (Promise.resolve()), and initialize() recreates it on every\n // call. Creating a pending promise in the constructor would be orphaned\n // since initialize() unconditionally overwrites it.\n }\n\n /** Get or create a BoxBuilder for the given namespace storage root (namespace-isolated). */\n private boxBuilderFor(storage: StorageManager): BoxBuilder {\n const dir = storage.dir;\n if (!this.boxBuilders.has(dir)) {\n this.boxBuilders.set(\n dir,\n new BoxBuilder(dir, {\n memoryBoxesEnabled: this.config.memoryBoxesEnabled,\n traceWeaverEnabled: this.config.traceWeaverEnabled,\n boxTopicShiftThreshold: this.config.boxTopicShiftThreshold,\n boxTimeGapMs: this.config.boxTimeGapMs,\n boxMaxMemories: this.config.boxMaxMemories,\n traceWeaverLookbackDays: this.config.traceWeaverLookbackDays,\n traceWeaverOverlapThreshold: this.config.traceWeaverOverlapThreshold,\n }),\n );\n }\n return this.boxBuilders.get(dir)!;\n }\n\n private effectiveRecencyWeight(): number {\n return applyRuntimeRetrievalPolicy(\n { recencyWeight: this.config.recencyWeight },\n this.runtimePolicyValues,\n ).recencyWeight;\n }\n\n private effectiveCronRecallInstructionHeavyTokenCap(): number {\n return (\n this.runtimePolicyValues?.cronRecallInstructionHeavyTokenCap ??\n this.config.cronRecallInstructionHeavyTokenCap\n );\n }\n\n private currentPolicyVersion(): string {\n const thresholds = this.effectiveLifecycleThresholds();\n const payload = {\n recencyWeight: this.effectiveRecencyWeight(),\n lifecyclePromoteHeatThreshold: thresholds.promoteHeatThreshold,\n lifecycleStaleDecayThreshold: thresholds.staleDecayThreshold,\n cronRecallInstructionHeavyTokenCap:\n this.effectiveCronRecallInstructionHeavyTokenCap(),\n utilityRankingBoostMultiplier:\n this.utilityRuntimeValues?.rankingBoostMultiplier ?? 1,\n utilityRankingSuppressMultiplier:\n this.utilityRuntimeValues?.rankingSuppressMultiplier ?? 1,\n utilityPromoteThresholdDelta:\n this.utilityRuntimeValues?.promoteThresholdDelta ?? 0,\n utilityDemoteThresholdDelta:\n this.utilityRuntimeValues?.demoteThresholdDelta ?? 0,\n };\n return createHash(\"sha256\")\n .update(JSON.stringify(payload))\n .digest(\"hex\")\n .slice(0, 12);\n }\n\n private effectiveLifecycleThresholds(): {\n promoteHeatThreshold: number;\n staleDecayThreshold: number;\n archiveDecayThreshold: number;\n } {\n const archiveDecayThreshold = this.config.lifecycleArchiveDecayThreshold;\n const staleDecayThreshold = Math.min(\n this.runtimePolicyValues?.lifecycleStaleDecayThreshold ??\n this.config.lifecycleStaleDecayThreshold,\n archiveDecayThreshold,\n );\n return {\n promoteHeatThreshold:\n this.runtimePolicyValues?.lifecyclePromoteHeatThreshold ??\n this.config.lifecyclePromoteHeatThreshold,\n staleDecayThreshold,\n archiveDecayThreshold,\n };\n }\n\n private routeEngineOptions(): RoutingEngineOptions {\n const allowedNamespaces = this.config.namespacesEnabled\n ? Array.from(\n new Set([\n this.config.defaultNamespace,\n this.config.sharedNamespace,\n ...this.config.namespacePolicies.map((policy) => policy.name),\n ]),\n )\n : [this.config.defaultNamespace];\n return { allowedNamespaces };\n }\n\n private getRoutingRulesStore(): RoutingRulesStore {\n if (!this.routingRulesStore) {\n this.routingRulesStore = new RoutingRulesStore(\n this.config.memoryDir,\n this.config.routingRulesStateFile,\n );\n }\n return this.routingRulesStore;\n }\n\n private async loadRoutingRules(): Promise<RouteRule[]> {\n if (!this.config.routingRulesEnabled) return [];\n try {\n return await this.getRoutingRulesStore().read(this.routeEngineOptions());\n } catch (err) {\n log.warn(\n `routing rules unavailable; fail-open to default writes: ${err}`,\n );\n return [];\n }\n }\n\n private async resolveArtifactSourceStatuses(\n storage: StorageManager,\n sourceIds: string[],\n ): Promise<Map<string, \"active\" | \"superseded\" | \"archived\" | \"missing\">> {\n const currentStatusVersion = storage.getMemoryStatusVersion();\n const cached = this.artifactSourceStatusCache.get(storage);\n let snapshot = cached;\n const isFresh =\n snapshot !== undefined &&\n Date.now() - snapshot.loadedAtMs <=\n Orchestrator.ARTIFACT_STATUS_CACHE_TTL_MS &&\n snapshot.statusVersion === currentStatusVersion;\n\n const rebuildSnapshot = async () => {\n const MAX_STABLE_READ_ATTEMPTS = 3;\n let latestStatuses = new Map<\n string,\n \"active\" | \"superseded\" | \"archived\" | \"missing\"\n >();\n let latestVersionAfter = storage.getMemoryStatusVersion();\n\n for (let attempt = 0; attempt < MAX_STABLE_READ_ATTEMPTS; attempt += 1) {\n const versionBefore = storage.getMemoryStatusVersion();\n const allMemories = await storage.readAllMemories();\n const versionAfter = storage.getMemoryStatusVersion();\n latestVersionAfter = versionAfter;\n latestStatuses = new Map(\n allMemories.map((m) => [\n m.frontmatter.id,\n (m.frontmatter.status ?? \"active\") as\n | \"active\"\n | \"superseded\"\n | \"archived\"\n | \"missing\",\n ]),\n );\n\n if (versionAfter === versionBefore) {\n const rebuilt = {\n loadedAtMs: Date.now(),\n statusVersion: versionAfter,\n statuses: latestStatuses,\n };\n this.artifactSourceStatusCache.set(storage, rebuilt);\n return rebuilt;\n }\n }\n\n // Sustained write churn: return latest read without caching a potentially torn snapshot.\n return {\n loadedAtMs: Date.now(),\n statusVersion: latestVersionAfter,\n statuses: latestStatuses,\n };\n };\n\n if (!isFresh) {\n snapshot = await rebuildSnapshot();\n } else {\n // Warm cache may miss brand-new sourceMemoryId values created after snapshot build.\n // Refresh once on-demand when unseen IDs are requested.\n const hasUnknownSourceIds = sourceIds.some(\n (id) => !snapshot?.statuses.has(id),\n );\n if (hasUnknownSourceIds) {\n snapshot = await rebuildSnapshot();\n }\n }\n\n // Persist negative lookups in the cached snapshot so stale source IDs do not\n // trigger repeated full snapshot rebuilds on every matching recall.\n for (const id of sourceIds) {\n if (!snapshot?.statuses.has(id)) {\n snapshot?.statuses.set(id, \"missing\");\n }\n }\n\n const statuses = new Map<\n string,\n \"active\" | \"superseded\" | \"archived\" | \"missing\"\n >();\n for (const id of sourceIds) {\n const status = snapshot?.statuses.get(id);\n if (status) {\n statuses.set(id, status);\n } else {\n statuses.set(id, \"missing\");\n }\n }\n return statuses;\n }\n\n /**\n * Execute a fast-tier LLM chat completion.\n * When gateway model source is active and fastGatewayAgentId is configured,\n * routes through the gateway chain. Otherwise uses the local fast LLM.\n */\n private async fastChatCompletion(\n messages: Array<{ role: string; content: string }>,\n options: { temperature?: number; maxTokens?: number; timeoutMs?: number; operation?: string; priority?: \"background\" | \"recall-critical\" },\n ): Promise<{ content: string } | null> {\n if (this._fastGatewayLlm && this.config.modelSource === \"gateway\") {\n const agentId =\n this.config.fastGatewayAgentId || this.config.gatewayAgentId || undefined;\n const result = await this._fastGatewayLlm.chatCompletion(\n messages as Array<{ role: \"system\" | \"user\" | \"assistant\"; content: string }>,\n { temperature: options.temperature, maxTokens: options.maxTokens, timeoutMs: options.timeoutMs, agentId },\n );\n return result ? { content: result.content } : null;\n }\n const result = await this.fastLlm.chatCompletion(messages, {\n ...options,\n forceDisableThinking: true,\n });\n return result ? { content: result.content } : null;\n }\n\n /**\n * Get a fast-tier LLM client compatible with the rerank interface.\n * When gateway model source is active, routes through the gateway fast chain.\n * Otherwise returns the local fast LLM directly.\n */\n get fastLlmForRerank(): {\n chatCompletion: (\n messages: Array<{ role: string; content: string }>,\n options?: { maxTokens?: number; temperature?: number; timeoutMs?: number; operation?: string; priority?: \"recall-critical\" | \"background\" },\n ) => Promise<{ content: string } | null>;\n } {\n if (this._fastGatewayLlm && this.config.modelSource === \"gateway\") {\n return {\n chatCompletion: (messages, options) =>\n this.fastChatCompletion(messages, options ?? {}),\n };\n }\n return {\n chatCompletion: (messages, options) =>\n this.fastLlm.chatCompletion(messages, {\n ...(options ?? {}),\n forceDisableThinking: true,\n }),\n };\n }\n\n /**\n * Build a briefing follow-up generator backed by the configured LLM chain\n * (gateway model source or local LLM). Returns `undefined` when no chain\n * is available so `buildBriefing` can surface a clear unavailable reason\n * instead of failing at call time. Used by the access service and CLI as\n * the fallback when no direct `openaiApiKey` is configured, so briefing\n * follow-ups ride the same routing as every other fast-tier LLM feature.\n */\n get briefingChainFollowupGenerator(): BriefingFollowupGenerator | undefined {\n // Plugin mode gates on `localLlmEnabled` alone: `LocalLlmClient.chatCompletion`\n // returns null when the master switch is off, so `localLlmFastEnabled` by\n // itself cannot serve requests (Cursor review on PR #1463).\n const chainAvailable =\n this.config.modelSource === \"gateway\"\n ? this._fastGatewayLlm?.isAvailable(\n this.config.fastGatewayAgentId || this.config.gatewayAgentId || undefined,\n ) === true\n : this.config.localLlmEnabled;\n if (!chainAvailable) return undefined;\n return buildChainFollowupGenerator(this.fastLlmForRerank);\n }\n\n async initialize(): Promise<void> {\n // Recreate the deferred-ready gate on every initialize() call.\n // The same Orchestrator instance may be reused across stop/start cycles\n // (src/index.ts does this). Without this reset, the second cycle's\n // `await orchestrator.deferredReady` resolves immediately (already settled\n // from the first cycle) while the new deferredInitialize() is still running.\n this.deferredReady = new Promise<void>((resolve) => {\n this.resolveDeferredReady = resolve;\n });\n\n try {\n await migrateFromEngram({\n quiet: true,\n logger: (message) => log.info(message),\n });\n await this.storage.ensureDirectories();\n await this.storage.loadAliases();\n if (this.config.namespacesEnabled) {\n const namespaces = new Set<string>([\n this.config.defaultNamespace,\n this.config.sharedNamespace,\n ...this.config.namespacePolicies.map((p) => p.name),\n ]);\n for (const ns of namespaces) {\n const sm = await this.storageRouter.storageFor(ns);\n await sm.ensureDirectories();\n await sm.loadAliases().catch(() => undefined);\n }\n // Explicitly seed the catalog with all configured namespaces at startup\n // (round 6, cursor Medium — NBLlR). The storageFor loop above fires the\n // router's onResolve hook, but a warm router cache (reused instance\n // across stop/start) can skip onResolve, leaving policy namespaces absent\n // from the live catalog until an operator runs `rebuild --apply`. This\n // call is cheap, idempotent, and best-effort: a catalog failure must\n // never break initialization (rule #13, #40).\n await this.namespaceCatalog.registerConfiguredNamespaces().catch(() => undefined);\n }\n await this.relevance.load();\n await this.negatives.load();\n await this.lastRecall.load();\n await this.tierMigrationStatus.load();\n await this.sessionObserver.load();\n this.runtimePolicyValues = await this.policyRuntime.loadRuntimeValues();\n this.utilityRuntimeValues = await loadUtilityRuntimeValues({\n memoryDir: this.config.memoryDir,\n memoryUtilityLearningEnabled: this.config.memoryUtilityLearningEnabled,\n promotionByOutcomeEnabled: this.config.promotionByOutcomeEnabled,\n });\n\n // Initialize content-hash dedup index\n if (this.config.factDeduplicationEnabled) {\n this.contentHashIndex = this.storage.createContentHashIndex();\n await this.contentHashIndex.load();\n log.info(\n `content-hash dedup: loaded ${this.contentHashIndex.size} hashes`,\n );\n }\n await this.transcript.initialize();\n await this.summarizer.initialize();\n if (this.sharedContext) {\n await this.sharedContext.ensureStructure();\n }\n if (this.compounding) {\n await this.compounding.ensureDirs();\n }\n\n // Buffer and compaction cleanup are fast and needed for basic operation —\n // load them before the init gate so turn buffering works immediately.\n try {\n await this.buffer.load();\n } catch (bufErr) {\n log.error(\n `buffer.load() failed (init gate will still open): ${bufErr}`,\n );\n this.buffer.resetToEmpty();\n }\n if (this.config.compactionResetEnabled) {\n try {\n const wsDir = this.config.workspaceDir || defaultWorkspaceDir();\n const files = await readdir(wsDir).catch(() => [] as string[]);\n for (const f of files) {\n if (!f.startsWith(\".compaction-reset-signal-\")) continue;\n const fp = path.join(wsDir, f);\n const s = await stat(fp).catch(() => null);\n if (s && Date.now() - s.mtimeMs >= COMPACTION_SIGNAL_MAX_AGE_MS) {\n await unlink(fp).catch(() => {});\n log.debug(`initialize: removed stale compaction signal ${f}`);\n }\n }\n } catch (err) {\n log.debug(\"initialize: stale signal sweep failed:\", err);\n }\n }\n\n // QMD probe + collection check: determines the final QMD state (real\n // client vs NoopSearchBackend). Must complete BEFORE the init gate opens\n // so that recall() — which awaits initPromise — always observes the final\n // QMD state. Without this ordering, a concurrent recall() could read\n // this.qmd while it's still the real client, then get errors when\n // deferredInitialize() swaps it to NoopSearchBackend mid-query.\n try {\n const available = await this.qmd.probe();\n if (available) {\n log.info(`Search backend: available ${this.qmd.debugStatus()}`);\n // Ensure collections at startup for the catalog-union namespace set, not\n // just the configured set (issue #1499 sweep, same class as NHZEV): a\n // dynamic namespace that exists only in the persisted catalog must have\n // its QMD collection checked/ensured on boot so recall against it works\n // after a restart. `registerConfiguredNamespaces()` already seeded the\n // catalog above, so `maintenanceNamespaces()` is readable here; it falls\n // back to the configured set on any catalog read failure.\n const namespaces = this.config.namespacesEnabled\n ? await this.maintenanceNamespaces()\n : [this.config.defaultNamespace];\n const states = await Promise.all(\n namespaces.map(async (namespace) => {\n const collectionCheckAbort = new AbortController();\n const state = await qmdStartupCollectionCheckWithTimeout(\n this.config.namespacesEnabled\n ? this.namespaceSearchRouter.ensureNamespaceCollection(\n namespace,\n { signal: collectionCheckAbort.signal },\n )\n : this.qmd.ensureCollection(\n this.config.memoryDir,\n this.config.qmdCollection,\n { signal: collectionCheckAbort.signal },\n ),\n collectionCheckAbort,\n namespace,\n );\n return { namespace, state };\n }),\n );\n const defaultState =\n states.find(\n (entry) => entry.namespace === this.config.defaultNamespace,\n )?.state ?? \"unknown\";\n if (defaultState === \"missing\") {\n await this.disposeSearchBackendIfNeeded();\n this.qmd = new NoopSearchBackend();\n log.warn(\n \"Search collection missing for Remnic memory store; disabling search retrieval for this runtime (fallback retrieval remains enabled)\",\n );\n } else if (defaultState === \"unknown\") {\n log.warn(\n \"Search collection check unavailable; keeping search retrieval enabled for fail-open behavior\",\n );\n } else if (defaultState === \"skipped\") {\n log.debug(\n \"Search collection check skipped (remote or daemon-only mode)\",\n );\n }\n for (const entry of states) {\n if (entry.namespace === this.config.defaultNamespace) continue;\n if (entry.state === \"missing\") {\n log.warn(\n `Search collection missing for namespace '${entry.namespace}'; namespace retrieval will fail open to non-search paths`,\n );\n }\n }\n } else if (this.qmd instanceof NoopSearchBackend) {\n log.debug(`Search backend: noop (search intentionally disabled)`);\n } else {\n log.warn(`Search backend: not available ${this.qmd.debugStatus()}`);\n }\n } catch (err) {\n log.error(`QMD probe/collection check failed (non-fatal): ${err}`);\n }\n\n // Open the init gate — essential state (storage, aliases, relevance,\n // transcript, summarizer, buffer) is loaded AND QMD state is finalized\n // (probe + collection check complete, NoopSearchBackend swap done if\n // needed). Warmup, sync, caches, and remaining heavy operations run in\n // the background after this point via deferredInitialize().\n if (this.resolveInit) {\n this.resolveInit();\n this.resolveInit = null;\n log.info(\"init gate opened (essential state + QMD state loaded)\");\n }\n\n // Deferred init: QMD sync, warmup, conversation index, caches, cron.\n // Runs in background so gateway_start returns fast. On low-power hardware\n // (Umbrel, RPi) QMD warmup/sync alone can take 30-60s and cause gateway\n // restart loops when they block the startup path. See issue #462.\n // Note: QMD probe + collection check (including NoopSearchBackend swap)\n // already ran above before the init gate, so this.qmd is finalized.\n //\n // Capture the resolver by value so a concurrent re-initialize() cannot\n // overwrite this.resolveDeferredReady before .finally() runs — that would\n // cause the first cycle's .finally() to resolve the *second* cycle's\n // promise prematurely while leaving the first cycle's promise pending.\n const resolveDeferred = this.resolveDeferredReady;\n this.resolveDeferredReady = null;\n this.deferredInitAbort = new AbortController();\n this.deferredInitialize(this.deferredInitAbort.signal)\n .catch((err) => {\n log.error(`deferred initialization failed (non-fatal): ${err}`);\n })\n .finally(() => {\n resolveDeferred?.();\n });\n } catch (err) {\n // Resolve both gates so callers never hang on permanently-pending promises\n // after catching the initialize() error:\n //\n // - initPromise: recall(), generateDaySummary(), etc. await this as a\n // readiness gate with a 15s timeout. Leaving it pending means every\n // subsequent call pays that timeout penalty.\n //\n // - deferredReady: CLI callers await this for full QMD readiness. Without\n // resolution it hangs forever since deferredInitialize() never ran.\n if (this.resolveInit) {\n this.resolveInit();\n this.resolveInit = null;\n }\n if (this.resolveDeferredReady) {\n this.resolveDeferredReady();\n this.resolveDeferredReady = null;\n }\n throw err;\n }\n }\n\n private async deferredInitialize(signal: AbortSignal): Promise<void> {\n\n // Sync QMD index with current disk state so recall finds recently-written\n // facts. Without this, the index stays stale from the last extraction-\n // triggered update — which can be days ago if the daemon restarted without\n // new extractions. This is the root cause of \"0 memories\" recall results\n // despite thousands of facts on disk.\n if (this.qmd.isAvailable() && this.config.qmdMaintenanceEnabled) {\n try {\n log.info(\"QMD startup sync: updating index to match current disk state\");\n if (this.config.namespacesEnabled) {\n // Cover cataloged dynamic namespaces at startup too (NHZEV, codex P2):\n // a dynamic namespace written before a daemon restart must be synced on\n // boot, not only by the debounced runQmdMaintenance() path. Same union +\n // catalog-read-failure fallback as runQmdMaintenance.\n await this.namespaceSearchRouter.updateNamespaces(\n await this.maintenanceNamespaces(),\n { signal },\n );\n } else {\n await this.qmd.update({ signal });\n }\n log.info(\"QMD startup sync: complete\");\n this.deferredSyncSucceeded = true;\n } catch (err) {\n log.warn(`QMD startup sync failed (non-fatal): ${err}`);\n // deferredSyncSucceeded stays false — server retry will attempt sync\n }\n } else if (!(this.qmd.isAvailable())) {\n // QMD not available at deferred init time — server retry will handle it\n } else {\n // QMD available but maintenance disabled — consider sync not needed\n this.deferredSyncSucceeded = true;\n }\n\n if (signal.aborted) return;\n\n // Warmup: run cheap searches to pre-load QMD embedding models and the\n // embedding-fallback JSON index so the first real recall is fast.\n const warmupPromises: Promise<void>[] = [];\n if (this.qmd.isAvailable()) {\n const warmupNs = this.config.defaultNamespace;\n log.info(\"QMD warmup: pre-loading models with a test search\");\n warmupPromises.push(\n this.qmd\n .search(\"warmup\", warmupNs, 1, undefined, { signal })\n .then(() => {\n log.info(\"QMD warmup: complete\");\n })\n .catch((err) => {\n log.debug(`QMD warmup search failed (non-fatal): ${err}`);\n }),\n );\n }\n if (this.config.embeddingFallbackEnabled) {\n warmupPromises.push(\n this.embeddingFallback\n .isAvailable()\n .then((ok) => {\n log.info(\n `Embedding fallback warmup: ${ok ? \"available\" : \"unavailable (no provider)\"}`,\n );\n })\n .catch((err) => {\n log.debug(`Embedding fallback warmup failed (non-fatal): ${err}`);\n }),\n );\n }\n await Promise.all(warmupPromises);\n if (signal.aborted) return;\n\n // Pre-warm knowledge index, memory, and entity caches.\n // Awaited so callers of `deferredReady` can rely on warmups being complete\n // and shutdown sequencing does not race with in-flight cache builds.\n const cacheWarmups: Promise<void>[] = [];\n if (this.config.knowledgeIndexEnabled) {\n cacheWarmups.push(\n (async () => {\n try {\n const t0 = Date.now();\n await this.storage.buildKnowledgeIndex(this.config);\n log.info(`Knowledge Index warmup: complete in ${Date.now() - t0}ms`);\n } catch (err) {\n log.debug(`Knowledge Index warmup failed (non-fatal): ${err}`);\n }\n })(),\n );\n }\n cacheWarmups.push(this.storage.readAllMemories().then(() => {}).catch(() => {}));\n cacheWarmups.push(this.storage.readAllEntityFiles().then(() => {}).catch(() => {}));\n await Promise.all(cacheWarmups);\n if (signal.aborted) return;\n\n if (this.config.conversationIndexEnabled && this.conversationIndexBackend) {\n try {\n const init = await this.conversationIndexBackend.initialize();\n if (!init.enabled) {\n this.config.conversationIndexEnabled = false;\n }\n if (init.logLevel === \"info\") {\n log.info(init.message);\n } else if (init.logLevel === \"warn\") {\n log.warn(init.message);\n } else {\n log.debug(init.message);\n }\n } catch (err) {\n log.error(`Conversation index initialization failed (non-fatal): ${err}`);\n this.config.conversationIndexEnabled = false;\n }\n }\n\n if (signal.aborted) return;\n\n if (this.config.localLlmEnabled) {\n try {\n await this.validateLocalLlmModel();\n } catch (err) {\n log.error(`Local LLM validation failed (non-fatal): ${err}`);\n }\n }\n\n if (signal.aborted) return;\n\n // Await cron auto-registration so callers that `await deferredReady` can\n // rely on cron jobs being registered when it resolves. Without this, the\n // fire-and-forget pattern lets deferredReady settle while cron writes are\n // still in flight. Errors are non-fatal — catch individually.\n if (this.config.daySummaryEnabled) {\n try {\n await this.autoRegisterDaySummaryCron();\n } catch (err) {\n log.debug(`day-summary cron auto-register failed (non-fatal): ${err}`);\n }\n }\n if (this.config.nightlyGovernanceCronAutoRegister) {\n try {\n await this.autoRegisterNightlyGovernanceCron();\n } catch (err) {\n log.debug(`nightly governance cron auto-register failed (non-fatal): ${err}`);\n }\n }\n if (this.config.procedural?.proceduralMiningCronAutoRegister) {\n try {\n await this.autoRegisterProceduralMiningCron();\n } catch (err) {\n log.debug(`procedural mining cron auto-register failed (non-fatal): ${err}`);\n }\n }\n\n // Auto-register contradiction scan cron (gated by config)\n if (this.config.contradictionScan?.enabled) {\n try {\n await this.autoRegisterContradictionScanCron();\n } catch (err) {\n log.debug(`contradiction scan cron auto-register failed (non-fatal): ${err}`);\n }\n }\n\n // Auto-register pattern-reinforcement cron (issue #687 PR 2/4).\n // Gated on the feature flag so memory-only users without the\n // cron daemon installed never see a stray jobs.json mutation.\n if (this.config.patternReinforcementEnabled) {\n try {\n await this.autoRegisterPatternReinforcementCron();\n } catch (err) {\n log.debug(`pattern reinforcement cron auto-register failed (non-fatal): ${err}`);\n }\n }\n\n // Auto-register graph-edge decay cron (gated by config — issue #681 PR 2/3).\n if (this.config.graphEdgeDecayEnabled) {\n try {\n await this.autoRegisterGraphEdgeDecayCron();\n } catch (err) {\n log.debug(`graph edge decay cron auto-register failed (non-fatal): ${err}`);\n }\n }\n\n // First-start lifecycle migration (issue #686 retention-completion).\n // When lifecyclePolicyEnabled is true and the memoryDir has never been\n // touched by the lifecycle policy, run a one-time rate-limited demotion\n // sweep (capped at 50 demotions) so the hot tier isn't flooded on the\n // first real cron pass. Non-fatal — a failure here must not break init.\n if (signal.aborted) return;\n if (this.config.lifecyclePolicyEnabled && this.config.qmdTierMigrationEnabled) {\n try {\n const { runFirstStartMigration } = await import(\n \"./maintenance/first-start-migration.js\"\n );\n const result = await runFirstStartMigration({\n storage: this.storage,\n config: this.config,\n qmd: this.qmd,\n hotCollection: this.config.qmdCollection,\n coldCollection: this.config.qmdColdCollection,\n signal,\n });\n if (!result.skipped) {\n log.info(\n `first-start lifecycle migration: demoted ${result.demotedCount} of ${result.candidateCount} candidates (cap=${result.cappedAt})`,\n );\n } else {\n log.debug(`first-start lifecycle migration skipped: ${result.skipReason}`);\n }\n } catch (err) {\n log.warn(`first-start lifecycle migration failed (non-fatal): ${err}`);\n }\n }\n\n // Wearables auto-sync: in-process periodic transcript refresh for\n // long-lived hosts (default on). Today's transcript keeps growing\n // while the wearable records; a once-per-local-day deep pass picks\n // up late uploads and provider re-processing. Static config gate —\n // sources can't appear at runtime, so checking once here is safe.\n // The timer is unref'd, so one-shot CLI runs exit naturally without\n // ever ticking; idempotent across stop/start cycles via the handle\n // guard. Non-fatal: a failure to start must not break init.\n if (signal.aborted) return;\n if (\n !this.wearablesAutoSyncHandle &&\n this.config.wearables.enabled &&\n this.config.wearables.autoSyncEnabled &&\n Object.values(this.config.wearables.sources).some((source) => source.enabled)\n ) {\n try {\n const { startWearablesAutoSync } = await import(\"./wearables/auto-sync.js\");\n // Re-check after the await: destroy() may have aborted while\n // the import was in flight, having found no handle to stop —\n // starting now would leave a live interval on a destroyed\n // orchestrator (Cursor review on PR #1464). Handle creation\n // below is synchronous, so no further window exists.\n if (signal.aborted) return;\n this.wearablesAutoSyncHandle = startWearablesAutoSync(\n {\n intervalMinutes: this.config.wearables.autoSyncIntervalMinutes,\n days: this.config.wearables.autoSyncDays,\n deepDays: this.config.wearables.autoSyncDeepDays,\n ...(this.config.wearables.timezone !== undefined\n ? { timezone: this.config.wearables.timezone }\n : {}),\n },\n {\n sync: (options) => this.getWearablesService().sync(options),\n log: {\n info: (message) => log.info(message),\n warn: (message) => log.warn(message),\n },\n },\n );\n log.info(\n `wearables auto-sync started: every ${this.config.wearables.autoSyncIntervalMinutes}m over ${this.config.wearables.autoSyncDays}d (deep ${this.config.wearables.autoSyncDeepDays}d daily)`,\n );\n } catch (err) {\n const { displayErrorDetail } = await import(\"./runtime/better-sqlite.js\");\n log.warn(\n `wearables auto-sync failed to start (non-fatal): ${displayErrorDetail(err)}`,\n );\n }\n }\n\n log.info(\"orchestrator initialized (full — deferred steps complete)\");\n }\n\n /**\n * Namespace-aware startup search sync. Re-probes QMD, ensures collections\n * (namespace-aware when namespacesEnabled), runs update, and warms up search.\n * Designed for server retry paths that run after the deferred init completes\n * when QMD was not available during initial startup.\n *\n * Accepts an optional AbortSignal so callers can interrupt the sync during\n * shutdown. The signal is checked between phases and forwarded into the QMD\n * update and warmup search calls so a long-running `qmd update` subprocess\n * is killed promptly rather than left in flight after `httpServer.stop()`.\n *\n * Returns true if the sync succeeded (QMD now available), false otherwise.\n */\n async startupSearchSync(signal?: AbortSignal): Promise<boolean> {\n if (signal?.aborted) return false;\n\n const available = await this.qmd.probe();\n if (!available) return false;\n if (signal?.aborted) {\n log.debug(\"startupSearchSync: aborted after probe\");\n return false;\n }\n\n log.info(`startupSearchSync: backend now available ${this.qmd.debugStatus()}`);\n\n // Clear namespace router cache so re-probe picks up newly available backends\n if (this.config.namespacesEnabled) {\n this.namespaceSearchRouter.clearCache();\n }\n\n // Ensure collections — namespace-aware when enabled.\n // Use the catalog-union namespace set (issue #1499 sweep, same class as\n // NHZEV): this is the QMD startup-recovery sync that ensures collections AND\n // runs `updateNamespaces(...)` below over the SAME `namespaces` set. A dynamic\n // namespace that exists only in the persisted catalog must be ensured and\n // re-synced here too, otherwise after a backend-was-unavailable-at-boot\n // recovery its collection stays stale. Falls back to the configured set on any\n // catalog read failure.\n const namespaces = this.config.namespacesEnabled\n ? await this.maintenanceNamespaces()\n : [this.config.defaultNamespace];\n\n const states = await Promise.all(\n namespaces.map(async (namespace) => ({\n namespace,\n state: this.config.namespacesEnabled\n ? await this.namespaceSearchRouter.ensureNamespaceCollection(namespace, { signal })\n : await this.qmd.ensureCollection(this.config.memoryDir, this.config.qmdCollection, { signal }),\n })),\n );\n\n if (signal?.aborted) {\n log.debug(\"startupSearchSync: aborted after ensureCollection\");\n return false;\n }\n\n const defaultState =\n states.find((e) => e.namespace === this.config.defaultNamespace)?.state ?? \"unknown\";\n if (defaultState === \"missing\") {\n // Reset the real backend's available flag before replacing it with noop.\n // probe() set available=true earlier in this call; without this reset,\n // any code that captured a reference to the old backend (e.g. a concurrent\n // recall() that read this.qmd before the reassignment) would observe\n // isAvailable()===true against a backend with a missing collection.\n if (\"available\" in this.qmd) {\n (this.qmd as any).available = false;\n }\n await this.disposeSearchBackendIfNeeded();\n this.qmd = new NoopSearchBackend();\n log.warn(\"startupSearchSync: search collection missing; disabling search (fallback retrieval remains enabled)\");\n return false;\n }\n\n // Run index update — namespace-aware when enabled.\n // qmd.update() swallows errors internally, so we: (1) snapshot fail/run\n // timestamps, (2) reset throttles so the update isn't skipped by stale\n // backoff, and (3) verify timestamps after update to confirm it executed\n // and didn't fail silently.\n // The abort signal is forwarded into the QMD subprocess call so the\n // long-running `qmd update` process is killed promptly on shutdown.\n if (this.config.qmdMaintenanceEnabled) {\n try {\n const failTsBefore = \"lastUpdateFailedAtMs\" in this.qmd\n ? (this.qmd as any).lastUpdateFailedAtMs as number | null\n : null;\n const hasRunTs = \"lastUpdateRanAtMs\" in this.qmd;\n if (\"resetUpdateThrottles\" in this.qmd) {\n (this.qmd as any).resetUpdateThrottles();\n }\n log.info(\"startupSearchSync: updating index to match current disk state\");\n let namespacesUpdated = 0;\n if (this.config.namespacesEnabled) {\n namespacesUpdated = await this.namespaceSearchRouter.updateNamespaces(\n namespaces,\n { signal },\n );\n } else {\n await this.qmd.update({ signal });\n }\n if (signal?.aborted) {\n log.debug(\"startupSearchSync: aborted after update\");\n return false;\n }\n const failTsAfter = \"lastUpdateFailedAtMs\" in this.qmd\n ? (this.qmd as any).lastUpdateFailedAtMs as number | null\n : null;\n const runTsAfter = hasRunTs\n ? (this.qmd as any).lastUpdateRanAtMs as number | null\n : null;\n if (failTsAfter !== null && failTsAfter !== failTsBefore) {\n log.warn(\"startupSearchSync: update silently failed (detected via fail timestamp)\");\n return false;\n }\n if (this.config.namespacesEnabled) {\n if (namespacesUpdated === 0) {\n log.warn(\"startupSearchSync: no namespace backends were eligible for update (all unavailable or collections missing)\");\n return false;\n }\n log.info(`startupSearchSync: namespace updates succeeded (${namespacesUpdated}/${namespaces.length} namespaces updated)`);\n } else if (hasRunTs && runTsAfter === null) {\n log.warn(\"startupSearchSync: update was throttled/skipped (run timestamp is null after reset + update)\");\n return false;\n }\n log.info(\"startupSearchSync: sync complete\");\n } catch (err) {\n log.warn(`startupSearchSync: update failed: ${err}`);\n return false;\n }\n }\n\n // Warmup search to pre-load embedding models\n if (!signal?.aborted) {\n try {\n await this.qmd.search(\"warmup\", this.config.defaultNamespace, 1, undefined, { signal });\n log.info(\"startupSearchSync: warmup complete\");\n } catch (err) {\n log.debug(`startupSearchSync: warmup search failed (non-fatal): ${err}`);\n }\n }\n\n return true;\n }\n\n /**\n * Auto-register the engram-day-summary cron job in OpenClaw.\n * Reconciles model and timezone on every startup so config changes propagate.\n * Fire-and-forget — never blocks init or crashes on failure.\n * Issues #1474, #1475.\n */\n private async autoRegisterDaySummaryCron(): Promise<void> {\n const home = resolveHomeDir();\n const jobsPath = path.join(home, \".openclaw\", \"cron\", \"jobs.json\");\n\n try {\n if (!existsSync(jobsPath)) {\n log.debug(\n \"day-summary cron: jobs.json not found, skipping auto-register\",\n );\n return;\n }\n\n // Resolve an OpenClaw cron-routing model only in gateway mode. In plugin\n // mode, summaryModel is a direct-client model id for Remnic's own LLM\n // calls and may be unroutable as an OpenClaw agentTurn model.\n const rawSummaryModel = this.config.summaryModel;\n const taskPrimary = this.config.taskModelChain?.primary;\n const isGateway = this.config.modelSource === \"gateway\";\n const model = isGateway ? (rawSummaryModel || taskPrimary || undefined) : undefined;\n // Attach task-chain fallbacks only when the model matches the task-chain\n // primary. If summaryModel is a distinct override, its fallbacks would\n // be unrelated to the task chain. Also append gateway default models as\n // tail fallbacks (de-duped) so a task-chain outage doesn't stop the cron\n // before reaching the gateway default chain. Mirrors hourly cron pattern.\n const fallbacks: string[] = [];\n if (model && taskPrimary && model === taskPrimary) {\n const seen = new Set<string>(model ? [model] : []);\n const addUnique = (value: string | undefined) => {\n if (typeof value !== \"string\") return;\n const trimmed = value.trim();\n if (trimmed.length > 0 && !seen.has(trimmed)) {\n seen.add(trimmed);\n fallbacks.push(trimmed);\n }\n };\n for (const fb of this.config.taskModelChain?.fallbacks ?? []) addUnique(fb);\n const gwDefaults = this.config.gatewayConfig?.agents?.defaults?.model;\n addUnique(gwDefaults?.primary);\n if (Array.isArray(gwDefaults?.fallbacks)) {\n for (const fb of gwDefaults.fallbacks) addUnique(fb);\n }\n }\n\n // Resolve timezone: configurable override, then server default\n const timezone = this.config.daySummaryTimezone\n || Intl.DateTimeFormat().resolvedOptions().timeZone;\n\n const result = await ensureDaySummaryCron(jobsPath, {\n timezone,\n ...(model ? { model } : {}),\n ...(fallbacks.length > 0 ? { fallbacks } : {}),\n });\n if (result.created) {\n log.info(\n `day-summary cron auto-registered (${result.jobId}, 23:47 ${timezone}${model ? `, model: ${model}` : \"\"})`,\n );\n } else if (result.updated) {\n log.info(\n `day-summary cron reconciled (${result.jobId}, timezone: ${timezone}${model ? `, model: ${model}` : \"\"})`,\n );\n } else {\n log.debug(\"day-summary cron already up to date\");\n }\n } catch (err) {\n log.debug(`day-summary cron auto-register error: ${err}`);\n }\n }\n\n private async autoRegisterNightlyGovernanceCron(): Promise<void> {\n const home = resolveHomeDir();\n const jobsPath = path.join(home, \".openclaw\", \"cron\", \"jobs.json\");\n\n try {\n if (!existsSync(jobsPath)) {\n log.debug(\"nightly governance cron: jobs.json not found, skipping auto-register\");\n return;\n }\n\n const created = await ensureNightlyGovernanceCron(jobsPath, {\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n });\n if (created.created) {\n log.info(\n `nightly governance cron auto-registered (${created.jobId}, 02:23 ${Intl.DateTimeFormat().resolvedOptions().timeZone})`,\n );\n } else {\n log.debug(\"nightly governance cron already exists, skipping auto-register\");\n }\n } catch (err) {\n log.debug(`nightly governance cron auto-register error: ${err}`);\n }\n }\n\n private async autoRegisterProceduralMiningCron(): Promise<void> {\n const home = resolveHomeDir();\n const jobsPath = path.join(home, \".openclaw\", \"cron\", \"jobs.json\");\n try {\n if (!existsSync(jobsPath)) {\n log.debug(\"procedural mining cron: jobs.json not found, skipping auto-register\");\n return;\n }\n const created = await ensureProceduralMiningCron(jobsPath, {\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n });\n if (created.created) {\n log.info(`procedural mining cron auto-registered (${created.jobId})`);\n } else {\n log.debug(\"procedural mining cron already exists, skipping auto-register\");\n }\n } catch (err) {\n log.debug(`procedural mining cron auto-register error: ${err}`);\n }\n }\n\n private async autoRegisterContradictionScanCron(): Promise<void> {\n const home = resolveHomeDir();\n const jobsPath = path.join(home, \".openclaw\", \"cron\", \"jobs.json\");\n try {\n if (!existsSync(jobsPath)) {\n log.debug(\"contradiction scan cron: jobs.json not found, skipping auto-register\");\n return;\n }\n const created = await ensureContradictionScanCron(jobsPath, {\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n });\n if (created.created) {\n log.info(`contradiction scan cron auto-registered (${created.jobId})`);\n } else {\n log.debug(\"contradiction scan cron already exists, skipping auto-register\");\n }\n } catch (err) {\n log.debug(`contradiction scan cron auto-register error: ${err}`);\n }\n }\n\n private async autoRegisterPatternReinforcementCron(): Promise<void> {\n const home = resolveHomeDir();\n const jobsPath = path.join(home, \".openclaw\", \"cron\", \"jobs.json\");\n try {\n if (!existsSync(jobsPath)) {\n log.debug(\"pattern reinforcement cron: jobs.json not found, skipping auto-register\");\n return;\n }\n const created = await ensurePatternReinforcementCron(jobsPath, {\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n });\n if (created.created) {\n log.info(`pattern reinforcement cron auto-registered (${created.jobId})`);\n } else {\n log.debug(\"pattern reinforcement cron already exists, skipping auto-register\");\n }\n } catch (err) {\n log.debug(`pattern reinforcement cron auto-register error: ${err}`);\n }\n }\n\n /**\n * Run the pattern-reinforcement maintenance job (issue #687 PR 2/4).\n *\n * Cadence-gated on `patternReinforcementCadenceMs` so every caller\n * (orchestrator cron path, MCP tool, CLI) shares a single floor —\n * none can call this on a hot loop and burn the corpus. When the\n * feature is disabled or the cadence has not elapsed, returns a\n * synthetic \"skipped\" result rather than throwing.\n *\n * Cadence tracking is per-namespace so a tenant-scoped MCP run in\n * one namespace does not silence a cron run in another (PR #730\n * review feedback, Codex P2). Pass `force: true` for ad-hoc\n * operator runs that must bypass the cadence floor — mirrors the\n * pattern used by other maintenance MCP tools.\n *\n * `force` deliberately does NOT bypass the master\n * `patternReinforcementEnabled` flag (PR #730 review feedback,\n * Cursor Medium). Operators who have explicitly disabled the\n * feature must not have their corpus mutated by an MCP tool call —\n * the only way to run the job is to enable the feature in config.\n */\n async runPatternReinforcement(options: {\n force?: boolean;\n namespace?: string;\n } = {}): Promise<{\n ran: boolean;\n skippedReason?: \"disabled\" | \"cadence\";\n namespace: string;\n result?: PatternReinforcementResult;\n }> {\n const cadenceKey = options.namespace ?? \"\";\n // Master switch: a disabled feature is never bypassed, even with\n // force=true. `force` only relaxes the cadence floor below.\n if (!this.config.patternReinforcementEnabled) {\n return { ran: false, skippedReason: \"disabled\", namespace: cadenceKey };\n }\n const cadence = this.config.patternReinforcementCadenceMs;\n const lastAt = this.lastPatternReinforcementAtByNs.get(cadenceKey);\n if (\n !options.force &&\n cadence > 0 &&\n lastAt !== undefined &&\n Date.now() - lastAt < cadence\n ) {\n return { ran: false, skippedReason: \"cadence\", namespace: cadenceKey };\n }\n const storage = options.namespace\n ? await this.getStorage(options.namespace)\n : this.storage;\n const result = await runPatternReinforcement(storage, {\n categories: this.config.patternReinforcementCategories,\n minCount: this.config.patternReinforcementMinCount,\n });\n this.lastPatternReinforcementAtByNs.set(cadenceKey, Date.now());\n log.debug(\n `pattern reinforcement [ns=${cadenceKey || \"(default)\"}]: clusters=${result.clustersFound} canonicalsUpdated=${result.canonicalsUpdated} duplicatesSuperseded=${result.duplicatesSuperseded}`,\n );\n return { ran: true, result, namespace: cadenceKey };\n }\n\n private async autoRegisterGraphEdgeDecayCron(): Promise<void> {\n const home = resolveHomeDir();\n const jobsPath = path.join(home, \".openclaw\", \"cron\", \"jobs.json\");\n try {\n if (!existsSync(jobsPath)) {\n log.debug(\"graph edge decay cron: jobs.json not found, skipping auto-register\");\n return;\n }\n const scheduleExpr = graphEdgeDecayCadenceToCronExpr(this.config.graphEdgeDecayCadenceMs);\n const created = await ensureGraphEdgeDecayCron(jobsPath, {\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n scheduleExpr,\n });\n if (created.created) {\n log.info(`graph edge decay cron auto-registered (${created.jobId}, ${scheduleExpr})`);\n } else {\n log.debug(\"graph edge decay cron already exists, skipping auto-register\");\n }\n } catch (err) {\n log.debug(`graph edge decay cron auto-register error: ${err}`);\n }\n }\n\n async runLiveConnectors(options: {\n force?: boolean;\n abortSignal?: AbortSignal;\n } = {}): Promise<LiveConnectorsRunSummary> {\n return runLiveConnectorsOnce({\n memoryDir: this.config.memoryDir,\n connectors: this.config.connectors,\n force: options.force === true,\n abortSignal: options.abortSignal,\n ingestDocuments: async (docs) => {\n const fetchedAt = new Date().toISOString();\n const turns = docs.map((doc) => ({\n role: \"assistant\" as const,\n content: doc.title\n ? `# ${doc.title}\\n\\n${doc.content}`\n : doc.content,\n timestamp: fetchedAt,\n }));\n await this.ingestBulkImportBatch(turns);\n },\n });\n }\n\n\n async applyBehaviorRuntimePolicy(\n state: BehaviorLoopPolicyState,\n ): Promise<{\n applied: boolean;\n rolledBack: boolean;\n values: RuntimePolicyValues | null;\n reason: string;\n }> {\n const result = await this.policyRuntime.applyFromBehaviorState(state);\n this.runtimePolicyValues = await this.policyRuntime.loadRuntimeValues();\n return result;\n }\n\n async rollbackBehaviorRuntimePolicy(): Promise<boolean> {\n const rolledBack = await this.policyRuntime.rollback();\n this.runtimePolicyValues = await this.policyRuntime.loadRuntimeValues();\n return rolledBack;\n }\n\n async maybeRunFileHygiene(): Promise<void> {\n const hygiene = this.config.fileHygiene;\n if (!hygiene?.enabled) return;\n\n const now = Date.now();\n if (now - this.lastFileHygieneRunAtMs < hygiene.runMinIntervalMs) return;\n this.lastFileHygieneRunAtMs = now;\n\n // Rotation first (keeps bootstrap files small).\n if (hygiene.rotateEnabled) {\n for (const rel of hygiene.rotatePaths) {\n const abs = path.isAbsolute(rel)\n ? rel\n : path.join(this.config.workspaceDir, rel);\n try {\n const raw = await readFile(abs, \"utf-8\");\n if (raw.length > hygiene.rotateMaxBytes) {\n const archiveDir = path.join(\n this.config.workspaceDir,\n hygiene.archiveDir,\n );\n const base = path.basename(abs);\n const prefix =\n base\n .toUpperCase()\n .replace(/\\.MD$/i, \"\")\n .replace(/[^A-Z0-9]+/g, \"-\") || \"FILE\";\n const { newContent } = await rotateMarkdownFileToArchive({\n filePath: abs,\n archiveDir,\n archivePrefix: prefix,\n keepTailChars: hygiene.rotateKeepTailChars,\n });\n await writeFile(abs, newContent, \"utf-8\");\n }\n } catch {\n // ignore missing/unreadable targets\n }\n }\n }\n\n // Lint (warn before truncation risk).\n if (hygiene.lintEnabled) {\n const warnings = await lintWorkspaceFiles({\n workspaceDir: this.config.workspaceDir,\n paths: hygiene.lintPaths,\n budgetBytes: hygiene.lintBudgetBytes,\n warnRatio: hygiene.lintWarnRatio,\n });\n for (const w of warnings) {\n log.warn(w.message);\n }\n\n if (hygiene.warningsLogEnabled && warnings.length > 0) {\n const fp = path.join(this.config.memoryDir, hygiene.warningsLogPath);\n await mkdir(path.dirname(fp), { recursive: true });\n const stamp = new Date().toISOString();\n const block =\n `\\n\\n## ${stamp}\\n\\n` +\n warnings.map((w) => `- ${w.message}`).join(\"\\n\") +\n \"\\n\";\n let existing = \"\";\n try {\n existing = await readFile(fp, \"utf-8\");\n } catch {\n existing = \"# Engram File Hygiene Warnings\\n\";\n }\n await writeFile(fp, existing + block, \"utf-8\");\n }\n }\n }\n\n async runBootstrap(options: BootstrapOptions): Promise<BootstrapResult> {\n const engine = new BootstrapEngine(this.config, this);\n return engine.run(options);\n }\n\n async runConsolidationNow(): Promise<{\n memoriesProcessed: number;\n merged: number;\n invalidated: number;\n }> {\n return this.runConsolidation();\n }\n\n async reindexMemoryById(\n id: string,\n options?: { storage?: StorageManager },\n ): Promise<void> {\n await this.indexPersistedMemory(options?.storage ?? this.storage, id);\n this.requestQmdMaintenance();\n }\n\n registerConsolidationObserver(\n observer: (observation: ConsolidationObservation) => Promise<void> | void,\n ): () => void {\n this.consolidationObservers.add(observer);\n return () => {\n this.consolidationObservers.delete(observer);\n };\n }\n\n async runSemanticConsolidationNow(options?: {\n dryRun?: boolean;\n thresholdOverride?: number;\n storage?: StorageManager;\n }): Promise<SemanticConsolidationResult> {\n return this.runSemanticConsolidation({ ...options, force: true });\n }\n\n async runDeepSleepGovernanceNow(options?: {\n dryRun?: boolean;\n storage?: StorageManager;\n }): Promise<{ scannedMemories: number; appliedActionCount: number; notes?: string }> {\n const targetStorage = options?.storage ?? this.storage;\n const { runMemoryGovernance } = await import(\"./maintenance/memory-governance.js\");\n const { summarizeGovernanceResultForDreams } = await import(\"./maintenance/dreams-ledger.js\");\n const govResult = await runMemoryGovernance({\n memoryDir: targetStorage.dir,\n mode: options?.dryRun === true ? \"shadow\" : \"apply\",\n });\n if (options?.dryRun !== true) {\n try {\n await this.processEntitySynthesisQueue(\n this.namespaceFromStorageDir(targetStorage.dir),\n 5,\n );\n } catch (error) {\n log.debug(`deep-sleep governance: entity synthesis refresh failed after apply: ${error}`);\n }\n }\n return summarizeGovernanceResultForDreams(govResult, options?.dryRun === true);\n }\n\n private async runSemanticConsolidation(options?: {\n dryRun?: boolean;\n thresholdOverride?: number;\n force?: boolean;\n storage?: StorageManager;\n }): Promise<SemanticConsolidationResult> {\n const targetStorage = options?.storage ?? this.storage;\n const result: SemanticConsolidationResult = {\n clustersFound: 0,\n memoriesConsolidated: 0,\n memoriesArchived: 0,\n errors: 0,\n clusters: [],\n };\n\n if (!this.config.semanticConsolidationEnabled && !options?.force) {\n log.debug(\"[semantic-consolidation] disabled in config\");\n return result;\n }\n\n log.info(\"[semantic-consolidation] starting run\");\n\n const allMemories = await targetStorage.readAllMemories();\n if (allMemories.length < 10) {\n log.debug(\"[semantic-consolidation] too few memories, skipping\");\n return result;\n }\n\n const threshold =\n options?.thresholdOverride ?? this.config.semanticConsolidationThreshold;\n const clusters = findSimilarClusters(allMemories, {\n threshold,\n minClusterSize: this.config.semanticConsolidationMinClusterSize,\n excludeCategories: this.config.semanticConsolidationExcludeCategories,\n maxPerRun: this.config.semanticConsolidationMaxPerRun,\n });\n\n result.clustersFound = clusters.length;\n result.clusters = clusters;\n\n if (clusters.length === 0) {\n log.info(\"[semantic-consolidation] no clusters found\");\n return result;\n }\n\n log.info(`[semantic-consolidation] found ${clusters.length} cluster(s)`);\n\n if (options?.dryRun) {\n log.info(\n \"[semantic-consolidation] dry run — skipping LLM synthesis and archival\",\n );\n return result;\n }\n\n // Use FallbackLlmClient for LLM calls (same pattern as causal-consolidation.ts)\n // Honor semanticConsolidationModel: \"auto\" = primary, \"fast\" = local fast, or specific model\n const { FallbackLlmClient, gatewayTaskChainOptions } = await import(\"./fallback-llm.js\");\n const useGateway = this.config.modelSource === \"gateway\";\n const modelSetting = this.config.semanticConsolidationModel;\n if (modelSetting === \"fast\" && this.fastLlm && !useGateway) {\n log.info(\"[semantic-consolidation] using fast local LLM for synthesis\");\n }\n // Gateway routing: an explicit \"fast\" setting keeps the fast persona chain\n // (the operator's deliberate fast-tier choice). Otherwise route through the\n // shared task-chain resolution so taskModelChain applies to semantic\n // consolidation like every other background task (gotcha #22). Issue #1365.\n const gatewayChainOptions: { modelChain?: AgentPersonaModelConfig; agentId?: string } =\n !useGateway\n ? {}\n : modelSetting === \"fast\"\n ? (this.config.fastGatewayAgentId\n ? { agentId: this.config.fastGatewayAgentId }\n : this.config.gatewayAgentId\n ? { agentId: this.config.gatewayAgentId }\n : {})\n : gatewayTaskChainOptions(this.config);\n const llm = new FallbackLlmClient(\n this.config.gatewayConfig,\n fallbackLlmRuntimeContextFromConfig(this.config),\n );\n if (!llm.isAvailable(gatewayChainOptions) && !(modelSetting === \"fast\" && this.fastLlm && !useGateway)) {\n log.warn(\n \"[semantic-consolidation] no LLM available — skipping synthesis\",\n );\n return result;\n }\n\n // Discover memory extensions once for all clusters (#382)\n let extensionsBlock = \"\";\n try {\n extensionsBlock = await buildExtensionsBlockForConsolidation(this.config);\n } catch (err) {\n log.warn(`[semantic-consolidation] extension discovery failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`);\n }\n\n for (const cluster of clusters) {\n let canonicalWriteCompleted = false;\n try {\n // Operator-aware prompt (issue #561 PR 3): ask the LLM to pick the\n // SPLIT/MERGE/UPDATE operator alongside the canonical output. Falls\n // back to the legacy plain-blob prompt when operator-aware\n // consolidation is explicitly disabled via config, so rollbacks stay\n // clean.\n // Use the `=== true` idiom for default-false flags (PR #632\n // review, cursor Low): sibling disabled-by-default flags like\n // `semanticConsolidationEnabled` follow the same convention,\n // while `!== false` is reserved for default-on flags.\n const operatorAwareEnabled =\n this.config.operatorAwareConsolidationEnabled === true;\n let prompt = operatorAwareEnabled\n ? buildOperatorAwareConsolidationPrompt(cluster)\n : buildConsolidationPrompt(cluster);\n if (extensionsBlock.length > 0) {\n prompt += \"\\n\\n\" + extensionsBlock;\n }\n const messages = [\n {\n role: \"system\" as const,\n content: operatorAwareEnabled\n ? 'You are a memory consolidation system. Return ONLY a JSON object with two keys, \"operator\" and \"output\". The \"operator\" value MUST be one of the exact strings \"merge\", \"update\", or \"split\" — never a pipe-separated placeholder, never prose. The \"output\" value is the canonical memory text.'\n : \"You are a memory consolidation system. Output only the consolidated memory text.\",\n },\n { role: \"user\" as const, content: prompt },\n ];\n const llmOpts = { temperature: 0.2, maxTokens: 2000 };\n\n // Route to the configured model\n let response: { content: string } | null = null;\n if (useGateway) {\n // Gateway model source — use the appropriate agent chain\n response = await llm.chatCompletion(messages, { ...llmOpts, ...gatewayChainOptions });\n } else if (modelSetting === \"fast\" && this.fastLlm) {\n const fastResult = await this.fastLlm.chatCompletion(messages, {\n operation: \"semantic-consolidation\",\n maxTokens: llmOpts.maxTokens,\n temperature: llmOpts.temperature,\n priority: \"background\",\n forceDisableThinking: true,\n });\n response = fastResult ? { content: fastResult.content } : null;\n } else {\n response = await llm.chatCompletion(messages, llmOpts);\n }\n\n if (!response?.content) {\n log.warn(\n `[semantic-consolidation] empty LLM response for cluster in \"${cluster.category}\"`,\n );\n result.errors++;\n continue;\n }\n\n // Operator-aware parse (issue #561 PR 3). In legacy mode we fall\n // back to the plain-text parser and derive the operator from the\n // cluster-shape heuristic so `derived_via` still lands.\n // Restricted to `SemanticConsolidationLlmOperator`\n // (split/merge/update) — `pattern-reinforcement` joined the\n // wider `ConsolidationOperator` type in #687 PR 2/4 but is\n // reserved for the maintenance job and must never be assignable\n // here (Cursor Bugbot review, PR #730).\n let canonicalContent: string;\n let operator: SemanticConsolidationLlmOperator;\n if (operatorAwareEnabled) {\n const parsed = parseOperatorAwareConsolidationResponse(\n response.content,\n cluster,\n );\n canonicalContent = parsed.output;\n operator = parsed.operator;\n } else {\n canonicalContent = parseConsolidationResponse(response.content);\n operator = chooseConsolidationOperator(cluster);\n }\n cluster.canonicalContent = canonicalContent;\n\n // Pick the most recent memory's metadata as the basis for lineage\n const sorted = [...cluster.memories].sort(\n (a, b) =>\n new Date(b.frontmatter.created).getTime() -\n new Date(a.frontmatter.created).getTime(),\n );\n const newest = sorted[0];\n const lineageIds = cluster.memories.map((m) => m.frontmatter.id);\n\n // Consolidation provenance (issue #561 PR 2+3): snapshot each\n // source memory BEFORE archiving it, collecting\n // \"<relpath>:<versionId>\" pointers for the new canonical memory's\n // `derived_from` frontmatter field. Snapshots are best-effort — if\n // page-versioning is disabled (default in `config.ts`) or a single\n // source fails to snapshot we simply omit that entry rather than\n // abort the consolidation. The `derived_via` operator is chosen\n // above (PR 3) from the LLM response or the cluster-shape\n // heuristic fallback and emitted unconditionally so consolidation\n // outputs stay identifiable even when no snapshots are captured\n // (PR #624 review feedback).\n const derivedFromEntries: string[] = [];\n for (const m of cluster.memories) {\n if (!m.path) continue;\n const entry = await targetStorage.snapshotForProvenance(m.path);\n if (entry) derivedFromEntries.push(entry);\n }\n\n // Write the canonical memory\n const canonicalId = await targetStorage.writeMemory(\n newest.frontmatter.category,\n canonicalContent,\n {\n actor: \"semantic-consolidation\",\n confidence: newest.frontmatter.confidence,\n tags: [\n ...new Set(\n cluster.memories.flatMap((m) => m.frontmatter.tags ?? []),\n ),\n ],\n source: \"semantic-consolidation\",\n lineage: lineageIds,\n derivedFrom: derivedFromEntries.length > 0 ? derivedFromEntries : undefined,\n derivedVia: operator,\n },\n );\n canonicalWriteCompleted = true;\n\n result.memoriesConsolidated++;\n\n // Archive originals\n for (const m of cluster.memories) {\n const archiveResult = await targetStorage.archiveMemory(m, {\n actor: \"semantic-consolidation\",\n reasonCode: \"semantic-consolidation\",\n relatedMemoryIds: [canonicalId],\n });\n if (archiveResult) {\n // Remove from the same storage-scoped content-hash index that\n // originally deduped this memory.\n await this.removeContentHashForMemory(\n targetStorage,\n m,\n \"semantic-consolidation\",\n );\n // Best-effort index cleanup: a failure here (e.g. on-disk index save\n // under disk-full) must NOT abort the archival loop and thereby skip\n // the catalog write touch below for an already-durable canonical write\n // (kilo NV0mh).\n try {\n await this.embeddingFallback.removeFromIndex(m.frontmatter.id);\n if (\n this.config.queryAwareIndexingEnabled &&\n m.path &&\n m.frontmatter?.created\n ) {\n deindexMemory(\n targetStorage.dir,\n m.path,\n m.frontmatter.created,\n m.frontmatter.tags ?? [],\n );\n }\n } catch (cleanupErr) {\n log.warn(\n `[semantic-consolidation] index cleanup failed (non-fatal): ${cleanupErr}`,\n );\n }\n result.memoriesArchived++;\n }\n }\n\n log.info(\n `[semantic-consolidation] consolidated ${cluster.memories.length} memories → ${canonicalId}`,\n );\n } catch (err) {\n log.warn(\n `[semantic-consolidation] cluster processing failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n result.errors++;\n } finally {\n if (canonicalWriteCompleted) {\n // Catalog write touch (issue #1499 sweep): record after the canonical\n // write and, on the happy path, after archival of superseded cluster\n // memories, so `lastWriteAt` reflects every durable mutation in this\n // consolidation (cursor NUtCK). The `finally` also covers partial\n // failures where the canonical memory was written but a later archive\n // step throws and the cluster catch continues (codex NY-dK).\n // Best-effort; namespace decoded from the storage dir since this path\n // has no routed namespace name.\n this.markCatalogWrite(\n this.namespaceFromStorageDir(targetStorage.dir),\n targetStorage.dir,\n );\n }\n }\n }\n\n // Save hash indexes if we modified them.\n if (result.memoriesArchived > 0) {\n await this.saveContentHashIndexes().catch((err) =>\n log.warn(\n `[semantic-consolidation] content-hash index save failed: ${err}`,\n ),\n );\n }\n\n log.info(\n `[semantic-consolidation] complete: clusters=${result.clustersFound}, consolidated=${result.memoriesConsolidated}, archived=${result.memoriesArchived}, errors=${result.errors}`,\n );\n\n // #378: fire the Codex materialize post-hook so `codexMaterializeOnConsolidation`\n // actually has a runtime effect. The helper silently no-ops when the\n // feature flag or the per-trigger toggle is off, when the sentinel is\n // missing, or when nothing has changed since the previous run, so it's\n // safe to always call here. Wrapped in a try/catch because a failed\n // materialize must never abort the consolidation result — consolidation\n // is the load-bearing operation; materialization is an optional mirror.\n try {\n await materializeAfterSemanticConsolidation({\n config: this.config,\n memoryDir: targetStorage.dir,\n });\n } catch (err) {\n log.warn(\n `[semantic-consolidation] Codex materialize post-hook failed (non-fatal): ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n\n // Issue #679 PR 2/5 — async peer profile reasoner runs as part of\n // the REM phase, immediately after semantic consolidation. Gated\n // on `peerProfileReasonerEnabled` (default false, opt-in). Wrapped\n // in a try/catch because reasoner I/O (LLM call, peer-profile\n // writes) must never abort the consolidation result. The reasoner\n // itself also defends against partial failure — see profile-reasoner.ts.\n if (this.config.peerProfileReasonerEnabled) {\n try {\n const { runPeerProfileReasoner } = await import(\"./peers/index.js\");\n const llm = new FallbackLlmClient(\n this.config.gatewayConfig,\n fallbackLlmRuntimeContextFromConfig(this.config),\n );\n const peerResult = await runPeerProfileReasoner({\n memoryDir: targetStorage.dir,\n enabled: true,\n llm,\n model: this.config.peerProfileReasonerModel,\n minInteractions: this.config.peerProfileReasonerMinInteractions,\n maxFieldsPerRun: this.config.peerProfileReasonerMaxFieldsPerRun,\n log: {\n debug: (msg) => log.debug(msg),\n info: (msg) => log.info(msg),\n warn: (msg) => log.warn(msg),\n },\n });\n log.info(\n `[peer-profile-reasoner] complete: peers=${peerResult.peersConsidered}, processed=${peerResult.peersProcessed}, fields=${peerResult.fieldsApplied}`,\n );\n } catch (err) {\n log.warn(\n `[peer-profile-reasoner] post-consolidation hook failed (non-fatal): ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n }\n\n return result;\n }\n\n async waitForExtractionIdle(timeoutMs: number = 60_000): Promise<boolean> {\n const started = Date.now();\n while (this.queueProcessing || this.extractionQueue.length > 0) {\n if (Date.now() - started > timeoutMs) {\n log.warn(`waitForExtractionIdle timed out after ${timeoutMs}ms`);\n return false;\n }\n await new Promise((resolve) => setTimeout(resolve, 50));\n }\n return true;\n }\n\n async waitForConsolidationIdle(timeoutMs: number = 60_000): Promise<boolean> {\n const started = Date.now();\n while (this.consolidationInFlight) {\n if (Date.now() - started > timeoutMs) {\n log.warn(`waitForConsolidationIdle timed out after ${timeoutMs}ms`);\n return false;\n }\n await new Promise((resolve) => setTimeout(resolve, 50));\n }\n return true;\n }\n\n async getStorage(namespace?: string): Promise<StorageManager> {\n const ns =\n namespace && namespace.length > 0\n ? namespace\n : this.config.defaultNamespace;\n return this.storageRouter.storageFor(ns);\n }\n\n async processEntitySynthesisQueue(\n namespace?: string,\n maxEntities: number = 5,\n ): Promise<number> {\n if (\n !this.config.entitySummaryEnabled\n || maxEntities <= 0\n || this.config.entitySynthesisMaxTokens <= 0\n ) return 0;\n const storage = await this.getStorage(namespace);\n const queued = await storage.refreshEntitySynthesisQueue();\n let processed = 0;\n let attempted = 0;\n\n for (const entityName of queued) {\n if (attempted >= maxEntities) break;\n attempted += 1;\n try {\n const raw = await storage.readEntity(entityName);\n if (!raw) continue;\n const entity = parseEntityFile(raw, this.config.entitySchemas);\n const previousSynthesis = entity.synthesis || entity.summary || \"\";\n const sortedTimelineEntries = entity.timeline\n .slice()\n .sort((left, right) => compareEntityTimestamps(right.timestamp, left.timestamp));\n const newerTimelineEntries = sortedTimelineEntries.filter(\n (entry) =>\n !entity.synthesisUpdatedAt\n || compareEntityTimestamps(entry.timestamp, entity.synthesisUpdatedAt) > 0,\n );\n const appendedTimelineEntries = entity.synthesisTimelineCount === undefined\n ? []\n : entity.timeline.slice(Math.max(0, entity.synthesisTimelineCount));\n const structuredEvidenceEntries = flattenStructuredSectionEvidence(entity.structuredSections);\n const structuredEvidenceCount = structuredEvidenceEntries.length;\n const structuredEvidenceDigest = fingerprintEntityStructuredFacts(entity);\n const structuredEvidenceDrifted = structuredEvidenceDigest !== (entity.synthesisStructuredFactDigest?.trim() || undefined);\n const appendedStructuredEvidenceEntries = entity.synthesisStructuredFactCount === undefined\n || structuredEvidenceDrifted\n ? structuredEvidenceEntries\n : structuredEvidenceEntries.slice(Math.max(0, entity.synthesisStructuredFactCount));\n const candidateEvidenceEntries = [\n ...newerTimelineEntries,\n ...appendedTimelineEntries,\n ...appendedStructuredEvidenceEntries,\n ]\n .slice()\n .sort((left, right) => compareEntityTimestamps(right.timestamp, left.timestamp));\n const dedupedEvidenceEntries = dedupeEntitySynthesisEvidenceEntries(\n candidateEvidenceEntries.length > 0\n ? candidateEvidenceEntries\n : [...sortedTimelineEntries, ...structuredEvidenceEntries],\n );\n const chronologicalEvidenceEntries = dedupedEvidenceEntries\n .slice()\n .sort((left, right) => compareEntityTimestamps(left.timestamp, right.timestamp));\n if (chronologicalEvidenceEntries.length === 0) continue;\n const latestEvidenceTimestamp = chronologicalEvidenceEntries\n .slice()\n .reverse()\n .map((entry) => entry.timestamp?.trim() || undefined)\n .find((timestamp) => Boolean(timestamp));\n const previousSynthesisUpdatedAt = entity.synthesisUpdatedAt?.trim() || undefined;\n const nextSynthesisUpdatedAt = compareEntityTimestamps(\n latestEvidenceTimestamp,\n previousSynthesisUpdatedAt,\n ) >= 0\n ? latestEvidenceTimestamp\n : previousSynthesisUpdatedAt;\n const evidenceBatches: typeof chronologicalEvidenceEntries[] = [];\n for (let index = 0; index < chronologicalEvidenceEntries.length; index += 8) {\n evidenceBatches.push(chronologicalEvidenceEntries.slice(index, index + 8));\n }\n\n let nextSynthesis = previousSynthesis;\n let batchFailed = false;\n for (const evidenceEntries of evidenceBatches) {\n const evidenceText = evidenceEntries\n .map((entry) => {\n const sectionTitle = entry.source?.startsWith(\"section:\")\n ? entry.source.slice(\"section:\".length)\n : \"\";\n const metadata = [\n `timestamp=${entry.timestamp}`,\n sectionTitle ? `section=${sectionTitle}` : entry.source ? `source=${entry.source}` : \"\",\n entry.sessionKey ? `session=${entry.sessionKey}` : \"\",\n entry.principal ? `principal=${entry.principal}` : \"\",\n ]\n .filter(Boolean)\n .join(\", \");\n return `- ${metadata}: ${entry.text}`;\n })\n .join(\"\\n\");\n const response = await this.fastChatCompletion(\n [\n {\n role: \"system\",\n content:\n \"Rewrite the entity synthesis as compact current truth. Preserve uncertainty when evidence conflicts. Return plain text only.\",\n },\n {\n role: \"user\",\n content: [\n `Entity: ${entity.name} (${entity.type})`,\n nextSynthesis ? `Previous synthesis:\\n${nextSynthesis}` : \"Previous synthesis: none\",\n `New evidence:\\n${evidenceText}`,\n ].join(\"\\n\\n\"),\n },\n ],\n {\n temperature: 0.2,\n maxTokens: this.config.entitySynthesisMaxTokens,\n operation: \"entity_summary\",\n priority: \"background\",\n },\n );\n const synthesis = response?.content?.trim().replace(/^[\"']|[\"']$/g, \"\");\n const maxSynthesisChars = Math.max(2_000, this.config.entitySynthesisMaxTokens * 8);\n if (!synthesis || synthesis.length < 10 || synthesis.length > maxSynthesisChars) {\n batchFailed = true;\n break;\n }\n nextSynthesis = synthesis;\n }\n if (batchFailed || nextSynthesis.length === 0) continue;\n const latestRaw = await storage.readEntity(entityName);\n if (!latestRaw) continue;\n const latestEntity = parseEntityFile(latestRaw, this.config.entitySchemas);\n if (\n fingerprintEntitySynthesisEvidence(latestEntity)\n !== fingerprintEntitySynthesisEvidence(entity)\n ) {\n continue;\n }\n await storage.updateEntitySynthesis(entityName, nextSynthesis, {\n entityUpdatedAt: new Date().toISOString(),\n synthesisStructuredFactDigest: structuredEvidenceDigest,\n synthesisStructuredFactCount: structuredEvidenceCount,\n synthesisTimelineCount: entity.timeline.length,\n updatedAt: nextSynthesisUpdatedAt,\n });\n processed += 1;\n } catch (err) {\n log.debug(`entity synthesis refresh failed for ${entityName}: ${err}`);\n }\n }\n\n return processed;\n }\n\n async generateDaySummary(\n memories: string | MemoryFile[],\n ): Promise<DaySummaryResult | null> {\n if (this.initPromise) {\n let initGateTimeoutHandle: ReturnType<typeof setTimeout> | undefined;\n try {\n await Promise.race([\n this.initPromise.catch(() => undefined),\n new Promise((resolve) => {\n initGateTimeoutHandle = setTimeout(\n resolve,\n this.config.initGateTimeoutMs,\n );\n }),\n ]);\n } finally {\n if (initGateTimeoutHandle) clearTimeout(initGateTimeoutHandle);\n }\n }\n return this.extraction.generateDaySummary(memories);\n }\n\n /**\n * Auto-gather today's facts and hourly summaries from storage, then generate a day summary.\n * Returns null if no facts are found for today.\n */\n async generateDaySummaryAuto(\n namespace?: string,\n options: DaySummaryGatherOptions = {},\n ): Promise<DaySummaryResult | null> {\n const gathered = await this.gatherTodayFacts(namespace, options);\n if (!gathered || !gathered.trim()) {\n log.warn(\"generateDaySummaryAuto: no facts found for today, skipping\");\n return null;\n }\n return this.generateDaySummary(gathered);\n }\n\n /**\n * Read today's facts and hourly summaries from storage, returning them\n * as a formatted string suitable for generateDaySummary().\n */\n async gatherTodayFacts(\n namespace?: string,\n options: DaySummaryGatherOptions = {},\n ): Promise<string> {\n const ns =\n namespace && namespace.length > 0\n ? namespace\n : this.config.defaultNamespace;\n const storage = await this.storageRouter.storageFor(ns);\n const configuredTimeZone = normalizeIanaTimeZone(options.timeZone)\n ?? normalizeIanaTimeZone(this.config.daySummaryTimezone);\n const timeZone =\n configuredTimeZone ?? Intl.DateTimeFormat().resolvedOptions().timeZone;\n const now = options.now instanceof Date && Number.isFinite(options.now.getTime())\n ? options.now\n : new Date();\n const targetLocalDate = formatDateInTimeZone(now, timeZone);\n // Facts are stored under UTC date directories, while the summary target is\n // a local calendar day. Scan the UTC-date envelope that overlaps the local\n // day, then filter parseable fact timestamps to that configured local day.\n const datesToScan = utcDateKeysForLocalDay(now, timeZone);\n const factsBaseDir = path.join(storage.dir, \"facts\");\n const MAX_CHARS = 100_000;\n\n // --- Read fact files from each date directory ---\n const facts: MemoryFile[] = [];\n for (const date of datesToScan) {\n const factsDir = path.join(factsBaseDir, date);\n try {\n const entries = await readdir(factsDir, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.name.endsWith(\".md\")) continue;\n const fullPath = path.join(factsDir, entry.name);\n try {\n const raw = await readFile(fullPath, \"utf-8\");\n const fmMatch = raw.match(/^---\\n([\\s\\S]*?)\\n---\\n?([\\s\\S]*)$/);\n if (!fmMatch) continue;\n const fmBlock = fmMatch[1];\n const content = fmMatch[2].trim();\n const fm: Record<string, string> = {};\n for (const line of fmBlock.split(\"\\n\")) {\n const colonIdx = line.indexOf(\":\");\n if (colonIdx === -1) continue;\n fm[line.slice(0, colonIdx).trim()] = line\n .slice(colonIdx + 1)\n .trim();\n }\n const created = fm.created || \"unknown\";\n const createdAt = parseFiniteDate(created);\n if (\n createdAt &&\n formatDateInTimeZone(createdAt, timeZone) !== targetLocalDate\n ) {\n continue;\n }\n facts.push({\n path: fullPath,\n frontmatter: {\n id: fm.id || path.basename(entry.name, \".md\"),\n category: (fm.category as any) || \"fact\",\n created,\n updated: fm.updated || created,\n source: fm.source || \"unknown\",\n confidence: parseFloat(fm.confidence || \"0.8\"),\n confidenceTier: (fm.confidenceTier as any) || \"implied\",\n tags: [],\n },\n content,\n });\n } catch {\n // Skip unreadable files\n }\n }\n } catch {\n // Directory doesn't exist — no facts for this date\n }\n }\n\n // Sort facts by created timestamp (most recent last) so truncation keeps newest\n facts.sort((a, b) => {\n if (a.frontmatter.created === b.frontmatter.created) return 0;\n return a.frontmatter.created < b.frontmatter.created ? -1 : 1;\n });\n\n // --- Read hourly summaries for the scanned dates ---\n const hourlySummaries: string[] = [];\n const hourlyBaseDir = path.join(storage.dir, \"summaries\", \"hourly\");\n try {\n const sessionKeys = await readdir(hourlyBaseDir, { withFileTypes: true });\n for (const sk of sessionKeys) {\n if (!sk.isDirectory()) continue;\n for (const date of datesToScan) {\n const summaryFile = path.join(hourlyBaseDir, sk.name, `${date}.md`);\n try {\n const raw = await readFile(summaryFile, \"utf-8\");\n const filtered = filterHourlySummaryMarkdownForLocalDay(\n raw,\n date,\n timeZone,\n targetLocalDate,\n );\n if (filtered) {\n hourlySummaries.push(filtered);\n }\n } catch {\n // No summary file for this session/date\n }\n }\n }\n } catch {\n // No hourly summaries directory\n }\n\n // --- Format and truncate ---\n let formatted = formatDaySummaryMemories(facts);\n if (hourlySummaries.length > 0) {\n formatted +=\n \"\\n\\n---\\n## Hourly Summaries\\n\\n\" +\n hourlySummaries.join(\"\\n\\n---\\n\\n\");\n }\n\n // Truncate intelligently if over budget: drop oldest facts first\n if (formatted.length > MAX_CHARS) {\n // Re-build with fewer facts, keeping most recent\n while (facts.length > 1 && formatted.length > MAX_CHARS) {\n facts.shift(); // drop oldest\n formatted = formatDaySummaryMemories(facts);\n if (hourlySummaries.length > 0) {\n formatted +=\n \"\\n\\n---\\n## Hourly Summaries\\n\\n\" +\n hourlySummaries.join(\"\\n\\n---\\n\\n\");\n }\n }\n // If still over, hard truncate\n if (formatted.length > MAX_CHARS) {\n formatted = formatted.slice(0, MAX_CHARS);\n }\n }\n\n log.info(\n `gatherTodayFacts: collected ${facts.length} facts, ${hourlySummaries.length} hourly summaries for ${targetLocalDate} (${timeZone}, ${formatted.length} chars)`,\n );\n\n return formatted;\n }\n\n previewMemoryActionEvent(\n event: Omit<MemoryActionEvent, \"timestamp\"> & { timestamp?: string },\n ): MemoryActionEvent {\n const namespace =\n typeof event.namespace === \"string\" && event.namespace.length > 0\n ? event.namespace\n : this.config.defaultNamespace;\n const eligibility = parseMemoryActionEligibilityContext(\n event.policyEligibility,\n );\n const policy = evaluateMemoryActionPolicy({\n action: event.action,\n eligibility,\n options: {\n actionsEnabled: this.config.contextCompressionActionsEnabled,\n maxCompressionTokensPerHour: this.config.maxCompressionTokensPerHour,\n },\n });\n const dryRun = event.dryRun === true;\n\n const normalizedOutcome = dryRun\n ? event.outcome === \"failed\"\n ? \"failed\"\n : \"skipped\"\n : policy.decision === \"allow\"\n ? event.outcome\n : event.outcome === \"failed\"\n ? \"failed\"\n : \"skipped\";\n const sourceSessionKey =\n typeof event.sourceSessionKey === \"string\" &&\n event.sourceSessionKey.length > 0\n ? event.sourceSessionKey\n : typeof event.sessionKey === \"string\" && event.sessionKey.length > 0\n ? event.sessionKey\n : undefined;\n const outputMemoryIds = Array.isArray(event.outputMemoryIds)\n ? Array.from(\n new Set(\n event.outputMemoryIds.filter(\n (value): value is string =>\n typeof value === \"string\" && value.length > 0,\n ),\n ),\n )\n : [];\n\n const reasonParts = [\n event.reason,\n `policy:${policy.decision}`,\n policy.rationale,\n ].filter(\n (part): part is string => typeof part === \"string\" && part.length > 0,\n );\n\n return {\n ...event,\n schemaVersion: event.schemaVersion ?? 1,\n actionId:\n typeof event.actionId === \"string\" && event.actionId.length > 0\n ? event.actionId\n : `memact-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n outcome: normalizedOutcome,\n status:\n event.status ??\n (dryRun && policy.decision === \"allow\" && event.outcome !== \"failed\"\n ? \"validated\"\n : normalizedOutcome === \"applied\"\n ? \"applied\"\n : \"rejected\"),\n actor:\n typeof event.actor === \"string\" && event.actor.length > 0\n ? event.actor\n : \"engram\",\n subsystem:\n typeof event.subsystem === \"string\" && event.subsystem.length > 0\n ? event.subsystem\n : \"memory_action\",\n reason: reasonParts.join(\" | \"),\n namespace,\n sessionKey: sourceSessionKey ?? event.sessionKey,\n sourceSessionKey,\n inputSummary:\n typeof event.inputSummary === \"string\" && event.inputSummary.length > 0\n ? event.inputSummary\n : undefined,\n outputMemoryIds,\n dryRun,\n policyVersion:\n typeof event.policyVersion === \"string\" &&\n event.policyVersion.length > 0\n ? event.policyVersion\n : \"memory-action-policy.v1\",\n timestamp:\n typeof event.timestamp === \"string\" && event.timestamp.length > 0\n ? event.timestamp\n : new Date().toISOString(),\n policyDecision: policy.decision,\n policyRationale: policy.rationale,\n policyEligibility: eligibility,\n };\n }\n\n async appendMemoryActionEvent(\n event: Omit<MemoryActionEvent, \"timestamp\"> & { timestamp?: string },\n ): Promise<boolean> {\n try {\n const toWrite = this.previewMemoryActionEvent(event);\n const storage = await this.getStorage(toWrite.namespace);\n await storage.appendMemoryActionEvents([toWrite]);\n return true;\n } catch (err) {\n log.warn(`appendMemoryActionEvent failed (non-fatal): ${err}`);\n return false;\n }\n }\n\n async getLastGraphRecallSnapshot(\n namespace?: string,\n ): Promise<GraphRecallSnapshot | null> {\n const storage = await this.getStorage(namespace);\n const snapshotPath = path.join(\n storage.dir,\n \"state\",\n \"last_graph_recall.json\",\n );\n try {\n const raw = await readFile(snapshotPath, \"utf-8\");\n const parsed = JSON.parse(raw) as Partial<GraphRecallSnapshot>;\n if (!parsed || typeof parsed !== \"object\") return null;\n return {\n recordedAt:\n typeof parsed.recordedAt === \"string\" ? parsed.recordedAt : \"\",\n mode: typeof parsed.mode === \"string\" ? parsed.mode : \"full\",\n queryHash: typeof parsed.queryHash === \"string\" ? parsed.queryHash : \"\",\n queryLength:\n typeof parsed.queryLength === \"number\" ? parsed.queryLength : 0,\n namespaces: Array.isArray(parsed.namespaces)\n ? parsed.namespaces.filter((v): v is string => typeof v === \"string\")\n : [],\n seedCount: typeof parsed.seedCount === \"number\" ? parsed.seedCount : 0,\n expandedCount:\n typeof parsed.expandedCount === \"number\" ? parsed.expandedCount : 0,\n seeds: Array.isArray(parsed.seeds)\n ? parsed.seeds.filter((v): v is string => typeof v === \"string\")\n : [],\n expanded: clampGraphRecallExpandedEntries(parsed.expanded, 64),\n status:\n parsed.status === \"completed\" ||\n parsed.status === \"skipped\" ||\n parsed.status === \"aborted\"\n ? parsed.status\n : undefined,\n reason: typeof parsed.reason === \"string\" ? parsed.reason : undefined,\n shadowMode: parsed.shadowMode === true,\n queryIntent: parseMemoryIntentSnapshot(parsed.queryIntent),\n seedResults: parseGraphRecallRankedResults(parsed.seedResults),\n finalResults: parseGraphRecallRankedResults(parsed.finalResults),\n shadowComparison:\n parsed.shadowComparison && typeof parsed.shadowComparison === \"object\"\n ? {\n baselineCount:\n typeof parsed.shadowComparison.baselineCount === \"number\"\n ? parsed.shadowComparison.baselineCount\n : 0,\n graphCount:\n typeof parsed.shadowComparison.graphCount === \"number\"\n ? parsed.shadowComparison.graphCount\n : 0,\n overlapCount:\n typeof parsed.shadowComparison.overlapCount === \"number\"\n ? parsed.shadowComparison.overlapCount\n : 0,\n overlapRatio:\n typeof parsed.shadowComparison.overlapRatio === \"number\"\n ? parsed.shadowComparison.overlapRatio\n : 0,\n averageOverlapDelta:\n typeof parsed.shadowComparison.averageOverlapDelta ===\n \"number\"\n ? parsed.shadowComparison.averageOverlapDelta\n : 0,\n }\n : undefined,\n };\n } catch {\n return null;\n }\n }\n\n async getLastIntentSnapshot(\n namespace?: string,\n ): Promise<IntentDebugSnapshot | null> {\n const storage = await this.getStorage(namespace);\n const snapshotPath = path.join(storage.dir, \"state\", \"last_intent.json\");\n try {\n const raw = await readFile(snapshotPath, \"utf-8\");\n const parsed = JSON.parse(raw) as Partial<IntentDebugSnapshot>;\n if (!parsed || typeof parsed !== \"object\") return null;\n const graphDecision =\n parsed.graphDecision && typeof parsed.graphDecision === \"object\"\n ? parsed.graphDecision\n : undefined;\n return {\n recordedAt:\n typeof parsed.recordedAt === \"string\" ? parsed.recordedAt : \"\",\n promptHash:\n typeof parsed.promptHash === \"string\" ? parsed.promptHash : \"\",\n promptLength:\n typeof parsed.promptLength === \"number\" ? parsed.promptLength : 0,\n retrievalQueryHash:\n typeof parsed.retrievalQueryHash === \"string\"\n ? parsed.retrievalQueryHash\n : \"\",\n retrievalQueryLength:\n typeof parsed.retrievalQueryLength === \"number\"\n ? parsed.retrievalQueryLength\n : 0,\n plannerEnabled: parsed.plannerEnabled !== false,\n plannedMode:\n parsed.plannedMode === \"no_recall\" ||\n parsed.plannedMode === \"minimal\" ||\n parsed.plannedMode === \"full\" ||\n parsed.plannedMode === \"graph_mode\"\n ? parsed.plannedMode\n : \"full\",\n effectiveMode:\n parsed.effectiveMode === \"no_recall\" ||\n parsed.effectiveMode === \"minimal\" ||\n parsed.effectiveMode === \"full\" ||\n parsed.effectiveMode === \"graph_mode\"\n ? parsed.effectiveMode\n : \"full\",\n recallResultLimit:\n typeof parsed.recallResultLimit === \"number\"\n ? parsed.recallResultLimit\n : 0,\n queryIntent: parseMemoryIntentSnapshot(parsed.queryIntent),\n graphExpandedIntentDetected:\n parsed.graphExpandedIntentDetected === true,\n graphDecision: {\n status:\n graphDecision?.status === \"skipped\" ||\n graphDecision?.status === \"completed\" ||\n graphDecision?.status === \"aborted\"\n ? graphDecision.status\n : \"not_requested\",\n reason:\n typeof graphDecision?.reason === \"string\"\n ? graphDecision.reason\n : undefined,\n shadowMode: graphDecision?.shadowMode === true,\n qmdAvailable: graphDecision?.qmdAvailable !== false,\n graphRecallEnabled: graphDecision?.graphRecallEnabled !== false,\n multiGraphMemoryEnabled:\n graphDecision?.multiGraphMemoryEnabled !== false,\n },\n };\n } catch {\n return null;\n }\n }\n\n async getLastQmdRecallSnapshot(\n namespace?: string,\n ): Promise<QmdRecallSnapshot | null> {\n const storage = await this.getStorage(namespace);\n const snapshotPath = path.join(\n storage.dir,\n \"state\",\n \"last_qmd_recall.json\",\n );\n try {\n const raw = await readFile(snapshotPath, \"utf-8\");\n const parsed = JSON.parse(raw) as Partial<QmdRecallSnapshot>;\n if (!parsed || typeof parsed !== \"object\") return null;\n return {\n recordedAt:\n typeof parsed.recordedAt === \"string\" ? parsed.recordedAt : \"\",\n queryHash: typeof parsed.queryHash === \"string\" ? parsed.queryHash : \"\",\n queryLength:\n typeof parsed.queryLength === \"number\" ? parsed.queryLength : 0,\n collection:\n typeof parsed.collection === \"string\" ? parsed.collection : undefined,\n namespaces: Array.isArray(parsed.namespaces)\n ? parsed.namespaces.filter(\n (value): value is string => typeof value === \"string\",\n )\n : [],\n fetchLimit:\n typeof parsed.fetchLimit === \"number\" ? parsed.fetchLimit : 0,\n primaryResultCount:\n typeof parsed.primaryResultCount === \"number\"\n ? parsed.primaryResultCount\n : 0,\n hybridResultCount:\n typeof parsed.hybridResultCount === \"number\"\n ? parsed.hybridResultCount\n : 0,\n queryAwareSeedCount:\n typeof parsed.queryAwareSeedCount === \"number\"\n ? parsed.queryAwareSeedCount\n : 0,\n resultCount:\n typeof parsed.resultCount === \"number\" ? parsed.resultCount : 0,\n intentHint:\n typeof parsed.intentHint === \"string\" ? parsed.intentHint : undefined,\n explainEnabled: parsed.explainEnabled === true,\n hybridTopUpUsed: parsed.hybridTopUpUsed === true,\n hybridTopUpSkippedReason:\n typeof parsed.hybridTopUpSkippedReason === \"string\"\n ? parsed.hybridTopUpSkippedReason\n : undefined,\n results: parseQmdRecallResults(parsed.results),\n };\n } catch {\n return null;\n }\n }\n\n async explainLastGraphRecall(options?: {\n namespace?: string;\n maxExpanded?: number;\n }): Promise<string> {\n const snapshot = await this.getLastGraphRecallSnapshot(options?.namespace);\n if (!snapshot) return \"No graph-recall snapshot found yet.\";\n const maxExpanded = Math.max(1, Math.min(50, options?.maxExpanded ?? 10));\n const expanded = snapshot.expanded.slice(0, maxExpanded);\n const seedResults = (snapshot.seedResults ?? []).slice(0, maxExpanded);\n const finalResults = (snapshot.finalResults ?? []).slice(0, maxExpanded);\n const queryIntent = snapshot.queryIntent ?? {\n goal: \"unknown\",\n actionType: \"unknown\",\n entityTypes: [],\n };\n return [\n \"## Last Graph Recall\",\n \"\",\n `Recorded at: ${snapshot.recordedAt || \"unknown\"}`,\n `Mode: ${snapshot.mode}`,\n `Status: ${snapshot.status ?? \"completed\"}${snapshot.shadowMode ? \" (shadow)\" : \"\"}`,\n `Reason: ${snapshot.reason ?? \"n/a\"}`,\n `Query hash: ${snapshot.queryHash || \"unknown\"} (len=${snapshot.queryLength})`,\n `Query intent: goal=${queryIntent.goal}, action=${queryIntent.actionType}, entityTypes=${queryIntent.entityTypes.length > 0 ? queryIntent.entityTypes.join(\", \") : \"none\"}`,\n `Namespaces: ${snapshot.namespaces.length > 0 ? snapshot.namespaces.join(\", \") : \"none\"}`,\n `Seed results (${snapshot.seedResults?.length ?? 0}, showing ${seedResults.length}):`,\n ...seedResults.map(\n (entry) =>\n `- ${entry.path} (score=${entry.score.toFixed(3)}, sources=${entry.sourceLabels.join(\",\") || \"baseline\"})`,\n ),\n `Seed paths (${snapshot.seedCount}):`,\n ...snapshot.seeds.map((p) => `- ${p}`),\n `Expanded paths (${snapshot.expandedCount}, showing ${expanded.length}):`,\n ...expanded.map((e) => {\n // Issue #681 PR 3/3 — surface per-edge confidence in the\n // graph-explain document. Legacy snapshots without\n // `edgeConfidence` render as `conf=n/a` so older payloads\n // remain readable.\n const confLabel =\n typeof e.edgeConfidence === \"number\" && Number.isFinite(e.edgeConfidence)\n ? e.edgeConfidence.toFixed(2)\n : \"n/a\";\n return `- ${e.path} (score=${e.score.toFixed(3)}, ns=${e.namespace}, seed=${e.seed || \"unknown\"}, hop=${e.hopDepth}, w=${e.decayedWeight.toFixed(3)}, type=${e.graphType}, conf=${confLabel})`;\n }),\n `Final ranked results (${snapshot.finalResults?.length ?? 0}, showing ${finalResults.length}):`,\n ...finalResults.map(\n (entry) =>\n `- ${entry.path} (score=${entry.score.toFixed(3)}, sources=${entry.sourceLabels.join(\",\") || \"baseline\"})`,\n ),\n ...(snapshot.shadowComparison\n ? [\n `Shadow comparison: baseline=${snapshot.shadowComparison.baselineCount}, graph=${snapshot.shadowComparison.graphCount}, overlap=${snapshot.shadowComparison.overlapCount} (${snapshot.shadowComparison.overlapRatio.toFixed(2)}), avgDelta=${snapshot.shadowComparison.averageOverlapDelta.toFixed(3)}`,\n ]\n : []),\n ].join(\"\\n\");\n }\n\n async explainLastIntent(options?: { namespace?: string }): Promise<string> {\n const snapshot = await this.getLastIntentSnapshot(options?.namespace);\n if (!snapshot) return \"No intent-debug snapshot found yet.\";\n return [\n \"## Last Intent Debug\",\n \"\",\n `Recorded at: ${snapshot.recordedAt || \"unknown\"}`,\n `Prompt hash: ${snapshot.promptHash || \"unknown\"} (len=${snapshot.promptLength})`,\n `Retrieval query hash: ${snapshot.retrievalQueryHash || \"unknown\"} (len=${snapshot.retrievalQueryLength})`,\n `Planner enabled: ${snapshot.plannerEnabled ? \"yes\" : \"no\"}`,\n `Planned mode: ${snapshot.plannedMode}`,\n `Effective mode: ${snapshot.effectiveMode}`,\n `Recall result limit: ${snapshot.recallResultLimit}`,\n `Query intent: goal=${snapshot.queryIntent.goal}, action=${snapshot.queryIntent.actionType}, entityTypes=${snapshot.queryIntent.entityTypes.length > 0 ? snapshot.queryIntent.entityTypes.join(\", \") : \"none\"}`,\n `Broad graph intent: ${snapshot.graphExpandedIntentDetected ? \"yes\" : \"no\"}`,\n `Graph decision: status=${snapshot.graphDecision.status}, reason=${snapshot.graphDecision.reason ?? \"n/a\"}, shadow=${snapshot.graphDecision.shadowMode ? \"yes\" : \"no\"}, qmdAvailable=${snapshot.graphDecision.qmdAvailable ? \"yes\" : \"no\"}, graphRecallEnabled=${snapshot.graphDecision.graphRecallEnabled ? \"yes\" : \"no\"}, multiGraphMemoryEnabled=${snapshot.graphDecision.multiGraphMemoryEnabled ? \"yes\" : \"no\"}`,\n ].join(\"\\n\");\n }\n\n async explainLastQmdRecall(options?: {\n namespace?: string;\n maxResults?: number;\n }): Promise<string> {\n const snapshot = await this.getLastQmdRecallSnapshot(options?.namespace);\n if (!snapshot) return \"No QMD recall snapshot found yet.\";\n const maxResults = Math.max(1, Math.min(25, options?.maxResults ?? 10));\n const shown = snapshot.results.slice(0, maxResults);\n return [\n \"## Last QMD Recall\",\n \"\",\n `Recorded at: ${snapshot.recordedAt || \"unknown\"}`,\n `Query hash: ${snapshot.queryHash || \"unknown\"} (len=${snapshot.queryLength})`,\n `Collection: ${snapshot.collection ?? \"default\"}`,\n `Namespaces: ${snapshot.namespaces.length > 0 ? snapshot.namespaces.join(\", \") : \"none\"}`,\n `Fetch limit: ${snapshot.fetchLimit}`,\n `Primary results: ${snapshot.primaryResultCount}`,\n `Hybrid top-up results: ${snapshot.hybridResultCount}`,\n `Query-aware seeds: ${snapshot.queryAwareSeedCount}`,\n `Final results: ${snapshot.resultCount}`,\n `Intent hint: ${snapshot.intentHint ?? \"none\"}`,\n `Explain enabled: ${snapshot.explainEnabled ? \"yes\" : \"no\"}`,\n `Hybrid top-up used: ${snapshot.hybridTopUpUsed ? \"yes\" : \"no\"}`,\n `Hybrid top-up skipped reason: ${snapshot.hybridTopUpSkippedReason ?? \"n/a\"}`,\n `Top results (${shown.length}):`,\n ...shown.map((result) => {\n const explainParts = [\n typeof result.explain?.blendedScore === \"number\"\n ? `blended=${result.explain.blendedScore.toFixed(3)}`\n : null,\n typeof result.explain?.rerankScore === \"number\"\n ? `rerank=${result.explain.rerankScore.toFixed(3)}`\n : null,\n typeof result.explain?.rrf === \"number\"\n ? `rrf=${result.explain.rrf.toFixed(3)}`\n : null,\n ].filter((entry): entry is string => Boolean(entry));\n const explainText =\n explainParts.length > 0 ? `, explain=${explainParts.join(\"/\")}` : \"\";\n return `- ${result.path} (score=${result.score.toFixed(3)}, transport=${result.transport ?? \"unknown\"}${explainText})`;\n }),\n ].join(\"\\n\");\n }\n\n private async searchConversationRecallResults(\n retrievalQuery: string,\n topK: number,\n ): Promise<Array<{ path: string; snippet: string; score: number }>> {\n if (this.conversationIndexBackend) {\n return this.conversationIndexBackend.search(retrievalQuery, topK);\n }\n return [];\n }\n\n private formatConversationRecallSection(\n results: Array<{ path: string; snippet: string; score: number }>,\n maxChars: number,\n ): string | null {\n if (!Array.isArray(results) || results.length === 0) return null;\n const lines: string[] = [\"## Semantic Recall (Past Conversations)\", \"\"];\n let used = 0;\n for (const r of results) {\n if (!r?.snippet) continue;\n const chunk =\n `### ${r.path}\\n` +\n `Score: ${r.score.toFixed(3)}\\n\\n` +\n `${r.snippet.trim()}\\n`;\n if (used + chunk.length > maxChars) break;\n lines.push(chunk);\n used += chunk.length;\n }\n return used > 0 ? lines.join(\"\\n\") : null;\n }\n\n private async countConversationChunkDocs(dir: string): Promise<number> {\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n let total = 0;\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n total += await this.countConversationChunkDocs(fullPath);\n continue;\n }\n if (entry.isFile() && entry.name.endsWith(\".md\")) {\n total += 1;\n }\n }\n return total;\n } catch {\n return 0;\n }\n }\n\n private async buildConversationIndexChunks(\n sessionKey?: string,\n hours: number = 24,\n ): Promise<ReturnType<typeof chunkTranscriptEntries>> {\n const entries = await this.transcript.readRecent(hours, sessionKey);\n const effectiveSessionKey = sessionKey ?? \"all-sessions\";\n return chunkTranscriptEntries(effectiveSessionKey, entries, {\n maxChars: this.config.conversationRecallMaxChars * 2,\n maxTurns: Math.max(10, this.config.hourlySummariesMaxTurnsPerRun),\n });\n }\n\n async getConversationIndexHealth(): Promise<{\n enabled: boolean;\n backend: \"qmd\" | \"faiss\";\n status: \"ok\" | \"degraded\" | \"disabled\";\n chunkDocCount: number;\n lastUpdateAt: string | null;\n qmdAvailable?: boolean;\n faiss?: {\n ok: boolean;\n status: \"ok\" | \"degraded\" | \"error\";\n indexPath: string;\n message?: string;\n manifest?: {\n version: number;\n modelId: string;\n normalizedModelId: string;\n dimension: number;\n chunkCount: number;\n updatedAt: string;\n lastSuccessfulRebuildAt: string;\n };\n };\n }> {\n const chunkDocCount = await this.countConversationChunkDocs(\n this.conversationIndexDir,\n );\n const lastUpdateAtMs = Math.max(\n 0,\n ...this.conversationIndexLastUpdateAtMs.values(),\n );\n const lastUpdateAt =\n lastUpdateAtMs > 0 ? new Date(lastUpdateAtMs).toISOString() : null;\n\n if (!this.config.conversationIndexEnabled) {\n return {\n enabled: false,\n backend: this.config.conversationIndexBackend,\n status: \"disabled\",\n chunkDocCount,\n lastUpdateAt,\n };\n }\n const backendHealth = this.conversationIndexBackend\n ? await this.conversationIndexBackend.health()\n : {\n backend: this.config.conversationIndexBackend,\n status: \"degraded\" as const,\n };\n return {\n enabled: true,\n chunkDocCount,\n lastUpdateAt,\n ...backendHealth,\n };\n }\n\n async inspectConversationIndex(): Promise<\n ConversationIndexBackendInspection & {\n enabled: boolean;\n chunkDocCount: number;\n lastUpdateAt: string | null;\n }\n > {\n const chunkDocCount = await this.countConversationChunkDocs(\n this.conversationIndexDir,\n );\n const lastUpdateAtMs = Math.max(\n 0,\n ...this.conversationIndexLastUpdateAtMs.values(),\n );\n const lastUpdateAt =\n lastUpdateAtMs > 0 ? new Date(lastUpdateAtMs).toISOString() : null;\n\n if (!this.config.conversationIndexEnabled) {\n return {\n enabled: false,\n backend: this.config.conversationIndexBackend,\n status: \"disabled\",\n available: false,\n indexPath: this.conversationIndexDir,\n supportsIncrementalUpdate: true,\n message: \"Conversation index disabled by config\",\n metadata: {\n chunkCount: chunkDocCount,\n },\n chunkDocCount,\n lastUpdateAt,\n };\n }\n\n const inspection = this.conversationIndexBackend\n ? await this.conversationIndexBackend.inspect()\n : {\n backend: this.config.conversationIndexBackend,\n status: \"degraded\" as const,\n available: false,\n indexPath: this.conversationIndexDir,\n supportsIncrementalUpdate: true,\n message: \"Conversation index backend unavailable\",\n metadata: {\n chunkCount: chunkDocCount,\n },\n };\n\n return {\n enabled: true,\n chunkDocCount,\n lastUpdateAt,\n ...inspection,\n };\n }\n\n async getRecoverySummary(sessionKey?: string): Promise<{\n generatedAt: string;\n sessionKey?: string;\n healthy: boolean;\n issueCount: number;\n incompleteTurns: number;\n brokenChains: number;\n checkpointHealthy: boolean;\n }> {\n return this.transcript.getRecoverySummary(sessionKey);\n }\n\n async updateConversationIndex(\n sessionKey: string,\n hours: number = 24,\n opts?: { embed?: boolean; enforceMinInterval?: boolean },\n ): Promise<{\n chunks: number;\n skipped: boolean;\n reason?: string;\n retryAfterMs?: number;\n embedded?: boolean;\n }> {\n if (!this.config.conversationIndexEnabled) {\n return { chunks: 0, skipped: true, reason: \"disabled\", embedded: false };\n }\n const enforceMinInterval = opts?.enforceMinInterval !== false;\n if (enforceMinInterval) {\n const minIntervalMs = Math.max(\n 0,\n this.config.conversationIndexMinUpdateIntervalMs,\n );\n const now = Date.now();\n const last = this.conversationIndexLastUpdateAtMs.get(sessionKey) ?? 0;\n const elapsed = now - last;\n if (minIntervalMs > 0 && elapsed < minIntervalMs) {\n return {\n chunks: 0,\n skipped: true,\n reason: \"min_interval\",\n retryAfterMs: minIntervalMs - elapsed,\n embedded: false,\n };\n }\n }\n const chunks = await this.buildConversationIndexChunks(sessionKey, hours);\n await writeConversationChunks(this.conversationIndexDir, chunks);\n const retentionCutoffMs =\n Number.isFinite(this.config.conversationIndexRetentionDays) &&\n this.config.conversationIndexRetentionDays > 0\n ? Date.now() -\n this.config.conversationIndexRetentionDays * 24 * 60 * 60 * 1000\n : undefined;\n await cleanupConversationChunks(\n this.conversationIndexDir,\n this.config.conversationIndexRetentionDays,\n );\n const shouldEmbed =\n opts?.embed ?? this.config.conversationIndexEmbedOnUpdate;\n let embedded = false;\n\n if (this.conversationIndexBackend) {\n const result = await this.conversationIndexBackend.update(chunks, {\n embed: shouldEmbed,\n ...(retentionCutoffMs !== undefined ? { retentionCutoffMs } : {}),\n });\n embedded = result.embedded;\n }\n\n this.conversationIndexLastUpdateAtMs.set(sessionKey, Date.now());\n return { chunks: chunks.length, skipped: false, embedded };\n }\n\n async rebuildConversationIndex(\n sessionKey?: string,\n hours: number = 24,\n opts?: { embed?: boolean },\n ): Promise<{\n chunks: number;\n skipped: boolean;\n reason?: string;\n embedded?: boolean;\n rebuilt?: boolean;\n }> {\n if (!this.config.conversationIndexEnabled) {\n return {\n chunks: 0,\n skipped: true,\n reason: \"disabled\",\n embedded: false,\n rebuilt: false,\n };\n }\n\n const chunks = await this.buildConversationIndexChunks(sessionKey, hours);\n await writeConversationChunks(this.conversationIndexDir, chunks);\n await cleanupConversationChunks(\n this.conversationIndexDir,\n this.config.conversationIndexRetentionDays,\n );\n\n const shouldEmbed =\n opts?.embed ?? this.config.conversationIndexEmbedOnUpdate;\n let embedded = false;\n let rebuilt = false;\n if (this.conversationIndexBackend) {\n const result = await this.conversationIndexBackend.rebuild(chunks, {\n embed: shouldEmbed,\n });\n embedded = result.embedded;\n rebuilt = result.rebuilt;\n }\n\n const stamp = Date.now();\n if (sessionKey) {\n this.conversationIndexLastUpdateAtMs.set(sessionKey, stamp);\n } else {\n this.conversationIndexLastUpdateAtMs.set(\"__rebuild__\", stamp);\n }\n return { chunks: chunks.length, skipped: false, embedded, rebuilt };\n }\n\n /**\n * Validate local LLM model availability and context window compatibility.\n * Warns the user if there's a mismatch.\n */\n private async validateLocalLlmModel(): Promise<void> {\n log.debug(\"Local LLM: validating model configuration\");\n try {\n const modelInfo = await this.localLlm.getLoadedModelInfo();\n if (!modelInfo) {\n log.warn(\n \"Local LLM validation: Could not query model info from server\",\n );\n log.warn(\n \"Local LLM validation: Could not query model info. \" +\n \"Ensure LM Studio/Ollama is running with the model loaded.\",\n );\n return;\n }\n\n // Check for context window mismatch\n const configuredMaxContext = this.config.localLlmMaxContext;\n\n if (modelInfo.contextWindow) {\n log.debug(\n `Local LLM: ${modelInfo.id} loaded with ${modelInfo.contextWindow.toLocaleString()} token context window`,\n );\n\n if (\n configuredMaxContext &&\n configuredMaxContext > modelInfo.contextWindow\n ) {\n log.warn(\n `Local LLM context mismatch: engram configured for ${configuredMaxContext.toLocaleString()} tokens, ` +\n `but ${modelInfo.id} only supports ${modelInfo.contextWindow.toLocaleString()}. ` +\n `Reducing to ${modelInfo.contextWindow.toLocaleString()} to avoid errors.`,\n );\n // Update the config in-memory to match actual capability\n // (This is a temporary fix - user should update their config)\n (this.config as { localLlmMaxContext?: number }).localLlmMaxContext =\n modelInfo.contextWindow;\n }\n } else {\n log.debug(\n `Local LLM: ${modelInfo.id} loaded (context window not reported by server)`,\n );\n\n if (!configuredMaxContext) {\n log.warn(\n \"Local LLM: Server did not report context window. \" +\n \"If you get 'context length exceeded' errors, set localLlmMaxContext in your config. \" +\n \"Common defaults: LM Studio (32K), Ollama (2K-128K depending on model).\",\n );\n }\n }\n } catch (err) {\n log.warn(`Local LLM validation failed: ${err}`);\n }\n }\n\n async recall(\n prompt: string,\n sessionKey?: string,\n options: RecallInvocationOptions = {},\n ): Promise<string> {\n const abortController = new AbortController();\n const onAbort = () => {\n abortController.abort();\n };\n if (options.abortSignal?.aborted) {\n abortController.abort();\n } else {\n options.abortSignal?.addEventListener(\"abort\", onAbort, { once: true });\n }\n\n const principal =\n typeof options.principalOverride === \"string\" &&\n options.principalOverride.length > 0\n ? options.principalOverride\n : resolvePrincipal(sessionKey, this.config);\n if (this.config.namespacesEnabled && !principal) {\n throw new Error(\"authentication required: namespaces are enabled and no principal was supplied\");\n }\n\n // Wait for initialization to complete before attempting recall. The timeout\n // is configurable so OpenClaw's per-hook budget and Remnic's internal init\n // gate can stay aligned during cold starts.\n let initGateTimeoutHandle: NodeJS.Timeout | null = null;\n let onInitGateAbort: (() => void) | null = null;\n if (this.initPromise) {\n const gateResult = await Promise.race([\n this.initPromise.then(() => \"ok\" as const),\n new Promise<\"timeout\">((resolve) => {\n initGateTimeoutHandle = setTimeout(\n () => resolve(\"timeout\"),\n this.config.initGateTimeoutMs,\n );\n }),\n abortController.signal.aborted\n ? Promise.resolve(\"aborted\" as const)\n : new Promise<\"aborted\">((resolve) => {\n onInitGateAbort = () => resolve(\"aborted\");\n abortController.signal.addEventListener(\n \"abort\",\n onInitGateAbort,\n { once: true },\n );\n }),\n ]);\n if (initGateTimeoutHandle) clearTimeout(initGateTimeoutHandle);\n if (onInitGateAbort)\n abortController.signal.removeEventListener(\"abort\", onInitGateAbort);\n if (gateResult === \"aborted\") {\n this.logRecallFailure(abortRecallError(\"recall aborted before init\"));\n return \"\";\n }\n if (gateResult === \"timeout\") {\n log.warn(\"recall: init gate timed out — proceeding without full init\");\n }\n }\n\n // Secure-store lock gate (issue #690 PR 3/4).\n // If secure-store is enabled but the keyring holds no key for this\n // memory directory, reject recall with a clear human-readable error\n // rather than surfacing a cryptic SecureStoreLockedError from deep\n // inside the storage layer.\n if (this.config.secureStoreEnabled && !this.storage.isSecureStoreUnlocked()) {\n const lockedMsg =\n \"[secure-store locked] Memory store is encrypted and locked. \" +\n \"Unlock the secure-store inside this daemon process, or restart the daemon through a secure-store aware launcher that installs the key.\";\n log.warn(\"recall blocked: secure-store is locked\");\n return lockedMsg;\n }\n\n // Keep outer recall timeout above worst-case serialized hybrid search:\n // QMD subprocess BM25 (30s) + vector (30s) can consume ~60s under contention.\n try {\n const recallPromise = this.recallInternal(prompt, sessionKey, {\n ...options,\n abortSignal: abortController.signal,\n });\n const RECALL_TIMEOUT_MS = this.config.recallOuterTimeoutMs ?? 75_000;\n if (RECALL_TIMEOUT_MS <= 0) {\n return await recallPromise;\n }\n\n let timeoutHandle: NodeJS.Timeout | null = null;\n const timeoutPromise = new Promise<string>((_, reject) => {\n timeoutHandle = setTimeout(() => {\n abortController.abort();\n reject(new Error(\"recall timeout\"));\n }, RECALL_TIMEOUT_MS);\n });\n\n let recallResult: string;\n try {\n recallResult = await Promise.race([recallPromise, timeoutPromise]);\n } finally {\n if (timeoutHandle) clearTimeout(timeoutHandle);\n }\n\n // Observation-mode direct-answer tier (issue #518 slice 3c).\n // Runs after the user's recall already succeeded, fire-and-forget,\n // so annotation latency can never delay the caller's response.\n if (this.config.recallDirectAnswerEnabled && sessionKey) {\n try {\n this.enqueueDirectAnswerObservation(\n prompt,\n sessionKey,\n options.namespace?.trim() || undefined,\n options.principalOverride,\n );\n } catch (err) {\n log.debug(`direct-answer observation setup failed: ${err}`);\n }\n }\n\n return recallResult;\n } catch (err) {\n this.logRecallFailure(err);\n // endTrace() is safe here: if no trace is active (disabled or already\n // closed by recallInternal's try/finally), it returns null immediately.\n this.profiler.endTrace();\n return \"\"; // Return empty context on timeout/error\n } finally {\n options.abortSignal?.removeEventListener(\"abort\", onAbort);\n }\n }\n\n /**\n * Return the most recent X-ray snapshot captured during a\n * `recall()` call that passed `xrayCapture: true` (issue #570 PR 1).\n * Returns `null` when no such capture has occurred on this\n * orchestrator instance. Returned snapshot is a deep copy so\n * caller mutation cannot tear the stored value.\n */\n getLastXraySnapshot(): RecallXraySnapshot | null {\n if (!this.lastXraySnapshot) return null;\n return structuredClone(this.lastXraySnapshot);\n }\n\n /** Clear the captured X-ray snapshot. Exposed for tests / explicit reset. */\n clearLastXraySnapshot(): void {\n this.lastXraySnapshot = null;\n }\n\n /**\n * Await the in-flight observation-mode direct-answer annotation chain.\n * Resolves to true when settled, false on timeout.\n */\n async waitForDirectAnswerObservationIdle(\n timeoutMs: number = 60_000,\n ): Promise<boolean> {\n let timeoutHandle: NodeJS.Timeout | null = null;\n try {\n const timeoutPromise = new Promise<\"timeout\">((resolve) => {\n timeoutHandle = setTimeout(() => resolve(\"timeout\"), timeoutMs);\n });\n const result = await Promise.race([\n this.directAnswerObservationChain.then(() => \"ok\" as const),\n timeoutPromise,\n ]);\n if (result === \"timeout\") {\n log.warn(\n `waitForDirectAnswerObservationIdle timed out after ${timeoutMs}ms`,\n );\n return false;\n }\n return true;\n } finally {\n if (timeoutHandle) clearTimeout(timeoutHandle);\n }\n }\n\n private enqueueDirectAnswerObservation(\n prompt: string,\n sessionKey: string,\n namespaceOverride: string | undefined,\n principalOverride: string | undefined,\n ): void {\n const expectedSnapshot = this.lastRecall.get(sessionKey);\n if (expectedSnapshot === null) return;\n if (expectedSnapshot.plannerMode === \"no_recall\") return;\n\n const principal = principalOverride ?? resolvePrincipal(sessionKey, this.config);\n // Coding-agent overlay (issue #569) is applied when the session has a\n // coding context and there is no explicit namespaceOverride — mirrors\n // the main recall path above.\n const observationCodingOverlay =\n namespaceOverride && canReadNamespace(principal, namespaceOverride, this.config)\n ? null\n : this.applyCodingRecallOverlay(sessionKey);\n const observationPrincipalSelf = defaultNamespaceForPrincipal(principal, this.config);\n const observationCodingSelf = observationCodingOverlay\n ? combineNamespaces(observationPrincipalSelf, observationCodingOverlay.namespace)\n : null;\n const observationScopeProfilePlan =\n namespaceOverride && canReadNamespace(principal, namespaceOverride, this.config)\n ? null\n : resolveScopeProfilePlan({\n config: this.config,\n principal,\n codingContext: sessionKey\n ? this.getCodingContextForSession(sessionKey)\n : null,\n codingOverlay: observationCodingOverlay,\n });\n let observationNamespaces: string[];\n if (namespaceOverride && canReadNamespace(principal, namespaceOverride, this.config)) {\n observationNamespaces = [namespaceOverride];\n } else if (observationScopeProfilePlan) {\n observationNamespaces = expandScopeProfileReadNamespaces({\n profilePlan: observationScopeProfilePlan,\n principalSelfNamespace: observationScopeProfilePlan.baseNamespace,\n config: this.config,\n principal,\n codingOverlay: observationCodingOverlay,\n legacyRecallNamespaces: recallNamespacesForPrincipal(principal, this.config),\n });\n } else if (observationCodingOverlay && observationCodingSelf) {\n // Rule 42 / parity with the main recall path: substitute the self\n // namespace within the principal's recall list rather than\n // replacing the full list. Preserves shared and policy-include\n // namespaces for direct-answer observation queries.\n const base = recallNamespacesForPrincipal(principal, this.config);\n const mapped = base.map((ns) =>\n ns === observationPrincipalSelf ? observationCodingSelf : ns,\n );\n const fallbackNs = observationCodingOverlay.readFallbacks.map((fallback) =>\n combineNamespaces(observationPrincipalSelf, fallback),\n );\n observationNamespaces = Array.from(new Set<string>([...mapped, ...fallbackNs]));\n } else {\n observationNamespaces = recallNamespacesForPrincipal(principal, this.config);\n }\n const observationQueryPolicy = buildRecallQueryPolicy(prompt, sessionKey, {\n cronRecallPolicyEnabled: this.config.cronRecallPolicyEnabled,\n cronRecallNormalizedQueryMaxChars:\n this.config.cronRecallNormalizedQueryMaxChars,\n cronRecallInstructionHeavyTokenCap:\n this.effectiveCronRecallInstructionHeavyTokenCap(),\n cronConversationRecallMode: this.config.cronConversationRecallMode,\n });\n const observationQuery = observationQueryPolicy.retrievalQuery || prompt;\n const expectedIdentity = {\n writeNonce: expectedSnapshot.writeNonce,\n traceId: expectedSnapshot.traceId,\n recordedAt: expectedSnapshot.recordedAt,\n };\n const previous = this.directAnswerObservationChain;\n this.directAnswerObservationChain = previous\n .catch(() => undefined)\n .then(async () => {\n try {\n await this.annotateDirectAnswerTier(\n observationQuery,\n sessionKey,\n observationNamespaces,\n expectedIdentity,\n undefined,\n );\n } catch (err) {\n log.debug(`direct-answer observation chain error: ${err}`);\n }\n });\n }\n\n private async annotateDirectAnswerTier(\n prompt: string,\n sessionKey: string,\n namespaces: string[],\n expectedIdentity:\n | { writeNonce?: string; traceId?: string; recordedAt?: string }\n | undefined,\n _parentAbortSignal?: AbortSignal,\n ): Promise<void> {\n const tierStart = Date.now();\n try {\n if (namespaces.length === 0) return;\n\n const trustZoneByNsAndRecordId = new Map<\n string,\n \"quarantine\" | \"working\" | \"trusted\"\n >();\n const trustZoneKey = (ns: string, recordId: string) =>\n `${ns}\\u0000${recordId}`;\n const scopedStorages = new Map<\n string,\n Awaited<ReturnType<typeof this.storageRouter.storageFor>>\n >();\n\n for (const ns of namespaces) {\n const storage = await this.storageRouter.storageFor(ns);\n scopedStorages.set(ns, storage);\n const trustZones = await listTrustZoneRecords({\n memoryDir: storage.dir,\n trustZoneStoreDir: this.config.trustZoneStoreDir,\n limit: 200,\n }).catch(() => ({\n allRecords: [] as Array<{\n recordId: string;\n zone: \"quarantine\" | \"working\" | \"trusted\";\n }>,\n }));\n for (const record of trustZones.allRecords ?? []) {\n trustZoneByNsAndRecordId.set(\n trustZoneKey(ns, record.recordId),\n record.zone,\n );\n }\n }\n\n const memoryNamespaceByPath = new Map<string, string>();\n const memoryNamespaceById = new Map<string, string>();\n let candidatesConsidered = 0;\n\n const sources: DirectAnswerSources = {\n taxonomy: DEFAULT_TAXONOMY,\n listCandidateMemories: async (options: { namespace: string; abortSignal?: AbortSignal }) => {\n const targetNs = options.namespace;\n const storage =\n scopedStorages.get(targetNs) ??\n (await this.storageRouter.storageFor(targetNs));\n const all = await storage.readAllMemories();\n const active: MemoryFile[] = [];\n for (const m of all) {\n if ((m.frontmatter.status ?? \"active\") === \"active\") {\n active.push(m);\n memoryNamespaceByPath.set(m.path, targetNs);\n if (m.frontmatter.id) {\n memoryNamespaceById.set(m.frontmatter.id, targetNs);\n }\n }\n }\n candidatesConsidered += active.length;\n return active;\n },\n trustZoneFor: async (memoryId: string) => {\n const ns = memoryNamespaceById.get(memoryId);\n if (!ns) return null;\n return (\n trustZoneByNsAndRecordId.get(\n trustZoneKey(ns, memoryId),\n ) ?? null\n );\n },\n importanceFor: (memory) =>\n typeof memory.frontmatter.importance?.score === \"number\"\n ? memory.frontmatter.importance.score\n : 0,\n };\n\n let result: import(\"./direct-answer.js\").DirectAnswerResult | undefined;\n for (const ns of namespaces) {\n const r = await tryDirectAnswer({\n query: prompt,\n namespace: ns,\n config: this.config,\n sources,\n });\n if (r.eligible && r.winner) {\n result = r;\n break;\n }\n }\n\n if (!result?.eligible || !result?.winner) return;\n\n const explain: RecallTierExplain = {\n tier: \"direct-answer\",\n tierReason: result.narrative,\n filteredBy: result.filteredBy,\n candidatesConsidered,\n latencyMs: Date.now() - tierStart,\n sourceAnchors: [{ path: result.winner.memory.path }],\n };\n\n await this.lastRecall.annotateTierExplain(\n sessionKey,\n explain,\n expectedIdentity,\n );\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") return;\n log.debug(`direct-answer observation failed: ${err}`);\n }\n }\n\n private logRecallFailure(err: unknown): void {\n const now = Date.now();\n const errorMsg = err instanceof Error ? err.message : String(err);\n const LOG_WINDOW_MS = 60_000;\n const idleSinceLastFailureMs = now - this.lastRecallFailureAtMs;\n this.lastRecallFailureAtMs = now;\n if (idleSinceLastFailureMs >= LOG_WINDOW_MS) {\n this.suppressedRecallFailures = 0;\n }\n\n if (now - this.lastRecallFailureLogAtMs >= LOG_WINDOW_MS) {\n const suffix =\n this.suppressedRecallFailures > 0\n ? ` (suppressed ${this.suppressedRecallFailures} similar failures in last minute)`\n : \"\";\n log.warn(`recall timed out or failed: ${errorMsg}${suffix}`);\n this.lastRecallFailureLogAtMs = now;\n this.suppressedRecallFailures = 0;\n return;\n }\n\n this.suppressedRecallFailures += 1;\n log.debug(`recall timed out or failed (suppressed): ${errorMsg}`);\n }\n\n private artifactTypeForCategory(\n category: string,\n ):\n | \"decision\"\n | \"constraint\"\n | \"todo\"\n | \"definition\"\n | \"commitment\"\n | \"correction\"\n | \"fact\" {\n if (category === \"decision\") return \"decision\";\n if (category === \"commitment\") return \"commitment\";\n if (category === \"correction\") return \"correction\";\n if (category === \"principle\") return \"constraint\";\n return \"fact\";\n }\n\n private truncateArtifactForRecall(text: string, maxChars = 280): string {\n if (text.length <= maxChars) return text;\n return `${text.slice(0, maxChars - 1)}…`;\n }\n\n private async fetchActiveArtifactsForNamespace(\n namespace: string,\n prompt: string,\n targetCount: number,\n ): Promise<MemoryFile[]> {\n const storage = await this.storageRouter.storageFor(namespace);\n let fetchLimit = computeArtifactCandidateFetchLimit(targetCount);\n const maxFetchLimit = Math.min(800, Math.max(fetchLimit, targetCount * 8));\n const MAX_ATTEMPTS = 4;\n let bestFiltered: MemoryFile[] = [];\n\n for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt += 1) {\n const rawResults = await storage.searchArtifacts(prompt, fetchLimit);\n const sourceIds = Array.from(\n new Set(\n rawResults\n .map((a) => a.frontmatter.sourceMemoryId)\n .filter(\n (id): id is string => typeof id === \"string\" && id.length > 0,\n ),\n ),\n );\n const sourceStatus =\n sourceIds.length > 0\n ? await this.resolveArtifactSourceStatuses(storage, sourceIds)\n : new Map<string, \"active\" | \"superseded\" | \"archived\" | \"missing\">();\n\n const filtered: MemoryFile[] = [];\n for (const artifact of rawResults) {\n const sourceId = artifact.frontmatter.sourceMemoryId;\n if (!sourceId) {\n filtered.push(artifact);\n if (filtered.length >= targetCount) break;\n continue;\n }\n const status = sourceStatus.get(sourceId) ?? \"missing\";\n if (status !== \"active\") continue;\n filtered.push(artifact);\n if (filtered.length >= targetCount) break;\n }\n\n if (filtered.length >= targetCount) return filtered.slice(0, targetCount);\n if (filtered.length > bestFiltered.length) {\n bestFiltered = filtered;\n }\n if (rawResults.length === 0) return filtered;\n if (rawResults.length < fetchLimit && filtered.length > 0)\n return filtered;\n if (fetchLimit >= maxFetchLimit) return filtered;\n\n const growth = Math.max(targetCount * 2, 12);\n fetchLimit = Math.min(maxFetchLimit, fetchLimit + growth);\n }\n\n return bestFiltered;\n }\n\n private async recallArtifactsAcrossNamespaces(\n prompt: string,\n recallNamespaces: string[],\n targetCount: number,\n ): Promise<MemoryFile[]> {\n if (targetCount <= 0) return [];\n const namespaces = Array.from(new Set(recallNamespaces));\n const filteredByNamespace = await Promise.all(\n namespaces.map((namespace) =>\n this.fetchActiveArtifactsForNamespace(namespace, prompt, targetCount),\n ),\n );\n\n return mergeArtifactRecallCandidates(filteredByNamespace, targetCount);\n }\n\n private scopeQueryAwarePaths(\n paths: Set<string> | null,\n recallNamespaces: string[],\n ): Set<string> | null {\n if (!paths) return null;\n const scoped = new Set<string>();\n for (const memoryPath of paths) {\n if (!memoryPath || isArtifactMemoryPath(memoryPath)) continue;\n if (\n this.config.namespacesEnabled &&\n !recallNamespaces.includes(this.namespaceFromPath(memoryPath))\n ) {\n continue;\n }\n scoped.add(memoryPath);\n }\n return scoped;\n }\n\n private async buildQueryAwarePrefilter(\n prompt: string,\n recallNamespaces: string[],\n ): Promise<QueryAwarePrefilter> {\n if (!this.config.queryAwareIndexingEnabled || !prompt.trim()) {\n return {\n candidatePaths: null,\n temporalFromDate: null,\n matchedTags: [],\n expandedTags: [],\n combination: \"none\",\n filteredToFullSearch: false,\n };\n }\n\n const temporalFromDate = isTemporalQuery(prompt)\n ? recencyWindowFromPrompt(prompt, Date.now())\n : null;\n const [rawTemporal, tagSignals] = await Promise.all([\n temporalFromDate\n ? queryByDateRangeAsync(this.config.memoryDir, temporalFromDate)\n : Promise.resolve<Set<string> | null>(null),\n resolvePromptTagPrefilterAsync(this.config.memoryDir, prompt).catch(\n () => ({\n matchedTags: extractTagsFromPrompt(prompt),\n expandedTags: extractTagsFromPrompt(prompt),\n paths: null,\n }),\n ),\n ]);\n\n const temporalCandidates = this.scopeQueryAwarePaths(\n rawTemporal,\n recallNamespaces,\n );\n const tagCandidates = this.scopeQueryAwarePaths(\n tagSignals.paths,\n recallNamespaces,\n );\n const maxCandidates = this.config.queryAwareIndexingMaxCandidates;\n\n let candidatePaths: Set<string> | null = null;\n let combination: QueryAwarePrefilter[\"combination\"] = \"none\";\n let filteredToFullSearch = false;\n\n if (\n tagSignals.matchedTags.length > 0 &&\n tagCandidates !== null &&\n tagCandidates.size === 0\n ) {\n candidatePaths = tagCandidates;\n combination = \"tag\";\n } else if (temporalCandidates !== null && tagCandidates !== null) {\n const intersection = new Set(\n Array.from(temporalCandidates).filter((memoryPath) =>\n tagCandidates.has(memoryPath),\n ),\n );\n if (intersection.size > 0) {\n candidatePaths = intersection;\n combination = \"intersection\";\n } else {\n candidatePaths = new Set([...temporalCandidates, ...tagCandidates]);\n combination = \"union\";\n }\n } else if (temporalCandidates !== null) {\n candidatePaths = temporalCandidates;\n combination = \"temporal\";\n } else if (tagCandidates !== null) {\n candidatePaths = tagCandidates;\n combination = \"tag\";\n }\n\n if (\n candidatePaths &&\n maxCandidates > 0 &&\n candidatePaths.size > maxCandidates\n ) {\n filteredToFullSearch = true;\n candidatePaths = null;\n }\n\n return {\n candidatePaths,\n temporalFromDate,\n matchedTags: tagSignals.matchedTags,\n expandedTags: tagSignals.expandedTags,\n combination,\n filteredToFullSearch,\n };\n }\n\n private async searchScopedMemoryCandidates(\n candidatePaths: Set<string>,\n query: string,\n limit: number,\n options?: {\n allowArchived?: boolean;\n },\n ): Promise<QmdSearchResult[]> {\n const cappedLimit = Math.max(0, limit);\n if (cappedLimit === 0 || candidatePaths.size === 0) return [];\n\n const tokens = Array.from(new Set(tokenizeRecallQuery(query)));\n const memories = (\n await Promise.all(\n Array.from(candidatePaths).map(async (memoryPath) => {\n const namespace = this.config.namespacesEnabled\n ? this.namespaceFromPath(memoryPath)\n : this.config.defaultNamespace;\n const storage = await this.storageRouter.storageFor(namespace);\n return await storage.readMemoryByPath(memoryPath);\n }),\n )\n ).filter((memory): memory is MemoryFile => memory !== null);\n\n const results: QmdSearchResult[] = [];\n for (const memory of memories) {\n const status = memory.frontmatter.status ?? \"active\";\n if (!options?.allowArchived && status !== \"active\") continue;\n\n const haystack = [\n memory.content,\n memory.frontmatter.category,\n ...(memory.frontmatter.tags ?? []),\n ]\n .join(\" \")\n .toLowerCase();\n let hits = 0;\n for (const token of tokens) {\n if (haystack.includes(token)) hits += 1;\n }\n const score = tokens.length > 0 ? hits / tokens.length : 0.01;\n if (tokens.length > 0 && hits === 0) continue;\n\n results.push({\n docid: memory.frontmatter.id,\n path: memory.path,\n score,\n snippet: memory.content.slice(0, 400).replace(/\\n/g, \" \"),\n transport: \"scoped_prefilter\",\n });\n }\n\n return results.sort((a, b) => b.score - a.score).slice(0, cappedLimit);\n }\n\n private async fetchQmdMemoryResultsWithArtifactTopUp(\n prompt: string,\n qmdFetchLimit: number,\n qmdHybridFetchLimit: number,\n options: {\n namespacesEnabled: boolean;\n recallNamespaces: string[];\n resolveNamespace: (path: string) => string;\n collection?: string;\n queryAwarePrefilter?: QueryAwarePrefilter;\n searchOptions?: SearchQueryOptions;\n onDebugSnapshot?: (snapshot: QmdRecallSnapshot) => Promise<void>;\n abortSignal?: AbortSignal;\n },\n ): Promise<QmdSearchResult[]> {\n throwIfRecallAborted(options.abortSignal);\n const queryAwarePrefilter =\n options.queryAwarePrefilter ??\n (await this.buildQueryAwarePrefilter(prompt, options.recallNamespaces));\n const scopedSeedResults = queryAwarePrefilter.candidatePaths?.size\n ? await this.searchScopedMemoryCandidates(\n queryAwarePrefilter.candidatePaths,\n prompt,\n qmdFetchLimit,\n { allowArchived: options.collection !== undefined },\n )\n : [];\n\n let fetchLimit = Math.max(qmdFetchLimit, qmdHybridFetchLimit);\n const maxFetchLimit = Math.min(\n 320,\n Math.max(fetchLimit, qmdFetchLimit * 5),\n );\n const MAX_ATTEMPTS = 2;\n const qmdRecallBudgetMs = this.config.recallEnrichmentDeadlineMs ?? 25_000;\n const qmdRecallBudgetEnabled = qmdRecallBudgetMs > 0;\n const startedAtMs = Date.now();\n let lastPrimaryResultCount = 0;\n let lastHybridResultCount = 0;\n let lastHybridTopUpUsed = false;\n let lastHybridTopUpSkippedReason: string | undefined;\n const backendHonorsQmdSearchSignals =\n (this.config.searchBackend ?? \"qmd\") === \"qmd\";\n const resolvedSearchOptions = (() => {\n const resolver = (\n this.qmd as {\n resolveSupportedSearchOptions?: (\n options?: SearchQueryOptions,\n ) => SearchQueryOptions | undefined;\n }\n ).resolveSupportedSearchOptions;\n if (typeof resolver === \"function\") {\n return resolver.call(this.qmd, options.searchOptions);\n }\n return options.searchOptions;\n })();\n const primarySearchOptions = backendHonorsQmdSearchSignals\n ? resolvedSearchOptions\n : options.searchOptions;\n const debugSearchOptions = backendHonorsQmdSearchSignals\n ? resolvedSearchOptions\n : undefined;\n let bestFiltered = filterRecallCandidates(scopedSeedResults, {\n namespacesEnabled: options.namespacesEnabled,\n recallNamespaces: options.recallNamespaces,\n resolveNamespace: options.resolveNamespace,\n limit: qmdFetchLimit,\n });\n const emitDebugSnapshot = async (\n results: QmdSearchResult[],\n currentFetchLimit: number,\n ) => {\n if (!options.onDebugSnapshot) return;\n await options.onDebugSnapshot({\n recordedAt: new Date().toISOString(),\n queryHash: createHash(\"sha256\").update(prompt).digest(\"hex\"),\n queryLength: prompt.length,\n collection: options.collection,\n namespaces: options.recallNamespaces,\n fetchLimit: currentFetchLimit,\n primaryResultCount: lastPrimaryResultCount,\n hybridResultCount: lastHybridResultCount,\n queryAwareSeedCount: scopedSeedResults.length,\n resultCount: results.length,\n intentHint: debugSearchOptions?.intent,\n explainEnabled: debugSearchOptions?.explain === true,\n hybridTopUpUsed: lastHybridTopUpUsed,\n hybridTopUpSkippedReason: lastHybridTopUpSkippedReason,\n results: results.slice(0, 32).map((result) => ({\n ...result,\n snippet: result.snippet.slice(0, 280),\n })),\n });\n };\n if (queryAwarePrefilter.candidatePaths?.size === 0) {\n await emitDebugSnapshot([], fetchLimit);\n return [];\n }\n\n for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt += 1) {\n throwIfRecallAborted(options.abortSignal);\n if (\n qmdRecallBudgetEnabled &&\n Date.now() - startedAtMs >= qmdRecallBudgetMs\n ) {\n break;\n }\n\n const primaryResults = options.collection\n ? options.abortSignal\n ? await this.qmd.search(\n prompt,\n options.collection,\n fetchLimit,\n primarySearchOptions,\n {\n signal: options.abortSignal,\n },\n )\n : await this.qmd.search(\n prompt,\n options.collection,\n fetchLimit,\n primarySearchOptions,\n )\n : await this.searchAcrossNamespaces({\n query: prompt,\n namespaces: options.namespacesEnabled\n ? options.recallNamespaces\n : undefined,\n maxResults: fetchLimit,\n mode: \"search\",\n searchOptions: primarySearchOptions,\n execution: { signal: options.abortSignal },\n });\n lastPrimaryResultCount = primaryResults.length;\n lastHybridResultCount = 0;\n lastHybridTopUpUsed = false;\n lastHybridTopUpSkippedReason = undefined;\n let mergedResults = primaryResults;\n\n // Backfill with hybrid results only when primary retrieval underfills.\n if (\n primaryResults.length < qmdFetchLimit &&\n (!qmdRecallBudgetEnabled ||\n Date.now() - startedAtMs < qmdRecallBudgetMs)\n ) {\n if (debugSearchOptions?.intent) {\n lastHybridTopUpSkippedReason = \"intent_hint_active\";\n } else if (this.config.qmdSearchStrategy === \"lex\") {\n // BM25-only strategy: a hybrid top-up runs vectorSearch (see\n // QmdClient.hybridSearch), which would reintroduce the vector path the\n // operator opted out of. Keep \"lex\" BM25-only end-to-end so the gate is\n // uniform across primary + top-up (gotcha #39). Issue #1335 (codex review #1422).\n lastHybridTopUpSkippedReason = \"lex_strategy\";\n } else {\n const hybridResults = options.collection\n ? await this.qmd.hybridSearch(\n prompt,\n options.collection,\n fetchLimit,\n {\n signal: options.abortSignal,\n },\n )\n : await this.searchAcrossNamespaces({\n query: prompt,\n namespaces: options.namespacesEnabled\n ? options.recallNamespaces\n : undefined,\n maxResults: fetchLimit,\n mode: \"hybrid\",\n execution: { signal: options.abortSignal },\n });\n lastHybridResultCount = hybridResults.length;\n lastHybridTopUpUsed = hybridResults.length > 0;\n if (hybridResults.length > 0) {\n const mergedByPath = new Map<string, QmdSearchResult>();\n for (const result of [...primaryResults, ...hybridResults]) {\n const key = result.path || result.docid;\n const existing = mergedByPath.get(key);\n if (!existing || result.score > existing.score) {\n mergedByPath.set(key, {\n ...result,\n transport: result.transport ?? \"hybrid\",\n snippet: result.snippet || existing?.snippet || \"\",\n });\n }\n }\n mergedResults = [...mergedByPath.values()]\n .sort((a, b) => b.score - a.score)\n .slice(0, fetchLimit);\n }\n }\n }\n\n if (scopedSeedResults.length > 0) {\n const mergedByPath = new Map<string, QmdSearchResult>();\n for (const result of [...scopedSeedResults, ...mergedResults]) {\n const key = result.path || result.docid;\n const existing = mergedByPath.get(key);\n if (!existing || result.score > existing.score) {\n mergedByPath.set(key, {\n ...result,\n snippet: result.snippet || existing?.snippet || \"\",\n });\n }\n }\n mergedResults = [...mergedByPath.values()]\n .sort((a, b) => b.score - a.score)\n .slice(0, fetchLimit);\n }\n\n const filteredResults = filterRecallCandidates(mergedResults, {\n namespacesEnabled: options.namespacesEnabled,\n recallNamespaces: options.recallNamespaces,\n resolveNamespace: options.resolveNamespace,\n limit: fetchLimit,\n });\n\n if (filteredResults.length >= qmdFetchLimit) {\n const capped = filteredResults.slice(0, qmdFetchLimit);\n await emitDebugSnapshot(capped, fetchLimit);\n return capped;\n }\n if (filteredResults.length > bestFiltered.length) {\n bestFiltered = filteredResults;\n }\n if (mergedResults.length === 0) {\n await emitDebugSnapshot(filteredResults, fetchLimit);\n return filteredResults;\n }\n if (mergedResults.length < fetchLimit && filteredResults.length > 0) {\n await emitDebugSnapshot(filteredResults, fetchLimit);\n return filteredResults;\n }\n if (fetchLimit >= maxFetchLimit) {\n break;\n }\n\n const growth = Math.max(20, Math.floor(fetchLimit / 2));\n fetchLimit = Math.min(maxFetchLimit, fetchLimit + growth);\n }\n\n const capped = bestFiltered.slice(0, qmdFetchLimit);\n await emitDebugSnapshot(capped, fetchLimit);\n return capped;\n }\n\n private async expandResultsViaGraph(options: {\n memoryResults: QmdSearchResult[];\n recallNamespaces: string[];\n recallResultLimit: number;\n deadlineAtMs?: number | null;\n /** Issue #681 — when true, bypass graphTraversalConfidenceFloor. */\n includeLowConfidence?: boolean;\n }): Promise<{\n merged: QmdSearchResult[];\n seedPaths: string[];\n expandedPaths: GraphRecallExpandedEntry[];\n seedResults: QmdSearchResult[];\n }> {\n const deadlineExpired = (): boolean =>\n typeof options.deadlineAtMs === \"number\" &&\n Date.now() >= options.deadlineAtMs;\n const byNamespace = new Map<string, QmdSearchResult[]>();\n const addResultForNamespace = (\n namespace: string,\n result: QmdSearchResult,\n ): void => {\n const existing = byNamespace.get(namespace);\n if (existing) {\n existing.push(result);\n } else {\n byNamespace.set(namespace, [result]);\n }\n };\n const resolvedAmbiguousSeeds = new Map<\n string,\n { namespace: string; result: QmdSearchResult } | null\n >();\n const resolveAmbiguousSeedOwner = async (\n result: QmdSearchResult,\n parts: { collection: string; relativePath: string } | null,\n ): Promise<{ namespace: string; result: QmdSearchResult } | null> => {\n const cached = resolvedAmbiguousSeeds.get(result.path);\n if (cached !== undefined) return cached;\n if (deadlineExpired()) {\n resolvedAmbiguousSeeds.set(result.path, null);\n return null;\n }\n\n let resolvedPath = result.path;\n let resolvedResult = result;\n if (parts) {\n const resolvedCold = await this.resolveColdQmdResultForRecall(\n result,\n this.storage,\n options.recallNamespaces,\n );\n if (!resolvedCold || deadlineExpired()) {\n resolvedAmbiguousSeeds.set(result.path, null);\n return null;\n }\n resolvedPath = resolvedCold.result.path;\n resolvedResult = resolvedCold.result;\n }\n\n if (!path.isAbsolute(resolvedPath)) {\n resolvedAmbiguousSeeds.set(result.path, null);\n return null;\n }\n const ownerStorage = await this.storageForAbsoluteQmdResultPath(\n resolvedPath,\n this.storage,\n options.recallNamespaces,\n );\n const ownerNamespace = ownerStorage?.namespace ?? null;\n const resolved =\n ownerNamespace && options.recallNamespaces.includes(ownerNamespace)\n ? { namespace: ownerNamespace, result: resolvedResult }\n : null;\n resolvedAmbiguousSeeds.set(result.path, resolved);\n return resolved;\n };\n const coldCollection = this.config.qmdColdCollection ?? \"openclaw-engram-cold\";\n for (const result of options.memoryResults) {\n if (deadlineExpired()) break;\n const parts = qmdCollectionPathParts(result.path);\n if (parts?.collection === coldCollection) {\n const resolved = await resolveAmbiguousSeedOwner(result, parts);\n if (resolved) {\n addResultForNamespace(resolved.namespace, resolved.result);\n }\n continue;\n }\n if (path.isAbsolute(result.path)) {\n const resolved = await resolveAmbiguousSeedOwner(result, null);\n if (resolved) {\n addResultForNamespace(resolved.namespace, resolved.result);\n }\n continue;\n }\n const ns = this.namespaceFromPath(result.path);\n if (!options.recallNamespaces.includes(ns)) continue;\n addResultForNamespace(ns, result);\n }\n\n const perNamespaceSeedCap = Math.max(3, options.recallResultLimit);\n const perNamespaceExpandedCap = Math.max(8, options.recallResultLimit * 2);\n const seedPaths: string[] = [];\n const seedResults: QmdSearchResult[] = [];\n const expandedPaths: GraphRecallExpandedEntry[] = [];\n const expandedResults: QmdSearchResult[] = [];\n\n for (const [namespace, nsResults] of byNamespace.entries()) {\n if (deadlineExpired()) break;\n const storage = await this.storageRouter.storageFor(namespace);\n const seedCandidates = nsResults.slice(0, perNamespaceSeedCap);\n seedResults.push(...seedCandidates);\n const seedRelativePaths =\n typeof options.deadlineAtMs === \"number\"\n ? await this.graphSeedPathsWithinDeadline(\n storage,\n seedCandidates,\n options.deadlineAtMs,\n [namespace],\n )\n : (\n await Promise.all(\n seedCandidates.map((result) =>\n this.graphSeedPathRelativeToStorage(storage, result, [\n namespace,\n ]),\n ),\n )\n ).filter(\n (value): value is string =>\n typeof value === \"string\" && value.length > 0,\n );\n if (deadlineExpired()) break;\n if (seedRelativePaths.length === 0) continue;\n\n const seedRecallScore = seedCandidates.reduce(\n (max, item) => Math.max(max, item.score),\n 0,\n );\n seedPaths.push(\n ...seedRelativePaths.map((rel) => path.join(storage.dir, rel)),\n );\n const seedSet = new Set(seedRelativePaths);\n const expanded = await this.graphIndexFor(storage).spreadingActivation(\n seedRelativePaths,\n this.config.maxGraphTraversalSteps,\n {\n ...(options.includeLowConfidence === true ? { includeLowConfidence: true } : {}),\n ...(typeof options.deadlineAtMs === \"number\"\n ? { deadlineAtMs: options.deadlineAtMs }\n : {}),\n },\n );\n if (expanded.length === 0) continue;\n if (deadlineExpired()) break;\n\n for (const candidate of expanded.slice(0, perNamespaceExpandedCap)) {\n if (deadlineExpired()) break;\n if (seedSet.has(candidate.path)) continue;\n const memoryPath = path.resolve(storage.dir, candidate.path);\n const memory = await storage.readMemoryByPath(memoryPath);\n if (deadlineExpired()) break;\n if (!memory) continue;\n if (isArtifactMemoryPath(memory.path)) continue;\n if (memory.frontmatter.status && memory.frontmatter.status !== \"active\")\n continue;\n\n const snippet = memory.content.slice(0, 400);\n const score = blendGraphExpandedRecallScore({\n graphActivationScore: candidate.score,\n seedRecallScore,\n activationWeight: this.config.graphExpansionActivationWeight,\n blendMin: this.config.graphExpansionBlendMin,\n blendMax: this.config.graphExpansionBlendMax,\n });\n expandedResults.push({\n docid: memory.frontmatter.id,\n path: memory.path,\n snippet,\n score,\n });\n expandedPaths.push({\n path: memory.path,\n score,\n namespace,\n seed: path.resolve(storage.dir, candidate.seed),\n hopDepth: candidate.hopDepth,\n decayedWeight: candidate.decayedWeight,\n graphType: candidate.graphType,\n // Issue #681 PR 3/3 — surface the per-edge confidence used for\n // PageRank weighting / floor pruning so downstream observability\n // (recall_xray, memory_graph_explain) can attribute ranking and\n // pruning decisions to specific edges.\n edgeConfidence: candidate.edgeConfidence,\n });\n }\n }\n\n return {\n merged: mergeGraphExpandedResults(options.memoryResults, expandedResults),\n seedPaths,\n expandedPaths,\n seedResults,\n };\n }\n\n private async recordLastGraphRecallSnapshot(options: {\n storage: StorageManager;\n prompt: string;\n recallMode: RecallPlanMode;\n recallNamespaces: string[];\n seedPaths: string[];\n expandedPaths: GraphRecallExpandedEntry[];\n status: \"completed\" | \"skipped\" | \"aborted\";\n reason?: string;\n shadowMode?: boolean;\n queryIntent: MemoryIntent;\n seedResults?: GraphRecallRankedResult[];\n finalResults?: GraphRecallRankedResult[];\n shadowComparison?: GraphRecallShadowComparison;\n }): Promise<void> {\n try {\n const snapshotPath = path.join(\n options.storage.dir,\n \"state\",\n \"last_graph_recall.json\",\n );\n await mkdir(path.dirname(snapshotPath), { recursive: true });\n const now = new Date().toISOString();\n const totalSeedCount = options.seedPaths.length;\n const totalExpandedCount = options.expandedPaths.length;\n const seeds = options.seedPaths.slice(0, 64);\n const expanded = clampGraphRecallExpandedEntries(\n options.expandedPaths,\n 64,\n );\n const payload = {\n recordedAt: now,\n mode: options.recallMode,\n queryHash: createHash(\"sha256\").update(options.prompt).digest(\"hex\"),\n queryLength: options.prompt.length,\n namespaces: options.recallNamespaces,\n seedCount: totalSeedCount,\n expandedCount: totalExpandedCount,\n seeds,\n expanded,\n status: options.status,\n reason: options.reason,\n shadowMode: options.shadowMode === true,\n queryIntent: options.queryIntent,\n seedResults: (options.seedResults ?? []).slice(0, 64),\n finalResults: (options.finalResults ?? []).slice(0, 64),\n shadowComparison: options.shadowComparison,\n };\n await writeFile(snapshotPath, JSON.stringify(payload, null, 2), \"utf-8\");\n } catch (err) {\n log.debug(`last graph recall write failed: ${err}`);\n }\n }\n\n private async recordLastIntentSnapshot(options: {\n storage: StorageManager;\n snapshot: IntentDebugSnapshot;\n }): Promise<void> {\n try {\n const snapshotPath = path.join(\n options.storage.dir,\n \"state\",\n \"last_intent.json\",\n );\n await mkdir(path.dirname(snapshotPath), { recursive: true });\n await writeFile(\n snapshotPath,\n JSON.stringify(options.snapshot, null, 2),\n \"utf-8\",\n );\n } catch (err) {\n log.debug(`last intent write failed: ${err}`);\n }\n }\n\n private async recordLastQmdRecallSnapshot(options: {\n storage: StorageManager;\n snapshot: QmdRecallSnapshot;\n }): Promise<void> {\n try {\n const snapshotPath = path.join(\n options.storage.dir,\n \"state\",\n \"last_qmd_recall.json\",\n );\n await mkdir(path.dirname(snapshotPath), { recursive: true });\n await writeFile(\n snapshotPath,\n JSON.stringify(options.snapshot, null, 2),\n \"utf-8\",\n );\n } catch (err) {\n log.debug(`last qmd recall write failed: ${err}`);\n }\n }\n\n private async recordLastIntentSnapshotForNamespace(options: {\n namespace: string;\n snapshot: IntentDebugSnapshot;\n }): Promise<void> {\n try {\n const stateDir = await this.resolveStateDirForNamespace(\n options.namespace,\n );\n const snapshotPath = path.join(stateDir, \"last_intent.json\");\n await mkdir(path.dirname(snapshotPath), { recursive: true });\n await writeFile(\n snapshotPath,\n JSON.stringify(options.snapshot, null, 2),\n \"utf-8\",\n );\n } catch (err) {\n log.debug(`last intent write failed: ${err}`);\n }\n }\n\n private async resolveStateDirForNamespace(\n namespace: string,\n ): Promise<string> {\n if (!this.config.namespacesEnabled) {\n return path.join(this.config.memoryDir, \"state\");\n }\n if (namespace !== this.config.defaultNamespace) {\n return path.join(this.config.memoryDir, \"namespaces\", namespace, \"state\");\n }\n const candidate = path.join(\n this.config.memoryDir,\n \"namespaces\",\n this.config.defaultNamespace,\n );\n try {\n const candidateStat = await stat(candidate);\n if (candidateStat.isDirectory()) {\n return path.join(candidate, \"state\");\n }\n } catch {\n // Fall back to the legacy root when the migrated default namespace directory is absent.\n }\n return path.join(this.config.memoryDir, \"state\");\n }\n\n private buildGraphRecallRankedResults(\n results: QmdSearchResult[],\n sourceLabelResolver: (path: string) => string[],\n limit: number = 64,\n ): GraphRecallRankedResult[] {\n return results.slice(0, limit).map((result) => ({\n path: result.path,\n score: result.score,\n docid: result.docid,\n sourceLabels: sourceLabelResolver(result.path),\n }));\n }\n\n private getRecallSectionEntry(\n sectionId: string,\n ): RecallSectionConfig | undefined {\n const pipeline = Array.isArray(this.config.recallPipeline)\n ? this.config.recallPipeline\n : [];\n return pipeline.find((entry) => entry.id === sectionId);\n }\n\n private isRecallSectionEnabled(\n sectionId: string,\n defaultEnabled: boolean = true,\n ): boolean {\n const entry = this.getRecallSectionEntry(sectionId);\n if (!entry) return defaultEnabled;\n return entry.enabled !== false;\n }\n\n private isSpecializedRecallSectionEnabled(\n sectionId: string,\n topLevelEnabled: boolean,\n ): boolean {\n const entry = this.getRecallSectionEntry(sectionId);\n if (!entry) return topLevelEnabled;\n return entry.enabled === true || (topLevelEnabled && entry.enabled !== false);\n }\n\n private getRecallSectionMaxChars(\n sectionId: string,\n ): number | null | undefined {\n const entry = this.getRecallSectionEntry(sectionId);\n if (!entry) return undefined;\n if (entry.maxChars === null) return null;\n if (typeof entry.maxChars !== \"number\") return undefined;\n return Math.max(0, Math.floor(entry.maxChars));\n }\n\n private getRecallSectionNumber(\n sectionId: string,\n key: keyof RecallSectionConfig,\n ): number | undefined {\n const entry = this.getRecallSectionEntry(sectionId);\n if (!entry) return undefined;\n const value = entry[key];\n if (typeof value !== \"number\" || !Number.isFinite(value)) return undefined;\n return Math.max(0, Math.floor(value));\n }\n\n private appendRecallSection(\n sectionBuckets: Map<string, string[]>,\n sectionId: string,\n content: string,\n ): boolean {\n // Returns true when the section was actually appended to sectionBuckets,\n // false when it was dropped (disabled, empty, or maxChars===0). Callers\n // that need to know whether injection occurred (e.g. xray annotation for\n // peer-profile) must gate on this return value rather than on whether the\n // section text was computed (Codex P2 finding, PR #764).\n if (!this.isRecallSectionEnabled(sectionId)) return false;\n const trimmed = content.trim();\n if (trimmed.length === 0) return false;\n\n const maxChars = this.getRecallSectionMaxChars(sectionId);\n let finalContent = trimmed;\n if (maxChars === 0) return false;\n if (typeof maxChars === \"number\" && finalContent.length > maxChars) {\n finalContent = `${finalContent.slice(0, maxChars)}\\n\\n...(trimmed)\\n`;\n }\n\n const existing = sectionBuckets.get(sectionId) ?? [];\n existing.push(finalContent);\n sectionBuckets.set(sectionId, existing);\n return true;\n }\n\n private truncateRecallSectionToBudget(\n content: string,\n maxChars: number,\n ): string {\n if (maxChars <= 0) return \"\";\n if (content.length <= maxChars) return content;\n const suffix = \"\\n\\n...(memory context trimmed)\";\n if (maxChars <= suffix.length) {\n return content.slice(0, maxChars);\n }\n return `${content.slice(0, maxChars - suffix.length)}${suffix}`;\n }\n\n private protectedRecallSectionIds(\n sectionBuckets: Map<string, string[]>,\n ): Set<string> {\n const protectedIds = new Set<string>();\n if ((sectionBuckets.get(\"memories\")?.length ?? 0) > 0) {\n protectedIds.add(\"memories\");\n }\n return protectedIds;\n }\n\n private protectedRecallReservationChars(content: string): number {\n const headingBoundary = content.indexOf(\"\\n\\n\");\n const headingChars =\n headingBoundary >= 0 ? headingBoundary + 2 : Math.min(content.length, 24);\n return Math.min(content.length, Math.max(headingChars, 24));\n }\n\n private estimateReservedRecallBudget(\n entries: Array<{ id: string; content: string }>,\n startIndex: number,\n protectedIds: Set<string>,\n alreadyIncludedCount: number,\n ): number {\n const separatorLength = \"\\n\\n---\\n\\n\".length;\n let reserved = 0;\n let simulatedIncluded = alreadyIncludedCount;\n for (let i = startIndex; i < entries.length; i += 1) {\n const entry = entries[i];\n if (!entry || !protectedIds.has(entry.id)) continue;\n if (simulatedIncluded > 0) {\n reserved += separatorLength;\n }\n reserved += this.protectedRecallReservationChars(entry.content);\n simulatedIncluded += 1;\n }\n return reserved;\n }\n\n private getRecallBudgetChars(override?: number): number {\n if (\n typeof override === \"number\" &&\n Number.isFinite(override) &&\n override >= 0\n ) {\n return Math.floor(override);\n }\n const configuredBudget = this.config.recallBudgetChars;\n if (\n typeof configuredBudget === \"number\" &&\n Number.isFinite(configuredBudget) &&\n configuredBudget >= 0\n ) {\n return Math.floor(configuredBudget);\n }\n const tokenBudget = this.config.maxMemoryTokens;\n if (\n typeof tokenBudget === \"number\" &&\n Number.isFinite(tokenBudget) &&\n tokenBudget >= 0\n ) {\n return Math.floor(tokenBudget * 4);\n }\n return 0;\n }\n\n private assembleRecallSections(\n sectionBuckets: Map<string, string[]>,\n budgetOverride?: number,\n ): {\n sections: string[];\n includedIds: string[];\n omittedIds: string[];\n truncated: boolean;\n finalChars: number;\n } {\n const orderedEntries: Array<{ id: string; content: string }> = [];\n const pipeline = Array.isArray(this.config.recallPipeline)\n ? this.config.recallPipeline\n : [];\n const orderedIds = pipeline\n .filter((entry) => entry.enabled !== false)\n .map((entry) => entry.id);\n const seen = new Set<string>();\n\n for (const id of orderedIds) {\n const chunks = sectionBuckets.get(id);\n if (!chunks || chunks.length === 0) continue;\n orderedEntries.push({ id, content: chunks.join(\"\\n\\n\") });\n seen.add(id);\n }\n\n for (const [id, chunks] of sectionBuckets.entries()) {\n if (seen.has(id)) continue;\n if (chunks.length === 0) continue;\n orderedEntries.push({ id, content: chunks.join(\"\\n\\n\") });\n }\n\n const budget = this.getRecallBudgetChars(budgetOverride);\n if (budget === 0) {\n return {\n sections: [],\n includedIds: [],\n omittedIds: orderedEntries.map((entry) => entry.id),\n truncated: orderedEntries.length > 0,\n finalChars: 0,\n };\n }\n\n const separator = \"\\n\\n---\\n\\n\";\n const protectedIds = this.protectedRecallSectionIds(sectionBuckets);\n const sections: string[] = [];\n const includedIds: string[] = [];\n const omittedIds: string[] = [];\n let usedChars = 0;\n let truncated = false;\n\n for (let index = 0; index < orderedEntries.length; index += 1) {\n const entry = orderedEntries[index]!;\n const separatorChars = sections.length > 0 ? separator.length : 0;\n const reserve = protectedIds.has(entry.id)\n ? 0\n : this.estimateReservedRecallBudget(\n orderedEntries,\n index + 1,\n protectedIds,\n sections.length + 1,\n );\n const availableForEntry = budget - usedChars - separatorChars - reserve;\n if (availableForEntry <= 0) {\n omittedIds.push(entry.id);\n truncated = true;\n continue;\n }\n const finalContent = this.truncateRecallSectionToBudget(\n entry.content,\n availableForEntry,\n );\n if (!finalContent) {\n omittedIds.push(entry.id);\n truncated = true;\n continue;\n }\n if (finalContent.length < entry.content.length) {\n truncated = true;\n }\n sections.push(finalContent);\n includedIds.push(entry.id);\n usedChars += separatorChars + finalContent.length;\n }\n\n return {\n sections,\n includedIds,\n omittedIds,\n truncated,\n finalChars: usedChars,\n };\n }\n\n private async recallInternal(\n prompt: string,\n sessionKey?: string,\n options: RecallInvocationOptions = {},\n ): Promise<string> {\n const recallStart = Date.now();\n // Issue #680 — historical recall. Parse `options.asOf` once at the\n // top of the recall so each boost-pass uses identical filter logic.\n // Invalid values are rejected at input boundaries (CLI / HTTP / MCP)\n // per CLAUDE.md rule 51; if a malformed value sneaks through here,\n // we treat it as \"no historical pin\" rather than throwing inside\n // recall — the upstream surfaces are the source of truth.\n let asOfMs: number | undefined;\n if (typeof options.asOf === \"string\" && options.asOf.length > 0) {\n const parsed = Date.parse(options.asOf);\n if (Number.isFinite(parsed)) asOfMs = parsed;\n }\n const timings: Record<string, string> = {};\n const profileTraceId = this.profiler.startTrace(\"recall\", sessionKey, {\n qmdEnabled: this.config.qmdEnabled,\n rerankEnabled: this.config.rerankEnabled,\n parallelRetrieval: this.config.parallelRetrievalEnabled,\n });\n this.profiler.startSpan(\"planning\", profileTraceId);\n let profileTraceClosed = false;\n const closeProfileTrace = () => {\n if (profileTraceClosed) return;\n profileTraceClosed = true;\n this.profiler.endTrace(profileTraceId); // persists to JSONL file\n };\n const recallSectionDeadlineMs = this.config.recallCoreDeadlineMs ?? 75_000;\n const enrichmentSectionDeadlineMs =\n this.config.recallEnrichmentDeadlineMs ?? 25_000;\n // Wrap entire recall body in try/finally so profiling trace is always closed,\n // even on unexpected exceptions (e.g., throwIfRecallAborted, phase-1 errors).\n try {\n type DeferredEnrichmentOutcome<T> =\n | { status: \"resolved\"; value: T }\n | { status: \"rejected\"; error: unknown };\n type ObservedDeferredEnrichmentPromise<T> =\n Promise<DeferredEnrichmentOutcome<T>> & {\n getSettledOutcome: () => DeferredEnrichmentOutcome<T> | undefined;\n cancel: () => void;\n };\n const createEnrichmentAbortHandle = (parentSignal?: AbortSignal) => {\n const controller = new AbortController();\n const onAbort = () => controller.abort();\n if (parentSignal?.aborted) {\n controller.abort();\n } else if (parentSignal) {\n parentSignal.addEventListener(\"abort\", onAbort, { once: true });\n }\n let disposed = false;\n const dispose = () => {\n if (disposed) return;\n disposed = true;\n parentSignal?.removeEventListener(\"abort\", onAbort);\n };\n return {\n signal: controller.signal,\n cancel: () => {\n controller.abort();\n dispose();\n },\n dispose,\n };\n };\n const observeEnrichmentPromise = <T>(\n promise: Promise<T>,\n cancel: () => void = () => {},\n ): ObservedDeferredEnrichmentPromise<T> => {\n let settledOutcome: DeferredEnrichmentOutcome<T> | undefined;\n const observed = promise\n .then<DeferredEnrichmentOutcome<T>, DeferredEnrichmentOutcome<T>>(\n (value) => ({ status: \"resolved\", value }),\n (error) => ({ status: \"rejected\", error }),\n )\n .then((outcome) => {\n settledOutcome = outcome;\n return outcome;\n }) as ObservedDeferredEnrichmentPromise<T>;\n observed.getSettledOutcome = () => settledOutcome;\n observed.cancel = cancel;\n return observed;\n };\n const recordRecallSectionMetric = createRecallSectionMetricRecorder({\n timings,\n logger: log,\n });\n const promptHash = createHash(\"sha256\").update(prompt).digest(\"hex\");\n const traceId = createHash(\"sha256\")\n .update(`${sessionKey ?? \"default\"}:${recallStart}:${promptHash}`)\n .digest(\"hex\")\n .slice(0, 16);\n const sectionBuckets = new Map<string, string[]>();\n // The effective LCM read session_id SET is computed below from\n // `recallNamespaces` (the SAME read-authorized namespace set normal QMD/file\n // recall searches, incl. coding `readFallbacks`). See the\n // `lcmReadSessionIds` derivation after `recallNamespaces` is built.\n const queryPolicy = buildRecallQueryPolicy(prompt, sessionKey, {\n cronRecallPolicyEnabled: this.config.cronRecallPolicyEnabled,\n cronRecallNormalizedQueryMaxChars:\n this.config.cronRecallNormalizedQueryMaxChars,\n cronRecallInstructionHeavyTokenCap:\n this.effectiveCronRecallInstructionHeavyTokenCap(),\n cronConversationRecallMode: this.config.cronConversationRecallMode,\n });\n const retrievalQuery = queryPolicy.retrievalQuery || prompt;\n const retrievalQueryHash = createHash(\"sha256\")\n .update(retrievalQuery)\n .digest(\"hex\");\n const policyVersion = this.currentPolicyVersion();\n let impressionRecorded = false;\n let recallSource:\n | \"none\"\n | \"hot_qmd\"\n | \"hot_embedding\"\n | \"cold_fallback\"\n | \"recent_scan\" = \"none\";\n let recalledMemoryCount = 0;\n let recalledMemoryIds: string[] = [];\n let recalledMemoryPaths: string[] = [];\n // Boosted QmdSearchResult array for the serving branch (issue #687 PR 3/4).\n // Populated alongside recalledMemoryPaths so the X-ray capture can read\n // per-result explain data (e.g. reinforcementBoost) from the result that\n // was actually served.\n let xrayRecalledResults: QmdSearchResult[] = [];\n const lcmStructuredXrayResults: RecallXrayResult[] = [];\n // Per-branch pre-limit candidate pool size for the X-ray filter\n // trace (issue #570 PR 1). `recalledMemoryCount` is assigned\n // AFTER MMR + truncation so using it alone would make the\n // `recall-result-limit` trace report `considered == admitted`\n // even when many candidates were dropped. Each entry captures\n // the pool size BEFORE truncation at that branch. The X-ray\n // capture block picks the pool that corresponds to the branch\n // that actually produced the admitted results (via `recallSource`)\n // so a pool from a branch whose candidates were killed by an\n // earlier gate cannot leak into the `considered` count.\n const xrayBranchPoolSize: Record<\n \"hot_qmd\" | \"hot_embedding\" | \"cold_fallback\" | \"recent_scan\",\n number\n > = {\n hot_qmd: 0,\n hot_embedding: 0,\n cold_fallback: 0,\n recent_scan: 0,\n };\n // Shared out-parameter sink the cold-fallback pipeline writes\n // its pre-truncation pool size into (issue #570 PR 1). Declared\n // once so every call to `applyColdFallbackPipeline` (four call\n // sites) updates the same counter; the X-ray capture block\n // reads this as the cold-fallback pool.\n const xrayColdPoolSink = { size: 0 };\n let identityInjectionModeUsed: IdentityInjectionMode | \"none\" = \"none\";\n let identityInjectedChars = 0;\n let identityInjectionTruncated = false;\n timings.queryPolicy = `${queryPolicy.promptShape}/${queryPolicy.retrievalBudgetMode}${queryPolicy.skipConversationRecall ? \"/skip-conv\" : \"\"}`;\n const recallModeDecisionOptions = {\n plannerEnabled: this.config.recallPlannerEnabled,\n graphRecallEnabled: this.config.graphRecallEnabled,\n multiGraphMemoryEnabled: this.config.multiGraphMemoryEnabled,\n graphExpandedIntentEnabled:\n this.config.graphExpandedIntentEnabled === true,\n prompt,\n };\n const requestedMode = options.mode;\n // When the caller forces a mode, skip the (async, possibly LLM-backed)\n // planner entirely — the decision is overridden anyway. Otherwise consult\n // the LLM planner when opted in (issue #1367 / Option C); it falls back to\n // the heuristic on disable / shadow / timeout / error.\n const recallDecision =\n requestedMode !== undefined\n ? resolveRecallModeDecision(recallModeDecisionOptions)\n : await resolveRecallModeDecisionAsync({\n ...recallModeDecisionOptions,\n config: this.config,\n signal: options.abortSignal,\n });\n if (\n this.config.recallPlannerTelemetryEnabled &&\n recallDecision.plannerSource &&\n recallDecision.plannerSource !== \"heuristic\"\n ) {\n log.debug(\n `[recall-planner] mode=${recallDecision.shadowLlmMode ?? recallDecision.effectiveMode} ` +\n `source=${recallDecision.plannerSource} ` +\n `planned=${recallDecision.plannedMode} ` +\n `heuristic=${recallDecision.plannerHeuristicMode ?? recallDecision.plannedMode} ` +\n `model=${recallDecision.plannerModelUsed ?? \"n/a\"} ` +\n `latencyMs=${recallDecision.plannerLatencyMs ?? 0} ` +\n `fallback=${recallDecision.plannerFallbackUsed ?? false}` +\n (recallDecision.shadowLlmMode ? \" (shadow)\" : \"\"),\n );\n }\n this.profiler.endSpan(\"planning\", profileTraceId);\n const recallMode: RecallPlanMode =\n requestedMode ?? recallDecision.effectiveMode;\n const queryIntent = inferIntentFromText(retrievalQuery);\n const qmdSearchOptions =\n this.buildConfiguredQmdSearchOptions(retrievalQuery);\n timings.recallPlan = recallMode;\n const plannerRecallResultLimit =\n recallMode === \"no_recall\"\n ? 0\n : recallMode === \"minimal\"\n ? Math.max(\n 0,\n Math.min(\n this.config.qmdMaxResults,\n this.config.recallPlannerMaxQmdResultsMinimal,\n ),\n )\n : this.config.qmdMaxResults;\n const policyMinimalLimit = Math.max(\n 0,\n Math.min(\n this.config.qmdMaxResults,\n this.config.recallPlannerMaxQmdResultsMinimal,\n ),\n );\n const baseRecallResultLimit =\n recallMode !== \"no_recall\" &&\n queryPolicy.retrievalBudgetMode === \"minimal\"\n ? Math.min(plannerRecallResultLimit, policyMinimalLimit)\n : plannerRecallResultLimit;\n const memoriesSectionEnabled = this.isRecallSectionEnabled(\"memories\");\n const memorySectionMaxResults = this.getRecallSectionNumber(\n \"memories\",\n \"maxResults\",\n );\n const requestedTopK =\n typeof options.topK === \"number\" && Number.isFinite(options.topK)\n ? Math.max(0, Math.min(200, Math.floor(options.topK)))\n : undefined;\n const recallResultLimit = memoriesSectionEnabled\n ? (() => {\n let limit = baseRecallResultLimit;\n if (memorySectionMaxResults !== undefined) {\n limit = Math.min(limit, memorySectionMaxResults);\n }\n if (requestedTopK !== undefined) {\n limit = Math.min(limit, requestedTopK);\n }\n return limit;\n })()\n : 0;\n const recallHeadroom = this.config.verbatimArtifactsEnabled\n ? Math.max(12, this.config.verbatimArtifactsMaxRecall * 4)\n : 12;\n const computedFetchLimit =\n recallResultLimit === 0\n ? 0\n : Math.max(\n recallResultLimit,\n Math.min(200, recallResultLimit + recallHeadroom),\n );\n const qmdFetchLimit = computedFetchLimit;\n const qmdHybridFetchLimit = computeQmdHybridFetchLimit(\n qmdFetchLimit,\n this.config.verbatimArtifactsEnabled,\n this.config.verbatimArtifactsMaxRecall,\n );\n const embeddingFetchLimit = computedFetchLimit;\n // Principal resolution honours the access-surface override (issue\n // #570 PR 4). Access surfaces that have already authenticated the\n // caller at the transport layer (HTTP / MCP) pass their resolved\n // principal directly so namespace ACL decisions use the same\n // identity the surface authorized, instead of re-running\n // `resolvePrincipal(sessionKey)` which only maps raw session keys\n // through configured rules and otherwise collapses to `\"default\"`.\n const principal =\n typeof options.principalOverride === \"string\"\n && options.principalOverride.length > 0\n ? options.principalOverride\n : resolvePrincipal(sessionKey, this.config);\n if (this.config.namespacesEnabled && !principal) {\n throw new Error(\"authentication required: namespaces are enabled and no principal was supplied\");\n }\n const namespaceOverride = options.namespace?.trim() || undefined;\n const readableRecallNamespaces = recallNamespacesForPrincipal(\n principal,\n this.config,\n );\n if (\n namespaceOverride &&\n !canReadNamespace(principal, namespaceOverride, this.config)\n ) {\n throw new Error(\n `namespace override is not readable: ${namespaceOverride}`,\n );\n }\n // Recall path — overlay the coding-agent namespace (issue #569) when\n // the session has a codingContext and `codingMode.projectScope` is true.\n // Explicit `namespace` option still wins, preserving pre-#569 semantics.\n //\n // Rule 42: the overlay substitutes the SELF namespace within the\n // principal's recall list — it does NOT replace the full list. Shared\n // and `includeInRecallByDefault` policy namespaces stay in the recall\n // set so coding sessions continue to see team/shared memories. The\n // overlay is combined with the principal base through `combineNamespaces`\n // to preserve principal isolation (cross-tenant leakage guard).\n const codingOverlay = namespaceOverride ? null : this.applyCodingRecallOverlay(sessionKey);\n const principalSelfNamespace = defaultNamespaceForPrincipal(principal, this.config);\n const codingSelfNamespace = codingOverlay\n ? combineNamespaces(principalSelfNamespace, codingOverlay.namespace)\n : null;\n const scopeProfilePlan = namespaceOverride\n ? null\n : resolveScopeProfilePlan({\n config: this.config,\n principal,\n codingContext: sessionKey\n ? this.getCodingContextForSession(sessionKey)\n : null,\n codingOverlay,\n });\n const profileEffectiveNamespace = scopeProfilePlan?.writeNamespace || scopeProfilePlan?.readNamespaces[0];\n const selfNamespace =\n namespaceOverride ??\n profileEffectiveNamespace ??\n codingSelfNamespace ??\n principalSelfNamespace;\n let recallNamespaces: string[];\n if (namespaceOverride) {\n recallNamespaces = [namespaceOverride];\n } else if (scopeProfilePlan) {\n recallNamespaces = expandScopeProfileReadNamespaces({\n profilePlan: scopeProfilePlan,\n principalSelfNamespace: scopeProfilePlan.baseNamespace,\n config: this.config,\n principal,\n codingOverlay,\n legacyRecallNamespaces: readableRecallNamespaces,\n });\n } else if (codingOverlay && codingSelfNamespace) {\n // Substitute the principal's self namespace with the coding-scoped\n // one, and append any read fallbacks (branch→project, PR 3) combined\n // with the principal base so principal isolation is preserved on\n // fallback entries as well.\n const mapped = readableRecallNamespaces.map((ns) =>\n ns === principalSelfNamespace ? codingSelfNamespace : ns,\n );\n const fallbackNs = codingOverlay.readFallbacks.map((fallback) =>\n combineNamespaces(principalSelfNamespace, fallback),\n );\n recallNamespaces = Array.from(new Set<string>([...mapped, ...fallbackNs]));\n } else {\n recallNamespaces = readableRecallNamespaces;\n }\n // Catalog touch (issue #1499): record reads against the recalled namespaces\n // so the catalog reflects active read scopes. Best-effort, failure-tolerant.\n // Round 3 (codex P2): gate behind the no_recall guard — when the planner\n // selects `no_recall` retrieval is skipped entirely (see the early return at\n // `recallMode === \"no_recall\"` below), so marking every readable namespace as\n // read would falsely inflate `lastReadAt` / catalog recency.\n // Round 4 (codex P2): also skip when the effective memory result limit is\n // zero (`topK: 0`, a disabled/zero `memories` recall section, etc.). The QMD\n // path explicitly returns before searching when `recallResultLimit <= 0`, so\n // no namespace is actually read and the touch would be spurious.\n // NOTE: the catalog read touch is recorded LATER, immediately after the\n // Phase 1 `throwIfRecallAborted` gate (round 6, codex P2 / cursor Medium —\n // NDXHa/NDmle), so it fires only once retrieval is actually about to run.\n // Recording it here (recall entry) would set `lastReadAt` for recalls that\n // are aborted, error out, or short-circuit before any QMD/filesystem read.\n\n // Effective LCM read NAMESPACE SET (#1505 thread \"Include coding fallback\n // namespaces in LCM reads\"). `observe` archives LCM / structured history\n // under `${effectiveNamespace}:${sessionKey}` for whichever namespace was\n // effective at write time. A branch-scoped session whose evidence was\n // archived at project / root scope must still surface it, exactly as normal\n // QMD/file recall does — QMD/file recall searches the primary overlay key AND\n // `codingOverlay.readFallbacks` (project / root), NOT just the primary\n // overlay key. The prior single `lcmReadSessionId` only targeted the primary\n // overlay, so branch-scoped sessions missed fallback LCM evidence.\n //\n // READ-AUTHORIZATION (preserved from the prior round's\n // `lcmReadNamespaceForSession` gate; rule 39 / 42 / 48): the coding-overlay\n // namespace AND its fallbacks are `<principal>-project-*` sub-namespaces of\n // the principal SELF base, authorized transitively by that base. They are\n // included ONLY when the principal self base is in the readable recall set\n // (`readableRecallNamespaces` — gated by `defaultRecallNamespaces.includes\n // (\"self\")` AND `canReadNamespace`). When the self base is NOT readable (e.g.\n // a write-only / self-omitted principal), the overlay rows are unauthorized\n // for this reader, so the LCM read collapses to the default store — exactly\n // what an unqualified, unauthorized recall resolves to — and NEVER searches a\n // `<principal>-project-*` key (no cross-tenant read leak). This mirrors what\n // the rest of recall surfaces for such a principal (its readable\n // shared/policy namespaces have no per-session LCM key, so they contribute\n // nothing here). `recallNamespaces` itself appends fallbacks unconditionally\n // for QMD/file recall; the LCM read keys apply the stricter, self-base gate\n // so the prior round's authorization invariant is preserved.\n const codingOverlaySelfReadable =\n codingOverlay !== null &&\n (scopeProfilePlan\n ? scopeProfilePlan.layers.some((layer) => layer.id === \"userProject\" && layer.readable)\n : readableRecallNamespaces.includes(principalSelfNamespace));\n let lcmReadNamespaces: string[];\n if (namespaceOverride) {\n // Explicit namespace already read-authorized above (canReadNamespace gate).\n lcmReadNamespaces = [namespaceOverride];\n } else if (scopeProfilePlan) {\n // Scope profiles define a layered read stack; LCM-backed evidence uses the\n // same namespace set as QMD/file recall so team/global/shared observations\n // are not silently skipped.\n lcmReadNamespaces = recallNamespaces;\n } else if (codingOverlay && codingSelfNamespace && codingOverlaySelfReadable) {\n // Self base readable → overlay rows authorized. Read the primary overlay\n // key first, then each coding read fallback (project → root), combined with\n // the principal base for isolation — the SAME ordered set QMD/file recall\n // searches for this authorized coding session.\n const fallbackNs = codingOverlay.readFallbacks.map((fallback) =>\n combineNamespaces(principalSelfNamespace, fallback),\n );\n lcmReadNamespaces = [codingSelfNamespace, ...fallbackNs];\n } else {\n // No overlay, OR overlay present but self base unreadable → collapse to the\n // default store (raw sessionKey), exactly as the prior round did. No\n // `<principal>-project-*` overlay key is searched.\n lcmReadNamespaces = [this.config.defaultNamespace];\n }\n // Map the ordered, read-authorized namespace set → ordered, deduped LCM read\n // session_id set. Single-user / no-overlay recall passes a single-namespace\n // set that collapses to the raw `sessionKey`, so this is `[sessionKey]` —\n // byte-for-byte the pre-#1495 single-key behavior.\n const lcmReadSessionIds =\n scopeProfilePlan && !sessionKey\n ? []\n : lcmReadSessionIdsForNamespaces(\n lcmReadNamespaces,\n sessionKey,\n this.config.defaultNamespace,\n );\n // Query an LCM-backed read across the ordered read key set and return the\n // FIRST non-empty result (#1505 fallback-namespace unification). The primary\n // overlay key is tried first; if a branch-scoped session has no rows under its\n // branch key, the project / root fallback keys are tried in order.\n //\n // #1505 codex P2 (\"Merge LCM fallback reads instead of short-circuiting\"): the\n // query-SCORED sections (explicit-cue, targeted-facts, focused-list,\n // response-guidance, event-order, structured message-parts) no longer use this\n // helper — they MERGE candidates across EVERY authorized key under their single\n // budget (a weak primary-key hit must not mask stronger fallback evidence; the\n // section builders take `sessionIds`, structured-parts merges inline below).\n // This first-non-empty helper now serves ONLY the compressed-history section,\n // which is a per-session HOLISTIC DAG narrative with no per-item id to merge or\n // dedupe on — see its call site for the rationale.\n //\n // When the set is a single key (single-user / no-overlay / explicit-namespace),\n // this is exactly one call — unchanged. `lcmSessionId` is `string | undefined`:\n // a legacy SESSIONLESS recall yields the single `undefined` key so the read\n // runs ONE archive-wide read with no `session_id` filter (pre-#1505 behavior).\n // Hosted scope profiles are stricter: without a session key there is no\n // namespace-scoped LCM key to query, so the key set stays empty and LCM cannot\n // bypass the profile read stack via an archive-wide read. NEVER the literal\n // \"default\" session id (codex P2).\n const firstNonEmptyLcmRead = async <T>(\n read: (lcmSessionId: string | undefined) => Promise<T>,\n isEmpty: (value: T) => boolean,\n empty: T,\n ): Promise<T> => {\n for (const lcmSessionId of lcmReadSessionIds) {\n const value = await read(lcmSessionId);\n if (!isEmpty(value)) return value;\n }\n return empty;\n };\n const qmdAvailable = this.qmd.isAvailable();\n let graphDecisionStatus: IntentDebugSnapshot[\"graphDecision\"][\"status\"] =\n recallDecision.plannedMode === \"graph_mode\" ? \"skipped\" : \"not_requested\";\n let graphDecisionReason = recallDecision.graphReason;\n let graphDecisionShadowMode = false;\n let shouldPersistGraphSnapshot =\n recallDecision.plannedMode === \"graph_mode\";\n let graphSnapshotStatus: GraphRecallSnapshot[\"status\"] | undefined =\n recallDecision.plannedMode === \"graph_mode\" ? \"skipped\" : undefined;\n let graphSnapshotReason = recallDecision.graphReason;\n let graphSnapshotSeedPaths: string[] = [];\n let graphSnapshotExpandedPaths: GraphRecallExpandedEntry[] = [];\n let graphSnapshotSeedResults: GraphRecallRankedResult[] = [];\n let graphSnapshotFinalResults: GraphRecallRankedResult[] = [];\n let graphSnapshotShadowComparison: GraphRecallShadowComparison | undefined;\n const graphBaselinePaths = new Set<string>();\n const graphExpandedResultPaths = new Set<string>();\n const graphSourceLabelsForPath = (resultPath: string): string[] => {\n const labels: string[] = [];\n const normalizedPath = resultPath.split(path.sep).join(\"/\");\n const isEntityPath =\n normalizedPath.startsWith(\"entities/\") ||\n normalizedPath.includes(\"/entities/\");\n if (graphBaselinePaths.has(resultPath)) labels.push(\"baseline\");\n if (graphExpandedResultPaths.has(resultPath))\n labels.push(\"graph_expanded\");\n if (isEntityPath) labels.push(\"reconstructed_entity\");\n return labels.length > 0 ? labels : [\"baseline\"];\n };\n const buildIntentDebugSnapshot = (): IntentDebugSnapshot => ({\n recordedAt: new Date().toISOString(),\n promptHash,\n promptLength: prompt.length,\n retrievalQueryHash,\n retrievalQueryLength: retrievalQuery.length,\n plannerEnabled: this.config.recallPlannerEnabled,\n plannedMode: requestedMode ?? recallDecision.plannedMode,\n effectiveMode: recallMode,\n recallResultLimit,\n queryIntent,\n graphExpandedIntentDetected: recallDecision.graphExpandedIntentDetected,\n graphDecision: {\n status: graphDecisionStatus,\n reason: graphDecisionReason,\n shadowMode: graphDecisionShadowMode,\n qmdAvailable,\n graphRecallEnabled: this.config.graphRecallEnabled,\n multiGraphMemoryEnabled: this.config.multiGraphMemoryEnabled,\n },\n });\n\n if (recallMode === \"no_recall\") {\n const intentSnapshot = buildIntentDebugSnapshot();\n await this.recordLastIntentSnapshotForNamespace({\n namespace: selfNamespace,\n snapshot: intentSnapshot,\n });\n // Clean up workspace selection before early return to prevent Map leaks.\n const earlySessionKey = sessionKey ?? \"default\";\n this._recallWorkspaceOverrides.delete(earlySessionKey);\n timings.total = `${Date.now() - recallStart}ms`;\n // X-ray capture for the `no_recall` early-return path\n // (issue #570 PR 1). `no_recall` skips retrieval entirely, so\n // the snapshot carries zero results and an empty-budget accounting\n // — but we STILL capture it when the caller opts in so\n // `getLastXraySnapshot()` returns a useful debug document rather\n // than silently `null` (or a stale prior capture).\n //\n // Skip capture when the caller has already aborted this recall —\n // otherwise a canceled call could clobber a prior successful\n // capture (issue #570 PR 1 review follow-up).\n if (\n options.xrayCapture === true &&\n !options.abortSignal?.aborted\n ) {\n try {\n this.lastXraySnapshot = buildXraySnapshot({\n query: retrievalQuery,\n tierExplain: null,\n results: [],\n filters: [\n {\n name: \"planner-mode\",\n considered: 0,\n admitted: 0,\n reason: \"no_recall\",\n },\n ],\n budget: {\n chars: this.getRecallBudgetChars(options.budgetCharsOverride),\n used: 0,\n },\n sessionKey,\n namespace: selfNamespace,\n traceId,\n });\n } catch (err) {\n // Capture is a best-effort side channel: a capture failure\n // must NEVER propagate into the primary recall path.\n log.debug(`x-ray capture (no_recall) failed: ${err}`);\n }\n }\n if (sessionKey) {\n this.lastRecall\n .record({\n sessionKey,\n query: retrievalQuery,\n memoryIds: [],\n namespace: selfNamespace,\n traceId,\n plannerMode: recallMode,\n requestedMode,\n source: recallSource,\n fallbackUsed: false,\n sourcesUsed: [],\n budgetsApplied: this.buildLastRecallBudgetSummary({\n requestedTopK,\n recallResultLimit,\n qmdFetchLimit,\n qmdHybridFetchLimit,\n }),\n latencyMs: Date.now() - recallStart,\n resultPaths: [],\n policyVersion,\n appendImpression: this.config.recordEmptyRecallImpressions,\n identityInjection: {\n mode: identityInjectionModeUsed,\n injectedChars: identityInjectedChars,\n truncated: identityInjectionTruncated,\n },\n })\n .catch((err) => log.debug(`last recall record failed: ${err}`));\n }\n if (sessionKey) {\n this.queueEvalShadowRecall({\n traceId,\n recordedAt: new Date().toISOString(),\n sessionKey,\n promptHash,\n promptLength: prompt.length,\n retrievalQueryHash,\n retrievalQueryLength: retrievalQuery.length,\n recallMode,\n recallResultLimit,\n source: recallSource,\n recalledMemoryCount,\n injected: false,\n contextChars: 0,\n memoryIds: [],\n policyVersion,\n identityInjectionMode: identityInjectionModeUsed,\n identityInjectedChars,\n identityInjectionTruncated,\n durationMs: Date.now() - recallStart,\n timings: { ...timings },\n });\n }\n closeProfileTrace();\n this.emitTrace({\n kind: \"recall_summary\",\n traceId,\n operation: \"recall\",\n sessionKey,\n promptHash,\n promptLength: prompt.length,\n retrievalQueryHash,\n retrievalQueryLength: retrievalQuery.length,\n recallMode,\n recallResultLimit,\n qmdEnabled: this.config.qmdEnabled,\n qmdAvailable: this.qmd.isAvailable(),\n recallNamespaces: [],\n source: recallSource,\n recalledMemoryCount,\n injected: false,\n contextChars: 0,\n policyVersion,\n identityInjectionMode: identityInjectionModeUsed,\n identityInjectedChars,\n identityInjectionTruncated,\n durationMs: Date.now() - recallStart,\n timings: { ...timings },\n });\n return \"\";\n }\n\n const profileStorageNamespaces = scopeProfilePlan ? recallNamespaces : [selfNamespace];\n const profileStorages = await Promise.all(\n profileStorageNamespaces.map((namespace) => this.storageRouter.storageFor(namespace)),\n );\n const emptyProfileStorage = new Proxy(\n { dir: path.join(this.config.memoryDir, \".empty-scope-profile\") } as any,\n {\n get(target, prop: string | symbol) {\n if (prop in target) return target[prop];\n if (prop === \"readProfile\") return async () => \"\";\n if (\n prop === \"readQuestions\" ||\n prop === \"listEntityNames\" ||\n prop === \"readContinuityIncidents\"\n )\n return async () => [];\n if (\n prop === \"readIdentityAnchor\" ||\n prop === \"readIdentityImprovementLoops\"\n )\n return async () => \"\";\n if (prop === \"readEntity\" || prop === \"readMemoryByPath\")\n return async () => null;\n return async () => [];\n },\n },\n );\n const profileStorage =\n profileStorages.length <= 1\n ? profileStorages[0] ?? emptyProfileStorage\n : new Proxy(profileStorages[0] as any, {\n get(target, prop: string | symbol) {\n if (prop === \"readProfile\") {\n return async () => {\n for (const storage of profileStorages) {\n const profile = await storage.readProfile();\n if (profile.trim().length > 0) return profile;\n }\n return \"\";\n };\n }\n if (prop === \"readQuestions\") {\n return async (...args: any[]) => {\n const merged: any[] = [];\n const seen = new Set<string>();\n const priorityOf = (question: any): number => {\n const priority = Number(question?.priority ?? 0);\n return Number.isFinite(priority) ? priority : 0;\n };\n for (const storage of profileStorages) {\n const questions = await (storage.readQuestions as any)(...args);\n for (const question of questions) {\n const key = typeof question === \"string\" ? question : JSON.stringify(question);\n if (seen.has(key)) continue;\n seen.add(key);\n merged.push(question);\n }\n }\n return merged.sort(\n (left, right) =>\n priorityOf(right) - priorityOf(left) ||\n String(left?.id ?? \"\").localeCompare(String(right?.id ?? \"\")),\n );\n };\n }\n if (prop === \"readIdentityAnchor\") {\n return async () => {\n for (const storage of profileStorages) {\n const anchor = (await storage.readIdentityAnchor()) ?? \"\";\n if (anchor.trim().length > 0) return anchor;\n }\n return \"\";\n };\n }\n if (prop === \"readIdentityImprovementLoops\") {\n return async () => {\n const sections: string[] = [];\n const seen = new Set<string>();\n for (const storage of profileStorages) {\n const loops = ((await storage.readIdentityImprovementLoops()) ?? \"\").trim();\n if (!loops || seen.has(loops)) continue;\n seen.add(loops);\n sections.push(loops);\n }\n return sections.join(\"\\n\\n\");\n };\n }\n if (prop === \"readContinuityIncidents\") {\n return async (...args: any[]) => {\n const limit = typeof args[0] === \"number\" && Number.isFinite(args[0]) ? Math.max(0, args[0]) : undefined;\n const incidents: any[] = [];\n const seen = new Set<string>();\n const incidentTime = (incident: any): number => {\n const raw = incident?.updatedAt ?? incident?.openedAt ?? incident?.createdAt;\n const parsed = typeof raw === \"string\" ? Date.parse(raw) : Number.NaN;\n return Number.isFinite(parsed) ? parsed : 0;\n };\n for (const storage of profileStorages) {\n for (const incident of await (storage.readContinuityIncidents as any)(...args)) {\n const key = JSON.stringify(incident);\n if (seen.has(key)) continue;\n seen.add(key);\n incidents.push(incident);\n }\n }\n incidents.sort(\n (left, right) =>\n incidentTime(right) - incidentTime(left) ||\n String(left?.id ?? \"\").localeCompare(String(right?.id ?? \"\")),\n );\n return limit === undefined ? incidents : incidents.slice(0, limit);\n };\n }\n if (prop === \"listEntityNames\") {\n return async (...args: any[]) => {\n const names = new Set<string>();\n for (const storage of profileStorages) {\n for (const name of await (storage.listEntityNames as any)(...args)) names.add(name);\n }\n return [...names];\n };\n }\n if (prop === \"readEntity\" || prop === \"readMemoryByPath\") {\n return async (...args: any[]) => {\n for (const storage of profileStorages) {\n const value = await (storage as any)[prop](...args);\n if (value) return value;\n }\n return null;\n };\n }\n if (prop === \"readAllMemories\") {\n return async (...args: any[]) => {\n const memories: any[] = [];\n const seen = new Set<string>();\n for (const storage of profileStorages) {\n for (const memory of await (storage.readAllMemories as any)(...args)) {\n const key = String(memory?.path ?? memory?.frontmatter?.id ?? JSON.stringify(memory));\n if (seen.has(key)) continue;\n seen.add(key);\n memories.push(memory);\n }\n }\n return memories;\n };\n }\n return target[prop];\n },\n });\n const profileStorageDirs = Array.from(\n new Set(profileStorages.map((storage) => storage.dir).filter((dir): dir is string => typeof dir === \"string\" && dir.length > 0)),\n );\n\n // --- Phase 1: Launch ALL independent data fetches in parallel ---\n throwIfRecallAborted(options.abortSignal);\n\n // Catalog read touch (issue #1499): record reads against the recalled\n // namespaces HERE — after the abort gate, immediately before retrieval\n // actually runs — so `lastReadAt` reflects a real read, not a recall that was\n // aborted/errored/short-circuited before reaching this point (round 3/4/6,\n // codex/cursor — no_recall, zero-limit, aborted, and pre-read-error cases).\n // `no_recall` already returned earlier, so it cannot reach here. Best-effort\n // and failure-tolerant.\n if (\n this.namespaceCatalog.enabled &&\n recallResultLimit > 0 &&\n !options.abortSignal?.aborted\n ) {\n for (const ns of recallNamespaces) this.markCatalogRead(ns);\n }\n\n // 0. Shared context (v4.0, optional)\n const sharedContextPromise = (async (): Promise<string | null> => {\n if (\n !this.isRecallSectionEnabled(\n \"shared-context\",\n this.config.sharedContextEnabled === true,\n )\n )\n return null;\n if (!this.sharedContext) return null;\n if (\n scopeProfilePlan &&\n !(\n scopeProfilePlan.profile.readOrder.includes(\"serverShared\") &&\n scopeProfilePlan.readNamespaces.includes(this.config.sharedNamespace)\n )\n )\n return null;\n const t0 = Date.now();\n const [priorities, roundtable, crossSignals] = await Promise.all([\n this.sharedContext.readPriorities(),\n this.sharedContext.readLatestRoundtable(),\n this.sharedContext.readLatestCrossSignals(),\n ]);\n const max = Math.max(500, this.config.sharedContextMaxInjectChars);\n const capSection = (\n label: string,\n body: string | null,\n limit: number,\n ): string => {\n const trimmedBody = body?.trim();\n if (!trimmedBody) return \"\";\n const safeLimit = Math.max(120, limit);\n const section = `${label}\\n\\n${trimmedBody}`;\n return section.length > safeLimit\n ? `${section.slice(0, safeLimit)}\\n\\n...(trimmed)\\n`\n : section;\n };\n\n const prioritiesSection = capSection(\n \"### Priorities\",\n priorities,\n Math.floor(max * 0.35),\n );\n const crossSignalsSection = capSection(\n \"### Latest Cross-Signals\",\n crossSignals,\n Math.floor(max * 0.35),\n );\n const fixedSections = [prioritiesSection, crossSignalsSection].filter(\n (section) => section.trim().length > 0,\n );\n const fixedPrefix = [\"## Shared Context\", ...fixedSections].join(\"\\n\\n\");\n const reserved = fixedPrefix.length + \"\\n\\n\".length;\n const roundtableBudget = Math.max(160, max - reserved);\n const roundtableSection = capSection(\n \"### Latest Roundtable\",\n roundtable,\n roundtableBudget,\n );\n const combined = [\n \"## Shared Context\",\n ...fixedSections,\n roundtableSection,\n ]\n .filter((s) => s.trim().length > 0)\n .join(\"\\n\\n\");\n\n const trimmed =\n combined.length > max\n ? combined.slice(0, max) + \"\\n\\n...(trimmed)\\n\"\n : combined;\n recordRecallSectionMetric({\n section: \"sharedCtx\",\n priority: \"core\",\n durationMs: Date.now() - t0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"fresh\",\n success: true,\n });\n return trimmed.trim().length > 0 ? trimmed : null;\n })();\n\n // 1. Profile\n const profilePromise = (async (): Promise<string | null> => {\n if (!this.isRecallSectionEnabled(\"profile\")) return null;\n const t0 = Date.now();\n const profile = await profileStorage.readProfile();\n recordRecallSectionMetric({\n section: \"profile\",\n priority: \"core\",\n durationMs: Date.now() - t0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"fresh\",\n success: true,\n });\n return profile || null;\n })();\n\n // 1p. Peer profile injection (issue #679 PR 3/5).\n // Reads the profile.md for the peer registered on this session and\n // injects the most-recently-updated N fields into context. Wrapped\n // in a try-catch (CLAUDE.md #13 — external I/O must not crash the\n // primary recall flow). Gate: `peerProfileRecallEnabled` must be\n // true AND `peerProfileRecallMaxFields` must be > 0 AND a peer ID\n // must be registered for this session (rule 30 — new\n // filters/transforms must have configuration gates).\n //\n // Issue #679 completion: side-channel annotation for recall X-ray.\n // We capture the peer id and injected-field count separately from\n // the promise result string so the xray snapshot builder can record\n // them without re-parsing the rendered section text.\n //\n // Three-state semantics (mirrors docs/peers.md X-ray contract):\n // undefined — feature off, no peer registered, or maxFields=0 (field\n // absent from snapshot — peerProfileInjection not set).\n // null — feature enabled + peer registered, but no profile or no\n // fields found (snapshot carries explicit null).\n // object — injection occurred (snapshot carries { peerId, fieldsInjected }).\n //\n // Cursor Bugbot (PR #764): must start as `undefined` so early-return\n // paths that never enter the feature-enabled branch leave the annotation\n // absent. Starting as `null` incorrectly sets peerProfileInjection:null\n // on the snapshot even when peerProfileRecallEnabled is false.\n let peerProfileXrayAnnotation:\n | { peerId: string; fieldsInjected: number }\n | null\n | undefined = undefined;\n const peerProfileRecallPromise = (async (): Promise<string | null> => {\n if (!this.config.peerProfileRecallEnabled) return null;\n if (this.config.peerProfileRecallMaxFields <= 0) return null;\n const peerId = this.getPeerIdForSession(sessionKey);\n if (!peerId) return null;\n const t0 = Date.now();\n try {\n const { readPeerProfile: _readPeerProfile } = await import(\"./peers/index.js\");\n const peerProfile = await _readPeerProfile(this.config.memoryDir, peerId);\n recordRecallSectionMetric({\n section: \"peerProfile\",\n priority: \"core\",\n durationMs: Date.now() - t0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"fresh\",\n success: true,\n });\n if (!peerProfile) {\n // Feature on + peer registered, but no profile written yet.\n // Three-state contract: explicit null = \"enabled but no profile\".\n peerProfileXrayAnnotation = null;\n return null;\n }\n const allFields = Object.entries(peerProfile.fields);\n if (allFields.length === 0) {\n // Profile exists but has no fields — same semantic as no profile.\n peerProfileXrayAnnotation = null;\n return null;\n }\n // Select the top-N most-recently-updated fields by consulting\n // provenance. Fields without provenance get epoch-0 ms so they\n // sort last (least recent).\n // Codex P2: parse ISO-8601 to epoch ms rather than comparing\n // strings. ISO-8601 strings with different timezone offsets\n // (e.g. \"2026-04-20T00:00:00+05:00\" vs \"2026-04-20T00:00:00Z\")\n // can order incorrectly under lexicographic comparison even\n // though they may refer to different instants. `Date.parse`\n // returns NaN on malformed input — we fall back to 0 (epoch)\n // so invalid timestamps sort last rather than causing NaN\n // comparison instability.\n const fieldsByRecency = allFields\n .map(([key, value]) => {\n const prov = peerProfile.provenance[key];\n // Find the most recent observedAt (epoch ms) across all\n // provenance entries for this field. Fall back to 0 if none\n // recorded or if all entries are malformed.\n let latestMs = 0;\n if (Array.isArray(prov) && prov.length > 0) {\n for (const p of prov) {\n if (typeof p.observedAt === \"string\") {\n const parsed = Date.parse(p.observedAt);\n if (Number.isFinite(parsed) && parsed > latestMs) {\n latestMs = parsed;\n }\n }\n }\n }\n return { key, value, latestMs };\n })\n // Descending: most-recently-updated first (rule 19 — sort\n // comparators must return 0 for equal items so use secondary key).\n .sort((a, b) => {\n if (b.latestMs !== a.latestMs) return b.latestMs - a.latestMs;\n return a.key < b.key ? -1 : a.key > b.key ? 1 : 0;\n });\n const capped = fieldsByRecency.slice(0, this.config.peerProfileRecallMaxFields);\n const lines = capped.map(({ key, value }) => `**${key}**: ${value}`);\n // Record xray annotation: peerId + how many fields were injected.\n peerProfileXrayAnnotation = { peerId, fieldsInjected: capped.length };\n return `## Peer Profile\\n\\n${lines.join(\"\\n\\n\")}`;\n } catch (err) {\n recordRecallSectionMetric({\n section: \"peerProfile\",\n priority: \"core\",\n durationMs: Date.now() - t0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"fresh\",\n success: false,\n timing: `error(${err instanceof Error ? err.message : String(err)})`,\n });\n log.debug(`peer profile recall injection failed (non-fatal): ${err}`);\n return null;\n }\n })();\n\n // 1a. Identity continuity signals (v8.4)\n const identityContinuityPromise = (async () => {\n if (\n !this.isRecallSectionEnabled(\n \"identity-continuity\",\n this.config.identityContinuityEnabled === true,\n )\n )\n return null;\n const t0 = Date.now();\n const section = await this.buildIdentityContinuitySection({\n storage: profileStorage,\n recallMode,\n prompt: retrievalQuery,\n });\n recordRecallSectionMetric({\n section: \"identityContinuity\",\n priority: \"core\",\n durationMs: Date.now() - t0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"fresh\",\n success: true,\n });\n return section;\n })();\n\n const entityRetrievalPromise = (async (): Promise<string | null> => {\n if (\n !this.isRecallSectionEnabled(\n \"entity-retrieval\",\n this.config.entityRetrievalEnabled,\n )\n )\n return null;\n if (!this.config.entityRetrievalEnabled) return null;\n const maxChars =\n this.getRecallSectionMaxChars(\"entity-retrieval\") ??\n this.config.entityRetrievalMaxChars;\n const maxHints =\n this.getRecallSectionNumber(\"entity-retrieval\", \"maxHints\") ??\n this.config.entityRetrievalMaxHints;\n const maxSupportingFacts =\n this.getRecallSectionNumber(\"entity-retrieval\", \"maxSupportingFacts\") ??\n this.config.entityRetrievalMaxSupportingFacts;\n const maxRelatedEntities =\n this.getRecallSectionNumber(\"entity-retrieval\", \"maxRelatedEntities\") ??\n this.config.entityRetrievalMaxRelatedEntities;\n const recentTurns =\n this.getRecallSectionNumber(\"entity-retrieval\", \"recentTurns\") ??\n this.config.entityRetrievalRecentTurns;\n if (maxChars === 0 || maxHints === 0 || maxSupportingFacts === 0) {\n recordRecallSectionMetric({\n section: \"entityRetrieval\",\n priority: \"core\",\n durationMs: 0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip(limit=0)\",\n });\n return null;\n }\n const t0 = Date.now();\n const transcriptEntries = sessionKey\n ? await readRecentEntityTranscriptEntries(\n this.transcript.readRecent(\n entityRecentTranscriptLookbackHours,\n sessionKey,\n ),\n recentTurns,\n )\n : [];\n const section = await buildEntityRecallSection({\n config: this.config,\n storage: profileStorage,\n namespaceStorage: (namespace) => this.getStorage(namespace),\n query: retrievalQuery,\n recallNamespaces,\n recentTurns,\n maxHints,\n maxSupportingFacts,\n maxRelatedEntities,\n maxChars,\n transcriptEntries,\n }).catch((err) => {\n log.warn(`entity retrieval build failed: ${err}`);\n return null;\n });\n recordRecallSectionMetric({\n section: \"entityRetrieval\",\n priority: \"core\",\n durationMs: Date.now() - t0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"fresh\",\n success: true,\n });\n return section;\n })();\n\n // 1b. Knowledge Index (v7.0)\n const knowledgeIndexPromise = (async (): Promise<{\n result: string;\n cached: boolean;\n } | null> => {\n if (\n !this.isRecallSectionEnabled(\n \"knowledge-index\",\n this.config.knowledgeIndexEnabled,\n )\n )\n return null;\n if (!this.config.knowledgeIndexEnabled) return null;\n const t0 = Date.now();\n try {\n const knowledgeIndexMaxChars =\n this.getRecallSectionNumber(\"knowledge-index\", \"maxChars\") ??\n this.config.knowledgeIndexMaxChars;\n const knowledgeIndexMaxEntities =\n this.getRecallSectionNumber(\"knowledge-index\", \"maxEntities\") ??\n this.config.knowledgeIndexMaxEntities;\n const knowledgeIndexOptions = {\n maxEntities: knowledgeIndexMaxEntities,\n maxChars: knowledgeIndexMaxChars,\n };\n const ki = scopeProfilePlan\n ? await (async () => {\n const perLayerOptions = {\n ...knowledgeIndexOptions,\n maxEntities: Number.MAX_SAFE_INTEGER,\n maxChars: Number.MAX_SAFE_INTEGER,\n };\n const results = await Promise.all(\n profileStorages.map((storage) =>\n storage.buildKnowledgeIndex(this.config, perLayerOptions),\n ),\n );\n const sections = results\n .map((result) => result.result.trim())\n .filter((section) => section.length > 0);\n const maxRows = Math.max(0, Math.floor(knowledgeIndexMaxEntities));\n const rows: string[] = [];\n let header: string[] | null = null;\n for (const section of sections) {\n const lines = section\n .split(\"\\n\")\n .map((line) => line.trimEnd())\n .filter((line) => line.length > 0);\n const tableHeaderIndex = lines.findIndex((line) =>\n line.startsWith(\"| Entity |\"),\n );\n if (tableHeaderIndex === -1) continue;\n header ??= lines.slice(0, tableHeaderIndex + 2);\n for (const row of lines.slice(tableHeaderIndex + 2)) {\n if (!row.startsWith(\"|\")) continue;\n if (rows.length >= maxRows) break;\n rows.push(row);\n }\n if (rows.length >= maxRows) break;\n }\n const merged =\n header && rows.length > 0\n ? `${header.join(\"\\n\")}\\n${rows.join(\"\\n\")}\\n`\n : \"\";\n return {\n result: this.truncateRecallSectionToBudget(\n merged,\n knowledgeIndexMaxChars,\n ),\n cached: results.every((result) => result.cached),\n };\n })()\n : await this.storage.buildKnowledgeIndex(this.config, knowledgeIndexOptions);\n recordRecallSectionMetric({\n section: \"ki\",\n priority: \"core\",\n durationMs: Date.now() - t0,\n deadlineMs: recallSectionDeadlineMs,\n source: ki.cached ? \"stale\" : \"fresh\",\n success: true,\n timing: `${Date.now() - t0}ms${ki.cached ? \" (cached)\" : \"\"}`,\n });\n return ki.result ? ki : null;\n } catch (err) {\n recordRecallSectionMetric({\n section: \"ki\",\n priority: \"core\",\n durationMs: Date.now() - t0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"skip\",\n success: false,\n timing: `${Date.now() - t0}ms (err)`,\n });\n log.warn(`Knowledge Index build failed: ${err}`);\n return null;\n }\n })();\n\n // 1c. Verbatim artifacts (v8.0 phase 1)\n const artifactsPromise = (async (): Promise<MemoryFile[]> => {\n if (\n !this.isRecallSectionEnabled(\n \"verbatim-artifacts\",\n this.config.verbatimArtifactsEnabled === true,\n )\n )\n return [];\n if (!this.config.verbatimArtifactsEnabled) return [];\n const t0 = Date.now();\n const targetCount = computeArtifactRecallLimit(\n recallMode,\n recallResultLimit,\n this.config.verbatimArtifactsMaxRecall,\n );\n if (targetCount <= 0) {\n recordRecallSectionMetric({\n section: \"artifacts\",\n priority: \"core\",\n durationMs: 0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip(limit=0)\",\n });\n return [];\n }\n const results = await this.recallArtifactsAcrossNamespaces(\n retrievalQuery,\n recallNamespaces,\n targetCount,\n );\n\n recordRecallSectionMetric({\n section: \"artifacts\",\n priority: \"core\",\n durationMs: Date.now() - t0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"fresh\",\n success: true,\n });\n return results;\n })();\n\n const objectiveStatePromise = (async (): Promise<string | null> => {\n const t0 = Date.now();\n if (\n !this.config.objectiveStateMemoryEnabled ||\n !this.config.objectiveStateRecallEnabled ||\n !this.isRecallSectionEnabled(\n \"objective-state\",\n this.config.objectiveStateRecallEnabled === true,\n )\n ) {\n recordRecallSectionMetric({\n section: \"objectiveState\",\n priority: \"core\",\n durationMs: 0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip\",\n });\n return null;\n }\n const maxResults =\n this.getRecallSectionNumber(\"objective-state\", \"maxResults\") ?? 4;\n if (maxResults <= 0) {\n recordRecallSectionMetric({\n section: \"objectiveState\",\n priority: \"core\",\n durationMs: 0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip(limit=0)\",\n });\n return null;\n }\n\n const objectiveStateSearches = await Promise.all(\n recallNamespaces.map(async (namespace) => {\n const storage = this.config.namespacesEnabled\n ? await this.getStorage(namespace)\n : null;\n return searchObjectiveStateSnapshots({\n memoryDir: this.config.namespacesEnabled\n ? storage!.dir\n : this.config.memoryDir,\n objectiveStateStoreDir: objectiveStateStoreOverrideForNamespace({\n memoryDir: this.config.memoryDir,\n configuredStoreDir: this.config.objectiveStateStoreDir,\n namespacesEnabled: this.config.namespacesEnabled,\n namespace,\n }),\n query: retrievalQuery,\n maxResults,\n sessionKey,\n });\n }),\n );\n const results = objectiveStateSearches\n .flat()\n .sort((left, right) => {\n if (right.score !== left.score) return right.score - left.score;\n return right.snapshot.recordedAt.localeCompare(left.snapshot.recordedAt);\n })\n .slice(0, maxResults);\n\n recordRecallSectionMetric({\n section: \"objectiveState\",\n priority: \"core\",\n durationMs: Date.now() - t0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"fresh\",\n success: true,\n });\n return results.length > 0\n ? this.formatObjectiveStateResults(results)\n : null;\n })();\n\n const causalTrajectoryPromise = (async (): Promise<string | null> => {\n const t0 = Date.now();\n if (\n !this.config.causalTrajectoryMemoryEnabled ||\n !this.config.causalTrajectoryRecallEnabled ||\n !this.isRecallSectionEnabled(\n \"causal-trajectories\",\n this.config.causalTrajectoryRecallEnabled === true,\n )\n ) {\n recordRecallSectionMetric({\n section: \"causalTrajectories\",\n priority: \"core\",\n durationMs: 0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip\",\n });\n return null;\n }\n const maxResults =\n this.getRecallSectionNumber(\"causal-trajectories\", \"maxResults\") ?? 3;\n if (maxResults <= 0) {\n recordRecallSectionMetric({\n section: \"causalTrajectories\",\n priority: \"core\",\n durationMs: 0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip(limit=0)\",\n });\n return null;\n }\n\n const results = await searchCausalTrajectories({\n memoryDir: this.config.memoryDir,\n causalTrajectoryStoreDir: this.config.causalTrajectoryStoreDir,\n query: retrievalQuery,\n maxResults,\n sessionKey,\n });\n\n recordRecallSectionMetric({\n section: \"causalTrajectories\",\n priority: \"core\",\n durationMs: Date.now() - t0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"fresh\",\n success: true,\n });\n return results.length > 0\n ? this.formatCausalTrajectoryResults(results)\n : null;\n })();\n\n const cmcRetrievalPromise = (async (): Promise<string | null> => {\n const t0 = Date.now();\n if (\n !this.config.cmcRetrievalEnabled ||\n !this.isRecallSectionEnabled(\n \"cmc-causal-chains\",\n this.config.cmcRetrievalEnabled === true,\n )\n ) {\n recordRecallSectionMetric({\n section: \"cmcCausalChains\",\n priority: \"core\",\n durationMs: 0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip\",\n });\n return null;\n }\n try {\n const { retrieveCausalChains } = await import(\"./causal-retrieval.js\");\n const section = await retrieveCausalChains({\n memoryDir: this.config.memoryDir,\n causalTrajectoryStoreDir: this.config.causalTrajectoryStoreDir,\n query: retrievalQuery,\n sessionKey,\n config: {\n maxDepth: this.config.cmcRetrievalMaxDepth,\n maxChars: this.config.cmcRetrievalMaxChars,\n counterfactualBoost: this.config.cmcRetrievalCounterfactualBoost,\n },\n });\n recordRecallSectionMetric({\n section: \"cmcCausalChains\",\n priority: \"core\",\n durationMs: Date.now() - t0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"fresh\",\n success: true,\n });\n return section;\n } catch (err) {\n log.warn(\"[cmc] causal retrieval failed (non-fatal)\", err);\n recordRecallSectionMetric({\n section: \"cmcCausalChains\",\n priority: \"core\",\n durationMs: Date.now() - t0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"skip\",\n success: false,\n timing: \"error\",\n });\n return null;\n }\n })();\n\n const calibrationPromise = (async (): Promise<string | null> => {\n const t0 = Date.now();\n if (\n !this.config.calibrationEnabled ||\n !this.isRecallSectionEnabled(\n \"calibration-rules\",\n this.config.calibrationEnabled === true,\n )\n ) {\n recordRecallSectionMetric({\n section: \"calibrationRules\",\n priority: \"core\",\n durationMs: 0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip\",\n });\n return null;\n }\n try {\n const { getCalibrationRulesForRecall, buildCalibrationRecallSection } =\n await import(\"./calibration.js\");\n const rules = await getCalibrationRulesForRecall(this.config.memoryDir);\n if (rules.length === 0) {\n recordRecallSectionMetric({\n section: \"calibrationRules\",\n priority: \"core\",\n durationMs: Date.now() - t0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip(no-rules)\",\n });\n return null;\n }\n const section = buildCalibrationRecallSection(\n rules.slice(0, this.config.calibrationMaxRulesPerRecall),\n retrievalQuery,\n this.config.calibrationMaxChars,\n );\n recordRecallSectionMetric({\n section: \"calibrationRules\",\n priority: \"core\",\n durationMs: Date.now() - t0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"fresh\",\n success: true,\n });\n return section;\n } catch (err) {\n log.warn(\"[calibration] recall section failed (non-fatal)\", err);\n recordRecallSectionMetric({\n section: \"calibrationRules\",\n priority: \"core\",\n durationMs: Date.now() - t0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"skip\",\n success: false,\n timing: \"error\",\n });\n return null;\n }\n })();\n\n const trustZonePromise = (async (): Promise<string | null> => {\n const t0 = Date.now();\n if (\n !this.config.trustZonesEnabled ||\n !this.config.trustZoneRecallEnabled ||\n !this.isRecallSectionEnabled(\n \"trust-zones\",\n this.config.trustZoneRecallEnabled === true,\n )\n ) {\n recordRecallSectionMetric({\n section: \"trustZones\",\n priority: \"core\",\n durationMs: 0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip\",\n });\n return null;\n }\n const maxResults =\n this.getRecallSectionNumber(\"trust-zones\", \"maxResults\") ?? 3;\n if (maxResults <= 0) {\n recordRecallSectionMetric({\n section: \"trustZones\",\n priority: \"core\",\n durationMs: 0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip(limit=0)\",\n });\n return null;\n }\n\n const results = await searchTrustZoneRecords({\n memoryDir: this.config.memoryDir,\n trustZoneStoreDir: this.config.trustZoneStoreDir,\n query: retrievalQuery,\n maxResults,\n sessionKey,\n });\n\n recordRecallSectionMetric({\n section: \"trustZones\",\n priority: \"core\",\n durationMs: Date.now() - t0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"fresh\",\n success: true,\n });\n return results.length > 0 ? this.formatTrustZoneResults(results) : null;\n })();\n\n const harmonicRetrievalAbort = createEnrichmentAbortHandle(\n options.abortSignal,\n );\n const harmonicRetrievalPromise = observeEnrichmentPromise(\n (async (): Promise<string | null> => {\n const t0 = Date.now();\n if (\n !this.config.harmonicRetrievalEnabled ||\n !this.isRecallSectionEnabled(\n \"harmonic-retrieval\",\n this.config.harmonicRetrievalEnabled === true,\n )\n ) {\n recordRecallSectionMetric({\n section: \"harmonicRetrieval\",\n priority: \"enrichment\",\n durationMs: 0,\n deadlineMs: enrichmentSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip\",\n });\n return null;\n }\n const maxResults =\n this.getRecallSectionNumber(\"harmonic-retrieval\", \"maxResults\") ?? 3;\n if (maxResults <= 0) {\n recordRecallSectionMetric({\n section: \"harmonicRetrieval\",\n priority: \"enrichment\",\n durationMs: 0,\n deadlineMs: enrichmentSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip(limit=0)\",\n });\n return null;\n }\n\n const harmonicSearchDirs = scopeProfilePlan ? profileStorageDirs : [this.config.memoryDir];\n const harmonicResultsByDir = await Promise.all(\n harmonicSearchDirs.map((memoryDir) =>\n searchHarmonicRetrieval({\n memoryDir,\n abstractionNodeStoreDir: scopeProfilePlan ? undefined : this.config.abstractionNodeStoreDir,\n query: retrievalQuery,\n maxResults,\n sessionKey,\n anchorsEnabled: this.config.abstractionAnchorsEnabled,\n abortSignal: harmonicRetrievalAbort.signal,\n }),\n ),\n );\n const harmonicByNodeId = new Map<string, HarmonicRetrievalResult>();\n for (const result of harmonicResultsByDir.flat()) {\n const existing = harmonicByNodeId.get(result.node.nodeId);\n if (!existing || result.score > existing.score) {\n harmonicByNodeId.set(result.node.nodeId, result);\n }\n }\n const results = [...harmonicByNodeId.values()]\n .sort(\n (left, right) =>\n right.score - left.score ||\n right.anchorScore - left.anchorScore ||\n right.node.recordedAt.localeCompare(left.node.recordedAt) ||\n left.node.nodeId.localeCompare(right.node.nodeId),\n )\n .slice(0, maxResults);\n\n recordRecallSectionMetric({\n section: \"harmonicRetrieval\",\n priority: \"enrichment\",\n durationMs: Date.now() - t0,\n deadlineMs: enrichmentSectionDeadlineMs,\n source: \"fresh\",\n success: true,\n });\n return results.length > 0\n ? this.formatHarmonicRetrievalResults(results)\n : null;\n })().finally(() => harmonicRetrievalAbort.dispose()),\n () => harmonicRetrievalAbort.cancel(),\n );\n\n // Verified recall and semantic rules both need readAllMemories().\n // Instead of a shared preload (which has namespace/dir mismatch issues),\n // each subsystem calls readAllMemories() on its correct storage instance.\n // The process-level memory cache (keyed by baseDir + memoryStatusVersion)\n // ensures only one actual disk scan happens — subsequent calls return\n // from cache in <1ms.\n\n const verifiedRecallPromise = (async (): Promise<string | null> => {\n const t0 = Date.now();\n if (\n !this.config.verifiedRecallEnabled ||\n !this.isRecallSectionEnabled(\n \"verified-episodes\",\n this.config.verifiedRecallEnabled === true,\n )\n ) {\n recordRecallSectionMetric({\n section: \"verifiedRecall\",\n priority: \"core\",\n durationMs: 0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip\",\n });\n return null;\n }\n const maxResults =\n this.getRecallSectionNumber(\"verified-episodes\", \"maxResults\") ?? 3;\n if (maxResults <= 0) {\n recordRecallSectionMetric({\n section: \"verifiedRecall\",\n priority: \"core\",\n durationMs: 0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip(limit=0)\",\n });\n return null;\n }\n\n const VERIFIED_RECALL_TIMEOUT_MS = 15_000;\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined;\n const results = await Promise.race([\n Promise.all(\n profileStorageDirs.map((memoryDir) =>\n searchVerifiedEpisodes({\n memoryDir,\n query: retrievalQuery,\n maxResults,\n boxRecallDays: this.config.boxRecallDays,\n }).catch((err) => {\n log.debug(`verified recall directory scan failed: ${err}`);\n return [] as VerifiedEpisodeResult[];\n }),\n ),\n ).then((groups) => {\n const merged: VerifiedEpisodeResult[] = [];\n const seen = new Set<string>();\n for (const result of groups.flat()) {\n const key = result.box.id || JSON.stringify(result);\n if (seen.has(key)) continue;\n seen.add(key);\n merged.push(result);\n }\n return merged.sort(compareVerifiedEpisodeResults).slice(0, maxResults);\n }),\n new Promise<[]>((resolve) => {\n timeoutHandle = setTimeout(\n () => resolve([]),\n VERIFIED_RECALL_TIMEOUT_MS,\n );\n }),\n ]).catch(() => [] as VerifiedEpisodeResult[]);\n if (timeoutHandle) clearTimeout(timeoutHandle);\n\n const durationMs = Date.now() - t0;\n if (durationMs >= VERIFIED_RECALL_TIMEOUT_MS) {\n log.debug(\n `verified recall: timed out after ${VERIFIED_RECALL_TIMEOUT_MS}ms`,\n );\n }\n recordRecallSectionMetric({\n section: \"verifiedRecall\",\n priority: \"core\",\n durationMs,\n deadlineMs: VERIFIED_RECALL_TIMEOUT_MS,\n source: \"fresh\",\n success: true,\n });\n return results.length > 0\n ? this.formatVerifiedEpisodeResults(results)\n : null;\n })();\n\n const verifiedRulesPromise = (async (): Promise<string | null> => {\n const t0 = Date.now();\n if (\n !this.config.semanticRuleVerificationEnabled ||\n !this.isRecallSectionEnabled(\n \"verified-rules\",\n this.config.semanticRuleVerificationEnabled === true,\n )\n ) {\n recordRecallSectionMetric({\n section: \"verifiedRules\",\n priority: \"core\",\n durationMs: 0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip\",\n });\n return null;\n }\n const maxResults =\n this.getRecallSectionNumber(\"verified-rules\", \"maxResults\") ?? 3;\n if (maxResults <= 0) {\n recordRecallSectionMetric({\n section: \"verifiedRules\",\n priority: \"core\",\n durationMs: 0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip(limit=0)\",\n });\n return null;\n }\n\n const VERIFIED_RULES_TIMEOUT_MS = 15_000;\n let rulesTimeoutHandle: ReturnType<typeof setTimeout> | undefined;\n const results = await Promise.race([\n Promise.all(\n profileStorageDirs.map((memoryDir) =>\n searchVerifiedSemanticRules({\n memoryDir,\n query: retrievalQuery,\n maxResults,\n }).catch((err) => {\n log.debug(`verified rules directory scan failed: ${err}`);\n return [] as VerifiedSemanticRuleResult[];\n }),\n ),\n ).then((groups) => {\n const merged: VerifiedSemanticRuleResult[] = [];\n const seen = new Set<string>();\n for (const result of groups.flat()) {\n const key = result.rule.frontmatter.id || result.rule.path || JSON.stringify(result);\n if (seen.has(key)) continue;\n seen.add(key);\n merged.push(result);\n }\n return merged.sort(compareVerifiedSemanticRuleResults).slice(0, maxResults);\n }),\n new Promise<[]>((resolve) => {\n rulesTimeoutHandle = setTimeout(\n () => resolve([]),\n VERIFIED_RULES_TIMEOUT_MS,\n );\n }),\n ]).catch(() => [] as VerifiedSemanticRuleResult[]);\n if (rulesTimeoutHandle) clearTimeout(rulesTimeoutHandle);\n\n const durationMs = Date.now() - t0;\n if (durationMs >= VERIFIED_RULES_TIMEOUT_MS) {\n log.debug(\n `verified rules: timed out after ${VERIFIED_RULES_TIMEOUT_MS}ms`,\n );\n }\n recordRecallSectionMetric({\n section: \"verifiedRules\",\n priority: \"core\",\n durationMs,\n deadlineMs: VERIFIED_RULES_TIMEOUT_MS,\n source: \"fresh\",\n success: true,\n });\n return results.length > 0\n ? this.formatVerifiedSemanticRuleResults(results)\n : null;\n })();\n\n const workProductsPromise = (async (): Promise<string | null> => {\n const t0 = Date.now();\n if (\n !this.config.creationMemoryEnabled ||\n !this.config.workProductRecallEnabled ||\n !this.isRecallSectionEnabled(\n \"work-products\",\n this.config.workProductRecallEnabled === true,\n )\n ) {\n recordRecallSectionMetric({\n section: \"workProducts\",\n priority: \"core\",\n durationMs: 0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip\",\n });\n return null;\n }\n const maxResults =\n this.getRecallSectionNumber(\"work-products\", \"maxResults\") ?? 3;\n if (maxResults <= 0) {\n recordRecallSectionMetric({\n section: \"workProducts\",\n priority: \"core\",\n durationMs: 0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip(limit=0)\",\n });\n return null;\n }\n\n const workProductSearchDirs = scopeProfilePlan ? profileStorageDirs : [this.config.memoryDir];\n const workProductResultsByDir = await Promise.all(\n workProductSearchDirs.map((memoryDir) =>\n searchWorkProductLedgerEntries({\n memoryDir,\n workProductLedgerDir: scopeProfilePlan ? undefined : this.config.workProductLedgerDir,\n query: retrievalQuery,\n maxResults,\n sessionKey,\n }),\n ),\n );\n const workProductByEntryId = new Map<string, WorkProductLedgerSearchResult>();\n for (const result of workProductResultsByDir.flat()) {\n const existing = workProductByEntryId.get(result.entry.entryId);\n if (!existing || result.score > existing.score) {\n workProductByEntryId.set(result.entry.entryId, result);\n }\n }\n const results = [...workProductByEntryId.values()]\n .sort(\n (left, right) =>\n right.score - left.score ||\n right.entry.recordedAt.localeCompare(left.entry.recordedAt) ||\n left.entry.entryId.localeCompare(right.entry.entryId),\n )\n .slice(0, maxResults);\n\n recordRecallSectionMetric({\n section: \"workProducts\",\n priority: \"core\",\n durationMs: Date.now() - t0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"fresh\",\n success: true,\n });\n return results.length > 0 ? this.formatWorkProductResults(results) : null;\n })();\n\n const queryAwarePrefilterPromise =\n (async (): Promise<QueryAwarePrefilter> => {\n const t0 = Date.now();\n if (!this.config.queryAwareIndexingEnabled || !prompt.trim()) {\n recordRecallSectionMetric({\n section: \"queryAware\",\n priority: \"enrichment\",\n durationMs: 0,\n deadlineMs: enrichmentSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip\",\n });\n return {\n candidatePaths: null,\n temporalFromDate: null,\n matchedTags: [],\n expandedTags: [],\n combination: \"none\",\n filteredToFullSearch: false,\n };\n }\n\n const prefilter = await this.buildQueryAwarePrefilter(\n retrievalQuery,\n recallNamespaces,\n );\n const candidateCount = prefilter.candidatePaths?.size ?? 0;\n const temporalLabel = prefilter.temporalFromDate ?? \"-\";\n const tagLabel =\n prefilter.expandedTags.length > 0\n ? prefilter.expandedTags.join(\"|\")\n : \"-\";\n const fallbackLabel = prefilter.filteredToFullSearch\n ? \"/full-search\"\n : \"\";\n recordRecallSectionMetric({\n section: \"queryAware\",\n priority: \"enrichment\",\n durationMs: Date.now() - t0,\n deadlineMs: enrichmentSectionDeadlineMs,\n source: prefilter.filteredToFullSearch ? \"stale\" : \"fresh\",\n success: true,\n timing: `${Date.now() - t0}ms(${prefilter.combination}${fallbackLabel};count=${candidateCount};time=${temporalLabel};tags=${tagLabel})`,\n });\n return prefilter;\n })();\n\n // 2. QMD search (the slow part — runs in parallel with preamble)\n type QmdPhaseResult = {\n memoryResultsLists: QmdSearchResult[][];\n globalResults: QmdSearchResult[];\n /** Top QMD score BEFORE contextual weight scaling from the agent merge.\n * Used by the confidence gate so that enabling parallel retrieval doesn't\n * silently lower scores below the calibrated gate threshold. */\n preAugmentTopScore: number;\n /** Max score from direct + temporal agents (post-weight) BEFORE merge.\n * Included in the confidence gate so that strong specialized hits (e.g.\n * an exact entity-name match) are not discarded just because the QMD\n * contextual pass returned a weak result. */\n maxSpecializedScore: number;\n } | null;\n\n const qmdEnrichmentAbort = createEnrichmentAbortHandle(options.abortSignal);\n const qmdPromise = observeEnrichmentPromise(\n (async (): Promise<QmdPhaseResult> => {\n const t0 = Date.now();\n if (recallResultLimit <= 0) {\n recordRecallSectionMetric({\n section: \"qmd\",\n priority: \"enrichment\",\n durationMs: Date.now() - t0,\n deadlineMs: enrichmentSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip(limit=0)\",\n });\n return null;\n }\n\n const qmdCacheKey = buildQmdRecallCacheKey({\n query: retrievalQuery,\n namespaces: recallNamespaces,\n recallMode,\n maxResults: qmdFetchLimit,\n memoryDir: this.config.memoryDir,\n searchOptions: qmdSearchOptions,\n searchStrategy: this.config.qmdSearchStrategy,\n subprocessStrategy: this.config.qmdSubprocessStrategy,\n });\n const cachedQmd = getCachedQmdRecall<Exclude<QmdPhaseResult, null>>(\n qmdCacheKey,\n {\n freshTtlMs: this.config.qmdRecallCacheTtlMs ?? 60_000,\n staleTtlMs: this.config.qmdRecallCacheStaleTtlMs ?? 10 * 60_000,\n },\n );\n const staleQmdFallback =\n cachedQmd?.source === \"stale\" ? cachedQmd : null;\n const queryAwarePrefilter = await queryAwarePrefilterPromise;\n const queryAwarePrefilterIsEmpty =\n queryAwarePrefilter.candidatePaths?.size === 0;\n const emptyQueryAwareQmdResult: Exclude<QmdPhaseResult, null> = {\n memoryResultsLists: [[]],\n globalResults: [],\n preAugmentTopScore: 0,\n maxSpecializedScore: 0,\n };\n if (cachedQmd?.source === \"fresh\") {\n recordRecallSectionMetric({\n section: \"qmd\",\n priority: \"enrichment\",\n durationMs: Date.now() - t0,\n deadlineMs: enrichmentSectionDeadlineMs,\n source: cachedQmd.source,\n success: true,\n timing: `${Math.max(0, Math.round(cachedQmd.ageMs))}ms-cache`,\n });\n if (queryAwarePrefilterIsEmpty) {\n return emptyQueryAwareQmdResult;\n }\n return cachedQmd.value;\n }\n\n if (!this.qmd.isAvailable()) {\n const now = Date.now();\n const QMD_REPROBE_COOLDOWN_MS = 60_000;\n if (\n this.lastQmdReprobeAtMs &&\n now - this.lastQmdReprobeAtMs < QMD_REPROBE_COOLDOWN_MS\n ) {\n if (staleQmdFallback) {\n recordRecallSectionMetric({\n section: \"qmd\",\n priority: \"enrichment\",\n durationMs: Date.now() - t0,\n deadlineMs: enrichmentSectionDeadlineMs,\n source: \"stale\",\n success: true,\n timing: `stale-cache(reprobe-cooldown:${Math.max(0, Math.round(staleQmdFallback.ageMs))}ms)`,\n });\n if (queryAwarePrefilterIsEmpty) {\n return emptyQueryAwareQmdResult;\n }\n return staleQmdFallback.value;\n }\n recordRecallSectionMetric({\n section: \"qmd\",\n priority: \"enrichment\",\n durationMs: Date.now() - t0,\n deadlineMs: enrichmentSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip(reprobe-cooldown)\",\n });\n return null;\n }\n this.lastQmdReprobeAtMs = now;\n const reprobed = await this.qmd.probe();\n if (!reprobed) {\n if (staleQmdFallback) {\n recordRecallSectionMetric({\n section: \"qmd\",\n priority: \"enrichment\",\n durationMs: Date.now() - t0,\n deadlineMs: enrichmentSectionDeadlineMs,\n source: \"stale\",\n success: true,\n timing: `stale-cache(reprobe-failed:${Math.max(0, Math.round(staleQmdFallback.ageMs))}ms)`,\n });\n if (queryAwarePrefilterIsEmpty) {\n return emptyQueryAwareQmdResult;\n }\n return staleQmdFallback.value;\n }\n recordRecallSectionMetric({\n section: \"qmd\",\n priority: \"enrichment\",\n durationMs: Date.now() - t0,\n deadlineMs: enrichmentSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip\",\n });\n log.debug(\n `Search skip (re-probe failed): ${this.qmd.debugStatus()}`,\n );\n return null;\n }\n log.info(`QMD re-probe succeeded: ${this.qmd.debugStatus()}`);\n }\n\n const maxPerAgent = this.config.parallelMaxResultsPerAgent;\n const specializedAgentPromise: Promise<\n [ParallelSearchResult[], ParallelSearchResult[]]\n > | null =\n !queryAwarePrefilterIsEmpty &&\n this.config.parallelRetrievalEnabled && maxPerAgent > 0\n ? Promise.all([\n shouldRunAgent(\"direct\", retrievalQuery, 0)\n ? Promise.all(\n profileStorageDirs.map((memoryDir) =>\n runDirectAgent(\n retrievalQuery,\n memoryDir,\n maxPerAgent,\n ).catch((err) => {\n log.debug(`DirectAgent pre-start failed: ${err}`);\n return [] as ParallelSearchResult[];\n }),\n ),\n ).then((groups) => {\n const merged: ParallelSearchResult[] = [];\n const seen = new Set<string>();\n for (const result of groups.flat()) {\n const key = (result as any).path ?? JSON.stringify(result);\n if (seen.has(key)) continue;\n seen.add(key);\n merged.push(result);\n }\n return merged\n .sort((a, b) => b.score - a.score)\n .slice(0, maxPerAgent);\n })\n : Promise.resolve([] as ParallelSearchResult[]),\n shouldRunAgent(\"temporal\", retrievalQuery, 0)\n ? Promise.all(\n profileStorageDirs.map((memoryDir) =>\n runTemporalAgent(\n retrievalQuery,\n memoryDir,\n maxPerAgent,\n queryAwarePrefilter.candidatePaths,\n ).catch((err) => {\n log.debug(`TemporalAgent pre-start failed for ${memoryDir}: ${err}`);\n return [] as ParallelSearchResult[];\n }),\n ),\n ).then((groups) => {\n const merged: ParallelSearchResult[] = [];\n const seen = new Set<string>();\n for (const result of groups.flat()) {\n const key = (result as any).path ?? JSON.stringify(result);\n if (seen.has(key)) continue;\n seen.add(key);\n merged.push(result);\n }\n return merged\n .sort((a, b) => b.score - a.score)\n .slice(0, maxPerAgent);\n })\n : Promise.resolve([] as ParallelSearchResult[]),\n ])\n : null;\n\n try {\n const filteredResults =\n await this.fetchQmdMemoryResultsWithArtifactTopUp(\n retrievalQuery,\n qmdFetchLimit,\n qmdHybridFetchLimit,\n {\n namespacesEnabled: this.config.namespacesEnabled,\n recallNamespaces,\n resolveNamespace: (p) => this.namespaceFromPath(p),\n queryAwarePrefilter,\n searchOptions: qmdSearchOptions,\n abortSignal: qmdEnrichmentAbort.signal,\n onDebugSnapshot: async (snapshot) => {\n await this.recordLastQmdRecallSnapshot({\n storage: profileStorage,\n snapshot,\n });\n },\n },\n );\n\n const preAugmentTopScore =\n filteredResults.length > 0\n ? Math.max(...filteredResults.map((r) => r.score))\n : 0;\n let augmentedResults = filteredResults;\n let maxSpecializedScore = 0;\n if (this.config.parallelRetrievalEnabled && specializedAgentPromise) {\n try {\n const [directResults, temporalResults] =\n await specializedAgentPromise;\n if (filteredResults.length > 0) {\n const w = this.config.parallelAgentWeights;\n maxSpecializedScore = Math.max(\n directResults.length > 0\n ? Math.max(...directResults.map((r) => r.score * w.direct))\n : 0,\n temporalResults.length > 0\n ? Math.max(\n ...temporalResults.map((r) => r.score * w.temporal),\n )\n : 0,\n );\n const lifecycleHeadroom =\n this.config.parallelMaxResultsPerAgent * 2;\n augmentedResults = await mergeWithAgentResults(\n filteredResults,\n directResults,\n temporalResults,\n this.config.parallelAgentWeights,\n qmdFetchLimit + lifecycleHeadroom,\n this.config.memoryDir,\n );\n }\n } catch (err) {\n log.debug(\n `parallelRetrieval augmentation failed, using base results: ${err}`,\n );\n maxSpecializedScore = 0;\n }\n }\n\n const result = {\n memoryResultsLists: [augmentedResults],\n globalResults: [],\n preAugmentTopScore,\n maxSpecializedScore,\n };\n if (\n augmentedResults.length > 0 ||\n result.globalResults.length > 0\n ) {\n setCachedQmdRecall(qmdCacheKey, result, {\n maxEntries: this.config.qmdRecallCacheMaxEntries ?? 128,\n });\n }\n recordRecallSectionMetric({\n section: \"qmd\",\n priority: \"enrichment\",\n durationMs: Date.now() - t0,\n deadlineMs: enrichmentSectionDeadlineMs,\n source: \"fresh\",\n success: true,\n });\n return result;\n } catch (err) {\n if (staleQmdFallback) {\n recordRecallSectionMetric({\n section: \"qmd\",\n priority: \"enrichment\",\n durationMs: Date.now() - t0,\n deadlineMs: enrichmentSectionDeadlineMs,\n source: \"stale\",\n success: true,\n timing: `stale-cache(${err instanceof Error ? err.message : String(err)})`,\n });\n if (queryAwarePrefilterIsEmpty) {\n return emptyQueryAwareQmdResult;\n }\n return staleQmdFallback.value;\n }\n throw err;\n }\n })()\n .catch((err): QmdPhaseResult => {\n if (options.abortSignal?.aborted) {\n log.debug(\n `recall phase-1 enrichment [qmd]: skipped after abort at +${Date.now() - phase1Start}ms`,\n );\n return null;\n }\n log.warn(\n `recall phase-1 enrichment [qmd] failed open: ${err instanceof Error ? err.message : String(err)}`,\n );\n return null;\n })\n .finally(() => qmdEnrichmentAbort.dispose()),\n () => qmdEnrichmentAbort.cancel(),\n );\n\n const transcriptPromise = (async (): Promise<string | null> => {\n const t0 = Date.now();\n if (\n !this.config.transcriptEnabled ||\n !this.isRecallSectionEnabled(\"transcript\", true)\n ) {\n recordRecallSectionMetric({\n section: \"transcript\",\n priority: \"core\",\n durationMs: 0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip\",\n });\n return null;\n }\n const transcriptMaxTokens =\n this.getRecallSectionNumber(\"transcript\", \"maxTokens\") ??\n this.config.maxTranscriptTokens;\n const transcriptMaxTurns =\n this.getRecallSectionNumber(\"transcript\", \"maxTurns\") ??\n this.config.maxTranscriptTurns;\n const transcriptLookbackHours =\n this.getRecallSectionNumber(\"transcript\", \"lookbackHours\") ??\n this.config.transcriptRecallHours;\n if (\n transcriptMaxTokens === 0 ||\n transcriptMaxTurns === 0 ||\n transcriptLookbackHours === 0\n ) {\n recordRecallSectionMetric({\n section: \"transcript\",\n priority: \"core\",\n durationMs: 0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip(limit=0)\",\n });\n return null;\n }\n\n let section: string | null = null;\n // Try checkpoint first (post-compaction recovery)\n let checkpointInjected = false;\n if (this.config.checkpointEnabled) {\n const checkpoint = await this.transcript.loadCheckpoint(sessionKey);\n log.debug(\n `recall: checkpoint loaded, turns=${checkpoint?.turns?.length ?? 0}`,\n );\n if (checkpoint && checkpoint.turns.length > 0) {\n const formatted = this.transcript.formatForRecall(\n checkpoint.turns,\n transcriptMaxTokens,\n );\n if (formatted) {\n section = `## Working Context (Recovered)\\n\\n${formatted}`;\n checkpointInjected = true;\n // Clear checkpoint after injection\n await this.transcript.clearCheckpoint();\n }\n }\n }\n\n if (!checkpointInjected) {\n const entries = await this.transcript.readRecent(\n transcriptLookbackHours,\n sessionKey,\n );\n log.debug(\n `recall: read ${entries.length} transcript entries for sessionKey=${sessionKey}`,\n );\n\n // Apply max turns cap\n const cappedEntries = entries.slice(-transcriptMaxTurns);\n if (cappedEntries.length > 0) {\n log.debug(\n `recall: injecting ${cappedEntries.length} transcript entries`,\n );\n const formatted = this.transcript.formatForRecall(\n cappedEntries,\n transcriptMaxTokens,\n );\n if (formatted) section = formatted;\n }\n }\n\n recordRecallSectionMetric({\n section: \"transcript\",\n priority: \"core\",\n durationMs: Date.now() - t0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"fresh\",\n success: true,\n });\n return section;\n })();\n\n // Compaction reset runs independently of transcript — it must work even when\n // transcriptEnabled=false, since compaction recovery is a separate concern.\n const compactionPromise = (async (): Promise<string | null> => {\n // Always clean up per-session workspace selections, even if the feature is off,\n // to prevent the Map from accumulating stale entries on long-running gateways.\n const effectiveSessionKey = sessionKey ?? \"default\";\n const compactionWorkspaceDir =\n this._recallWorkspaceOverrides.get(effectiveSessionKey);\n this._recallWorkspaceOverrides.delete(effectiveSessionKey);\n\n if (!this.config.compactionResetEnabled) return null;\n\n const workspaceDir =\n compactionWorkspaceDir ||\n this.config.workspaceDir ||\n defaultWorkspaceDir();\n const safeSessionKey = sanitizeSessionKeyForFilename(effectiveSessionKey);\n const signalPath = path.join(\n workspaceDir,\n `.compaction-reset-signal-${safeSessionKey}`,\n );\n const bootPath = path.join(workspaceDir, \"BOOT.md\");\n\n try {\n const signalStat = await stat(signalPath).catch(() => null);\n if (!signalStat) return null;\n\n const signalAge = Date.now() - signalStat.mtimeMs;\n const signalData = JSON.parse(await readFile(signalPath, \"utf-8\"));\n\n // Validate signal belongs to this session (defense-in-depth: filename\n // is already per-session, but the sessionKey inside provides a second check).\n // Use strict !== so missing/null sessionKey also fails validation.\n if (signalData.sessionKey !== effectiveSessionKey) {\n log.debug(\n `recall: compaction signal is for ${signalData.sessionKey}, not ${effectiveSessionKey} — skipping`,\n );\n return null;\n }\n\n if (signalAge >= COMPACTION_SIGNAL_MAX_AGE_MS) {\n log.debug(\n `recall: stale compaction signal (${Math.round(signalAge / 1000)}s old), skipping`,\n );\n await unlink(signalPath).catch(() => {});\n return null;\n }\n\n // Signal is fresh and belongs to this session — build recovery context\n let section = \"\\n\\n## Session Recovery (Post-Compaction)\\n\\n\";\n section += `⚠️ A compaction occurred at ${signalData.compactedAt} and this is a fresh session.\\n\\n`;\n\n try {\n const bootContent = await readFile(bootPath, \"utf-8\");\n section += \"### BOOT.md (working state before compaction)\\n\\n\";\n section += bootContent + \"\\n\";\n } catch {\n section += \"### ⚠️ BOOT.md is MISSING\\n\\n\";\n section +=\n \"The memory flush may not have written BOOT.md before compaction. \";\n section += \"Ask the user what you were working on — do not guess.\\n\";\n }\n\n log.info(\n `recall: injected compaction reset context for ${effectiveSessionKey}`,\n );\n await unlink(signalPath).catch(() => {});\n return section;\n } catch (err) {\n log.debug(\"recall: compaction signal check failed:\", err);\n // Remove corrupt/unreadable signal files so they don't cause repeated\n // parse failures on every recall() until the 1-hour sweep runs.\n await unlink(signalPath).catch(() => {});\n return null;\n }\n })();\n\n const summariesPromise = (async (): Promise<string | null> => {\n const t0 = Date.now();\n if (\n !this.config.hourlySummariesEnabled ||\n !sessionKey ||\n !this.isRecallSectionEnabled(\"summaries\", true)\n ) {\n recordRecallSectionMetric({\n section: \"summaries\",\n priority: \"core\",\n durationMs: 0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip\",\n });\n return null;\n }\n const summariesLookbackHours =\n this.getRecallSectionNumber(\"summaries\", \"lookbackHours\") ??\n this.config.summaryRecallHours;\n const summariesMaxCount =\n this.getRecallSectionNumber(\"summaries\", \"maxCount\") ??\n this.config.maxSummaryCount;\n if (summariesLookbackHours <= 0 || summariesMaxCount <= 0) {\n recordRecallSectionMetric({\n section: \"summaries\",\n priority: \"core\",\n durationMs: 0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip(limit=0)\",\n });\n return null;\n }\n\n const summaries = await this.summarizer.readRecent(\n sessionKey,\n summariesLookbackHours,\n );\n const cappedSummaries = summaries.slice(0, summariesMaxCount);\n const section =\n cappedSummaries.length > 0\n ? this.summarizer.formatForRecall(cappedSummaries, summariesMaxCount)\n : null;\n recordRecallSectionMetric({\n section: \"summaries\",\n priority: \"core\",\n durationMs: Date.now() - t0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"fresh\",\n success: true,\n });\n return section;\n })();\n\n const nativeKnowledgeAbort = createEnrichmentAbortHandle(\n options.abortSignal,\n );\n const nativeKnowledgePromise = observeEnrichmentPromise(\n (async (): Promise<string | null> => {\n const t0 = Date.now();\n if (\n !this.config.nativeKnowledge?.enabled ||\n !this.isRecallSectionEnabled(\n \"native-knowledge\",\n this.config.nativeKnowledge.enabled,\n )\n ) {\n recordRecallSectionMetric({\n section: \"nativeKnowledge\",\n priority: \"enrichment\",\n durationMs: 0,\n deadlineMs: enrichmentSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip\",\n });\n return null;\n }\n if (\n this.config.nativeKnowledge.maxResults === 0 ||\n this.config.nativeKnowledge.maxChars === 0\n ) {\n recordRecallSectionMetric({\n section: \"nativeKnowledge\",\n priority: \"enrichment\",\n durationMs: 0,\n deadlineMs: enrichmentSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip(limit=0)\",\n });\n return null;\n }\n\n const chunks = await collectNativeKnowledgeChunks({\n workspaceDir: this.config.workspaceDir,\n memoryDir: this.config.memoryDir,\n config: this.config.nativeKnowledge,\n recallNamespaces: this.config.namespacesEnabled\n ? recallNamespaces\n : undefined,\n defaultNamespace: this.config.defaultNamespace,\n abortSignal: nativeKnowledgeAbort.signal,\n }).catch(() => []);\n const results = searchNativeKnowledge({\n query: retrievalQuery,\n chunks,\n maxResults:\n this.getRecallSectionNumber(\"native-knowledge\", \"maxResults\") ??\n this.config.nativeKnowledge.maxResults,\n });\n const section = formatNativeKnowledgeSection({\n results,\n maxChars:\n this.getRecallSectionNumber(\"native-knowledge\", \"maxChars\") ??\n this.config.nativeKnowledge.maxChars,\n });\n recordRecallSectionMetric({\n section: \"nativeKnowledge\",\n priority: \"enrichment\",\n durationMs: Date.now() - t0,\n deadlineMs: enrichmentSectionDeadlineMs,\n source: \"fresh\",\n success: true,\n });\n return section;\n })().finally(() => nativeKnowledgeAbort.dispose()),\n () => nativeKnowledgeAbort.cancel(),\n );\n\n const conversationRecallPromise = (async (): Promise<string | null> => {\n const t0 = Date.now();\n if (\n !this.config.conversationIndexEnabled ||\n queryPolicy.skipConversationRecall ||\n !this.isRecallSectionEnabled(\"conversation-recall\", true)\n ) {\n recordRecallSectionMetric({\n section: \"convRecall\",\n priority: \"core\",\n durationMs: 0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip\",\n });\n return null;\n }\n\n const topKOverride = this.getRecallSectionNumber(\n \"conversation-recall\",\n \"topK\",\n );\n if (topKOverride === 0) {\n recordRecallSectionMetric({\n section: \"convRecall\",\n priority: \"core\",\n durationMs: 0,\n deadlineMs: recallSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip(topK=0)\",\n });\n return null;\n }\n\n const startedAtMs = Date.now();\n const timeoutMs = Math.max(\n 200,\n this.getRecallSectionNumber(\"conversation-recall\", \"timeoutMs\") ??\n this.config.conversationRecallTimeoutMs,\n );\n const topK = Math.max(\n 1,\n topKOverride ?? this.config.conversationRecallTopK,\n );\n const maxChars = Math.max(\n 400,\n this.getRecallSectionNumber(\"conversation-recall\", \"maxChars\") ??\n this.config.conversationRecallMaxChars,\n );\n\n const results = (await Promise.race([\n this.searchConversationRecallResults(retrievalQuery, topK),\n new Promise<[]>((resolve) => setTimeout(() => resolve([]), timeoutMs)),\n ]).catch(() => [])) as Array<{\n path: string;\n snippet: string;\n score: number;\n }>;\n\n const durationMs = Date.now() - startedAtMs;\n if (durationMs >= timeoutMs) {\n log.debug(`conversation recall: timed out after ${timeoutMs}ms`);\n }\n\n const section = this.formatConversationRecallSection(results, maxChars);\n recordRecallSectionMetric({\n section: \"convRecall\",\n priority: \"core\",\n durationMs: Date.now() - t0,\n deadlineMs: timeoutMs,\n source: \"fresh\",\n success: true,\n });\n return section;\n })();\n\n const procedureRecallPromise = (async (): Promise<string | null> => {\n if (this.config.procedural?.enabled !== true) return null;\n if (!this.isRecallSectionEnabled(\"procedure-recall\", true)) return null;\n try {\n return await buildProcedureRecallSection(\n profileStorage,\n retrievalQuery,\n this.config,\n );\n } catch (err) {\n log.debug(\n `procedure-recall: failed open: ${err instanceof Error ? err.message : String(err)}`,\n );\n return null;\n }\n })();\n\n const compoundingPromise = observeEnrichmentPromise(\n (async (): Promise<string | null> => {\n const t0 = Date.now();\n if (\n !this.compounding ||\n !this.config.compoundingInjectEnabled ||\n !this.isRecallSectionEnabled(\"compounding\", true)\n ) {\n recordRecallSectionMetric({\n section: \"compounding\",\n priority: \"enrichment\",\n durationMs: 0,\n deadlineMs: enrichmentSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip\",\n });\n return null;\n }\n const maxPatterns =\n this.getRecallSectionNumber(\"compounding\", \"maxPatterns\") ?? 40;\n const maxRubrics =\n this.getRecallSectionNumber(\"compounding\", \"maxRubrics\") ?? 4;\n if (maxPatterns === 0 && maxRubrics === 0) {\n recordRecallSectionMetric({\n section: \"compounding\",\n priority: \"enrichment\",\n durationMs: 0,\n deadlineMs: enrichmentSectionDeadlineMs,\n source: \"skip\",\n success: true,\n timing: \"skip(limit=0)\",\n });\n return null;\n }\n const section = await this.compounding.buildRecallSection(\n retrievalQuery,\n { maxPatterns, maxRubrics },\n );\n recordRecallSectionMetric({\n section: \"compounding\",\n priority: \"enrichment\",\n durationMs: Date.now() - t0,\n deadlineMs: enrichmentSectionDeadlineMs,\n source: \"fresh\",\n success: true,\n });\n return section;\n })(),\n );\n\n // Start memory-boxes read in parallel with the rest of phase-1 (it can take\n // several seconds on large box directories due to sequential I/O). We kick it\n // off here so it overlaps with QMD and other concurrent work rather than\n // running sequentially in phase-2 and blocking assembly.\n const recentBoxesPromise = observeEnrichmentPromise(\n this.isRecallSectionEnabled(\n \"memory-boxes\",\n this.config.memoryBoxesEnabled === true,\n ) &&\n this.config.memoryBoxesEnabled &&\n this.config.boxRecallDays > 0\n ? Promise.all(\n profileStorages.map((storage) =>\n this.boxBuilderFor(storage)\n .readRecentBoxes(this.config.boxRecallDays)\n .catch(() => [] as BoxFrontmatter[]),\n ),\n ).then((groups) => {\n const boxes: BoxFrontmatter[] = [];\n const seen = new Set<string>();\n for (const box of groups.flat()) {\n const key = JSON.stringify(box);\n if (seen.has(key)) continue;\n seen.add(key);\n boxes.push(box);\n }\n return boxes.sort((a, b) => {\n const aTime = Date.parse(a.sealedAt ?? \"\");\n const bTime = Date.parse(b.sealedAt ?? \"\");\n const aRank = Number.isFinite(aTime) ? aTime : 0;\n const bRank = Number.isFinite(bTime) ? bTime : 0;\n return bRank - aRank;\n });\n })\n : Promise.resolve([] as BoxFrontmatter[]),\n );\n\n // --- Wait for core sections first, then bounded enrichment ---\n this.profiler.startSpan(\"phase-1-parallel\", profileTraceId);\n const phase1Start = Date.now();\n log.info(\n `recall phase-1: starting parallel work at +${phase1Start - recallStart}ms`,\n );\n const [\n sharedCtx,\n profile,\n identityContinuity,\n entityRetrievalSection,\n kiResult,\n artifacts,\n objectiveStateSection,\n causalTrajectorySection,\n cmcCausalChainsSection,\n calibrationSection,\n procedureRecallSection,\n trustZoneSection,\n verifiedRecallSection,\n verifiedRulesSection,\n workProductsSection,\n transcriptSection,\n compactionSection,\n summariesSection,\n conversationRecallSection,\n peerProfileSection,\n ] = await raceRecallAbort(\n Promise.all(\n (\n [\n [\"shared\", sharedContextPromise],\n [\"profile\", profilePromise],\n [\"identity\", identityContinuityPromise],\n [\"entity\", entityRetrievalPromise],\n [\"ki\", knowledgeIndexPromise],\n [\"artifacts\", artifactsPromise],\n [\"objState\", objectiveStatePromise],\n [\"causalTraj\", causalTrajectoryPromise],\n [\"cmc\", cmcRetrievalPromise],\n [\"calibration\", calibrationPromise],\n [\"procedureRecall\", procedureRecallPromise],\n [\"trustZone\", trustZonePromise],\n [\"verifiedRecall\", verifiedRecallPromise],\n [\"verifiedRules\", verifiedRulesPromise],\n [\"workProducts\", workProductsPromise],\n [\"transcript\", transcriptPromise],\n [\"compaction\", compactionPromise],\n [\"summaries\", summariesPromise],\n [\"convRecall\", conversationRecallPromise],\n [\"peerProfile\", peerProfileRecallPromise],\n ] as const\n ).map(([name, p]) =>\n (p as Promise<unknown>).then((v) => {\n log.debug(\n `recall phase-1 core [${name}]: resolved at +${Date.now() - phase1Start}ms`,\n );\n return v;\n }),\n ),\n ) as Promise<\n [\n typeof sharedContextPromise extends Promise<infer T> ? T : never,\n typeof profilePromise extends Promise<infer T> ? T : never,\n typeof identityContinuityPromise extends Promise<infer T> ? T : never,\n typeof entityRetrievalPromise extends Promise<infer T> ? T : never,\n typeof knowledgeIndexPromise extends Promise<infer T> ? T : never,\n typeof artifactsPromise extends Promise<infer T> ? T : never,\n typeof objectiveStatePromise extends Promise<infer T> ? T : never,\n typeof causalTrajectoryPromise extends Promise<infer T> ? T : never,\n typeof cmcRetrievalPromise extends Promise<infer T> ? T : never,\n typeof calibrationPromise extends Promise<infer T> ? T : never,\n typeof procedureRecallPromise extends Promise<infer T> ? T : never,\n typeof trustZonePromise extends Promise<infer T> ? T : never,\n typeof verifiedRecallPromise extends Promise<infer T> ? T : never,\n typeof verifiedRulesPromise extends Promise<infer T> ? T : never,\n typeof workProductsPromise extends Promise<infer T> ? T : never,\n typeof transcriptPromise extends Promise<infer T> ? T : never,\n typeof compactionPromise extends Promise<infer T> ? T : never,\n typeof summariesPromise extends Promise<infer T> ? T : never,\n typeof conversationRecallPromise extends Promise<infer T> ? T : never,\n typeof peerProfileRecallPromise extends Promise<infer T> ? T : never,\n ]\n >,\n options.abortSignal,\n \"recall aborted during phase-one preamble\",\n );\n\n this.profiler.endSpan(\"phase-1-parallel\", profileTraceId);\n log.info(\n `recall phase-1: core work done at +${Date.now() - recallStart}ms ` +\n `(phase took ${Date.now() - phase1Start}ms); continuing with incremental enrichment assembly`,\n );\n throwIfRecallAborted(options.abortSignal);\n\n const enrichmentAssemblyDeadlineAtMs =\n enrichmentSectionDeadlineMs > 0\n ? Date.now() + enrichmentSectionDeadlineMs\n : null;\n\n const awaitEnrichmentSection = async <T>(\n name: string,\n promise: ObservedDeferredEnrichmentPromise<T>,\n ): Promise<T | null> => {\n const finalizeEnrichmentOutcome = (\n outcome: DeferredEnrichmentOutcome<T>,\n ): T | null => {\n if (outcome.status === \"resolved\") {\n log.debug(\n `recall phase-1 enrichment [${name}]: resolved at +${Date.now() - phase1Start}ms`,\n );\n return outcome.value;\n }\n\n if (options.abortSignal?.aborted) {\n log.debug(\n `recall phase-1 enrichment [${name}]: skipped after abort at +${Date.now() - phase1Start}ms`,\n );\n return null;\n }\n log.warn(\n `recall phase-1 enrichment [${name}] failed open: ` +\n `${outcome.error instanceof Error ? outcome.error.message : String(outcome.error)}`,\n );\n return null;\n };\n\n if (options.abortSignal?.aborted) {\n promise.cancel();\n log.debug(\n `recall phase-1 enrichment [${name}]: skipped after abort at +${Date.now() - phase1Start}ms`,\n );\n return null;\n }\n\n let timeoutHandle: NodeJS.Timeout | undefined;\n const timeoutMs =\n enrichmentAssemblyDeadlineAtMs === null\n ? null\n : Math.max(0, enrichmentAssemblyDeadlineAtMs - Date.now());\n if (timeoutMs === 0) {\n const settledOutcome = promise.getSettledOutcome();\n if (settledOutcome) {\n log.debug(\n `recall phase-1 enrichment [${name}]: consumed already-settled result after shared ${enrichmentSectionDeadlineMs}ms budget expired ` +\n `at +${Date.now() - phase1Start}ms`,\n );\n return finalizeEnrichmentOutcome(settledOutcome);\n }\n log.debug(\n `recall phase-1 enrichment [${name}]: skipped after shared ${enrichmentSectionDeadlineMs}ms budget expired ` +\n `at +${Date.now() - phase1Start}ms`,\n );\n promise.cancel();\n return null;\n }\n\n const outcome = await (timeoutMs !== null\n ? Promise.race<DeferredEnrichmentOutcome<T> | { status: \"timed_out\" }>([\n promise,\n new Promise<{ status: \"timed_out\" }>((resolve) => {\n timeoutHandle = setTimeout(\n () => resolve({ status: \"timed_out\" }),\n timeoutMs,\n );\n }),\n ])\n : promise);\n if (timeoutHandle) clearTimeout(timeoutHandle);\n\n if (outcome.status === \"timed_out\") {\n log.debug(\n `recall phase-1 enrichment [${name}]: timed out within shared ${enrichmentSectionDeadlineMs}ms budget ` +\n `at +${Date.now() - phase1Start}ms`,\n );\n promise.cancel();\n return null;\n }\n\n return finalizeEnrichmentOutcome(outcome);\n };\n\n const remainingEnrichmentAssemblyMs = (): number | null =>\n enrichmentAssemblyDeadlineAtMs === null\n ? null\n : Math.max(0, enrichmentAssemblyDeadlineAtMs - Date.now());\n\n const awaitAssemblyStep = async <T>(\n name: string,\n task: () => Promise<T>,\n fallback: T,\n ): Promise<T> => {\n if (options.abortSignal?.aborted) {\n log.debug(\n `recall phase-1 assembly [${name}]: skipped after abort at +${Date.now() - phase1Start}ms`,\n );\n return fallback;\n }\n\n const timeoutMs = remainingEnrichmentAssemblyMs();\n if (timeoutMs === 0) {\n log.debug(\n `recall phase-1 assembly [${name}]: skipped after shared ${enrichmentSectionDeadlineMs}ms budget expired ` +\n `at +${Date.now() - phase1Start}ms`,\n );\n return fallback;\n }\n\n let timeoutHandle: NodeJS.Timeout | undefined;\n try {\n const result = await (timeoutMs !== null\n ? Promise.race<T | { status: \"timed_out\" }>([\n task(),\n new Promise<{ status: \"timed_out\" }>((resolve) => {\n timeoutHandle = setTimeout(\n () => resolve({ status: \"timed_out\" }),\n timeoutMs,\n );\n }),\n ])\n : task());\n if (timeoutHandle) clearTimeout(timeoutHandle);\n if (\n typeof result === \"object\" &&\n result !== null &&\n \"status\" in result &&\n (result as { status?: unknown }).status === \"timed_out\"\n ) {\n log.debug(\n `recall phase-1 assembly [${name}]: timed out within shared ${enrichmentSectionDeadlineMs}ms budget ` +\n `at +${Date.now() - phase1Start}ms`,\n );\n return fallback;\n }\n return result as T;\n } catch (err) {\n if (timeoutHandle) clearTimeout(timeoutHandle);\n log.warn(\n `recall phase-1 assembly [${name}] failed open: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n return fallback;\n }\n };\n\n // --- Phase 2: Assemble sections in correct order ---\n this.profiler.startSpan(\"assembly\", profileTraceId);\n\n // 0. Shared context\n if (sharedCtx)\n this.appendRecallSection(sectionBuckets, \"shared-context\", sharedCtx);\n\n // 0a. Explicit cue evidence\n const explicitCueMaxChars =\n this.getRecallSectionMaxChars(\"explicit-cue\") ??\n this.config.explicitCueRecallMaxChars;\n if (\n this.config.explicitCueRecallEnabled &&\n this.isRecallSectionEnabled(\"explicit-cue\") &&\n explicitCueMaxChars !== 0 &&\n this.lcmEngine?.enabled &&\n (recallMode as RecallPlanMode) !== \"no_recall\"\n ) {\n try {\n const explicitCueSection = await buildExplicitCueRecallSection({\n engine: this.lcmEngine,\n // #1495 thread 3 + #1505 fallback unification: read across the ordered\n // LCM read key set (primary overlay → coding fallbacks) so a\n // branch-scoped session finds its own explicit-cue evidence even when\n // archived at project/root scope (rule 39). #1505 codex P2: the builder\n // MERGES candidates across every key under its single budget instead of\n // short-circuiting on the first non-empty key.\n sessionIds: lcmReadSessionIds,\n query: retrievalQuery,\n maxChars: explicitCueMaxChars,\n maxReferences:\n this.getRecallSectionNumber(\"explicit-cue\", \"maxResults\") ??\n this.config.explicitCueRecallMaxReferences,\n });\n if (explicitCueSection) {\n this.appendRecallSection(\n sectionBuckets,\n \"explicit-cue\",\n explicitCueSection,\n );\n }\n } catch (err) {\n log.debug(`Explicit cue recall assembly error: ${err}`);\n }\n }\n\n // 0b. Targeted factual evidence. This is query-triggered and lossless:\n // it uses the LCM archive to recover exact numeric facts that broad\n // compressed-history or search sections can crowd out.\n const targetedFactMaxChars =\n this.getRecallSectionMaxChars(\"targeted-facts\") ??\n this.config.targetedFactRecallMaxChars;\n if (\n this.isSpecializedRecallSectionEnabled(\n \"targeted-facts\",\n this.config.targetedFactRecallEnabled,\n ) &&\n targetedFactMaxChars !== 0 &&\n this.lcmEngine?.enabled &&\n (recallMode as RecallPlanMode) !== \"no_recall\" &&\n shouldRecallTargetedFactEvidence(retrievalQuery)\n ) {\n try {\n const targetedFactSection = await buildTargetedFactRecallSection({\n engine: this.lcmEngine,\n // #1495 + #1505 fallback unification: read across the ordered LCM read\n // key set so a branch-scoped session finds its own targeted-fact\n // evidence even when archived at project/root scope. #1505 codex P2: the\n // builder MERGES candidates across every key under its single budget.\n sessionIds: lcmReadSessionIds,\n query: retrievalQuery,\n maxChars: targetedFactMaxChars,\n maxSearchResults:\n this.getRecallSectionNumber(\"targeted-facts\", \"maxResults\") ??\n this.config.targetedFactRecallMaxResults,\n maxScanWindowTurns:\n this.getRecallSectionNumber(\"targeted-facts\", \"maxTurns\") ??\n this.config.targetedFactRecallScanWindowTurns,\n maxScanWindowTokens:\n this.getRecallSectionNumber(\"targeted-facts\", \"maxTokens\") ??\n this.config.targetedFactRecallScanWindowTokens,\n });\n if (targetedFactSection) {\n this.appendRecallSection(\n sectionBuckets,\n \"targeted-facts\",\n targetedFactSection,\n );\n }\n } catch (err) {\n log.debug(`Targeted fact recall assembly error: ${err}`);\n }\n }\n\n // 0c. Focused list/count evidence. This recovers user-specific list\n // candidates and countable facts that are easy to bury in broad search\n // results, while staying gated to explicit list/count/recommendation\n // prompts.\n const focusedListMaxChars =\n this.getRecallSectionMaxChars(\"focused-list\") ??\n this.config.focusedListRecallMaxChars;\n if (\n this.isSpecializedRecallSectionEnabled(\n \"focused-list\",\n this.config.focusedListRecallEnabled,\n ) &&\n focusedListMaxChars !== 0 &&\n this.lcmEngine?.enabled &&\n (recallMode as RecallPlanMode) !== \"no_recall\" &&\n shouldRecallFocusedListEvidence(retrievalQuery)\n ) {\n try {\n const focusedListSection = await buildFocusedListRecallSection({\n engine: this.lcmEngine,\n // #1495 thread 3 + #1505 fallback unification: read across the ordered\n // LCM read key set so a branch-scoped session reads its own\n // focused-list/count evidence even at project/root scope (rule 39).\n // #1505 codex P2: the builder MERGES candidates across every key under\n // its single budget.\n sessionIds: lcmReadSessionIds,\n query: retrievalQuery,\n maxChars: focusedListMaxChars,\n maxSearchResults:\n this.getRecallSectionNumber(\"focused-list\", \"maxResults\") ??\n this.config.focusedListRecallMaxResults,\n maxScanWindowTurns:\n this.getRecallSectionNumber(\"focused-list\", \"maxTurns\") ??\n this.config.focusedListRecallScanWindowTurns,\n maxScanWindowTokens:\n this.getRecallSectionNumber(\"focused-list\", \"maxTokens\") ??\n this.config.focusedListRecallScanWindowTokens,\n });\n if (focusedListSection) {\n this.appendRecallSection(\n sectionBuckets,\n \"focused-list\",\n focusedListSection,\n );\n }\n } catch (err) {\n log.debug(`Focused list recall assembly error: ${err}`);\n }\n }\n\n // 0d. Response guidance evidence. This recovers durable user\n // instructions and preferences that affect how an answer should be shaped\n // for the current query, such as requested date formats, tool/version\n // details, or preferred editing workflows.\n const responseGuidanceMaxChars =\n this.getRecallSectionMaxChars(\"response-guidance\") ??\n this.config.responseGuidanceRecallMaxChars;\n const responseGuidanceEntry = this.getRecallSectionEntry(\"response-guidance\");\n const responseGuidanceMatchesQuery = shouldRecallResponseGuidance(retrievalQuery);\n const responseGuidanceForcedByPipeline =\n responseGuidanceEntry?.forceGeneric === true && !responseGuidanceMatchesQuery;\n if (\n this.isSpecializedRecallSectionEnabled(\n \"response-guidance\",\n this.config.responseGuidanceRecallEnabled,\n ) &&\n responseGuidanceMaxChars !== 0 &&\n this.lcmEngine?.enabled &&\n (recallMode as RecallPlanMode) !== \"no_recall\" &&\n (responseGuidanceMatchesQuery || responseGuidanceForcedByPipeline)\n ) {\n try {\n const responseGuidanceSection = await buildResponseGuidanceRecallSection({\n engine: this.lcmEngine,\n // #1495 thread 3 + #1505 fallback unification: read across the ordered\n // LCM read key set so a branch-scoped session reads its own\n // response-guidance evidence even at project/root scope (rule 39).\n // #1505 codex P2: the builder MERGES candidates across every key under\n // its single budget.\n sessionIds: lcmReadSessionIds,\n query: retrievalQuery,\n maxChars: responseGuidanceMaxChars,\n maxSearchResults:\n this.getRecallSectionNumber(\"response-guidance\", \"maxResults\") ??\n this.config.responseGuidanceRecallMaxResults,\n maxScanWindowTurns:\n this.getRecallSectionNumber(\"response-guidance\", \"maxTurns\") ??\n this.config.responseGuidanceRecallScanWindowTurns,\n maxScanWindowTokens:\n this.getRecallSectionNumber(\"response-guidance\", \"maxTokens\") ??\n this.config.responseGuidanceRecallScanWindowTokens,\n forceGeneric: responseGuidanceForcedByPipeline,\n });\n if (responseGuidanceSection) {\n this.appendRecallSection(\n sectionBuckets,\n \"response-guidance\",\n responseGuidanceSection,\n );\n }\n } catch (err) {\n log.debug(`Response guidance recall assembly error: ${err}`);\n }\n }\n\n // 0e. Chronological event-order evidence. This recovers ordered user\n // turns for prompts asking how topics unfolded across a conversation.\n const eventOrderMaxChars =\n this.getRecallSectionMaxChars(\"event-order\") ??\n this.config.eventOrderRecallMaxChars;\n if (\n this.isSpecializedRecallSectionEnabled(\n \"event-order\",\n this.config.eventOrderRecallEnabled,\n ) &&\n eventOrderMaxChars !== 0 &&\n this.lcmEngine?.enabled &&\n (recallMode as RecallPlanMode) !== \"no_recall\" &&\n shouldRecallEventOrderEvidence(retrievalQuery)\n ) {\n try {\n // #1495 thread 3 + #1505 fallback unification: read across the ordered LCM\n // read key set so a branch-scoped session reads its own chronological\n // event-order evidence even at project/root scope. UNLIKE the relevance-\n // ranked sections, event-order must NOT merge across keys: `turn_index` is\n // LOCAL to each LCM `session_id` (`observe` numbers turns per session via\n // `getMaxTurnIndex`), so interleaving two keys and sorting by `turn_index`\n // would place an older project-scope turn after a newer branch-scope turn\n // and misstate the chronology (#1505 codex P2). Like compressed-history,\n // event-order is an inherently per-session ORDERED artifact, so it takes\n // the highest-priority authorized key (primary overlay → project/root)\n // that actually has chronological evidence — each key's timeline is\n // internally consistent.\n const eventOrderSection = await firstNonEmptyLcmRead(\n (lcmSessionId) =>\n buildEventOrderRecallSection({\n engine: this.lcmEngine,\n sessionId: lcmSessionId,\n query: retrievalQuery,\n maxChars: eventOrderMaxChars,\n maxItems:\n this.getRecallSectionNumber(\"event-order\", \"maxResults\") ??\n this.config.eventOrderRecallMaxResults,\n maxScanWindowTurns:\n this.getRecallSectionNumber(\"event-order\", \"maxTurns\") ??\n this.config.eventOrderRecallScanWindowTurns,\n maxScanWindowTokens:\n this.getRecallSectionNumber(\"event-order\", \"maxTokens\") ??\n this.config.eventOrderRecallScanWindowTokens,\n }),\n (s) => !s,\n \"\",\n );\n if (eventOrderSection) {\n this.appendRecallSection(\n sectionBuckets,\n \"event-order\",\n eventOrderSection,\n );\n }\n } catch (err) {\n log.debug(`Event order recall assembly error: ${err}`);\n }\n }\n\n // 1. Profile\n if (profile)\n this.appendRecallSection(\n sectionBuckets,\n \"profile\",\n `## User Profile\\n\\n${profile}`,\n );\n\n // 1p. Peer profile (issue #679 PR 3/5)\n // Codex P2 (PR #764): only finalize the xray annotation when the section\n // was actually appended — appendRecallSection may drop it (disabled,\n // maxChars===0). We clear the annotation when the section is dropped so\n // the xray snapshot never reports injection that didn't happen.\n if (peerProfileSection) {\n const peerSectionAppended = this.appendRecallSection(\n sectionBuckets,\n \"peer-profile\",\n peerProfileSection,\n );\n if (!peerSectionAppended) {\n // Section was gated out — treat as null (feature on + peer registered,\n // but no context actually injected).\n peerProfileXrayAnnotation = null;\n }\n }\n\n // 1-pre. Calibration rules (injected early so model sees adjustments first)\n if (calibrationSection) {\n this.appendRecallSection(\n sectionBuckets,\n \"calibration-rules\",\n calibrationSection,\n );\n }\n\n if (procedureRecallSection) {\n this.appendRecallSection(\n sectionBuckets,\n \"procedure-recall\",\n procedureRecallSection,\n );\n }\n\n // 1a. Identity continuity\n if (identityContinuity) {\n this.appendRecallSection(\n sectionBuckets,\n \"identity-continuity\",\n identityContinuity.section,\n );\n identityInjectionModeUsed = identityContinuity.mode;\n identityInjectedChars = identityContinuity.injectedChars;\n identityInjectionTruncated = identityContinuity.truncated;\n }\n\n if (entityRetrievalSection) {\n this.appendRecallSection(\n sectionBuckets,\n \"entity-retrieval\",\n entityRetrievalSection,\n );\n }\n\n // 1b. Knowledge Index\n if (kiResult?.result) {\n this.appendRecallSection(\n sectionBuckets,\n \"knowledge-index\",\n kiResult.result,\n );\n log.debug(\n `Knowledge Index: ${kiResult.result.split(\"\\n\").length - 4} entities, ${kiResult.result.length} chars${kiResult.cached ? \" (cached)\" : \"\"}`,\n );\n }\n\n const nativeKnowledgeSection = await awaitEnrichmentSection(\n \"nativeKnowledge\",\n nativeKnowledgePromise,\n );\n if (nativeKnowledgeSection) {\n this.appendRecallSection(\n sectionBuckets,\n \"native-knowledge\",\n nativeKnowledgeSection,\n );\n }\n\n // 1c. Verbatim artifacts (quote-first anchors)\n if (artifacts.length > 0) {\n const lines = artifacts.map((a) => {\n const artifactType = a.frontmatter.artifactType ?? \"fact\";\n const createdRaw =\n typeof a.frontmatter.created === \"string\"\n ? a.frontmatter.created\n : \"\";\n const created = createdRaw\n ? createdRaw.slice(0, 19).replace(\"T\", \" \")\n : \"unknown-time\";\n return `- [${artifactType}] \"${this.truncateArtifactForRecall(a.content)}\" (${created})`;\n });\n this.appendRecallSection(\n sectionBuckets,\n \"verbatim-artifacts\",\n `## Verbatim Artifacts\\n\\n${lines.join(\"\\n\")}`,\n );\n }\n\n // 1d. Memory Boxes (topic continuity windows, v8.0 Phase 2A)\n // recentBoxesPromise was kicked off before phase-1 so it ran concurrently.\n {\n const recentBoxes = await awaitEnrichmentSection(\n \"memory-boxes\",\n recentBoxesPromise,\n );\n if (recentBoxes && recentBoxes.length > 0) {\n const boxLines = recentBoxes.slice(0, 5).map((b: BoxFrontmatter) => {\n const sealedDate = b.sealedAt\n ? b.sealedAt.slice(0, 16).replace(\"T\", \" \")\n : \"?\";\n const traceNote = b.traceId\n ? ` [trace: ${b.traceId.slice(0, 12)}]`\n : \"\";\n return `- [${sealedDate}${traceNote}] Topics: ${b.topics.join(\", \")} (${b.memoryIds.length} memories)`;\n });\n this.appendRecallSection(\n sectionBuckets,\n \"memory-boxes\",\n `## Recent Topic Windows\\n\\n${boxLines.join(\"\\n\")}`,\n );\n }\n }\n\n // 1e. TMT node (temporal memory tree, v8.2)\n if (\n this.isRecallSectionEnabled(\n \"temporal-memory-tree\",\n this.config.temporalMemoryTreeEnabled === true,\n ) &&\n this.config.temporalMemoryTreeEnabled &&\n recallMode !== \"minimal\" &&\n (recallMode as RecallPlanMode) !== \"no_recall\"\n ) {\n const tmtNode = await this.tmtBuilder.getMostRelevantNode();\n if (tmtNode) {\n const levelLabel =\n tmtNode.level.charAt(0).toUpperCase() + tmtNode.level.slice(1);\n this.appendRecallSection(\n sectionBuckets,\n \"temporal-memory-tree\",\n `## Memory Timeline (${levelLabel})\\n\\n${tmtNode.summary}`,\n );\n }\n }\n\n // LCM compressed history section\n if (\n this.lcmEngine?.enabled &&\n recallMode !== \"minimal\" &&\n (recallMode as RecallPlanMode) !== \"no_recall\"\n ) {\n try {\n // #1495 + #1505 fallback unification: read across the ordered LCM read\n // key set so a branch-scoped session reads its own structured\n // message-part evidence even when archived at project/root scope.\n // #1505 codex P2: structured matches are query-SCORED evidence, so MERGE\n // across EVERY key (primary overlay → project/root fallbacks) instead of\n // short-circuiting on the first non-empty key — a weak branch-key hit must\n // not mask stronger project-fallback parts. Keys are queried in priority\n // order; dedupe by session_id+turn_index+part_id keeps the primary key's\n // row on collision. `formatStructuredRecall` applies the single budget\n // below. A sessionless key (`undefined`) normalizes to \"\" → no matches\n // (structured parts are inherently per-session; pre-#1505 behavior, codex\n // P2).\n // FAULT ISOLATION (allSettled, not all): the pre-#1505 first-non-empty read\n // short-circuited, so a fallback key was often never queried and its latent\n // search failure never surfaced. Querying every key eagerly must NOT let one\n // key's failure (e.g. a SqliteError from a corrupt/locked fallback index)\n // reject the batch and discard the OTHER keys' parts — or, since this and\n // the compressed-history read below share one try block, silently drop the\n // compressed-history section a healthy primary key would still produce. So\n // read each key independently and keep the fulfilled batches.\n const structuredSettled = await Promise.allSettled(\n lcmReadSessionIds.map((lcmSessionId) =>\n this.lcmEngine!.searchStructuredParts(lcmSessionId ?? \"\", retrievalQuery),\n ),\n );\n for (const settled of structuredSettled) {\n if (settled.status === \"rejected\") {\n log.debug(\n `LCM structured-parts read failed for one key: ${settled.reason}`,\n );\n }\n }\n const seenStructuredParts = new Set<string>();\n const structuredMatches = structuredSettled\n .flatMap((settled) => (settled.status === \"fulfilled\" ? settled.value : []))\n .filter((match) => {\n const key = `${match.session_id} ${match.turn_index} ${match.part_id}`;\n if (seenStructuredParts.has(key)) return false;\n seenStructuredParts.add(key);\n return true;\n })\n // Restore the archive's per-key ordering (score DESC, then turn DESC)\n // across the MERGED set so the strongest parts win the shared budget in\n // `formatStructuredRecall` — otherwise weak primary-key parts could crowd\n // out stronger fallback parts. Stable sort: a single key is already in\n // this order, so it stays byte-for-byte the pre-#1505 behavior.\n // `?? 0` is defensive: `LcmStructuredRecallMatch.score` is always a\n // number here, but a bare `b.score - a.score` would yield NaN (falsy)\n // for any future unscored match and silently fall through to turn order.\n .sort(\n (a, b) =>\n (b.score ?? 0) - (a.score ?? 0) || b.turn_index - a.turn_index,\n );\n const structuredSection = this.lcmEngine.formatStructuredRecall(\n structuredMatches,\n Math.ceil(this.config.recallBudgetChars * 0.08),\n );\n if (structuredSection) {\n const structuredAppended = this.appendRecallSection(\n sectionBuckets,\n \"lcm-message-parts\",\n structuredSection,\n );\n if (structuredAppended) {\n for (const match of structuredMatches) {\n lcmStructuredXrayResults.push({\n memoryId: `lcm-message-part-${match.part_id}`,\n path: `lcm://${match.session_id}/turn/${match.turn_index}/part/${match.part_id}`,\n servedBy: match.file_path ? \"lcm-file-parts\" : \"lcm-tool-parts\",\n scoreDecomposition: { final: match.score },\n admittedBy: [\"lcm-message-parts\"],\n });\n }\n }\n }\n // #1495 + #1505 fallback unification: read across the ordered LCM read key\n // set so a branch-scoped session reads its own compressed-history evidence\n // even at project/root scope. UNLIKE the query-scored sections above, the\n // compressed history is a per-session HOLISTIC DAG narrative, not a set of\n // independently-rankable evidence items — concatenating two sessions'\n // summaries would double-count the conversation and blow the budget, and\n // there is no per-item id to dedupe on. So this section deliberately keeps\n // first-non-empty semantics (#1505 codex P2 scope: \"merge the query-matched\n // sections\"): the highest-priority authorized key (primary overlay →\n // project/root) that actually has a compressed history wins. A sessionless\n // key (`undefined`) normalizes to empty → no section (pre-#1505 behavior).\n const lcmSection = await firstNonEmptyLcmRead(\n (lcmSessionId) =>\n this.lcmEngine!.assembleRecall(\n lcmSessionId ?? \"\",\n this.config.recallBudgetChars,\n ),\n (s) => !s,\n \"\",\n );\n if (lcmSection) {\n this.appendRecallSection(\n sectionBuckets,\n \"lcm-compressed-history\",\n lcmSection,\n );\n }\n } catch (err) {\n log.debug(`LCM recall assembly error: ${err}`);\n }\n }\n\n if (objectiveStateSection) {\n this.appendRecallSection(\n sectionBuckets,\n \"objective-state\",\n objectiveStateSection,\n );\n }\n\n if (causalTrajectorySection) {\n this.appendRecallSection(\n sectionBuckets,\n \"causal-trajectories\",\n causalTrajectorySection,\n );\n }\n\n if (cmcCausalChainsSection) {\n this.appendRecallSection(\n sectionBuckets,\n \"cmc-causal-chains\",\n cmcCausalChainsSection,\n );\n }\n\n if (trustZoneSection) {\n this.appendRecallSection(sectionBuckets, \"trust-zones\", trustZoneSection);\n }\n\n const harmonicRetrievalSection = await awaitEnrichmentSection(\n \"harmonic\",\n harmonicRetrievalPromise,\n );\n if (harmonicRetrievalSection) {\n this.appendRecallSection(\n sectionBuckets,\n \"harmonic-retrieval\",\n harmonicRetrievalSection,\n );\n }\n\n if (verifiedRecallSection) {\n this.appendRecallSection(\n sectionBuckets,\n \"verified-episodes\",\n verifiedRecallSection,\n );\n }\n\n if (verifiedRulesSection) {\n this.appendRecallSection(\n sectionBuckets,\n \"verified-rules\",\n verifiedRulesSection,\n );\n }\n\n if (workProductsSection) {\n this.appendRecallSection(\n sectionBuckets,\n \"work-products\",\n workProductsSection,\n );\n }\n\n // 2. QMD results — post-process and format\n const qmdWasSettledBeforeAssemblyWait =\n qmdPromise.getSettledOutcome() !== undefined;\n const qmdResult = await awaitEnrichmentSection(\"qmd\", qmdPromise);\n if (qmdResult) {\n const t0 = Date.now();\n const {\n memoryResultsLists,\n globalResults,\n preAugmentTopScore,\n maxSpecializedScore,\n } = qmdResult;\n\n // Merge/dedupe by path; keep the best score and first non-empty snippet.\n const memoryResultsRaw = mergeGraphExpandedResults(\n memoryResultsLists.flat(),\n [],\n );\n\n let memoryResults = memoryResultsRaw;\n\n // Enforce namespace read policies by filtering paths.\n if (this.config.namespacesEnabled) {\n memoryResults = memoryResults.filter((r) =>\n recallNamespaces.includes(this.namespaceFromPath(r.path)),\n );\n }\n // Artifacts are injected through dedicated verbatim recall flow only.\n memoryResults = memoryResults.filter(\n (r) => !isArtifactMemoryPath(r.path),\n );\n\n const isFullModeGraphAssist =\n this.config.multiGraphMemoryEnabled &&\n this.config.graphAssistInFullModeEnabled !== false &&\n recallMode === \"full\" &&\n memoryResults.length >=\n Math.max(1, this.config.graphAssistMinSeedResults ?? 3);\n const shouldRunGraphExpansion =\n recallMode === \"graph_mode\" || isFullModeGraphAssist;\n const graphShadowEvalEnabled =\n isFullModeGraphAssist &&\n this.config.graphAssistShadowEvalEnabled === true;\n if (shouldRunGraphExpansion) {\n shouldPersistGraphSnapshot = true;\n graphDecisionShadowMode = graphShadowEvalEnabled;\n }\n if (shouldRunGraphExpansion) {\n const baselineMemoryResults = memoryResults;\n graphBaselinePaths.clear();\n baselineMemoryResults.forEach((result) =>\n graphBaselinePaths.add(result.path),\n );\n if (baselineMemoryResults.length === 0) {\n graphSnapshotStatus = \"skipped\";\n graphDecisionStatus = \"skipped\";\n graphDecisionReason =\n \"graph recall skipped because baseline retrieval produced no seed results\";\n graphSnapshotReason = graphDecisionReason;\n graphSnapshotSeedPaths = [];\n graphSnapshotSeedResults = [];\n graphSnapshotExpandedPaths = [];\n graphExpandedResultPaths.clear();\n } else {\n try {\n const graphExpansion = await awaitAssemblyStep(\n \"graph-expansion\",\n () =>\n this.expandResultsViaGraph({\n memoryResults,\n recallNamespaces,\n recallResultLimit,\n deadlineAtMs: enrichmentAssemblyDeadlineAtMs,\n ...(options.includeLowConfidence === true ? { includeLowConfidence: true } : {}),\n }),\n null as Awaited<ReturnType<typeof this.expandResultsViaGraph>> | null,\n );\n if (!graphExpansion) {\n graphSnapshotStatus = \"aborted\";\n graphDecisionStatus = \"aborted\";\n graphDecisionReason = options.abortSignal?.aborted\n ? \"graph expansion skipped because recall assembly was aborted\"\n : \"graph expansion skipped because shared post-retrieval assembly budget expired\";\n graphSnapshotReason = graphDecisionReason;\n graphSnapshotSeedPaths = baselineMemoryResults\n .slice(0, Math.max(1, recallResultLimit))\n .map((result) => result.path);\n graphSnapshotSeedResults = this.buildGraphRecallRankedResults(\n baselineMemoryResults,\n () => [\"baseline\"],\n );\n graphSnapshotExpandedPaths = [];\n graphExpandedResultPaths.clear();\n memoryResults = baselineMemoryResults;\n } else {\n const {\n merged,\n seedPaths,\n expandedPaths,\n seedResults = baselineMemoryResults,\n } = graphExpansion;\n graphSnapshotStatus = \"completed\";\n graphDecisionStatus = \"completed\";\n graphDecisionReason = graphShadowEvalEnabled\n ? \"graph shadow evaluation completed without altering injected context\"\n : \"graph expansion merged into recall ranking\";\n graphSnapshotReason = graphDecisionReason;\n graphSnapshotSeedPaths = seedPaths;\n graphSnapshotExpandedPaths = expandedPaths;\n graphSnapshotSeedResults = this.buildGraphRecallRankedResults(\n seedResults,\n () => [\"baseline\"],\n );\n graphExpandedResultPaths.clear();\n expandedPaths.forEach((entry) =>\n graphExpandedResultPaths.add(entry.path),\n );\n memoryResults = graphShadowEvalEnabled\n ? baselineMemoryResults\n : merged;\n\n if (graphShadowEvalEnabled) {\n const comparison = summarizeGraphShadowComparison(\n baselineMemoryResults,\n merged,\n recallResultLimit,\n );\n graphSnapshotShadowComparison = comparison;\n recordRecallSectionMetric({\n section: \"graphShadow\",\n priority: \"enrichment\",\n durationMs: Date.now() - t0,\n deadlineMs: enrichmentSectionDeadlineMs,\n source: \"fresh\",\n success: true,\n timing:\n `on b=${comparison.baselineCount} g=${comparison.graphCount} ` +\n `ov=${comparison.overlapCount} (${comparison.overlapRatio.toFixed(2)}) ` +\n `avgDelta=${comparison.averageOverlapDelta.toFixed(3)}`,\n });\n }\n }\n } catch (err) {\n graphSnapshotStatus = \"aborted\";\n graphDecisionStatus = \"aborted\";\n graphDecisionReason = `graph expansion failed: ${err instanceof Error ? err.message : String(err)}`;\n graphSnapshotReason = graphDecisionReason;\n graphSnapshotSeedPaths = baselineMemoryResults\n .slice(0, Math.max(1, recallResultLimit))\n .map((result) => result.path);\n graphSnapshotSeedResults = this.buildGraphRecallRankedResults(\n baselineMemoryResults,\n () => [\"baseline\"],\n );\n graphSnapshotExpandedPaths = [];\n graphExpandedResultPaths.clear();\n log.warn(`graph recall failed open: ${graphDecisionReason}`);\n memoryResults = baselineMemoryResults;\n }\n }\n }\n\n // Apply mandatory recall safety filters before deadline-bound scoring\n // enrichment. If scoring times out, we must fall back to this filtered\n // list rather than raw QMD hits; boostSearchResults also removes\n // forgotten, lifecycle-filtered, superseded/as_of-invalid, and\n // dream/procedural memories.\n const qmdBoostInput = await this.filterSearchResultsForRecall(\n memoryResults,\n undefined,\n {\n asOfMs,\n // If QMD had already settled before the ordered assembly reached it,\n // do not let unrelated slow enrichment turn those known results into\n // unchecked misses. QMD that only settles during its own wait remains\n // bounded by the shared post-retrieval assembly deadline.\n deadlineAtMs: qmdWasSettledBeforeAssemblyWait\n ? null\n : enrichmentAssemblyDeadlineAtMs,\n abortSignal: options.abortSignal,\n dropUnresolved: true,\n recallNamespaces,\n },\n );\n\n // Apply recency and access count boosting\n memoryResults = await awaitAssemblyStep(\n \"qmd-boost\",\n () =>\n this.boostSearchResults(\n qmdBoostInput.results,\n recallNamespaces,\n retrievalQuery,\n qmdBoostInput.memoryByPath,\n { asOfMs },\n ),\n qmdBoostInput.results,\n );\n\n // Optional LLM reranking (default off). Fail-open if rerank fails/slow.\n if (this.config.rerankEnabled && this.config.rerankProvider === \"local\") {\n const ranked = await rerankLocalOrNoop({\n query: retrievalQuery,\n candidates: memoryResults\n .slice(0, this.config.rerankMaxCandidates)\n .map((r) => ({\n id: r.path,\n snippet: r.snippet || r.path,\n })),\n local: this.fastLlmForRerank,\n enabled: true,\n timeoutMs: this.config.rerankTimeoutMs,\n maxCandidates: this.config.rerankMaxCandidates,\n cache: this.rerankCache,\n cacheEnabled: this.config.rerankCacheEnabled,\n cacheTtlMs: this.config.rerankCacheTtlMs,\n });\n if (ranked && ranked.length > 0) {\n const byPath = new Map(memoryResults.map((r) => [r.path, r]));\n const reordered: QmdSearchResult[] = [];\n for (const p of ranked) {\n const it = byPath.get(p);\n if (it) reordered.push(it);\n }\n // Append any unranked items in original order.\n const rankedSet = new Set(ranked);\n for (const r of memoryResults) {\n if (!rankedSet.has(r.path)) reordered.push(r);\n }\n memoryResults = reordered;\n }\n }\n if (this.config.rerankEnabled && this.config.rerankProvider === \"cloud\") {\n log.debug(\n \"rerankProvider=cloud is reserved/experimental in v2.2.0; skipping rerank\",\n );\n }\n\n // Memory Worth recall filter (issue #560 PR 4). When enabled, multiply\n // each candidate's score by its Memory Worth factor so memories with\n // a history of failed outcomes sink. Default off in this PR; PR 5\n // flips the default once bench shows tie-or-win. Fail-open: any\n // lookup error leaves the original scores untouched rather than\n // breaking recall for the whole namespace.\n if (this.config.recallMemoryWorthFilterEnabled && memoryResults.length > 0) {\n try {\n memoryResults = await this.applyMemoryWorthRerank(memoryResults, recallNamespaces);\n } catch (err) {\n log.debug(\"memory-worth filter failed open\", { error: (err as Error).message });\n }\n }\n\n // Synapse-inspired confidence gate: check scores BEFORE slicing so\n // reranking doesn't affect which score the gate evaluates.\n //\n // Gate exclusively on the pre-augmentation QMD top score so the threshold\n // stays on the same scale it was calibrated against (raw QMD scores, not\n // post-merge weighted scores). This avoids two pitfalls:\n // 1. The 0.7× contextual weight silently lowering scores below threshold.\n // 2. A direct/temporal hit on a different scale inflating the gate score.\n // We also include maxSpecializedScore so that a strong direct/temporal hit (e.g.\n // an exact entity-name match at score 1.0) is not discarded just because the QMD\n // contextual pass returned a weak result. maxSpecializedScore is post-weight, so\n // direct hits at weight 1.0 stay on the same 0-1 scale as QMD scores.\n // IMPORTANT: maxSpecializedScore is only included when QMD also found something\n // (preAugmentTopScore > 0). When QMD returns nothing, a weak specialized hit must\n // NOT block the embedding fallback safety net — that path exists precisely for the\n // case where QMD finds nothing. Setting effectiveGateScore = 0 when QMD is empty\n // preserves the original behaviour: empty QMD → gate skipped → fallback available.\n const effectiveGateScore =\n preAugmentTopScore > 0\n ? Math.max(preAugmentTopScore, maxSpecializedScore)\n : 0;\n // Capture pre-gate pool size for X-ray before the confidence\n // gate can zero `memoryResults`. Placing the capture after the\n // gate would record 0 instead of the true pre-gate pool size\n // (issue #570 PR 1 review follow-up).\n xrayBranchPoolSize.hot_qmd = Math.max(\n xrayBranchPoolSize.hot_qmd,\n memoryResults.length,\n );\n let confidenceGateRejected = false;\n if (this.config.recallConfidenceGateEnabled && effectiveGateScore > 0) {\n if (effectiveGateScore < this.config.recallConfidenceGateThreshold) {\n log.debug(\n `recall: confidence gate rejected ${memoryResults.length} results (effective score ${effectiveGateScore.toFixed(3)} below ${this.config.recallConfidenceGateThreshold})`,\n );\n memoryResults = [];\n confidenceGateRejected = true;\n }\n }\n\n // Diversify via MMR over the full candidate pool *before* truncating to\n // the final recall limit. Running MMR after the slice would be unable\n // to promote diverse candidates sitting just below the cutoff.\n memoryResults = this.diversifyAndLimitRecallResults(\n \"memories\",\n memoryResults,\n recallResultLimit,\n retrievalQuery,\n );\n\n // E-Mem-inspired memory reconstruction: fill gaps for referenced entities\n if (this.config.memoryReconstructionEnabled && memoryResults.length > 0) {\n try {\n const snippets = memoryResults.map((r) => r.snippet);\n // Extract entity paths already present in recall results to avoid duplicates\n const coveredRefs = memoryResults\n .map((r) => r.path)\n .filter((p) => p.startsWith(\"entities/\"))\n .map((p) => p.replace(/^entities\\//, \"\").replace(/\\.md$/, \"\"));\n const knownEntities = await profileStorage.listEntityNames();\n const missing = findUnresolvedEntityRefs(\n snippets,\n coveredRefs,\n knownEntities,\n );\n if (missing.length > 0) {\n // Allow up to maxExpansions successful entity expansions\n const budget = this.config.memoryReconstructionMaxExpansions;\n let expanded = 0;\n for (const entityName of missing) {\n if (expanded >= budget) break;\n const raw = await profileStorage.readEntity(entityName);\n if (raw && raw.length > 0) {\n const snippet =\n raw.length > 300 ? raw.slice(0, 300) + \"…\" : raw;\n memoryResults.push({\n docid: `entity:${entityName}`,\n path: `entities/${entityName}.md`,\n snippet: `[Entity: ${entityName}] ${snippet}`,\n score: 0.1,\n });\n expanded++;\n }\n }\n if (expanded > 0) {\n log.debug(`recall: reconstructed ${expanded} entity contexts`);\n }\n }\n } catch (err) {\n log.warn(\"recall: memory reconstruction failed (non-fatal)\", err);\n }\n }\n\n if (memoryResults.length > 0) {\n if (shouldPersistGraphSnapshot) {\n graphSnapshotFinalResults = this.buildGraphRecallRankedResults(\n memoryResults,\n graphSourceLabelsForPath,\n );\n }\n recallSource = \"hot_qmd\";\n recalledMemoryCount = memoryResults.length;\n this.publishRecallResults({\n title: \"Relevant Memories\",\n results: memoryResults,\n sectionBuckets,\n retrievalQuery,\n sessionKey,\n identityInjection: {\n mode: identityInjectionModeUsed,\n injectedChars: identityInjectedChars,\n truncated: identityInjectionTruncated,\n },\n });\n recalledMemoryIds = this.extractMemoryIdsFromResults(memoryResults);\n recalledMemoryPaths = memoryResults\n .map((result) => result.path)\n .filter(Boolean);\n xrayRecalledResults = memoryResults;\n impressionRecorded = true;\n } else if (!confidenceGateRejected) {\n // Only attempt fallback paths if the confidence gate did NOT fire.\n // When the gate rejects, all recall pathways are skipped to prevent\n // low-relevance results from polluting context.\n const queryAwarePrefilter = await queryAwarePrefilterPromise;\n if (queryAwarePrefilter.candidatePaths?.size !== 0) {\n const scoped = await awaitAssemblyStep(\n \"embedding-fallback\",\n async () => {\n const embeddingResults = await this.searchEmbeddingFallback(\n retrievalQuery,\n embeddingFetchLimit,\n );\n const prefilteredEmbeddingResults = applyQueryAwareCandidateFilter(\n embeddingResults,\n queryAwarePrefilter.candidatePaths,\n );\n const scopedCandidates = filterRecallCandidates(\n prefilteredEmbeddingResults,\n {\n namespacesEnabled: this.config.namespacesEnabled,\n recallNamespaces,\n resolveNamespace: (p) => this.namespaceFromPath(p),\n limit: embeddingFetchLimit,\n },\n );\n const boostedScoped = await this.boostSearchResults(\n scopedCandidates,\n recallNamespaces,\n retrievalQuery,\n undefined,\n { asOfMs },\n );\n // MMR runs on the pre-truncation pool so diverse candidates just\n // below the cutoff can be promoted into the injected set.\n xrayBranchPoolSize.hot_embedding = Math.max(\n xrayBranchPoolSize.hot_embedding,\n boostedScoped.length,\n );\n return this.diversifyAndLimitRecallResults(\n \"memories\",\n boostedScoped,\n recallResultLimit,\n retrievalQuery,\n );\n },\n [] as QmdSearchResult[],\n );\n if (scoped.length > 0) {\n if (shouldPersistGraphSnapshot) {\n graphSnapshotFinalResults = this.buildGraphRecallRankedResults(\n scoped,\n graphSourceLabelsForPath,\n );\n }\n recallSource = \"hot_embedding\";\n recalledMemoryCount = scoped.length;\n this.publishRecallResults({\n title: \"Relevant Memories\",\n results: scoped,\n sectionBuckets,\n retrievalQuery,\n sessionKey,\n identityInjection: {\n mode: identityInjectionModeUsed,\n injectedChars: identityInjectedChars,\n truncated: identityInjectionTruncated,\n },\n });\n recalledMemoryIds = this.extractMemoryIdsFromResults(scoped);\n recalledMemoryPaths = scoped\n .map((result) => result.path)\n .filter(Boolean);\n xrayRecalledResults = scoped;\n impressionRecorded = true;\n } else {\n const longTerm = await this.applyColdFallbackPipeline({\n prompt: retrievalQuery,\n recallNamespaces,\n recallResultLimit,\n recallMode,\n queryAwarePrefilter,\n abortSignal: options.abortSignal,\n xrayPoolSizeSink: xrayColdPoolSink,\n deadlineAtMs: enrichmentAssemblyDeadlineAtMs,\n asOfMs,\n ...(options.includeLowConfidence === true ? { includeLowConfidence: true } : {}),\n });\n if (longTerm.length > 0) {\n if (shouldPersistGraphSnapshot) {\n graphSnapshotFinalResults = this.buildGraphRecallRankedResults(\n longTerm,\n graphSourceLabelsForPath,\n );\n }\n recallSource = \"cold_fallback\";\n recalledMemoryCount = longTerm.length;\n this.publishRecallResults({\n title: \"Long-Term Memories (Fallback)\",\n results: longTerm,\n sectionBuckets,\n retrievalQuery,\n sessionKey,\n identityInjection: {\n mode: identityInjectionModeUsed,\n injectedChars: identityInjectedChars,\n truncated: identityInjectionTruncated,\n },\n });\n recalledMemoryIds = this.extractMemoryIdsFromResults(longTerm);\n recalledMemoryPaths = longTerm\n .map((result) => result.path)\n .filter(Boolean);\n xrayRecalledResults = longTerm;\n impressionRecorded = true;\n }\n }\n }\n }\n\n if (globalResults.length > 0) {\n this.appendRecallSection(\n sectionBuckets,\n \"workspace-context\",\n this.formatQmdResults(\"Workspace Context\", globalResults),\n );\n }\n\n recordRecallSectionMetric({\n section: \"qmdPost\",\n priority: \"enrichment\",\n durationMs: Date.now() - t0,\n deadlineMs: enrichmentSectionDeadlineMs,\n source: \"fresh\",\n success: true,\n });\n\n // If the user is pushing back (\"that's not right\", \"why did you say that\"),\n // gently suggest an explicit workflow to inspect what was recalled and record feedback.\n // IMPORTANT: this is suggestion-only; never auto-mark negatives.\n if (isDisagreementPrompt(prompt)) {\n this.appendRecallSection(\n sectionBuckets,\n \"memories\",\n [\n \"## Retrieval Feedback Helper\",\n \"\",\n \"The user may be disputing an answer. To debug whether retrieval misled the response:\",\n \"- Use tool `memory_last_recall` to see which memory IDs were injected into context.\",\n \"- Use tool `memory_intent_debug` to inspect the planner mode decision and graph fallback reason.\",\n \"- If negative examples are enabled, you can use `memory_feedback_last_recall` to mark specific recalled IDs as not useful.\",\n \"\",\n \"Safety: do not mass-mark negatives automatically; prefer explicit IDs.\",\n ].join(\"\\n\"),\n );\n }\n } else if (recallResultLimit > 0 && !this.qmd.isAvailable()) {\n // Fallback: embeddings first, then recency-only.\n const queryAwarePrefilter = await queryAwarePrefilterPromise;\n if (queryAwarePrefilter.candidatePaths?.size !== 0) {\n const scoped = await awaitAssemblyStep(\n \"embedding-fallback\",\n async () => {\n const embeddingResults = await this.searchEmbeddingFallback(\n retrievalQuery,\n embeddingFetchLimit,\n );\n const prefilteredEmbeddingResults = applyQueryAwareCandidateFilter(\n embeddingResults,\n queryAwarePrefilter.candidatePaths,\n );\n const scopedCandidates = filterRecallCandidates(\n prefilteredEmbeddingResults,\n {\n namespacesEnabled: this.config.namespacesEnabled,\n recallNamespaces,\n resolveNamespace: (p) => this.namespaceFromPath(p),\n limit: embeddingFetchLimit,\n },\n );\n const boostedScoped = await this.boostSearchResults(\n scopedCandidates,\n recallNamespaces,\n retrievalQuery,\n undefined,\n { asOfMs },\n );\n // MMR runs on the pre-truncation pool so diverse candidates just\n // below the cutoff can be promoted into the injected set.\n xrayBranchPoolSize.hot_embedding = Math.max(\n xrayBranchPoolSize.hot_embedding,\n boostedScoped.length,\n );\n return this.diversifyAndLimitRecallResults(\n \"memories\",\n boostedScoped,\n recallResultLimit,\n retrievalQuery,\n );\n },\n [] as QmdSearchResult[],\n );\n if (scoped.length > 0) {\n if (shouldPersistGraphSnapshot) {\n graphSnapshotFinalResults = this.buildGraphRecallRankedResults(\n scoped,\n graphSourceLabelsForPath,\n );\n }\n recallSource = \"hot_embedding\";\n recalledMemoryCount = scoped.length;\n this.publishRecallResults({\n title: \"Relevant Memories\",\n results: scoped,\n sectionBuckets,\n retrievalQuery,\n sessionKey,\n identityInjection: {\n mode: identityInjectionModeUsed,\n injectedChars: identityInjectedChars,\n truncated: identityInjectionTruncated,\n },\n });\n recalledMemoryIds = this.extractMemoryIdsFromResults(scoped);\n recalledMemoryPaths = scoped\n .map((result) => result.path)\n .filter(Boolean);\n xrayRecalledResults = scoped;\n impressionRecorded = true;\n } else {\n const memories = await awaitAssemblyStep(\n \"recent-memory-read\",\n () => this.readAllMemoriesForNamespaces(recallNamespaces),\n [] as MemoryFile[],\n );\n if (memories.length > 0) {\n // Filter out non-active memories. Delegate to\n // shouldFilterSupersededFromRecall for superseded-status logic so\n // that the recent-scan path and the boostSearchResults (QMD) path\n // have identical semantics:\n // • temporalSupersessionEnabled=false → never filter superseded\n // (mirrors QMD path; user disabled the feature, so old marks\n // are ignored and all memories surface)\n // • temporalSupersessionIncludeInRecall=true → never filter (audit mode)\n // • enabled=true + includeInRecall=false → filter superseded\n // Previously the recent-scan path checked `enabled && includeInRecall`\n // directly, which disagreed with the QMD path when enabled=false\n // (memories were still filtered, contrary to the kill-switch intent).\n // Using the shared gate fixes both Finding 2 and Finding 3 from\n // PR #402 (round 6).\n const supersessionOptions = {\n enabled: this.config.temporalSupersessionEnabled,\n includeInRecall: this.config.temporalSupersessionIncludeInRecall,\n };\n // Cursor Medium on PR #713: when `as_of` is active, the\n // recent-scan path used to strip every non-active status\n // (including superseded) before `boostSearchResults` ran,\n // so the as_of bypass inside boostSearchResults never had\n // a chance to admit historically-valid records. Pass\n // superseded candidates through here when as_of is active;\n // boostSearchResults's `[valid_at, invalid_at)` evaluation\n // is the authoritative gate. Other non-active statuses\n // (archived, forgotten, rejected) stay excluded — historical\n // recall is about supersession history, not about reviving\n // records the operator explicitly dropped.\n const asOfActive =\n typeof asOfMs === \"number\" && Number.isFinite(asOfMs);\n const activeMemories = memories.filter(\n (m) => {\n if (isArtifactMemoryPath(m.path)) return false;\n const status = m.frontmatter.status;\n if (!status || status === \"active\") return true;\n if (status === \"superseded\") {\n if (asOfActive) return true;\n // Include superseded memory only if the canonical gate says\n // NOT to filter it (kill switch off or audit mode on).\n return !shouldFilterSupersededFromRecall(m.frontmatter, supersessionOptions);\n }\n // Other non-active statuses (archived, retired, etc.) are\n // excluded from the recent-scan path by default.\n return false;\n },\n );\n // Convert all active memories to QmdSearchResult with recency-based\n // baseline score, then pass through boostSearchResults so temporal/tag\n // boosts apply consistently with the primary QMD retrieval path.\n // Cap AFTER boosting so boosted-but-recency-ranked memories can surface.\n // Pass a pre-populated memoryByPath so boostSearchResults skips redundant\n // disk reads for files already loaded by readAllMemoriesForNamespaces.\n const queryAwareScopedMemories = queryAwarePrefilter.candidatePaths\n ? activeMemories.filter((memory) =>\n queryAwarePrefilter.candidatePaths?.has(memory.path),\n )\n : activeMemories;\n if (\n queryAwarePrefilter.candidatePaths &&\n queryAwareScopedMemories.length === 0\n ) {\n const longTerm = await this.applyColdFallbackPipeline({\n prompt: retrievalQuery,\n recallNamespaces,\n recallResultLimit,\n recallMode,\n queryAwarePrefilter,\n abortSignal: options.abortSignal,\n xrayPoolSizeSink: xrayColdPoolSink,\n deadlineAtMs: enrichmentAssemblyDeadlineAtMs,\n asOfMs,\n ...(options.includeLowConfidence === true ? { includeLowConfidence: true } : {}),\n });\n if (longTerm.length > 0) {\n recallSource = \"cold_fallback\";\n recalledMemoryCount = longTerm.length;\n this.publishRecallResults({\n title: \"Long-Term Memories (Fallback)\",\n results: longTerm,\n sectionBuckets,\n retrievalQuery,\n sessionKey,\n identityInjection: {\n mode: identityInjectionModeUsed,\n injectedChars: identityInjectedChars,\n truncated: identityInjectionTruncated,\n },\n });\n recalledMemoryIds = this.extractMemoryIdsFromResults(longTerm);\n recalledMemoryPaths = longTerm\n .map((result) => result.path)\n .filter(Boolean);\n xrayRecalledResults = longTerm;\n impressionRecorded = true;\n }\n } else {\n const recent = await awaitAssemblyStep(\n \"recent-memory-scan\",\n async () => {\n const recentSorted = queryAwareScopedMemories.sort(\n (a, b) =>\n new Date(b.frontmatter.updated).getTime() -\n new Date(a.frontmatter.updated).getTime(),\n );\n const preloadedMap = new Map<string, MemoryFile>(\n queryAwareScopedMemories\n .filter((m) => m.path)\n .map((m) => [m.path, m]),\n );\n const recentAsResults: QmdSearchResult[] = recentSorted.map(\n (m, i) => ({\n docid: m.frontmatter.id,\n path: m.path,\n snippet: m.content,\n score: 1.0 - i / Math.max(recentSorted.length, 1),\n }),\n );\n const boostedRecent = (\n await this.boostSearchResults(\n recentAsResults,\n recallNamespaces,\n retrievalQuery,\n preloadedMap,\n { asOfMs },\n )\n ).sort((a, b) => b.score - a.score);\n // MMR runs on the pre-truncation pool so diverse candidates just\n // below the cutoff can be promoted into the injected set.\n xrayBranchPoolSize.recent_scan = Math.max(\n xrayBranchPoolSize.recent_scan,\n boostedRecent.length,\n );\n return this.diversifyAndLimitRecallResults(\n \"memories\",\n boostedRecent,\n recallResultLimit,\n retrievalQuery,\n );\n },\n [] as QmdSearchResult[],\n );\n\n if (recent.length > 0) {\n if (shouldPersistGraphSnapshot) {\n graphSnapshotFinalResults = this.buildGraphRecallRankedResults(\n recent,\n graphSourceLabelsForPath,\n );\n }\n recallSource = \"recent_scan\";\n recalledMemoryCount = recent.length;\n this.publishRecallResults({\n title: \"Recent Memories\",\n results: recent,\n sectionBuckets,\n retrievalQuery,\n sessionKey,\n identityInjection: {\n mode: identityInjectionModeUsed,\n injectedChars: identityInjectedChars,\n truncated: identityInjectionTruncated,\n },\n });\n recalledMemoryIds = this.extractMemoryIdsFromResults(recent);\n recalledMemoryPaths = recent\n .map((result) => result.path)\n .filter(Boolean);\n xrayRecalledResults = recent;\n impressionRecorded = true;\n } else {\n const longTerm = await this.applyColdFallbackPipeline({\n prompt: retrievalQuery,\n recallNamespaces,\n recallResultLimit,\n recallMode,\n queryAwarePrefilter,\n abortSignal: options.abortSignal,\n xrayPoolSizeSink: xrayColdPoolSink,\n deadlineAtMs: enrichmentAssemblyDeadlineAtMs,\n asOfMs,\n ...(options.includeLowConfidence === true ? { includeLowConfidence: true } : {}),\n });\n if (longTerm.length > 0) {\n if (shouldPersistGraphSnapshot) {\n graphSnapshotFinalResults =\n this.buildGraphRecallRankedResults(\n longTerm,\n graphSourceLabelsForPath,\n );\n }\n recallSource = \"cold_fallback\";\n recalledMemoryCount = longTerm.length;\n this.publishRecallResults({\n title: \"Long-Term Memories (Fallback)\",\n results: longTerm,\n sectionBuckets,\n retrievalQuery,\n sessionKey,\n identityInjection: {\n mode: identityInjectionModeUsed,\n injectedChars: identityInjectedChars,\n truncated: identityInjectionTruncated,\n },\n });\n recalledMemoryIds = this.extractMemoryIdsFromResults(longTerm);\n recalledMemoryPaths = longTerm\n .map((result) => result.path)\n .filter(Boolean);\n xrayRecalledResults = longTerm;\n impressionRecorded = true;\n }\n }\n }\n } else {\n const longTerm = await this.applyColdFallbackPipeline({\n prompt: retrievalQuery,\n recallNamespaces,\n recallResultLimit,\n recallMode,\n queryAwarePrefilter,\n abortSignal: options.abortSignal,\n xrayPoolSizeSink: xrayColdPoolSink,\n deadlineAtMs: enrichmentAssemblyDeadlineAtMs,\n asOfMs,\n ...(options.includeLowConfidence === true ? { includeLowConfidence: true } : {}),\n });\n if (longTerm.length > 0) {\n if (shouldPersistGraphSnapshot) {\n graphSnapshotFinalResults = this.buildGraphRecallRankedResults(\n longTerm,\n graphSourceLabelsForPath,\n );\n }\n recallSource = \"cold_fallback\";\n recalledMemoryCount = longTerm.length;\n this.publishRecallResults({\n title: \"Long-Term Memories (Fallback)\",\n results: longTerm,\n sectionBuckets,\n retrievalQuery,\n sessionKey,\n identityInjection: {\n mode: identityInjectionModeUsed,\n injectedChars: identityInjectedChars,\n truncated: identityInjectionTruncated,\n },\n });\n recalledMemoryIds = this.extractMemoryIdsFromResults(longTerm);\n recalledMemoryPaths = longTerm\n .map((result) => result.path)\n .filter(Boolean);\n xrayRecalledResults = longTerm;\n impressionRecorded = true;\n }\n }\n }\n }\n\n if (isDisagreementPrompt(prompt)) {\n this.appendRecallSection(\n sectionBuckets,\n \"memories\",\n [\n \"## Retrieval Feedback Helper\",\n \"\",\n \"The user may be disputing an answer. To debug whether retrieval misled the response:\",\n \"- Use tool `memory_last_recall` to see which memory IDs were injected into context.\",\n \"- Use tool `memory_intent_debug` to inspect the planner mode decision and graph fallback reason.\",\n \"- If graph recall is enabled, use `memory_graph_explain_last_recall` to inspect seed/expanded graph paths.\",\n \"- If negative examples are enabled, you can use `memory_feedback_last_recall` to mark specific recalled IDs as not useful.\",\n \"\",\n \"Safety: do not mass-mark negatives automatically; prefer explicit IDs.\",\n ].join(\"\\n\"),\n );\n }\n }\n\n const phase2AfterQmdMs = Date.now() - recallStart;\n if (shouldPersistGraphSnapshot) {\n if (!graphSnapshotStatus) {\n graphSnapshotStatus = \"skipped\";\n }\n if (!graphSnapshotReason) {\n graphSnapshotReason = qmdAvailable\n ? \"graph recall skipped before expansion\"\n : \"graph recall skipped because QMD was unavailable\";\n }\n if (graphDecisionStatus === \"not_requested\") {\n graphDecisionStatus = graphSnapshotStatus;\n }\n if (!graphDecisionReason) {\n graphDecisionReason = graphSnapshotReason;\n }\n await this.recordLastGraphRecallSnapshot({\n storage: profileStorage,\n prompt: retrievalQuery,\n recallMode,\n recallNamespaces,\n seedPaths: graphSnapshotSeedPaths,\n expandedPaths: graphSnapshotExpandedPaths,\n status: graphSnapshotStatus,\n reason: graphSnapshotReason,\n shadowMode: graphDecisionShadowMode,\n queryIntent,\n seedResults: graphSnapshotSeedResults,\n finalResults: graphSnapshotFinalResults,\n shadowComparison: graphSnapshotShadowComparison,\n });\n }\n await this.recordLastIntentSnapshot({\n storage: profileStorage,\n snapshot: buildIntentDebugSnapshot(),\n });\n\n // 2.5. Compression guideline recall section (v8.11 Task 5)\n if (\n this.isRecallSectionEnabled(\n \"compression-guidelines\",\n this.config.compressionGuidelineLearningEnabled === true,\n )\n ) {\n const compressionGuidelineSection =\n await this.buildCompressionGuidelineRecallSection();\n if (compressionGuidelineSection) {\n this.appendRecallSection(\n sectionBuckets,\n \"compression-guidelines\",\n compressionGuidelineSection,\n );\n }\n }\n\n // 3. Transcript/summaries/conversation/compounding are fetched in parallel above,\n // then assembled here according to recallPipeline order.\n if (transcriptSection) {\n this.appendRecallSection(sectionBuckets, \"transcript\", transcriptSection);\n }\n // Compaction reset context — independent section so it works even when transcript is disabled.\n if (compactionSection) {\n this.appendRecallSection(\n sectionBuckets,\n \"compaction-reset\",\n compactionSection,\n );\n }\n if (summariesSection) {\n this.appendRecallSection(sectionBuckets, \"summaries\", summariesSection);\n }\n if (conversationRecallSection) {\n this.appendRecallSection(\n sectionBuckets,\n \"conversation-recall\",\n conversationRecallSection,\n );\n }\n const compoundingSection = await awaitEnrichmentSection(\n \"compounding\",\n compoundingPromise,\n );\n if (compoundingSection) {\n this.appendRecallSection(\n sectionBuckets,\n \"compounding\",\n compoundingSection,\n );\n }\n\n // 5. Inject most relevant question (if enabled) (existing)\n if (\n this.config.injectQuestions &&\n this.isRecallSectionEnabled(\"questions\", true)\n ) {\n const questions = await profileStorage.readQuestions({\n unresolvedOnly: true,\n });\n if (questions.length > 0) {\n // Find the most relevant question to the current prompt\n // Simple approach: use the highest-priority unresolved question\n // TODO: Could use QMD search to find the most contextually relevant one\n const topQuestion = questions[0]; // Already sorted by priority desc\n this.appendRecallSection(\n sectionBuckets,\n \"questions\",\n `## Open Question\\n\\nSomething I've been curious about: ${topQuestion.question}\\n\\n_Context: ${topQuestion.context}_`,\n );\n }\n }\n\n const phase2QuestionsDoneMs = Date.now() - recallStart;\n const finalizedQueryAwarePrefilter = await queryAwarePrefilterPromise;\n const phase2QapDoneMs = Date.now() - recallStart;\n throwIfRecallAborted(options.abortSignal);\n if (\n timings.queryAware &&\n finalizedQueryAwarePrefilter.candidatePaths?.size\n ) {\n const helpedCount = recalledMemoryPaths.filter((memoryPath) =>\n finalizedQueryAwarePrefilter.candidatePaths?.has(memoryPath),\n ).length;\n timings.queryAware = `${timings.queryAware};helped=${helpedCount}`;\n }\n\n // --- Timing summary ---\n timings.total = `${Date.now() - recallStart}ms`;\n this.profiler.endSpan(\"assembly\", profileTraceId);\n log.info(\n `recall phase-2 checkpoints: afterQmd=${phase2AfterQmdMs}ms, afterQuestions=${phase2QuestionsDoneMs}ms, afterQap=${phase2QapDoneMs}ms`,\n );\n const timingParts = Object.entries(timings)\n .map(([k, v]) => `${k}=${v}`)\n .join(\", \");\n log.info(`recall timings: ${timingParts}`);\n\n const assembledRecall = this.assembleRecallSections(\n sectionBuckets,\n options.budgetCharsOverride,\n );\n const context =\n assembledRecall.sections.length === 0\n ? \"\"\n : assembledRecall.sections.join(\"\\n\\n---\\n\\n\");\n const sourcesUsed = this.collectLastRecallSources(\n sectionBuckets,\n recallSource,\n );\n const budgetsApplied = this.buildLastRecallBudgetSummary({\n requestedTopK,\n recallResultLimit,\n qmdFetchLimit,\n qmdHybridFetchLimit,\n finalContextChars: assembledRecall.finalChars,\n truncated: assembledRecall.truncated,\n includedSections: assembledRecall.includedIds,\n omittedSections: assembledRecall.omittedIds,\n });\n\n // X-ray capture (issue #570 PR 1). Only fires when the caller\n // explicitly opts in via `xrayCapture: true`. No behavior change\n // when the flag is absent — this branch and the setter both\n // short-circuit. Captured data is composed from values we have\n // already derived above, so capture cost is a single object\n // allocation; no new recall work is performed.\n //\n // Skip capture when the caller has already aborted this recall —\n // otherwise a canceled call could clobber a prior successful\n // capture that the capturing caller has not yet read back\n // (issue #570 PR 1 review follow-up).\n if (\n options.xrayCapture === true &&\n !options.abortSignal?.aborted\n ) {\n try {\n const servedBy = mapRecallSourceToXrayServedBy(recallSource);\n // Derive xray results from `recalledMemoryPaths` as the single\n // source of truth — `recalledMemoryIds` and `recalledMemoryPaths`\n // are built with two independent filters upstream\n // (`extractMemoryIdsFromResults` drops paths whose filename does\n // not match `*.md`, while `.map(path).filter(Boolean)` drops\n // empty paths only), so zipping them positionally would silently\n // misalign when the two filters differ. Re-deriving `memoryId`\n // from the path here guarantees `memoryId` and `path` refer to\n // the same underlying result.\n const idFromPath = (p: string): string | null => {\n const match = p.match(/([^/]+)\\.md$/);\n return match ? match[1] ?? null : null;\n };\n // Build a path → QmdSearchResult index so we can pull per-result\n // explain data (e.g. reinforcementBoost) from the result that\n // boostSearchResults annotated before surfacing to xray.\n const xrayResultByPath = new Map<string, QmdSearchResult>(\n xrayRecalledResults.map((xr) => [xr.path, xr]),\n );\n const results: RecallXrayResult[] = [];\n for (const recalledPath of recalledMemoryPaths) {\n const derivedId = idFromPath(recalledPath);\n if (!derivedId) continue;\n const xrayResult = xrayResultByPath.get(recalledPath);\n const scoreDecomposition: RecallXrayScoreDecomposition = {\n final: xrayResult?.score ?? 0,\n };\n if (\n xrayResult?.explain?.reinforcementBoost !== undefined &&\n xrayResult.explain.reinforcementBoost > 0\n ) {\n scoreDecomposition.reinforcementBoost =\n xrayResult.explain.reinforcementBoost;\n }\n const resultNamespace = this.namespaceFromPath(recalledPath);\n let provenance: RecallXrayResult[\"provenance\"] | undefined;\n try {\n const resultStorage =\n await this.storageRouter.storageFor(resultNamespace);\n const memory = await resultStorage.readMemoryByPath(recalledPath);\n if (memory) {\n provenance = buildRetrievedMemoryProvenance(memory, {\n namespace: resultNamespace,\n retrievalReason: `served-by=${servedBy}`,\n currentContextScopes: options.currentContextScopes,\n });\n }\n } catch {\n // X-ray capture is best-effort; missing provenance must not\n // perturb recall or suppress the surfaced result.\n }\n results.push({\n memoryId: derivedId,\n path: recalledPath,\n servedBy,\n scoreDecomposition,\n admittedBy: [],\n ...(provenance ? { provenance } : {}),\n });\n }\n // `considered` must reflect the pool size of the branch that\n // actually produced the admitted results, NOT the max across\n // every branch that ran. Otherwise a flow where hot_qmd\n // assembled a large pool that was killed by the confidence\n // gate and a different branch (or none) ultimately served\n // the recall would report hot_qmd's pool as \"considered\" —\n // incorrectly attributing those drops to the result limit.\n // Pick the pool by `recallSource`; fall back to\n // `recalledMemoryCount` when no branch ran (e.g. every branch\n // returned zero). This path never runs for `no_recall` —\n // that branch captures its own snapshot earlier.\n let xrayConsidered: number;\n switch (recallSource) {\n case \"hot_qmd\":\n xrayConsidered = xrayBranchPoolSize.hot_qmd;\n break;\n case \"hot_embedding\":\n xrayConsidered = xrayBranchPoolSize.hot_embedding;\n break;\n case \"cold_fallback\":\n xrayConsidered = xrayColdPoolSink.size;\n break;\n case \"recent_scan\":\n xrayConsidered = xrayBranchPoolSize.recent_scan;\n break;\n case \"none\":\n xrayConsidered = recalledMemoryCount;\n break;\n default: {\n // Compile-time guard: adding a new `recallSource` value\n // must force this switch to be updated.\n const _exhaustive: never = recallSource;\n void _exhaustive;\n xrayConsidered = recalledMemoryCount;\n }\n }\n // `considered` must never be less than `admitted` — in degenerate\n // flows where a branch's pool counter missed an assignment, prefer\n // the admitted count as the floor so the trace stays self-consistent.\n xrayConsidered = Math.max(xrayConsidered, recalledMemoryIds.length);\n const filters: RecallFilterTrace[] = [\n {\n name: \"recall-result-limit\",\n considered: xrayConsidered,\n admitted: recalledMemoryIds.length,\n },\n ];\n if (lcmStructuredXrayResults.length > 0) {\n filters.push({\n name: \"lcm-message-parts\",\n considered: lcmStructuredXrayResults.length,\n admitted: lcmStructuredXrayResults.length,\n });\n }\n this.lastXraySnapshot = buildXraySnapshot({\n query: retrievalQuery,\n tierExplain: null,\n results: [...results, ...lcmStructuredXrayResults],\n filters,\n budget: {\n chars: this.getRecallBudgetChars(options.budgetCharsOverride),\n used: assembledRecall.finalChars,\n },\n sessionKey,\n namespace: selfNamespace,\n traceId,\n // Issue #679 completion: record peer-profile injection in the\n // xray snapshot. peerProfileXrayAnnotation is set inside\n // peerProfileRecallPromise when injection actually occurred,\n // and stays null otherwise. By the time xray capture runs,\n // phase-1 parallel work is complete so the annotation is\n // guaranteed to be populated.\n peerProfileInjection: peerProfileXrayAnnotation,\n });\n } catch (err) {\n // Capture is a best-effort side channel: a capture failure\n // must NEVER propagate into the primary recall path.\n log.debug(`x-ray capture failed: ${err}`);\n }\n }\n\n if (sessionKey) {\n throwIfRecallAborted(options.abortSignal);\n this.lastRecall\n .record({\n sessionKey,\n query: retrievalQuery,\n memoryIds: recalledMemoryIds,\n namespace: selfNamespace,\n recallNamespaces,\n traceId,\n plannerMode: recallMode,\n requestedMode,\n source: recallSource,\n fallbackUsed: recallSource !== \"none\" && recallSource !== \"hot_qmd\",\n sourcesUsed,\n budgetsApplied,\n latencyMs: Date.now() - recallStart,\n resultPaths: recalledMemoryPaths,\n policyVersion,\n appendImpression:\n impressionRecorded ||\n recalledMemoryIds.length > 0 ||\n this.config.recordEmptyRecallImpressions,\n identityInjection: {\n mode: identityInjectionModeUsed,\n injectedChars: identityInjectedChars,\n truncated: identityInjectionTruncated,\n },\n })\n .catch((err) => log.debug(`last recall record failed: ${err}`));\n }\n if (sessionKey) {\n this.queueEvalShadowRecall({\n traceId,\n recordedAt: new Date().toISOString(),\n sessionKey,\n promptHash,\n promptLength: prompt.length,\n retrievalQueryHash,\n retrievalQueryLength: retrievalQuery.length,\n recallMode,\n recallResultLimit,\n source: recallSource,\n recalledMemoryCount,\n injected: context.length > 0,\n contextChars: context.length,\n memoryIds: recalledMemoryIds,\n policyVersion,\n identityInjectionMode: identityInjectionModeUsed,\n identityInjectedChars,\n identityInjectionTruncated,\n durationMs: Date.now() - recallStart,\n timings: { ...timings },\n });\n }\n closeProfileTrace();\n this.emitTrace({\n kind: \"recall_summary\",\n traceId,\n operation: \"recall\",\n sessionKey,\n promptHash,\n promptLength: prompt.length,\n retrievalQueryHash,\n retrievalQueryLength: retrievalQuery.length,\n recallMode,\n recallResultLimit,\n qmdEnabled: this.config.qmdEnabled,\n qmdAvailable: this.qmd.isAvailable(),\n recallNamespaces,\n source: recallSource,\n recalledMemoryCount,\n injected: context.length > 0,\n contextChars: context.length,\n policyVersion,\n identityInjectionMode: identityInjectionModeUsed,\n identityInjectedChars,\n identityInjectionTruncated,\n durationMs: Date.now() - recallStart,\n timings: { ...timings },\n recalledContent:\n this.config.traceRecallContent && context.length > 0\n ? context\n : undefined,\n });\n\n return context;\n } finally {\n closeProfileTrace();\n }\n }\n\n async processTurn(\n role: \"user\" | \"assistant\",\n content: string,\n sessionKey?: string,\n options: {\n bufferKey?: string;\n logicalSessionKey?: string;\n providerThreadId?: string | null;\n turnFingerprint?: string;\n persistProcessedFingerprint?: boolean;\n } = {},\n ): Promise<void> {\n if (role !== \"user\" && role !== \"assistant\") {\n log.debug(`processTurn: ignoring unsupported role=${String(role)}`);\n return;\n }\n if (shouldSkipImplicitExtraction(this.config)) {\n log.debug(\n \"processTurn: skipping implicit extraction because captureMode=explicit\",\n );\n return;\n }\n\n const bufferKey =\n typeof options.bufferKey === \"string\" && options.bufferKey.length > 0\n ? options.bufferKey\n : typeof sessionKey === \"string\" && sessionKey.length > 0\n ? sessionKey\n : \"default\";\n const turn: BufferTurn = {\n role,\n content,\n timestamp: new Date().toISOString(),\n sessionKey,\n logicalSessionKey: options.logicalSessionKey ?? bufferKey,\n providerThreadId: options.providerThreadId ?? null,\n turnFingerprint: options.turnFingerprint,\n persistProcessedFingerprint: options.persistProcessedFingerprint === true,\n };\n\n const outcome =\n typeof this.buffer.addTurnWithOutcome === \"function\"\n ? await this.buffer.addTurnWithOutcome(bufferKey, turn)\n : { decision: await this.buffer.addTurn(bufferKey, turn) };\n\n if (outcome.decision === \"keep_buffering\") return;\n await this.queueBufferedExtraction(\n outcome.extractionTurns ?? this.buffer.getTurns(bufferKey),\n \"trigger_mode\",\n { bufferKey },\n );\n }\n\n async flushSession(\n sessionKey: string,\n options: {\n reason: string;\n abortSignal?: AbortSignal;\n bufferKey?: string;\n },\n ): Promise<void> {\n const explicitBufferKey =\n typeof options.bufferKey === \"string\" && options.bufferKey.length > 0\n ? options.bufferKey\n : null;\n const discoveredBufferKeys =\n explicitBufferKey ||\n typeof sessionKey !== \"string\" ||\n sessionKey.length === 0 ||\n typeof this.buffer.findBufferKeysForSession !== \"function\"\n ? []\n : await this.buffer.findBufferKeysForSession(sessionKey);\n const bufferKeys = explicitBufferKey\n ? [explicitBufferKey]\n : discoveredBufferKeys.length > 0\n ? discoveredBufferKeys\n : typeof sessionKey === \"string\" && sessionKey.length > 0\n ? [sessionKey]\n : [\"default\"];\n for (const bufferKey of bufferKeys) {\n const turns = this.buffer.getTurns(bufferKey);\n if (turns.length === 0) continue;\n await new Promise<void>((resolve, reject) => {\n void this\n .queueBufferedExtraction(turns, \"trigger_mode\", {\n bufferKey,\n clearBufferAfterExtraction: true,\n skipDedupeCheck: true,\n abortSignal: options.abortSignal,\n onTaskSettled: (error) => (error ? reject(error) : resolve()),\n })\n .catch(reject);\n });\n }\n }\n\n async ingestReplayBatch(\n turns: ReplayTurn[],\n options: {\n deadlineMs?: number;\n archiveLcm?: boolean;\n abortSignal?: AbortSignal;\n /**\n * Pin extraction writes to this namespace instead of deriving one from\n * `defaultNamespaceForPrincipal(resolvePrincipal(sessionKey))` + the\n * coding overlay (#1495). The access `observe` surface resolves a single\n * effective scope plan and passes its `writeNamespace` here so the\n * extracted memories land in the SAME namespace as LCM archival,\n * objective-state snapshots, and project-scoped recall — without relying\n * on re-deriving the namespace from a namespace-prefixed session key.\n * Same hook bulk-import uses (#460).\n */\n writeNamespaceOverride?: string;\n /**\n * Pin the provenance PRINCIPAL instead of deriving it from\n * `resolvePrincipal(turn.sessionKey)` (#1495 thread 1). The access\n * `observe` surface authenticates the caller at the transport layer and\n * passes its resolved principal here so extracted-memory provenance uses\n * the SAME identity the surface authorized — independent of storage\n * routing (`writeNamespaceOverride`) and of whatever `resolvePrincipal`\n * would parse from the raw session key. Mirrors the recall path's\n * `principalOverride` (issue #570 PR 4).\n */\n principalOverride?: string;\n } = {},\n ): Promise<void> {\n if (!Array.isArray(turns) || turns.length === 0) return;\n if (options.abortSignal?.aborted) {\n throw options.abortSignal.reason instanceof Error\n ? options.abortSignal.reason\n : new Error(\"ingestReplayBatch aborted\");\n }\n if (shouldSkipImplicitExtraction(this.config)) {\n log.debug(\n \"ingestReplayBatch: skipping implicit extraction because captureMode=explicit\",\n );\n return;\n }\n\n const bySession = new Map<string, BufferTurn[]>();\n for (const turn of turns) {\n if (turn.role !== \"user\" && turn.role !== \"assistant\") continue;\n const key = normalizeReplaySessionKey(turn.sessionKey);\n const list = bySession.get(key) ?? [];\n list.push({\n role: turn.role,\n content: turn.content,\n timestamp: turn.timestamp,\n sourceValidAt: turn.sourceValidAt,\n sessionKey: key,\n parts: turn.parts,\n rawContent: turn.rawContent,\n sourceFormat: turn.sourceFormat,\n });\n bySession.set(key, list);\n }\n\n const replaySlices: Array<{\n bufferKey: string;\n order: number;\n targetValidAtMs: number;\n turns: BufferTurn[];\n }> = [];\n for (const [key, sessionTurns] of bySession.entries()) {\n if (sessionTurns.length === 0) continue;\n if (options.abortSignal?.aborted) {\n throw options.abortSignal.reason instanceof Error\n ? options.abortSignal.reason\n : new Error(\"ingestReplayBatch aborted\");\n }\n if (options.archiveLcm !== false && this.lcmEngine?.enabled) {\n await this.lcmEngine.observeMessages(\n key,\n sessionTurns.map((turn) => ({\n role: turn.role,\n content: turn.content,\n parts: turn.parts,\n rawContent: turn.rawContent,\n sourceFormat: turn.sourceFormat,\n })),\n );\n }\n for (const sessionSlice of splitTurnsBySourceValidAt(sessionTurns)) {\n replaySlices.push({\n bufferKey: key,\n order: replaySlices.length,\n targetValidAtMs: targetSourceValidAtSortMs(sessionSlice),\n turns: sessionSlice,\n });\n }\n }\n\n const replayTasks = replaySlices\n .sort((a, b) => {\n if (a.targetValidAtMs < b.targetValidAtMs) return -1;\n if (a.targetValidAtMs > b.targetValidAtMs) return 1;\n if (a.order === b.order) return 0;\n return a.order < b.order ? -1 : 1;\n })\n .map(\n ({ bufferKey, turns: sessionSlice }) =>\n new Promise<void>((resolve, reject) => {\n void this.queueBufferedExtraction(sessionSlice, \"trigger_mode\", {\n skipDedupeCheck: true,\n clearBufferAfterExtraction: false,\n skipCharThreshold: true,\n skipUserTurnThreshold: true,\n bufferKey,\n extractionDeadlineMs: options.deadlineMs,\n abortSignal: options.abortSignal,\n writeNamespaceOverride: options.writeNamespaceOverride,\n principalOverride: options.principalOverride,\n onTaskSettled: (err) => (err ? reject(err) : resolve()),\n }).catch(reject);\n }),\n );\n if (replayTasks.length > 0) {\n const settled = await Promise.allSettled(replayTasks);\n const firstRejected = settled.find(\n (result): result is PromiseRejectedResult =>\n result.status === \"rejected\",\n );\n if (firstRejected) {\n throw firstRejected.reason;\n }\n }\n }\n\n /**\n * Return the namespace that `ingestBulkImportBatch` writes into (#460).\n *\n * Exposed so host CLIs can snapshot the same storage root that extraction\n * actually writes to, avoiding the \"CLI counts files at namespace A while\n * writes land in namespace B\" footgun that a naïve\n * `config.defaultNamespace` snapshot could hit when a namespace policy\n * named `\"default\"` also exists.\n *\n * Today bulk-import is pinned to `config.defaultNamespace`; future\n * per-invocation namespace routing would thread an explicit target here\n * and through `ingestBulkImportBatch`.\n */\n bulkImportWriteNamespace(): string {\n return this.config.defaultNamespace;\n }\n\n /**\n * Lazily-constructed wearables service (Limitless / Bee / Omi\n * transcript ingestion). All wearables surfaces — CLI, MCP tools,\n * HTTP routes — share this one instance so sync state, search, and\n * memory writes stay consistent. Writes are pinned to the same\n * deterministic namespace bulk-import uses.\n */\n getWearablesService(): WearablesService {\n if (!this.wearablesServiceInstance) {\n this.wearablesServiceInstance = new WearablesService({\n config: this.config.wearables,\n getStorage: async () =>\n await this.getStorageForNamespace(this.bulkImportWriteNamespace()),\n extract: (turns) => this.extraction.extract(turns),\n // Smart memoryMode runs candidates through the SAME extraction\n // judge (cache + defer counters included) the live extraction\n // pipeline uses, so wearable facts get identical LLM-as-judge\n // durability gating.\n judgeFacts: (candidates) =>\n judgeFactDurability(\n candidates,\n this.config,\n this.localLlm,\n new FallbackLlmClient(\n this.config.gatewayConfig,\n fallbackLlmRuntimeContextFromConfig(this.config),\n ),\n this.judgeVerdictCache,\n this.judgeDeferCounts,\n ),\n searchBackend: {\n search: async (query, maxResults) => {\n if (!this.qmd.isAvailable()) return null;\n try {\n const results = await this.qmd.search(query, undefined, maxResults);\n return results.map((result) => ({\n path: result.path,\n score: result.score,\n preview: result.snippet,\n }));\n } catch {\n // Backend hiccup → tell the service \"unavailable\" so it\n // runs its bounded scan fallback instead of returning a\n // silent empty result (CLAUDE.md rule 34).\n return null;\n }\n },\n },\n reindexSearch: async () => {\n await this.qmd.update();\n },\n });\n }\n return this.wearablesServiceInstance;\n }\n\n /**\n * Ingest a batch of bulk-import turns (#460). Like ingestReplayBatch, this\n * normalizes user/assistant turns into the extraction buffer and awaits\n * settlement, but it intentionally bypasses the captureMode=\"explicit\"\n * gate because bulk-import is itself an explicit user action — the user\n * ran `bulk-import --source <name> --file ...` and would be surprised to\n * see the command silently no-op when capture is otherwise restricted.\n *\n * Turns with role=\"other\" are skipped (not supported by the extraction\n * pipeline).\n *\n * Two design decisions worth calling out:\n *\n * - **sessionKey is truthy and per-batch-unique.**\n * `ThreadingManager.shouldStartNewThread` only applies the session-key\n * boundary check when `turn.sessionKey` is truthy (threading.ts:82);\n * with an empty string, imported turns could attach to the current\n * live thread or merge across unrelated import batches. A unique\n * `bulk-import:batch:<timestamp>-<rand>` key forces a fresh thread per\n * batch without matching common prefix/map rules in\n * `principalFromSessionKeyRules`. (Catch-all regex rules could still\n * remap the principal, but that only affects metadata provenance —\n * see the next point for why write routing is unaffected.)\n *\n * - **writeNamespaceOverride pins the storage target.**\n * We pass `writeNamespaceOverride: this.bulkImportWriteNamespace()` to\n * `queueBufferedExtraction`, which tells `runExtraction` to skip\n * `defaultNamespaceForPrincipal` and write directly into the\n * orchestrator's declared bulk-import write namespace. This keeps\n * writes deterministic even when namespace policies named `\"default\"`\n * exist alongside a different `config.defaultNamespace`, and also\n * guards against regex-catch-all principal rules steering bulk-import\n * into an unexpected tenant.\n *\n * Per-invocation namespace routing (letting callers target a namespace\n * other than `bulkImportWriteNamespace()`) is a separate feature tracked\n * as a follow-up — the hook is the `writeNamespaceOverride` option, but\n * the CLI surface does not yet expose a `--namespace` flag.\n */\n async ingestBulkImportBatch(\n turns: ImportTurn[],\n options: {\n deadlineMs?: number;\n failOnExtractionFailure?: boolean;\n includeSourceValidAtContext?: boolean;\n } = {},\n ): Promise<BulkImportBatchIngestResult> {\n if (!Array.isArray(turns) || turns.length === 0) {\n return {\n attemptedTurnCount: 0,\n extractionCount: 0,\n persistedCount: 0,\n durableOutputCount: 0,\n skippedCount: 0,\n failedCount: 0,\n postPersistMetadataFailureCount: 0,\n processedTurnCount: 0,\n };\n }\n\n // Per-batch unique sessionKey keeps threading honest without matching\n // typical prefix/map routing rules. Combined with writeNamespaceOverride\n // below, the storage target is independent of principal resolution.\n // Uses crypto.randomBytes (not Math.random) so CodeQL does not flag a\n // security-context insecure-randomness use even though this value never\n // leaves the process; the bytes just need to be collision-resistant\n // across concurrent bulk-import batches.\n const shouldUseStableBatchKey = turns.some(\n (turn) =>\n turn.persistProcessedFingerprint === true ||\n (typeof turn.turnFingerprint === \"string\" &&\n turn.turnFingerprint.length > 0),\n );\n const stableBatchFingerprint = shouldUseStableBatchKey\n ? createHash(\"sha256\")\n .update(\n turns\n .map((turn) =>\n [\n turn.role,\n typeof turn.turnFingerprint === \"string\" &&\n turn.turnFingerprint.length > 0\n ? turn.turnFingerprint\n : turn.content.replace(/\\s+/g, \" \").trim(),\n ].join(\":\"),\n )\n .join(\"\\n\"),\n )\n .digest(\"hex\")\n .slice(0, 32)\n : undefined;\n const sessionKey = stableBatchFingerprint\n ? `bulk-import:batch:${stableBatchFingerprint}`\n : `bulk-import:batch:${Date.now().toString(36)}-${randomBytes(6).toString(\"hex\")}`;\n\n const sessionTurns: BufferTurn[] = [];\n for (const turn of turns) {\n if (turn.role !== \"user\" && turn.role !== \"assistant\") continue;\n sessionTurns.push({\n role: turn.role,\n content: turn.content,\n timestamp: turn.timestamp,\n sourceValidAt: turn.timestamp,\n sessionKey,\n parts: turn.parts,\n rawContent: turn.rawContent,\n sourceFormat: turn.sourceFormat,\n importProvenance: turn.importProvenance,\n turnFingerprint: turn.turnFingerprint,\n persistProcessedFingerprint: turn.persistProcessedFingerprint === true,\n });\n }\n if (sessionTurns.length === 0) {\n return {\n attemptedTurnCount: 0,\n extractionCount: 0,\n persistedCount: 0,\n durableOutputCount: 0,\n skippedCount: 0,\n failedCount: 0,\n postPersistMetadataFailureCount: 0,\n processedTurnCount: 0,\n };\n }\n\n if (this.lcmEngine?.enabled) {\n await this.lcmEngine.observeMessages(\n sessionKey,\n sessionTurns.map((turn) => ({\n role: turn.role,\n content: turn.content,\n parts: turn.parts,\n rawContent: turn.rawContent,\n sourceFormat: turn.sourceFormat,\n })),\n );\n }\n\n const sessionSlices = splitTurnsBySourceValidAt(sessionTurns, {\n includeContext: options.includeSourceValidAtContext !== false,\n });\n const results: ExtractionRunResult[] = [];\n let processedTurnCount = 0;\n let firstRejected: unknown;\n for (const sessionSlice of sessionSlices) {\n try {\n const result = await new Promise<ExtractionRunResult>(\n (resolve, reject) => {\n void this.queueBufferedExtraction(sessionSlice, \"trigger_mode\", {\n skipDedupeCheck: true,\n clearBufferAfterExtraction: false,\n skipCharThreshold: true,\n skipUserTurnThreshold: true,\n bufferKey: sessionKey,\n extractionDeadlineMs: options.deadlineMs,\n failOnExtractionFailure: options.failOnExtractionFailure === true,\n writeNamespaceOverride: this.bulkImportWriteNamespace(),\n onTaskSettled: (err, result) =>\n err\n ? reject(err)\n : resolve(\n result ?? {\n status: \"skipped\",\n reason: \"missing_extraction_result\",\n persistedCount: 0,\n durableOutputCount: 0,\n },\n ),\n }).catch(reject);\n },\n );\n results.push(result);\n processedTurnCount += sessionSlice.filter(\n (turn) => turn.extractionContextOnly !== true,\n ).length;\n } catch (err) {\n firstRejected = err;\n break;\n }\n }\n const rejectedCount = firstRejected ? 1 : 0;\n const ingestResult: BulkImportBatchIngestResult = {\n attemptedTurnCount: sessionTurns.length,\n extractionCount: results.length,\n persistedCount: results.reduce(\n (sum, result) => sum + result.persistedCount,\n 0,\n ),\n durableOutputCount: results.reduce(\n (sum, result) => sum + result.durableOutputCount,\n 0,\n ),\n skippedCount: results.filter((result) => result.status === \"skipped\").length,\n failedCount: rejectedCount,\n postPersistMetadataFailureCount: results.filter(\n (result) => result.postPersistMetadataFailed === true,\n ).length,\n processedTurnCount:\n rejectedCount === 0 ? sessionTurns.length : processedTurnCount,\n };\n if (firstRejected) {\n if (processedTurnCount > 0) {\n throw new BulkImportBatchPartialFailureError(\n \"bulk import failed after partial processing\",\n ingestResult,\n firstRejected,\n );\n }\n throw firstRejected;\n }\n return ingestResult;\n }\n\n async observeSessionHeartbeat(\n sessionKey: string,\n options: { bufferKey?: string } = {},\n ): Promise<void> {\n if (this.config.sessionObserverEnabled !== true) return;\n if (!sessionKey || sessionKey.length === 0) return;\n\n const bufferKey =\n typeof options.bufferKey === \"string\" && options.bufferKey.length > 0\n ? options.bufferKey\n : sessionKey;\n const previous =\n this.heartbeatObserverChains.get(sessionKey) ?? Promise.resolve();\n const next = previous\n .catch(() => undefined)\n .then(async () => {\n const turns = this.buffer.getTurns(bufferKey);\n if (turns.length === 0) return;\n const normalizedSessionKey = normalizeReplaySessionKey(sessionKey);\n const allowSharedSessionBuffer = bufferKey.startsWith(\n CODEX_THREAD_KEY_PREFIX,\n );\n if (\n !allowSharedSessionBuffer &&\n turns.some(\n (turn) =>\n turn.sessionKey &&\n normalizeReplaySessionKey(turn.sessionKey) !== normalizedSessionKey,\n )\n ) {\n log.debug(\n `heartbeat observer skipped: mixed-session buffer contents for ${bufferKey}`,\n );\n return;\n }\n if (!this.shouldQueueExtraction(turns, {\n commit: false,\n bufferKey,\n })) {\n log.debug(\n `heartbeat observer skipped: extraction dedupe for ${bufferKey}`,\n );\n return;\n }\n const footprint =\n await this.transcript.estimateSessionFootprint(sessionKey);\n const decision = await this.sessionObserver.observe({\n sessionKey,\n totalBytes: footprint.bytes,\n totalTokens: footprint.tokens,\n });\n if (!decision.triggered) return;\n log.debug(\n `heartbeat observer trigger: session=${sessionKey} deltaBytes=${decision.deltaBytes} deltaTokens=${decision.deltaTokens}`,\n );\n await this.queueBufferedExtraction(turns, \"heartbeat_observer\", {\n bufferKey,\n });\n });\n\n this.heartbeatObserverChains.set(sessionKey, next);\n try {\n await next;\n } finally {\n if (this.heartbeatObserverChains.get(sessionKey) === next) {\n this.heartbeatObserverChains.delete(sessionKey);\n }\n }\n }\n\n private async queueBufferedExtraction(\n turnsToExtract: BufferTurn[],\n reason: \"trigger_mode\" | \"heartbeat_observer\",\n options: {\n skipDedupeCheck?: boolean;\n clearBufferAfterExtraction?: boolean;\n skipCharThreshold?: boolean;\n skipUserTurnThreshold?: boolean;\n extractionDeadlineMs?: number;\n failOnExtractionFailure?: boolean;\n onTaskSettled?: (\n error?: unknown,\n result?: ExtractionRunResult,\n ) => void;\n bufferKey?: string;\n abortSignal?: AbortSignal;\n /**\n * Explicit namespace override for the write path (#460). When set,\n * `runExtraction` writes to this namespace instead of deriving one\n * from `defaultNamespaceForPrincipal(resolvePrincipal(sessionKey))`.\n * Used by bulk-import to pin writes to a deterministic namespace\n * regardless of user-configured principal routing rules.\n */\n writeNamespaceOverride?: string;\n /**\n * Pin the provenance principal (#1495 thread 1). Forwarded to\n * `runExtraction` so access `observe` can record provenance under the\n * authenticated principal instead of `resolvePrincipal(sessionKey)`.\n */\n principalOverride?: string;\n } = {},\n ): Promise<void> {\n const bufferKey = options.bufferKey ?? turnsToExtract[0]?.sessionKey ?? \"default\";\n if (\n !options.skipDedupeCheck &&\n !this.shouldQueueExtraction(turnsToExtract, { bufferKey })\n ) {\n log.debug(`extraction dedupe skip: preserving buffer (${reason})`);\n options.onTaskSettled?.(undefined, {\n status: \"skipped\",\n reason: \"dedupe\",\n persistedCount: 0,\n durableOutputCount: 0,\n });\n return;\n }\n\n const extractionDeadlineMs =\n typeof options.extractionDeadlineMs === \"number\" &&\n Number.isFinite(options.extractionDeadlineMs)\n ? options.extractionDeadlineMs\n : undefined;\n let timeout: ReturnType<typeof setTimeout> | undefined;\n let settled = false;\n const clearQueueWaitTimer = (): void => {\n if (timeout) {\n clearTimeout(timeout);\n timeout = undefined;\n }\n };\n const settleTask = (\n error?: unknown,\n result?: ExtractionRunResult,\n ): boolean => {\n if (settled) return false;\n settled = true;\n clearQueueWaitTimer();\n options.onTaskSettled?.(error, result);\n return true;\n };\n\n if (typeof extractionDeadlineMs === \"number\") {\n const remainingMs = extractionDeadlineMs - Date.now();\n if (remainingMs <= 0) {\n settleTask(new Error(\"replay extraction deadline exceeded (queue_wait)\"));\n return;\n }\n timeout = setTimeout(() => {\n settleTask(new Error(\"replay extraction deadline exceeded (queue_wait)\"));\n }, remainingMs);\n }\n\n this.extractionQueue.push(async () => {\n if (settled) return;\n if (\n typeof extractionDeadlineMs === \"number\" &&\n extractionDeadlineMs <= Date.now()\n ) {\n settleTask(new Error(\"replay extraction deadline exceeded (queue_wait)\"));\n return;\n }\n clearQueueWaitTimer();\n try {\n const result = await this.runExtraction(turnsToExtract, {\n clearBufferAfterExtraction:\n options.clearBufferAfterExtraction ?? true,\n skipCharThreshold: options.skipCharThreshold ?? false,\n skipUserTurnThreshold: options.skipUserTurnThreshold ?? false,\n deadlineMs: extractionDeadlineMs,\n bufferKey,\n abortSignal: options.abortSignal,\n failOnExtractionFailure: options.failOnExtractionFailure === true,\n writeNamespaceOverride: options.writeNamespaceOverride,\n principalOverride: options.principalOverride,\n });\n settleTask(undefined, result);\n } catch (err) {\n if (settleTask(err)) {\n throw err;\n }\n }\n });\n\n if (!this.queueProcessing) {\n this.queueProcessing = true;\n this.processQueue().catch((err) => {\n this.logExtractionQueueFailure(err, \"processor\");\n this.queueProcessing = false;\n });\n }\n log.debug(`queued extraction from ${reason}`);\n }\n\n private normalizeExtractionFingerprintTurns(turns: BufferTurn[]): string[] {\n if (!Array.isArray(turns) || turns.length === 0) return [];\n return turns\n .filter((turn) => turn.role === \"user\" || turn.role === \"assistant\")\n .map((turn) => {\n if (\n typeof turn.turnFingerprint === \"string\" &&\n turn.turnFingerprint.length > 0\n ) {\n return `fp:${turn.turnFingerprint}`;\n }\n return `${turn.role}:${(turn.content ?? \"\").replace(/\\s+/g, \" \").trim().slice(0, this.config.extractionMaxTurnChars)}`;\n })\n .filter((value) => value.length > 0);\n }\n\n private buildExtractionFingerprint(\n turns: BufferTurn[],\n bufferKey: string,\n ): string | null {\n const normalized = this.normalizeExtractionFingerprintTurns(turns).join(\"\\n\");\n if (!normalized) return null;\n return createHash(\"sha256\")\n .update(`${bufferKey}\\n${normalized}`)\n .digest(\"hex\");\n }\n\n private shouldQueueExtraction(\n turns: BufferTurn[],\n options: { commit?: boolean; bufferKey?: string } = {},\n ): boolean {\n if (!this.config.extractionDedupeEnabled) return true;\n if (!Array.isArray(turns) || turns.length === 0) return false;\n\n const bufferKey = options.bufferKey ?? turns[0]?.sessionKey ?? \"default\";\n const fingerprint = this.buildExtractionFingerprint(turns, bufferKey);\n if (!fingerprint) return false;\n const now = Date.now();\n const seenAt = this.recentExtractionFingerprints.get(fingerprint);\n if (seenAt && now - seenAt < this.config.extractionDedupeWindowMs) {\n log.debug(\"extraction dedupe: skipped duplicate buffered turn set\");\n return false;\n }\n\n if (options.commit !== false) {\n this.recentExtractionFingerprints.set(fingerprint, now);\n }\n // Keep this cache bounded to avoid unbounded growth.\n if (\n options.commit !== false &&\n this.recentExtractionFingerprints.size > 200\n ) {\n const entries = Array.from(\n this.recentExtractionFingerprints.entries(),\n ).sort((a, b) => a[1] - b[1]);\n for (const [key] of entries.slice(0, entries.length - 200)) {\n this.recentExtractionFingerprints.delete(key);\n }\n }\n\n return true;\n }\n\n /**\n * Background serial queue processor.\n * Processes extractions one at a time to avoid race conditions.\n * Called automatically when items are queued.\n */\n private async processQueue(): Promise<void> {\n while (this.extractionQueue.length > 0) {\n const task = this.extractionQueue.shift();\n if (task) {\n try {\n await task();\n } catch (err) {\n this.logExtractionQueueFailure(err, \"task\");\n }\n }\n }\n\n this.queueProcessing = false;\n }\n\n /**\n * Classify + log a failure from either the per-task catch inside\n * `processQueue()` or the outer `processQueue().catch(...)` in\n * `queueBufferedExtraction()`. Issue #549: `throwIfRecallAborted`\n * (used throughout `runExtraction`) raises an Error whose `name` is\n * `\"AbortError\"`. That path fires when `before_reset` aborts a\n * queued task to avoid duplicate extraction — it is intentional\n * cancellation, not a failure. Downgrading the log to debug\n * prevents spurious `error`-level lines that routinely appear\n * right next to a successful `persisted: N facts, M entities` log\n * and that confuse operators into thinking extraction is broken.\n * Genuine extraction failures (network, parse, I/O) still log at\n * `error`.\n *\n * Source differentiates the two call sites so the log message\n * names the right layer (`task` vs `processor`).\n */\n private logExtractionQueueFailure(\n err: unknown,\n source: \"task\" | \"processor\",\n ): void {\n const aborted =\n source === \"task\"\n ? \"background extraction task aborted (session transition)\"\n : \"background extraction queue processor aborted (session transition)\";\n const failed =\n source === \"task\"\n ? \"background extraction task failed\"\n : \"background extraction queue processor failed\";\n if (isAbortError(err)) {\n log.debug(aborted);\n } else {\n log.error(failed, err);\n }\n }\n\n private async runExtraction(\n turns: BufferTurn[],\n options: {\n clearBufferAfterExtraction?: boolean;\n skipCharThreshold?: boolean;\n skipUserTurnThreshold?: boolean;\n deadlineMs?: number;\n bufferKey?: string;\n abortSignal?: AbortSignal;\n failOnExtractionFailure?: boolean;\n /**\n * Explicit namespace override for the write path (#460). When set,\n * extraction writes go to this namespace instead of the one derived\n * from `defaultNamespaceForPrincipal(resolvePrincipal(sessionKey))`.\n * The resolved `principal` is still threaded into memory metadata\n * for provenance; only the storage target is overridden.\n */\n writeNamespaceOverride?: string;\n /**\n * Pin the provenance principal instead of deriving it from\n * `resolvePrincipal(sessionKey)` (#1495 thread 1). When set, this is the\n * identity an access surface already authenticated; used so observed-turn\n * provenance is correct even though `turn.sessionKey` is the ORIGINAL\n * (un-prefixed) key and storage is pinned via `writeNamespaceOverride`.\n */\n principalOverride?: string;\n } = {},\n ): Promise<ExtractionRunResult> {\n log.debug(`running extraction on ${turns.length} turns`);\n const clearBufferAfterExtraction =\n options.clearBufferAfterExtraction ?? true;\n const skipCharThreshold = options.skipCharThreshold ?? false;\n const skipUserTurnThreshold = options.skipUserTurnThreshold ?? false;\n const deadlineMs =\n typeof options.deadlineMs === \"number\" &&\n Number.isFinite(options.deadlineMs)\n ? options.deadlineMs\n : undefined;\n const bufferKey = options.bufferKey ?? turns[0]?.sessionKey ?? \"default\";\n const throwIfDeadlineExceeded = (stage: string): void => {\n if (typeof deadlineMs === \"number\" && Date.now() > deadlineMs) {\n throw new Error(`replay extraction deadline exceeded (${stage})`);\n }\n };\n const throwIfAborted = (stage: string): void => {\n throwIfRecallAborted(options.abortSignal, `extraction aborted (${stage})`);\n };\n const clearBuffer = async (options?: { ignoreAbort?: boolean }) => {\n if (options?.ignoreAbort !== true) {\n throwIfAborted(\"before_clear_buffer\");\n }\n if (clearBufferAfterExtraction) {\n await this.buffer.clearAfterExtraction(bufferKey, turns);\n }\n };\n\n // Skip extraction for cron job sessions - these are system operations, not user conversations\n const sessionKey = turns[0]?.sessionKey ?? \"\";\n if (sessionKey.includes(\":cron:\")) {\n log.debug(`skipping extraction for cron session: ${sessionKey}`);\n await clearBuffer();\n return {\n status: \"skipped\",\n reason: \"cron_session\",\n persistedCount: 0,\n durableOutputCount: 0,\n };\n }\n\n const normalizedTurns = turns\n .filter(\n (t) =>\n (t.role === \"user\" || t.role === \"assistant\") &&\n typeof t.content === \"string\",\n )\n .map((t) => ({\n ...t,\n content: t.content.trim().slice(0, this.config.extractionMaxTurnChars),\n }))\n .filter((t) => t.content.length > 0);\n const targetTurns = normalizedTurns.filter(\n (turn) => turn.extractionContextOnly !== true,\n );\n if (targetTurns.length === 0) {\n log.debug(\"skipping extraction: no non-context turns after normalization\");\n await clearBuffer();\n return {\n status: \"skipped\",\n reason: \"empty_normalized_turns\",\n persistedCount: 0,\n durableOutputCount: 0,\n };\n }\n const sourceValidAt = latestSourceValidAtFromTurns(targetTurns);\n throwIfDeadlineExceeded(\"before_extract\");\n throwIfAborted(\"before_extract\");\n\n const userTurns = targetTurns.filter((t) => t.role === \"user\");\n const totalChars = targetTurns.reduce(\n (sum, t) => sum + t.content.length,\n 0,\n );\n const belowCharThreshold = totalChars < this.config.extractionMinChars;\n const belowUserTurnThreshold =\n !skipUserTurnThreshold &&\n userTurns.length < this.config.extractionMinUserTurns;\n if ((!skipCharThreshold && belowCharThreshold) || belowUserTurnThreshold) {\n log.debug(\n `skipping extraction: below threshold (totalChars=${totalChars}, userTurns=${userTurns.length})`,\n );\n await clearBuffer();\n return {\n status: \"skipped\",\n reason: \"below_threshold\",\n persistedCount: 0,\n durableOutputCount: 0,\n };\n }\n\n // Provenance principal honours the access-surface override (#1495 thread 1,\n // mirroring the recall path's `principalOverride`, issue #570 PR 4). Access\n // surfaces that authenticated the caller at the transport layer pass their\n // resolved principal so provenance uses the SAME identity the surface\n // authorized, instead of `resolvePrincipal(sessionKey)` — which on a\n // namespace-prefixed key would collapse to `default`. The ORIGINAL,\n // un-prefixed session key still drives threading.\n const principal =\n typeof options.principalOverride === \"string\" &&\n options.principalOverride.length > 0\n ? options.principalOverride\n : resolvePrincipal(sessionKey, this.config);\n // Write path — explicit callers still win. Otherwise, an active hosted\n // scope profile owns the extraction write target so hook-captured turns land\n // in the same layer that profile recall searches. Without a profile, preserve\n // the existing coding-agent overlay behavior (issue #569).\n const explicitWriteNamespace =\n typeof options.writeNamespaceOverride === \"string\" &&\n options.writeNamespaceOverride.length > 0\n ? options.writeNamespaceOverride\n : undefined;\n const codingContextForWrite = sessionKey\n ? this.getCodingContextForSession(sessionKey)\n : null;\n const codingOverlayForWrite = resolveCodingNamespaceOverlay(\n codingContextForWrite,\n this.config.codingMode,\n this.config.defaultNamespace,\n );\n const scopeProfileGatePlan = resolveScopeProfilePlan({\n config: this.config,\n principal,\n codingContext: codingContextForWrite,\n codingOverlay: codingOverlayForWrite,\n });\n const scopeProfileWritePlan = explicitWriteNamespace ? null : scopeProfileGatePlan;\n if (scopeProfileWritePlan) {\n const selectedLayer = scopeProfileWritePlan.layers.find(\n (layer) => layer.id === scopeProfileWritePlan.writeLayer,\n );\n const writeNamespaceReadable = scopeProfileWritePlan.readNamespaces.includes(\n scopeProfileWritePlan.writeNamespace,\n );\n if (!selectedLayer?.writable || !writeNamespaceReadable) {\n log.warn(\n `runExtraction: skipping scope profile ${scopeProfileWritePlan.profileId} because write layer ${scopeProfileWritePlan.writeLayer} is not writable inside the profile read stack`,\n );\n await clearBuffer();\n return {\n status: \"skipped\",\n reason: \"scope_profile_no_writable_layer\",\n persistedCount: 0,\n durableOutputCount: 0,\n };\n }\n }\n const selfNamespace =\n explicitWriteNamespace ??\n scopeProfileWritePlan?.writeNamespace ??\n this.applyCodingNamespaceOverlay(\n sessionKey,\n defaultNamespaceForPrincipal(principal, this.config),\n );\n const storage = await this.storageRouter.storageFor(selfNamespace);\n const shouldPersistProcessedFingerprint = targetTurns.some(\n (turn) => turn.persistProcessedFingerprint === true,\n );\n const extractionFingerprint = this.buildExtractionFingerprint(\n targetTurns,\n bufferKey,\n );\n let meta =\n extractionFingerprint && shouldPersistProcessedFingerprint\n ? await storage.loadMeta()\n : null;\n if (\n extractionFingerprint &&\n shouldPersistProcessedFingerprint &&\n (meta?.processedExtractionFingerprints ?? []).some(\n (entry) => entry.fingerprint === extractionFingerprint,\n )\n ) {\n log.debug(\n `runExtraction: skipping already-processed extraction fingerprint for ${bufferKey}`,\n );\n await clearBuffer();\n return {\n status: \"skipped\",\n reason: \"processed_fingerprint\",\n persistedCount: 0,\n durableOutputCount: 0,\n };\n }\n\n // Pass existing entity names so the LLM can reuse them instead of inventing variants\n const existingEntities = await storage.listEntityNames();\n const result = await raceRecallAbort(\n this.extraction.extract(\n normalizedTurns,\n existingEntities,\n ),\n options.abortSignal,\n \"extraction aborted (during_extract)\",\n );\n throwIfDeadlineExceeded(\"before_persist\");\n throwIfAborted(\"before_persist\");\n\n // Defensive: validate extraction result before processing. Explicit\n // fail-closed callers, such as flush-plan import, must not observe\n // malformed extractor output as a successful skip.\n if (!result) {\n log.warn(\"runExtraction: extraction returned null/undefined\");\n if (options.failOnExtractionFailure) {\n throw new Error(\"extraction failed: invalid_extraction_result\");\n }\n await clearBuffer();\n return {\n status: \"skipped\",\n reason: \"invalid_extraction_result\",\n persistedCount: 0,\n durableOutputCount: 0,\n };\n }\n const invalidExtractionResultFields = [\n [\"facts\", result.facts],\n [\"entities\", result.entities],\n [\"questions\", result.questions],\n [\"profileUpdates\", result.profileUpdates],\n ]\n .filter(([, value]) => !Array.isArray(value))\n .map(([field]) => field);\n if (invalidExtractionResultFields.length > 0) {\n log.warn(\n \"runExtraction: extraction returned invalid collection fields\",\n {\n invalidFields: invalidExtractionResultFields,\n resultKeys:\n typeof result === \"object\" && result !== null\n ? Object.keys(result)\n : [],\n },\n );\n if (options.failOnExtractionFailure) {\n throw new Error(\"extraction failed: invalid_extraction_result\");\n }\n await clearBuffer();\n return {\n status: \"skipped\",\n reason: \"invalid_extraction_result\",\n persistedCount: 0,\n durableOutputCount: 0,\n };\n }\n const extractionFailure =\n typeof result.extractionFailure === \"string\" &&\n result.extractionFailure.trim().length > 0\n ? result.extractionFailure\n : undefined;\n if (options.failOnExtractionFailure && extractionFailure) {\n throw new Error(`extraction failed: ${extractionFailure}`);\n }\n if (\n result.facts.length === 0 &&\n result.entities.length === 0 &&\n result.questions.length === 0 &&\n result.profileUpdates.length === 0\n ) {\n log.debug(\n \"runExtraction: extraction produced no durable outputs; skipping persistence\",\n );\n if (extractionFailure) {\n log.warn(\n \"runExtraction: extraction reported failure with no durable outputs; not marking fingerprint processed\",\n { extractionFailure },\n );\n }\n if (\n extractionFingerprint &&\n shouldPersistProcessedFingerprint &&\n !extractionFailure\n ) {\n meta ??= await storage.loadMeta();\n await this.recordProcessedExtractionFingerprint(\n storage,\n extractionFingerprint,\n meta,\n );\n meta.extractionCount += 1;\n meta.lastExtractionAt = new Date().toISOString();\n await storage.saveMeta(meta);\n }\n await clearBuffer();\n return {\n status: \"skipped\",\n reason: \"empty_extraction_result\",\n persistedCount: 0,\n durableOutputCount: 0,\n };\n }\n\n let threadIdForExtraction: string | null = null;\n if (this.config.threadingEnabled && turns.length > 0) {\n const lastTurn = turns[turns.length - 1];\n try {\n threadIdForExtraction = await this.threading.processTurn(lastTurn, []);\n } catch (err) {\n // Fail-open: threading errors must not block memory persistence.\n log.warn(\n \"[threading] processTurn failed before persistence (non-fatal)\",\n err,\n );\n }\n }\n\n const persistedIds = await this.persistExtraction(\n result,\n storage,\n threadIdForExtraction,\n { sessionKey, principal, validAt: sourceValidAt },\n // Pass the KNOWN base namespace (NHIdx) so the catalog write touch records the\n // real namespace rather than a guess decoded from the storage dir.\n selfNamespace,\n scopeProfileGatePlan,\n );\n let postPersistMetadataFailed = false;\n meta ??= await storage.loadMeta();\n if (extractionFingerprint && shouldPersistProcessedFingerprint) {\n try {\n await this.recordProcessedExtractionFingerprint(\n storage,\n extractionFingerprint,\n meta,\n );\n } catch (error) {\n log.warn(\n \"runExtraction: failed to persist processed extraction fingerprint; continuing with buffer clear\",\n error,\n );\n postPersistMetadataFailed = true;\n }\n }\n // Persist extraction counters and processed fingerprints before running\n // follow-on helpers so replay dedupe survives any later non-essential\n // failure. If this aggregate meta write fails, still clear the buffer:\n // the durable memories are already written and replaying the same turns\n // would duplicate them.\n meta.extractionCount += 1;\n meta.lastExtractionAt = new Date().toISOString();\n meta.totalMemories += Array.isArray(result?.facts)\n ? result.facts.length\n : 0;\n meta.totalEntities += Array.isArray(result?.entities)\n ? result.entities.length\n : 0;\n try {\n await storage.saveMeta(meta);\n } catch (error) {\n log.warn(\n \"runExtraction: failed to save extraction metadata after durable persistence; continuing with buffer clear\",\n error,\n );\n postPersistMetadataFailed = true;\n }\n\n const durableOutputCount =\n result.facts.length +\n result.entities.length +\n result.questions.length +\n result.profileUpdates.length;\n\n // Buffer retention for defer verdicts (issue #562, PR 2). When the judge\n // deferred at least one candidate, retain the tail of the current turn\n // window so the next extraction pass has the surrounding context that\n // may disambiguate the deferred fact. Non-defer runs clear the slot.\n //\n // Gated on:\n // - `clearBufferAfterExtraction` — replay / bulk-import paths call\n // `runExtraction` with this false and do not operate on live buffer\n // state. Writing retention there would create synthetic buffer\n // entries and cross-contaminate future live extractions.\n // - NOT `extractionJudgeShadow` — in shadow mode the judge is only\n // advisory; facts are still persisted regardless of verdict, so\n // retaining the turn window on top of a persisted write would both\n // waste buffer space and cause the same facts to re-enter the\n // pipeline on the next pass.\n try {\n if (\n clearBufferAfterExtraction &&\n !this.config.extractionJudgeShadow\n ) {\n const deferredCount = this.lastPersistExtractionDeferredCount;\n if (deferredCount > 0 && normalizedTurns.length > 0) {\n await this.buffer.retainDeferredTurns(\n bufferKey,\n normalizedTurns as BufferTurn[],\n 10,\n );\n } else {\n await this.buffer.retainDeferredTurns(bufferKey, [], 0);\n }\n }\n } catch (err) {\n // Fail-open: retention is a nice-to-have. If it fails the judge will\n // still cap deferrals and convert to reject on the next pass.\n log.debug(\n `extraction-judge: defer retention failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n\n await clearBuffer({ ignoreAbort: true });\n\n // Build memory box from this extraction (v8.0 Phase 2A)\n // Topics are derived from the current extraction's facts and entities only —\n // not from readAllMemories() — so box topics accurately reflect the current\n // session window and the call is free of expensive full-corpus I/O.\n if (this.config.memoryBoxesEnabled && persistedIds.length > 0) {\n const extractionTopics = deriveTopicsFromExtraction(result);\n // Derive episodic metadata from buffer turns (REMem-inspired)\n const firstUserTurn = turns.find((t) => t.role === \"user\");\n const boxGoal =\n firstUserTurn?.content?.slice(0, 100)?.trim() || undefined;\n await this.boxBuilderFor(storage)\n .onExtraction({\n topics: extractionTopics,\n memoryIds: persistedIds,\n timestamp: new Date().toISOString(),\n goal: boxGoal,\n })\n .catch((err) =>\n log.warn(\"[boxes] onExtraction failed (non-fatal)\", err),\n );\n }\n\n // Batch-append persisted IDs so non-fact memories (entities/questions) are\n // always attached to the thread.\n if (\n this.config.threadingEnabled &&\n threadIdForExtraction &&\n persistedIds.length > 0\n ) {\n try {\n await this.threading.appendEpisodeIds(\n threadIdForExtraction,\n persistedIds,\n );\n } catch (err) {\n log.warn(\n \"[threading] appendEpisodeIds failed after persistence (non-fatal)\",\n err,\n );\n }\n }\n\n // Thread title update for the already-established thread context.\n if (this.config.threadingEnabled && threadIdForExtraction) {\n const conversationContent = turns.map((t) => t.content).join(\" \");\n try {\n await this.threading.updateThreadTitle(\n threadIdForExtraction,\n conversationContent,\n );\n } catch (err) {\n log.warn(\n \"[threading] updateThreadTitle failed after persistence (non-fatal)\",\n err,\n );\n }\n }\n\n // Check if consolidation is needed (debounced + non-zero gated).\n const nonZeroExtraction = durableOutputCount > 0;\n try {\n if (nonZeroExtraction) this.nonZeroExtractionsSinceConsolidation += 1;\n this.maybeScheduleConsolidation(nonZeroExtraction);\n } catch (err) {\n log.warn(\n \"runExtraction: consolidation scheduling failed after persistence (non-fatal)\",\n err,\n );\n }\n\n try {\n this.requestQmdMaintenance();\n } catch (err) {\n log.warn(\n \"runExtraction: QMD maintenance scheduling failed after persistence (non-fatal)\",\n err,\n );\n }\n\n try {\n await this.runTierMigrationCycle(storage, \"extraction\");\n } catch (err) {\n log.warn(\n \"runExtraction: tier migration failed after persistence (non-fatal)\",\n err,\n );\n }\n\n return {\n status: \"completed\",\n persistedCount: persistedIds.length,\n durableOutputCount,\n postPersistMetadataFailed,\n };\n }\n\n private async recordProcessedExtractionFingerprint(\n storage: StorageManager,\n fingerprint: string,\n preloadedMeta?: Awaited<ReturnType<StorageManager[\"loadMeta\"]>>,\n ): Promise<void> {\n const meta = preloadedMeta ?? (await storage.loadMeta());\n const observedAt = new Date().toISOString();\n const seen = new Map(\n (meta.processedExtractionFingerprints ?? []).map((entry) => [\n entry.fingerprint,\n entry.observedAt,\n ]),\n );\n seen.set(fingerprint, observedAt);\n meta.processedExtractionFingerprints = Array.from(seen.entries())\n .map(([value, at]) => ({ fingerprint: value, observedAt: at }))\n .sort((left, right) => left.observedAt.localeCompare(right.observedAt))\n .slice(-500);\n if (!preloadedMeta) {\n await storage.saveMeta(meta);\n }\n }\n\n private async runTierMigrationCycle(\n storage: StorageManager,\n trigger: \"extraction\" | \"maintenance\" | \"manual\",\n options?: {\n dryRun?: boolean;\n limitOverride?: number;\n force?: boolean;\n },\n ): Promise<TierMigrationCycleSummary> {\n const dryRun = options?.dryRun === true;\n const persistSkipped = options?.force === true || trigger === \"manual\";\n if (!this.config.qmdTierMigrationEnabled && options?.force !== true) {\n const skipped: TierMigrationCycleSummary = {\n trigger,\n scanned: 0,\n migrated: 0,\n promoted: 0,\n demoted: 0,\n limit: 0,\n dryRun,\n skipped: \"tier_migration_disabled\",\n };\n if (persistSkipped) await this.tierMigrationStatus.recordCycle(skipped);\n return skipped;\n }\n if (\n trigger === \"maintenance\" &&\n !this.config.qmdTierAutoBackfillEnabled &&\n options?.force !== true\n ) {\n const skipped: TierMigrationCycleSummary = {\n trigger,\n scanned: 0,\n migrated: 0,\n promoted: 0,\n demoted: 0,\n limit: 0,\n dryRun,\n skipped: \"maintenance_backfill_disabled\",\n };\n if (persistSkipped) await this.tierMigrationStatus.recordCycle(skipped);\n return skipped;\n }\n if (this.tierMigrationInFlight) {\n const skipped: TierMigrationCycleSummary = {\n trigger,\n scanned: 0,\n migrated: 0,\n promoted: 0,\n demoted: 0,\n limit: 0,\n dryRun,\n skipped: \"migration_in_flight\",\n };\n if (persistSkipped) await this.tierMigrationStatus.recordCycle(skipped);\n return skipped;\n }\n\n const budgetTrigger = trigger === \"manual\" ? \"maintenance\" : trigger;\n const budget =\n this.compounding?.tierMigrationCycleBudget(budgetTrigger) ??\n defaultTierMigrationCycleBudget(this.config, budgetTrigger);\n const limit =\n options?.limitOverride !== undefined\n ? Math.max(0, Math.floor(options.limitOverride))\n : budget.limit;\n const nowMs = Date.now();\n if (\n options?.force !== true &&\n nowMs - this.lastTierMigrationRunAtMs < budget.minIntervalMs\n ) {\n const skipped: TierMigrationCycleSummary = {\n trigger,\n scanned: 0,\n migrated: 0,\n promoted: 0,\n demoted: 0,\n limit,\n dryRun,\n skipped: \"min_interval\",\n };\n if (persistSkipped) await this.tierMigrationStatus.recordCycle(skipped);\n return skipped;\n }\n\n const policy = applyUtilityPromotionRuntimePolicy(\n {\n enabled: this.config.qmdTierMigrationEnabled,\n demotionMinAgeDays: this.config.qmdTierDemotionMinAgeDays,\n demotionValueThreshold: this.config.qmdTierDemotionValueThreshold,\n promotionValueThreshold: this.config.qmdTierPromotionValueThreshold,\n },\n this.utilityRuntimeValues,\n );\n\n this.tierMigrationInFlight = true;\n try {\n const coldStorage = new StorageManager(path.join(storage.dir, \"cold\"));\n const [hotMemories, coldMemories] = await Promise.all([\n storage.readAllMemories(),\n coldStorage.readAllMemories(),\n ]);\n const now = new Date();\n const scanLimit = Math.max(0, Math.floor(budget.scanLimit));\n const hotScanLimit = Math.min(\n hotMemories.length,\n Math.ceil(scanLimit * 0.75),\n );\n const coldScanLimit = Math.min(\n coldMemories.length,\n Math.max(0, scanLimit - hotScanLimit),\n );\n const toTimestamp = (memory: MemoryFile): number =>\n Date.parse(memory.frontmatter.updated ?? memory.frontmatter.created);\n const hotCandidates = hotMemories\n .map((memory) => ({ memory, tier: \"hot\" as MemoryTier }))\n .sort((a, b) => toTimestamp(a.memory) - toTimestamp(b.memory))\n .slice(0, hotScanLimit);\n const coldCandidates = coldMemories\n .map((memory) => ({ memory, tier: \"cold\" as MemoryTier }))\n .sort((a, b) => toTimestamp(b.memory) - toTimestamp(a.memory))\n .slice(0, coldScanLimit);\n const candidates = [...hotCandidates, ...coldCandidates];\n\n const migration = new TierMigrationExecutor({\n storage,\n qmd: this.qmd,\n hotCollection: this.config.qmdCollection,\n coldCollection:\n this.config.qmdColdCollection ?? `${this.config.qmdCollection}-cold`,\n autoEmbed: this.config.qmdAutoEmbedEnabled,\n });\n\n let migrated = 0;\n let promoted = 0;\n let demoted = 0;\n for (const candidate of candidates) {\n if (migrated >= limit) break;\n const decision = decideTierTransition(\n candidate.memory,\n candidate.tier,\n policy,\n now,\n );\n if (!decision.changed) continue;\n\n if (!dryRun) {\n const res = await migration.migrateMemory({\n memory: candidate.memory,\n fromTier: candidate.tier,\n toTier: decision.nextTier,\n reason: `${trigger}:${decision.reason}`,\n });\n if (!res.changed) continue;\n }\n migrated += 1;\n if (decision.nextTier === \"cold\") demoted += 1;\n if (decision.nextTier === \"hot\") promoted += 1;\n }\n\n if (!dryRun) this.lastTierMigrationRunAtMs = Date.now();\n log.debug(\n `tier migration cycle completed: trigger=${trigger} scanned=${candidates.length} migrated=${migrated} limit=${limit}${dryRun ? \" dryRun=true\" : \"\"}`,\n );\n const summary: TierMigrationCycleSummary = {\n trigger,\n scanned: candidates.length,\n migrated,\n promoted,\n demoted,\n limit,\n dryRun,\n };\n const shouldPersistCycle = trigger === \"manual\" || migrated > 0;\n if (shouldPersistCycle)\n await this.tierMigrationStatus.recordCycle(summary);\n return summary;\n } catch (err) {\n this.lastTierMigrationRunAtMs = Date.now();\n log.warn(`tier migration cycle failed (${trigger}, fail-open): ${err}`);\n const failed: TierMigrationCycleSummary = {\n trigger,\n scanned: 0,\n migrated: 0,\n promoted: 0,\n demoted: 0,\n limit,\n dryRun,\n errorCount: 1,\n };\n await this.tierMigrationStatus.recordCycle(failed);\n return failed;\n } finally {\n this.tierMigrationInFlight = false;\n }\n }\n\n async getTierMigrationStatus(): Promise<TierMigrationStatusSnapshot> {\n return this.tierMigrationStatus.get();\n }\n\n async runTierMigrationNow(options?: {\n dryRun?: boolean;\n limit?: number;\n }): Promise<TierMigrationCycleSummary> {\n return this.runTierMigrationCycle(this.storage, \"manual\", {\n dryRun: options?.dryRun === true,\n limitOverride: options?.limit,\n force: false,\n });\n }\n\n private maybeScheduleConsolidation(nonZeroExtraction: boolean): void {\n if (this.config.consolidationRequireNonZeroExtraction && !nonZeroExtraction)\n return;\n if (\n this.nonZeroExtractionsSinceConsolidation < this.config.consolidateEveryN\n )\n return;\n\n const now = Date.now();\n if (\n now - this.lastConsolidationRunAtMs <\n this.config.consolidationMinIntervalMs\n )\n return;\n if (this.consolidationInFlight) return;\n\n this.consolidationInFlight = true;\n this.lastConsolidationRunAtMs = now;\n this.nonZeroExtractionsSinceConsolidation = 0;\n this.runConsolidation()\n .catch((err) => log.error(\"background consolidation failed\", err))\n .finally(() => {\n this.consolidationInFlight = false;\n });\n }\n\n private requestQmdMaintenance(): void {\n if (!this.qmd.isAvailable()) return;\n if (!this.config.qmdMaintenanceEnabled) return;\n\n this.qmdMaintenancePending = true;\n if (this.qmdMaintenanceTimer) return;\n\n this.qmdMaintenanceTimer = setTimeout(() => {\n this.qmdMaintenanceTimer = null;\n this.runQmdMaintenance().catch((err) =>\n log.debug(`background qmd maintenance failed: ${err}`),\n );\n }, this.config.qmdMaintenanceDebounceMs);\n }\n\n /**\n * Public entrypoint for tool-driven QMD maintenance requests.\n * Routes through existing debounced/singleflight maintenance controls.\n */\n requestQmdMaintenanceForTool(reason: string): void {\n try {\n this.requestQmdMaintenance();\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n log.warn(`qmd maintenance request failed (${reason}): ${msg}`);\n }\n }\n\n private async runQmdMaintenance(): Promise<void> {\n if (this.qmdMaintenanceInFlight) return;\n if (!this.qmdMaintenancePending) return;\n this.qmdMaintenanceInFlight = true;\n this.qmdMaintenancePending = false;\n\n try {\n if (this.config.namespacesEnabled) {\n // Include cataloged dynamic namespaces, not just the configured set\n // (NGnei), but run through the namespace-aware maintenance planner so\n // each namespace is budgeted, lock-protected, and status-recorded\n // independently (issue #1500).\n const plan = await this.namespaceMaintenancePlan(\"qmd\");\n const now = Date.now();\n const lastEmbedAtByNamespace =\n this.lastQmdEmbedAtMsByNamespace ?? (this.lastQmdEmbedAtMsByNamespace = new Map());\n const dueEmbedNamespaces = (namespaces: string[]): string[] => {\n if (!this.config.qmdAutoEmbedEnabled) return [];\n return namespaces.filter(\n (namespace) =>\n now - (lastEmbedAtByNamespace.get(namespace) ?? 0) >= this.config.qmdEmbedMinIntervalMs,\n );\n };\n const markEmbedded = (namespaces: string[]): void => {\n if (namespaces.length === 0) return;\n for (const namespace of namespaces) {\n lastEmbedAtByNamespace.set(namespace, now);\n }\n this.lastQmdEmbedAtMs = now;\n };\n await runNamespaceMaintenanceBatchPlan(\n this.config,\n plan,\n async (candidates) => {\n const namespaces = candidates.map((candidate) => candidate.namespace);\n const embedNamespaces = dueEmbedNamespaces(namespaces);\n let result: Awaited<ReturnType<NamespaceSearchRouter[\"updateNamespacesDetailed\"]>>;\n try {\n result = await this.namespaceSearchRouter.updateNamespacesDetailed(\n namespaces,\n undefined,\n { strict: true },\n );\n } catch (error) {\n if (\n embedNamespaces.length > 0 &&\n qmdMaintenanceSkipReasonForError(error) === \"throttled\"\n ) {\n await this.namespaceSearchRouter.embedNamespaces(embedNamespaces, { strict: true });\n markEmbedded(embedNamespaces);\n }\n throw error;\n }\n if (result.backendCount <= 0) {\n throw new Error(\"no eligible QMD backend for selected namespaces\");\n }\n if (result.eligibleNamespaces.length !== namespaces.length) {\n const eligible = new Set(result.eligibleNamespaces);\n const missing = namespaces.filter((namespace) => !eligible.has(namespace));\n throw new Error(`QMD backend ineligible for selected namespaces (${missing.length})`);\n }\n if (embedNamespaces.length > 0) {\n await this.namespaceSearchRouter.embedNamespaces(embedNamespaces, { strict: true });\n markEmbedded(embedNamespaces);\n }\n return { itemCount: result.backendCount };\n },\n this.namespaceCatalog,\n {\n skipReasonForError: qmdMaintenanceSkipReasonForError,\n },\n );\n } else {\n await this.qmd.update();\n const now = Date.now();\n if (\n this.config.qmdAutoEmbedEnabled &&\n now - this.lastQmdEmbedAtMs >= this.config.qmdEmbedMinIntervalMs\n ) {\n await this.qmd.embed();\n this.lastQmdEmbedAtMs = now;\n }\n }\n } finally {\n this.qmdMaintenanceInFlight = false;\n if (this.qmdMaintenancePending) {\n this.requestQmdMaintenance();\n }\n }\n }\n\n private async persistExtraction(\n result: ExtractionResult,\n storage: StorageManager,\n threadIdForExtraction?: string | null,\n sourceContext?: { sessionKey?: string; principal?: string; validAt?: string },\n baseNamespace?: string,\n scopeProfileWritePlan?: ResolvedScopeProfilePlan | null,\n ): Promise<string[]> {\n // Inline source attribution (issue #369). When enabled, every extracted\n // fact is rewritten to carry a compact provenance tag inside its body so\n // the citation survives hostile memory text, copy/paste, and LLM quoting.\n // The helper is a no-op when the feature flag is off, so legacy pipelines\n // see zero behavioral change.\n const citationEnabled = this.config.inlineSourceAttributionEnabled === true;\n const citationTemplate = this.config.inlineSourceAttributionFormat;\n // The stable fields (agent, session) are computed once; `ts` is intentionally\n // omitted here and added fresh per invocation so each fact in a large batch\n // gets its own insertion timestamp rather than sharing a single batch-start time.\n const citationContextBase: Omit<CitationContext, \"ts\"> = citationEnabled\n ? {\n agent: sourceContext?.principal,\n session: sourceContext?.sessionKey,\n }\n : {};\n const applyInlineCitation = (content: string): string => {\n if (!citationEnabled) return content;\n if (typeof content !== \"string\" || content.length === 0) return content;\n // Build a fresh CitationContext per call so `ts` reflects the actual\n // insertion time of each individual fact rather than the batch-start time.\n const citationContext: CitationContext = {\n ...citationContextBase,\n ts: new Date().toISOString(),\n };\n // `attachCitation` already calls `hasCitationForTemplate` internally and\n // is a no-op when the content already carries a citation (default or\n // custom template). The outer check was redundant and has been removed\n // to avoid a maintenance hazard where the two guard paths could diverge.\n return attachCitation(content, citationContext, citationTemplate);\n };\n const supersessionOrderingAt = (validAt?: string): string =>\n validAt && validAt.length > 0 ? validAt : new Date().toISOString();\n const persistedIds: string[] = [];\n const persistedIdsByStorage = new Map<\n string,\n { storage: StorageManager; ids: string[] }\n >();\n const trackPersistedId = (\n targetStorage: StorageManager,\n id: string,\n options: { includeReturnedIds?: boolean } = {},\n ): void => {\n if (options.includeReturnedIds !== false) {\n persistedIds.push(id);\n }\n const key = targetStorage.dir;\n const existing = persistedIdsByStorage.get(key);\n if (existing) {\n existing.ids.push(id);\n return;\n }\n persistedIdsByStorage.set(key, { storage: targetStorage, ids: [id] });\n };\n let dedupedCount = 0;\n // Counter for facts skipped by the importance write-gate (issue #372).\n // Emitted via the `importance_gated` metric below and rolled into the\n // final `persisted:` log line so operators can tune the threshold.\n let importanceGatedCount = 0;\n // UUI2: short-circuit semantic dedup after first backend-unavailable signal\n // within this batch. Once any fact in the batch gets reason=\"backend_unavailable\"\n // (meaning the embedding backend is degraded), subsequent facts skip the\n // lookup entirely and proceed directly to write. This prevents N-fact batches\n // from paying N × timeout when the backend is down. The flag resets per-batch\n // (declared here, inside persistExtraction) so a transient hiccup in one\n // batch does not permanently disable dedup in future batches.\n let batchBackendUnavailable = false;\n const behaviorSignalsByStorage = new Map<\n string,\n { storage: StorageManager; events: BehaviorSignalEvent[] }\n >();\n const trackBehaviorSignals = (\n targetStorage: StorageManager,\n events: BehaviorSignalEvent[],\n ): void => {\n if (events.length === 0) return;\n const key = targetStorage.dir;\n const existing = behaviorSignalsByStorage.get(key);\n if (existing) {\n existing.events.push(...events);\n return;\n }\n behaviorSignalsByStorage.set(key, {\n storage: targetStorage,\n events: [...events],\n });\n };\n const confidenceTierOrder = [\n \"explicit\",\n \"implied\",\n \"inferred\",\n \"speculative\",\n ] as const;\n const sharedProfileLayer = scopeProfileWritePlan?.layers.find(\n (layer) =>\n layer.id === \"serverShared\" &&\n layer.namespace === this.config.sharedNamespace,\n );\n const sharedPromotionTarget = scopeProfileWritePlan?.promotionTargets.find(\n (target) =>\n target.target === \"serverShared\" &&\n target.namespace === this.config.sharedNamespace,\n );\n const profileAllowsSharedWrites =\n !scopeProfileWritePlan ||\n Boolean(\n scopeProfileWritePlan.profile.readOrder.includes(\"serverShared\") &&\n scopeProfileWritePlan.readNamespaces.includes(this.config.sharedNamespace) &&\n sharedProfileLayer?.readable &&\n sharedProfileLayer.writable &&\n sharedPromotionTarget?.authorized,\n );\n const profileAutoPromotionAllows = (\n category: string,\n confidence: number,\n ): boolean => {\n if (!scopeProfileWritePlan) return false;\n const actualTier = confidenceTier(confidence);\n const actualRank = confidenceTierOrder.indexOf(actualTier);\n if (actualRank === -1) return false;\n const autoPromote = scopeProfileWritePlan.profile.autoPromote;\n if (!autoPromote.enabled) return false;\n if (!autoPromote.categories.includes(category as any)) return false;\n const minimumRank = confidenceTierOrder.indexOf(autoPromote.minConfidenceTier);\n return minimumRank !== -1 && actualRank <= minimumRank;\n };\n const sharedAutoPromotionAllows = (\n category: string,\n confidence: number,\n ): boolean => {\n if (!scopeProfileWritePlan) {\n const actualTier = confidenceTier(confidence);\n const actualRank = confidenceTierOrder.indexOf(actualTier);\n if (actualRank === -1) return false;\n if (!this.config.autoPromoteToSharedEnabled) return false;\n if (!this.config.autoPromoteToSharedCategories.includes(category as any))\n return false;\n const minimumRank = confidenceTierOrder.indexOf(\n this.config.autoPromoteMinConfidenceTier,\n );\n return minimumRank !== -1 && actualRank <= minimumRank;\n }\n return (\n scopeProfileWritePlan.profile.autoPromote.targets.includes(\"serverShared\") &&\n profileAutoPromotionAllows(category, confidence)\n );\n };\n const shouldPromoteToShared = (\n targetStorage: StorageManager,\n category: string,\n confidence: number,\n ): boolean => {\n if (\n !this.config.namespacesEnabled ||\n !profileAllowsSharedWrites ||\n !sharedAutoPromotionAllows(category, confidence)\n )\n return false;\n if (\n this.namespaceFromStorageDir(targetStorage.dir) ===\n this.config.sharedNamespace\n )\n return false;\n return true;\n };\n const promoteMemoryToProfileTargets = async (options: {\n sourceStorage: StorageManager;\n category: string;\n content: string;\n confidence: number;\n tags: string[];\n entityRef?: string;\n structuredAttributes?: Record<string, string>;\n sourceMemoryId: string;\n importance?: ReturnType<typeof scoreImportance>;\n intentGoal?: string;\n intentActionType?: string;\n intentEntityTypes?: string[];\n memoryKind?: MemoryFrontmatter[\"memoryKind\"];\n validAt?: string;\n source: string;\n }): Promise<void> => {\n if (\n !scopeProfileWritePlan ||\n !profileAutoPromotionAllows(options.category, options.confidence)\n )\n return;\n const autoTargets = new Set(scopeProfileWritePlan.profile.autoPromote.targets);\n const targets = scopeProfileWritePlan.promotionTargets.filter(\n (target) =>\n target.target !== \"serverShared\" &&\n autoTargets.has(target.target) &&\n target.authorized &&\n target.namespace,\n );\n if (targets.length === 0) return;\n const rawContent =\n citationEnabled && hasCitationForTemplate(options.content, citationTemplate)\n ? stripCitationForTemplate(options.content, citationTemplate)\n : options.content;\n const citedContent = applyInlineCitation(rawContent);\n const sanitizedBase = sanitizeMemoryContent(rawContent);\n const dedupContent =\n options.category === \"fact\" &&\n options.structuredAttributes &&\n Object.keys(options.structuredAttributes).length > 0\n ? `${sanitizedBase.text}\\n[Attributes: ${normalizeAttributePairs(options.structuredAttributes)}]`\n : sanitizedBase.text;\n for (const target of targets) {\n if (!target.namespace) continue;\n try {\n const targetStorage = await this.storageRouter.storageFor(target.namespace);\n if (targetStorage.dir === options.sourceStorage.dir) continue;\n if (\n options.category === \"fact\" &&\n (await targetStorage.hasFactContentHash(dedupContent))\n ) {\n continue;\n }\n const promotedId = await targetStorage.writeMemory(\n options.category as any,\n citedContent,\n {\n confidence: options.confidence,\n tags: [...options.tags, `${target.target}-promotion`],\n entityRef: options.entityRef,\n structuredAttributes: options.structuredAttributes,\n source: `${options.source}-${target.target}-promotion`,\n importance: options.importance,\n lineage: [options.sourceMemoryId],\n sourceMemoryId: options.sourceMemoryId,\n intentGoal: options.intentGoal,\n intentActionType: options.intentActionType,\n intentEntityTypes: options.intentEntityTypes,\n memoryKind: options.memoryKind,\n validAt: options.validAt,\n contentHashSource: options.category === \"fact\" ? dedupContent : rawContent,\n },\n );\n if (\n this.config.temporalSupersessionEnabled &&\n options.category === \"fact\" &&\n options.entityRef &&\n options.structuredAttributes &&\n Object.keys(options.structuredAttributes).length > 0\n ) {\n try {\n await applyTemporalSupersession({\n storage: targetStorage,\n newMemoryId: promotedId,\n entityRef: options.entityRef,\n structuredAttributes: options.structuredAttributes,\n createdAt: supersessionOrderingAt(options.validAt),\n enabled: true,\n });\n } catch (profileSupersessionErr) {\n log.warn(\n `persistExtraction: ${target.target} promotion temporal supersession failed open for promoted ${promotedId}: ${profileSupersessionErr}`,\n );\n }\n }\n this.markCatalogWrite(target.namespace, targetStorage.dir);\n trackPersistedId(targetStorage, promotedId, { includeReturnedIds: false });\n await this.indexPersistedMemory(targetStorage, promotedId);\n trackBehaviorSignals(\n targetStorage,\n buildBehaviorSignalsForMemory({\n memoryId: promotedId,\n category: options.category as any,\n content: options.content,\n namespace: target.namespace,\n confidence: options.confidence,\n source: \"extraction\",\n }),\n );\n } catch (err) {\n log.warn(\n `persistExtraction: ${target.target} promotion failed open for ${options.sourceMemoryId}: ${err}`,\n );\n }\n }\n };\n const promoteMemoryToShared = async (options: {\n sourceStorage: StorageManager;\n category: string;\n content: string;\n confidence: number;\n tags: string[];\n entityRef?: string;\n structuredAttributes?: Record<string, string>;\n sourceMemoryId: string;\n importance?: ReturnType<typeof scoreImportance>;\n intentGoal?: string;\n intentActionType?: string;\n intentEntityTypes?: string[];\n memoryKind?: MemoryFrontmatter[\"memoryKind\"];\n validAt?: string;\n source: string;\n }): Promise<void> => {\n await promoteMemoryToProfileTargets(options);\n if (\n !shouldPromoteToShared(\n options.sourceStorage,\n options.category,\n options.confidence,\n )\n )\n return;\n try {\n const sharedStorage = await this.storageRouter.storageFor(\n this.config.sharedNamespace,\n );\n // Dedup gate: canonicalize content before hashing.\n //\n // Issue #369 (PR #401): When inline attribution is enabled,\n // `applyInlineCitation` appends a timestamp-bearing marker (e.g.\n // `[Source: ..., ts=2026-04-11T...]`). Because the timestamp changes\n // on every call, hashing cited content produces a unique hash each\n // time — defeating dedup entirely and allowing the same logical fact to\n // be promoted repeatedly. Also, both promotion call sites pass\n // `fact.content`, which can already carry an inline citation (e.g. a\n // relayed or reprocessed fact). Strip any pre-existing citation so the\n // dedup key matches the hash stored from the original un-cited write.\n //\n // PR #402 round-6 (Fix #2 / chatgpt-codex P1 PRRT_kwDORJXyws56U74n):\n // Compute the enriched content before the hash-dedup check so the\n // lookup uses the same content that writeMemory will actually store.\n // When structuredAttributes are present, writeMemory appends an\n // \"[Attributes: ...]\" suffix before hashing; hasFactContentHash must\n // receive the same enriched body or the check is against a different\n // hash and dedup fails to fire (letting duplicates through) or fires\n // when it shouldn't (collapsing memories with different enrichments).\n // Fix #1 (P2 PRRT_kwDORJXyws56VHZc): use normalizeAttributePairs so\n // key order and casing are canonical — identical to the enrichment\n // applied by storage.writeMemory — preventing spurious hash misses\n // when attribute maps arrive with different insertion orders or casing.\n //\n // Fix #4 (Low PRRT_kwDORJXyws56VHth): sanitize the base content before\n // building dedupContent. writeMemory runs sanitizeMemoryContent on the\n // enriched body before hashing; if sanitization redacts the content to\n // REDACTED_PLACEHOLDER the stored hash is for the redacted form, not\n // the raw form. Computing dedupContent from sanitized.text here ensures\n // the hash lookup and the normalizedIncoming comparison both use the\n // same content that writeMemory will actually store.\n //\n // Combined fix: strip any pre-existing citation FIRST to obtain\n // rawContent (the canonical body), then sanitize rawContent (not\n // options.content) when building dedupContent, so that citation\n // stripping and sanitization are applied in a consistent order.\n const rawContent =\n citationEnabled &&\n hasCitationForTemplate(options.content, citationTemplate)\n ? stripCitationForTemplate(options.content, citationTemplate)\n : options.content;\n const citedContent = applyInlineCitation(rawContent);\n const sanitizedBase = sanitizeMemoryContent(rawContent);\n const dedupContent =\n options.category === \"fact\" &&\n options.structuredAttributes &&\n Object.keys(options.structuredAttributes).length > 0\n ? `${sanitizedBase.text}\\n[Attributes: ${normalizeAttributePairs(options.structuredAttributes)}]`\n : sanitizedBase.text;\n if (\n options.category === \"fact\" &&\n (await sharedStorage.hasFactContentHash(dedupContent))\n ) {\n // Uj6H fix: shared-namespace temporal supersession must also run when\n // the hash-dedup short-circuit fires. Without this, an existing shared\n // fact whose structuredAttributes are stale (or an older conflicting\n // shared fact that is still active) never gets retired — supersession\n // only ran in the post-writeMemory block which is unreachable here.\n //\n // Strategy: scan the shared namespace for the existing fact whose\n // normalized content matches the incoming content, then run\n // applyTemporalSupersession against it using the same logic that\n // would have run post-writeMemory. This is a best-effort / fail-open\n // step — if the lookup fails we skip silently (same as the normal path).\n if (\n this.config.temporalSupersessionEnabled &&\n options.entityRef &&\n options.structuredAttributes &&\n Object.keys(options.structuredAttributes).length > 0\n ) {\n // PR #402 round-7 (Fix #2 / Codex P1 PRRT_kwDORJXyws56VALC):\n // Track whether matchingFact lookup completed before the try block\n // so the catch block can distinguish an early-lookup failure (where\n // we don't know if a duplicate exists) from a post-lookup supersession\n // failure (where we confirmed a duplicate and must skip the write).\n let hashDedupMatchingFact: MemoryFile | undefined;\n let hashDedupLookupComplete = false;\n try {\n // Fix #2 (P2 PRRT_kwDORJXyws56VHZf): dedupContent is now built\n // from sanitizedBase.text (see fix #4 above), so normalizedIncoming\n // uses the same sanitized+normalized content that writeMemory hashes\n // and that hasFactContentHash just matched. Previously this used the\n // raw options.content, which diverged from the stored hash when\n // sanitization redacted the content, causing the candidate lookup to\n // return undefined and leaving stale facts active.\n const normalizedIncoming = ContentHashIndex.normalizeContent(dedupContent);\n const allShared = await sharedStorage.readAllMemories();\n // PR #402 round-12 (Finding Uybg): restrict hash-dedup matching to\n // the SAME entity. Content-hash equality alone can collide across\n // entities when two entities share identical fact text. Using an\n // unrelated entity's existing fact as `newMemoryId` would anchor\n // supersession to that entity's record and corrupt its\n // `supersededBy` links. Only consider facts whose normalized\n // `entityRef` matches the incoming entity.\n const incomingEntityNorm = normalizeSupersessionKey(options.entityRef);\n hashDedupMatchingFact = allShared.find((m) => {\n if (m.frontmatter.category !== \"fact\") return false;\n if ((m.frontmatter.status ?? \"active\") !== \"active\") return false;\n // Same-entity guard: skip if entity doesn't match.\n if (!m.frontmatter.entityRef) return false;\n if (normalizeSupersessionKey(m.frontmatter.entityRef) !== incomingEntityNorm) {\n log.debug(\n `persistExtraction: hash-dedup skipping cross-entity match (incoming=\"${incomingEntityNorm}\" candidate=\"${normalizeSupersessionKey(m.frontmatter.entityRef)}\")`,\n );\n return false;\n }\n // PR #402 round-7 (Fix #2): compare stored fact's full body\n // (including any appended \"[Attributes: ...]\" suffix) against the\n // enriched normalizedIncoming so the candidate selected is the one\n // whose hash actually matched in hasFactContentHash.\n return ContentHashIndex.normalizeContent(m.content ?? \"\") === normalizedIncoming;\n });\n hashDedupLookupComplete = true;\n if (hashDedupMatchingFact) {\n // Finding UvU1 (PR #402 round-11): anchor supersession to the\n // incoming event's time, not the existing fact's persisted\n // `created`. For source-dated replay/import, this is the\n // source valid_at; otherwise it is the current wall-clock. The\n // matching fact may be an old shared copy whose `created`\n // predates the incoming promotion event — using it as\n // `createdAt` would make the new memory appear older than the\n // existing one, preventing supersession from firing.\n // PR #402 round-12 (Finding Uyui): the matching fact is an\n // existing OLD memory — its persisted `frontmatter.created` is\n // stale relative to the incoming promotion event. Pass\n // `useCallerTimestamp: true` so the function uses\n // `createdAt` as the ordering anchor instead of the old fact's\n // timestamp, ensuring supersession fires correctly even when\n // the matching fact predates conflicting candidates.\n const hashDedupSupersession = await applyTemporalSupersession({\n storage: sharedStorage,\n newMemoryId: hashDedupMatchingFact.frontmatter.id,\n entityRef: options.entityRef,\n structuredAttributes: options.structuredAttributes,\n createdAt: supersessionOrderingAt(options.validAt),\n enabled: true,\n useCallerTimestamp: true,\n });\n // Catalog touch (issue #1499 — codex P2 NElSf): this dedup branch\n // returns WITHOUT reaching the post-write `markCatalogWrite` below,\n // but `applyTemporalSupersession` mutated the shared namespace\n // (it rewrote frontmatter to retire stale shared facts). When any\n // ids were actually superseded, the shared namespace changed, so we\n // must record the write — otherwise the shared record's\n // `lastWriteAt` stays stale and `writtenSince` maintenance / QMD\n // fanout skips the namespace after a supersession-only update.\n // Best-effort and failure-tolerant (markCatalogWrite swallows\n // errors); only touch when work happened to avoid spurious writes.\n if (hashDedupSupersession.supersededIds.length > 0) {\n this.markCatalogWrite(this.config.sharedNamespace, sharedStorage.dir);\n }\n // Active matching fact exists — normal short-circuit is safe.\n return;\n }\n // No active same-entity shared fact found with this content hash.\n // This can happen when the previously-written shared fact has since\n // been superseded (e.g. Austin → NYC → Austin reversion): the hash\n // index still records the hash but the fact is no longer active.\n // Fall through to the write path below so a new active shared\n // memory is created, then supersession fires post-write as usual.\n log.debug(\n `persistExtraction: hash-dedup found no active same-entity shared fact for ${options.sourceMemoryId}; falling through to write`,\n );\n } catch (hashDedupSupersessionErr) {\n log.warn(\n `persistExtraction: shared-namespace supersession on hash-dedup path failed open for ${options.sourceMemoryId}: ${hashDedupSupersessionErr}`,\n );\n // PR #402 round-7 (Fix #1 / cursor Medium PRRT_kwDORJXyws56U_ig):\n // Only skip the write if we CONFIRMED a matching active shared fact\n // before the error occurred (hashDedupLookupComplete is true AND\n // hashDedupMatchingFact is set). If the error was thrown before\n // matchingFact was resolved — e.g. readAllMemories() threw — we\n // cannot assume a duplicate exists, and unconditionally returning\n // would permanently lose the shared promotion. Fall through to the\n // write path so the fact is not silently dropped.\n if (hashDedupLookupComplete && hashDedupMatchingFact) {\n // A matching active shared fact was confirmed — skip the write to\n // avoid duplicating content that is already present. The existing\n // fact remains active and the supersession failure is logged above.\n return;\n }\n // Lookup did not complete or no candidate was found — we cannot\n // confirm a duplicate. Fall through to the write + post-write\n // supersession path so the shared promotion is not lost.\n log.debug(\n `persistExtraction: hash-dedup catch: lookup incomplete or no candidate found for ${options.sourceMemoryId}; falling through to write`,\n );\n }\n } else {\n // temporalSupersessionEnabled is off or no entity/attributes — keep\n // the original short-circuit behaviour.\n return;\n }\n }\n const promotedId = await sharedStorage.writeMemory(\n options.category as any,\n citedContent,\n {\n confidence: options.confidence,\n tags: [...options.tags, \"shared-promotion\"],\n entityRef: options.entityRef,\n structuredAttributes: options.structuredAttributes,\n source: `${options.source}-shared-promotion`,\n importance: options.importance,\n lineage: [options.sourceMemoryId],\n sourceMemoryId: options.sourceMemoryId,\n intentGoal: options.intentGoal,\n intentActionType: options.intentActionType,\n intentEntityTypes: options.intentEntityTypes,\n memoryKind: options.memoryKind,\n validAt: options.validAt,\n // Index the same canonical body used by hasFactContentHash above.\n // For structured facts this includes the normalized Attributes\n // suffix, matching StorageManager.writeMemory enrichment.\n contentHashSource: options.category === \"fact\" ? dedupContent : rawContent,\n },\n );\n // PR #402 Finding 3 fix: run temporal supersession against the shared\n // namespace after the promoted write lands so stale shared-namespace\n // copies of the same entity attribute are retired. Without this,\n // source-namespace supersession leaves the shared copy active and\n // shared recall continues returning the stale state. Reuses the same\n // applyTemporalSupersession helper — no logic duplication.\n if (\n this.config.temporalSupersessionEnabled &&\n options.entityRef &&\n options.structuredAttributes &&\n Object.keys(options.structuredAttributes).length > 0\n ) {\n try {\n await applyTemporalSupersession({\n storage: sharedStorage,\n newMemoryId: promotedId,\n entityRef: options.entityRef,\n structuredAttributes: options.structuredAttributes,\n createdAt: supersessionOrderingAt(options.validAt),\n enabled: true,\n });\n } catch (sharedSupersessionErr) {\n log.warn(\n `persistExtraction: shared-namespace temporal supersession failed open for promoted ${promotedId}: ${sharedSupersessionErr}`,\n );\n }\n }\n // Catalog touch (issue #1499, Issue B + ordering sweep): a shared-\n // namespace promotion is the ONLY write the shared namespace receives on\n // this path, so without this the shared record's lastWriteAt stays stale\n // and `writtenSince` filters / maintenance fanout skip it. Record AFTER\n // the promoted write and the shared temporal-supersession attempt so the\n // catalog timestamp never precedes a later durable frontmatter mutation in\n // the same promotion pass. The hot-path source-namespace touch uses a\n // different storage dir, so this does not double-count the source.\n // Best-effort and failure-tolerant — it must never crash the promotion.\n this.markCatalogWrite(this.config.sharedNamespace, sharedStorage.dir);\n trackPersistedId(sharedStorage, promotedId, {\n includeReturnedIds: false,\n });\n await this.indexPersistedMemory(sharedStorage, promotedId);\n trackBehaviorSignals(\n sharedStorage,\n buildBehaviorSignalsForMemory({\n memoryId: promotedId,\n category: options.category as any,\n content: options.content,\n namespace: this.config.sharedNamespace,\n confidence: options.confidence,\n source: \"extraction\",\n }),\n );\n } catch (err) {\n log.warn(\n `persistExtraction: shared promotion failed open for ${options.sourceMemoryId}: ${err}`,\n );\n }\n };\n\n // Defensive: validate result and facts array\n if (!result || !Array.isArray(result.facts)) {\n log.warn(\n \"persistExtraction: result or result.facts is invalid, skipping\",\n { resultType: typeof result, factsType: typeof result?.facts },\n );\n return persistedIds;\n }\n\n // Chunking config from plugin settings\n const chunkingConfig: ChunkingConfig = {\n targetTokens: this.config.chunkingTargetTokens,\n minTokens: this.config.chunkingMinTokens,\n overlapSentences: this.config.chunkingOverlapSentences,\n };\n\n const rawEntities = Array.isArray((result as any).entities)\n ? (result as any).entities\n : [];\n const rawQuestions = Array.isArray((result as any).questions)\n ? (result as any).questions\n : [];\n const rawProfileUpdates = Array.isArray((result as any).profileUpdates)\n ? (result as any).profileUpdates\n : [];\n\n const facts = result.facts.slice(0, this.config.extractionMaxFactsPerRun);\n const entities = rawEntities.slice(\n 0,\n this.config.extractionMaxEntitiesPerRun,\n );\n const questions = rawQuestions.slice(\n 0,\n this.config.extractionMaxQuestionsPerRun,\n );\n const profileUpdates = rawProfileUpdates.slice(\n 0,\n this.config.extractionMaxProfileUpdatesPerRun,\n );\n\n if (\n facts.length < result.facts.length ||\n entities.length < result.entities.length ||\n questions.length < result.questions.length ||\n profileUpdates.length < result.profileUpdates.length\n ) {\n log.warn(\n \"persistExtraction: capped extraction payload to guardrails \" +\n `(facts ${facts.length}/${result.facts.length}, entities ${entities.length}/${result.entities.length}, ` +\n `questions ${questions.length}/${result.questions.length}, profile ${profileUpdates.length}/${result.profileUpdates.length})`,\n );\n }\n\n // v8.2: pre-load all memories once for entity-sibling graph edges (avoids per-fact disk scan)\n type GraphStorageContext = {\n allMemsForGraph: Awaited<\n ReturnType<typeof storage.readAllMemories>\n > | null;\n memoryPathById: Map<string, string>;\n previousPersistedRelPath?: string;\n };\n const graphContextByStorageDir = new Map<string, GraphStorageContext>();\n const ensureGraphContext = async (\n targetStorage: StorageManager,\n ): Promise<GraphStorageContext> => {\n const existing = graphContextByStorageDir.get(targetStorage.dir);\n if (existing) return existing;\n const created: GraphStorageContext = {\n allMemsForGraph: null,\n memoryPathById: new Map<string, string>(),\n };\n if (this.config.multiGraphMemoryEnabled) {\n try {\n created.allMemsForGraph = await targetStorage.readAllMemories();\n for (const [id, relPath] of buildMemoryPathById(\n created.allMemsForGraph,\n targetStorage.dir,\n )) {\n created.memoryPathById.set(id, relPath);\n }\n } catch {\n /* fail-open */\n }\n }\n graphContextByStorageDir.set(targetStorage.dir, created);\n return created;\n };\n let threadEpisodeIdsForGraph: string[] | undefined;\n if (this.config.multiGraphMemoryEnabled && threadIdForExtraction) {\n try {\n const thread = await this.threading.loadThread(threadIdForExtraction);\n threadEpisodeIdsForGraph = thread?.episodeIds\n ? [...thread.episodeIds]\n : [];\n } catch {\n /* fail-open */\n }\n }\n const routeRules = await this.loadRoutingRules();\n const routeOptions = this.routeEngineOptions();\n\n // Pre-routing pass: compute the routed category for every fact BEFORE\n // building judge candidates. Route rules may override f.category (e.g.\n // via taxonomy remapping), and the judge must evaluate against the\n // *final* category that will actually be persisted — not the raw\n // extraction-time category. The per-fact write loop below reuses\n // these pre-computed results so routing is evaluated exactly once per\n // fact (no duplicated logic).\n const preRoutedCategories: Array<string | undefined> = new Array(facts.length);\n if (routeRules.length > 0) {\n for (let fi = 0; fi < facts.length; fi++) {\n const f = facts[fi];\n if (\n !f ||\n typeof f.content !== \"string\" ||\n !f.content.trim() ||\n typeof f.category !== \"string\" ||\n !f.category.trim()\n ) {\n continue;\n }\n try {\n const tags = Array.isArray(f.tags) ? f.tags : [];\n const routeText = `${f.category} ${tags.join(\" \")} ${f.content}`;\n const selected = selectRouteRule(routeText, routeRules, routeOptions);\n if (selected?.target.category) {\n preRoutedCategories[fi] = selected.target.category;\n }\n } catch {\n // Fail-open: routing errors fall through to the extracted category.\n }\n }\n }\n\n // Extraction judge gate (issue #376). When enabled, batch-evaluate all\n // candidate facts for durability before the per-fact write loop.\n // The verdicts map is keyed by candidate index — we maintain a\n // candidateIndexToFactIndex mapping so the write loop can look up\n // verdicts by original fact index.\n //\n // Candidates are built using the *routed* category (preRoutedCategories)\n // so the judge evaluates durability against the same category that will\n // be persisted, not the raw extraction-time category.\n let judgeVerdictsByFactIndex: Map<number, import(\"./extraction-judge.js\").JudgeVerdict> | null = null;\n let judgeGatedCount = 0;\n // Reset the side-channel defer count at the start of every\n // persistExtraction call so stale state from a prior call cannot leak\n // into the caller's buffer-retention decision.\n this.lastPersistExtractionDeferredCount = 0;\n if (this.config.extractionJudgeEnabled) {\n try {\n const judgeCandidates: JudgeCandidate[] = [];\n const candidateToFactIndex: number[] = [];\n for (let fi = 0; fi < facts.length; fi++) {\n const f = facts[fi];\n if (\n !f ||\n typeof f.content !== \"string\" ||\n !f.content.trim() ||\n typeof f.category !== \"string\" ||\n !f.category.trim()\n ) {\n continue;\n }\n // Use the routed category when available so the judge sees the\n // final persisted category, not the raw extraction-time value.\n // Cast to MemoryCategory — routing targets are always valid\n // category slugs defined in the taxonomy; the fallback is the\n // original ExtractedFact.category which is already typed.\n const judgeCategory = (preRoutedCategories[fi] ?? f.category) as import(\"./types.js\").MemoryCategory;\n if (judgeCategory === \"procedure\") {\n continue;\n }\n const tags = Array.isArray(f.tags) ? f.tags : [];\n const imp = scoreImportance(\n f.content,\n judgeCategory,\n tags,\n );\n // Pre-filter: skip facts below importance threshold to avoid\n // wasting LLM calls on facts that will be filtered anyway in\n // the per-fact write loop (issue #376 review finding).\n if (\n !isAboveImportanceThreshold(\n imp.level,\n this.config.extractionMinImportanceLevel,\n )\n ) {\n continue;\n }\n judgeCandidates.push({\n text: f.content,\n category: judgeCategory,\n confidence: typeof f.confidence === \"number\" ? f.confidence : 0.7,\n tags,\n importanceLevel: imp.level,\n });\n candidateToFactIndex.push(fi);\n }\n // Telemetry + training-pair emit (issue #562 PR 3 + PR 4). The\n // orchestrator wires two fire-and-forget writers behind a single\n // callback so `judgeFactDurability` does not need to know about\n // either ledger. Both handlers are skipped when their flags are\n // off; the combined callback itself is undefined when both are\n // disabled so there is zero overhead in the default configuration.\n const judgeTelemetryOpts = {\n enabled: this.config.extractionJudgeTelemetryEnabled === true,\n memoryDir: this.config.memoryDir,\n };\n const judgeTrainingOpts = {\n enabled: this.config.collectJudgeTrainingPairs === true,\n ...(this.config.judgeTrainingDir\n ? { directory: this.config.judgeTrainingDir }\n : {}),\n };\n const judgeTelemetryHandler =\n judgeTelemetryOpts.enabled || judgeTrainingOpts.enabled\n ? (obs: import(\"./extraction-judge.js\").JudgeVerdictObservation) => {\n const ts = new Date().toISOString();\n const verdictKind = getVerdictKind(obs.verdict);\n if (judgeTelemetryOpts.enabled) {\n const event: import(\"./extraction-judge-telemetry.js\").JudgeVerdictEvent = {\n version: 1,\n category: EXTRACTION_JUDGE_VERDICT_CATEGORY,\n ts,\n verdictKind,\n reason: obs.verdict.reason,\n deferrals: obs.priorDeferrals,\n elapsedMs: obs.elapsedMs,\n candidateCategory: obs.candidate.category,\n confidence: obs.candidate.confidence,\n contentHash: obs.contentHash,\n fromCache: obs.source === \"cache\",\n ...(obs.source === \"llm-cap-rejected\"\n ? { deferCapTriggered: true }\n : {}),\n };\n void recordJudgeVerdict(event, judgeTelemetryOpts);\n }\n if (judgeTrainingOpts.enabled) {\n const pair: import(\"./extraction-judge-training.js\").JudgeTrainingPair = {\n version: 1,\n ts,\n candidateText: obs.candidate.text,\n candidateCategory: obs.candidate.category,\n ...(typeof obs.candidate.confidence === \"number\"\n ? { candidateConfidence: obs.candidate.confidence }\n : {}),\n verdictKind,\n reason: obs.verdict.reason,\n priorDeferrals: obs.priorDeferrals,\n };\n void recordJudgeTrainingPair(pair, judgeTrainingOpts);\n }\n }\n : undefined;\n const judgeResult = await judgeFactDurability(\n judgeCandidates,\n this.config,\n this.localLlm,\n new FallbackLlmClient(\n this.config.gatewayConfig,\n fallbackLlmRuntimeContextFromConfig(this.config),\n ),\n this.judgeVerdictCache,\n this.judgeDeferCounts,\n judgeTelemetryHandler,\n );\n // Remap candidate-indexed verdicts to original fact indexes\n judgeVerdictsByFactIndex = new Map();\n for (const [candidateIdx, verdict] of judgeResult.verdicts) {\n const factIdx = candidateToFactIndex[candidateIdx];\n if (factIdx !== undefined) {\n judgeVerdictsByFactIndex.set(factIdx, verdict);\n }\n }\n log.info(\n `extraction-judge: ${judgeResult.verdicts.size}/${judgeCandidates.length} facts evaluated, ` +\n `${judgeResult.cached} cached, ${judgeResult.judged} judged, ` +\n `${judgeResult.deferred} deferred` +\n (judgeResult.deferredCappedToReject > 0\n ? ` (${judgeResult.deferredCappedToReject} cap-rejected)`\n : \"\") +\n `, ${judgeResult.elapsed}ms`,\n );\n // Expose defer count to the caller (issue #562 PR 2) so it can decide\n // whether to retain buffer turns for the next extraction pass.\n this.lastPersistExtractionDeferredCount = judgeResult.deferred;\n } catch (err) {\n // Fail-open: if the entire judge pipeline errors, proceed without filtering\n log.warn(\n `extraction-judge: pipeline error, proceeding without filtering (fail-open): ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n let factLoopIndex = -1;\n for (const fact of facts) {\n factLoopIndex++;\n if (\n !fact ||\n typeof (fact as any).content !== \"string\" ||\n !(fact as any).content.trim()\n ) {\n continue;\n }\n if (\n typeof (fact as any).category !== \"string\" ||\n !(fact as any).category.trim()\n ) {\n continue;\n }\n (fact as any).tags = Array.isArray((fact as any).tags)\n ? (fact as any).tags.filter((t: any) => typeof t === \"string\")\n : [];\n (fact as any).confidence =\n typeof (fact as any).confidence === \"number\"\n ? (fact as any).confidence\n : 0.7;\n\n // Content-hash dedup check (v6.0)\n //\n // Canonicalize pre-tagged facts before hashing (Codex P2 — issue #369).\n // When a fact already carries an inline citation (e.g. relayed or\n // reprocessed), hashing `fact.content` as-is would produce a different\n // hash than the one stored from the original write (which used the raw,\n // un-cited body as contentHashSource). Strip any citation first so the\n // dedup key matches what the hash index recorded.\n //\n // stripCitationForTemplate handles both the default and custom template\n // formats. For all-placeholder templates it cannot detect citations and\n // returns the text unchanged — dedup may miss in that edge case, which\n // is acceptable (no false-positive suppression).\n //\n // Routing runs before content-hash dedup and scoring so category overrides\n // affect both the dedup fingerprint and importance (issue #519 procedure routing).\n let writeCategory = fact.category;\n let targetStorage = storage;\n // Track the KNOWN target namespace NAME alongside targetStorage (round 6,\n // codex P2 — NCQI0). Re-deriving it from `targetStorage.dir` mangles a raw\n // namespace literally named like a canonical token (e.g. `ns-616c706861`\n // served from its legacy raw dir decodes to `alpha`). We seed it from the\n // EXPLICIT base namespace the caller used to obtain `storage` (NHIdx, codex\n // P2) — `selfNamespace`/`writeNamespaceOverride` — so the catalog write touch\n // records the real namespace, not a guess decoded from the directory. We only\n // fall back to decoding the dir when no base namespace was passed (legacy\n // callers). The EXPLICIT routed name (below) still overrides this verbatim.\n let targetNamespaceName =\n baseNamespace && baseNamespace.length > 0\n ? baseNamespace\n : this.namespaceFromStorageDir(targetStorage.dir);\n let routedRuleId: string | undefined;\n let routedNamespaceExplicit = false;\n if (routeRules.length > 0) {\n try {\n const routeText = `${fact.category} ${fact.tags.join(\" \")} ${fact.content}`;\n const selected = selectRouteRule(routeText, routeRules, routeOptions);\n if (selected) {\n routedRuleId = selected.rule.id;\n if (selected.target.category) {\n writeCategory = selected.target.category;\n }\n if (selected.target.namespace) {\n routedNamespaceExplicit = true;\n targetStorage = await this.storageRouter.storageFor(\n selected.target.namespace,\n );\n targetNamespaceName = selected.target.namespace;\n }\n }\n } catch (err) {\n log.warn(\n `routing evaluation failed; fail-open to extracted category/namespace: ${err}`,\n );\n }\n }\n\n // Scope-based namespace routing: when scope classification is enabled\n // and the LLM tagged this fact as \"global\", route it to the shared\n // namespace so cross-project knowledge is visible everywhere. Only\n // applies when namespaces are enabled and the fact was not already\n // routed to a specific namespace by a routing rule (routing rules\n // that set an explicit namespace take precedence; category-only rules\n // do not block scope routing). Rule 30: gated by\n // extractionScopeClassificationEnabled.\n if (\n this.config.extractionScopeClassificationEnabled &&\n this.config.namespacesEnabled &&\n fact.scope === \"global\" &&\n !routedNamespaceExplicit\n ) {\n const currentNs = this.namespaceFromStorageDir(targetStorage.dir);\n if (currentNs !== this.config.sharedNamespace && profileAllowsSharedWrites) {\n try {\n targetStorage = await this.storageRouter.storageFor(\n this.config.sharedNamespace,\n );\n targetNamespaceName = this.config.sharedNamespace;\n log.debug(\n `scope-routing: fact \"${fact.content.slice(0, 60)}…\" routed to shared namespace (scope=global)`,\n );\n } catch (scopeRouteErr) {\n log.warn(\n `scope-routing: failed to resolve shared namespace storage; writing to session namespace (fail-open): ${scopeRouteErr}`,\n );\n }\n } else if (currentNs !== this.config.sharedNamespace) {\n log.debug(\n `scope-routing: skipped shared namespace for global fact because active scope profile ${scopeProfileWritePlan?.profileId ?? \"none\"} does not authorize serverShared writes`,\n );\n }\n }\n\n // Procedures: fingerprint the full serialized body (title + steps), not\n // the title alone, so distinct step lists are not collapsed (issue #519).\n const canonicalContentForHash =\n citationEnabled &&\n hasCitationForTemplate(fact.content, citationTemplate)\n ? stripCitationForTemplate(fact.content, citationTemplate)\n : fact.content;\n const contentHashDedupKey =\n writeCategory === \"procedure\"\n ? buildProcedurePersistBody(fact.content, fact.procedureSteps)\n : canonicalContentForHash;\n let exactDuplicate = false;\n try {\n exactDuplicate = await this.hasContentHashDedup(\n targetStorage,\n contentHashDedupKey,\n );\n } catch (err) {\n log.warn(\n `content-hash dedup lookup failed for storage ${targetStorage.dir}; writing fact fail-open: ${err}`,\n );\n }\n if (exactDuplicate) {\n log.debug(\n `dedup: skipping duplicate fact \"${fact.content.slice(0, 60)}…\" in storage ${targetStorage.dir}`,\n );\n dedupedCount++;\n continue;\n }\n\n // Score importance using local heuristics (Phase 1B).\n // writeCategory / targetStorage already reflect routing.\n const importance = scoreImportance(\n fact.content,\n writeCategory,\n fact.tags,\n );\n\n if (writeCategory === \"procedure\" && this.config.procedural?.enabled !== true) {\n log.debug(\"persistExtraction: skip procedure memory (procedural.enabled is false)\");\n continue;\n }\n\n // Importance write-gate (issue #372). Drop facts whose locally-scored\n // level falls below the configured minimum BEFORE the semantic dedup\n // lookup so that low-importance facts never incur an embedding search.\n // scoreImportance() already applies category boosts (e.g. corrections\n // +0.15) before deriving the level, so a correction at raw ~0.35\n // still lands at \"normal\" and passes the default gate. Without this\n // gate, trivial turn-level chatter (\"hi\", \"k\", heartbeat pings) gets\n // persisted as a fact memory and dilutes the store.\n if (\n !isAboveImportanceThreshold(\n importance.level,\n this.config.extractionMinImportanceLevel,\n )\n ) {\n importanceGatedCount++;\n const snippet = fact.content.slice(0, 60).replace(/\\s+/g, \" \").trim();\n log.debug(`extraction: skip trivial \"${snippet}\"`);\n // Log-based counter (no dedicated metric bus in remnic-core yet).\n // Operators can grep for `metric:importance_gated` in gateway.log\n // to tune extractionMinImportanceLevel.\n log.debug(\n `metric:importance_gated level=${importance.level} threshold=${this.config.extractionMinImportanceLevel} category=${writeCategory} count=${importanceGatedCount}`,\n );\n continue;\n }\n\n // Extraction judge gate (issue #376 + #562 PR 2). After the local\n // importance gate passes, consult the judge verdict (computed before\n // the loop). In active mode, non-durable facts are dropped. In shadow\n // mode, verdicts are logged but all facts proceed to write.\n //\n // Defer verdicts (issue #562): do not persist now, but also do not\n // cache the outcome so the candidate is re-evaluated on a later\n // extraction pass. The judge module tracks how many times the same\n // content has been deferred and converts to reject at the configured\n // cap, so the orchestrator only needs to skip the write here.\n if (judgeVerdictsByFactIndex) {\n const verdict = judgeVerdictsByFactIndex.get(factLoopIndex);\n if (verdict && !verdict.durable) {\n const verdictKind = getVerdictKind(verdict);\n if (this.config.extractionJudgeShadow) {\n log.info(\n `extraction-judge[shadow]: would ${verdictKind} \"${fact.content.slice(0, 60)}…\" reason=\"${verdict.reason}\"`,\n );\n } else if (verdictKind === \"defer\") {\n judgeGatedCount++;\n log.debug(\n `extraction-judge: deferred \"${fact.content.slice(0, 60)}…\" reason=\"${verdict.reason}\"`,\n );\n continue;\n } else {\n judgeGatedCount++;\n log.debug(\n `extraction-judge: rejected \"${fact.content.slice(0, 60)}…\" reason=\"${verdict.reason}\"`,\n );\n continue;\n }\n }\n }\n\n // Procedure extraction gate (issue #519): ≥2 steps + trigger phrasing.\n // Runs even when extractionJudgeEnabled is false (durability judge is unrelated).\n // Never tied to extractionJudgeShadow — that flag is only for the LLM durability judge.\n if (writeCategory === \"procedure\") {\n const procGate = validateProcedureExtraction({\n content: fact.content,\n procedureSteps: fact.procedureSteps,\n });\n if (!procGate.durable) {\n log.debug(\n `extraction-procedure-gate: rejected \"${fact.content.slice(0, 60)}…\" reason=\"${procGate.reason}\"`,\n );\n continue;\n }\n }\n\n // Issue #373 — write-time semantic similarity guard. Hook runs after\n // the exact content-hash miss and the importance gate so that:\n // (a) paraphrased near-duplicates never reach writeMemory(), and\n // (b) low-importance facts that will be dropped never trigger an\n // embedding lookup (avoids unnecessary API latency/cost).\n // Fails open when the embedding backend is unavailable.\n //\n // Defense in depth (PR #399 review): decideSemanticDedup already\n // catches lookup errors internally, and the embedding fetch is\n // bounded by a timeout in embedding-fallback.ts. We still wrap the\n // whole call in its own try/catch here so that any unexpected\n // rejection (future refactors, misbehaving custom backends, etc.)\n // can never block the persist loop — a failure in the dedup path\n // must always default to \"not a duplicate\".\n // Track a pending semantic-skip decision (populated inside the block\n // below). The actual drop happens AFTER contradiction detection so that\n // a high-similarity update/correction is linked as a superseding\n // contradiction rather than silently dropped.\n let pendingSemanticSkip: (SemanticDedupDecision & { action: \"skip\" }) | null = null;\n if (this.config.semanticDedupEnabled) {\n let semanticDecision: SemanticDedupDecision;\n // UUI2: skip embedding lookup for the rest of this batch once we know\n // the backend is unavailable. The flag is reset per-batch (set to false\n // at the top of persistExtraction), so a transient hiccup in one call\n // does not permanently disable dedup in subsequent calls.\n if (batchBackendUnavailable) {\n semanticDecision = { action: \"keep\", reason: \"backend_unavailable\" };\n } else {\n try {\n // Pass the resolved target storage so the lookup scopes the\n // embedding index to the target namespace (PR #399 P1 fix).\n // Without this, a high-similarity hit in a different namespace\n // would cause the fact to be dropped here — cross-namespace\n // write suppression / data loss.\n const lookupStorage = targetStorage;\n semanticDecision = await decideSemanticDedup(\n fact.content,\n (content, limit) =>\n this.semanticDedupLookup(content, limit, lookupStorage),\n {\n enabled: true,\n threshold: this.config.semanticDedupThreshold,\n candidates: this.config.semanticDedupCandidates,\n },\n );\n } catch (err) {\n log.warn(\n `semantic dedup decision failed; failing open and writing fact: ${err}`,\n );\n semanticDecision = {\n action: \"keep\",\n reason: \"backend_unavailable\",\n };\n }\n // UUI2: cache the backend-unavailable signal for the rest of this batch.\n if (semanticDecision.reason === \"backend_unavailable\") {\n batchBackendUnavailable = true;\n }\n }\n if (semanticDecision.action === \"skip\") {\n pendingSemanticSkip = semanticDecision;\n }\n }\n\n const inferredIntent = this.config.intentRoutingEnabled\n ? inferIntentFromText(\n `${writeCategory} ${fact.tags.join(\" \")} ${fact.content}`,\n )\n : null;\n const extractionWriteSource =\n (fact as any).source === \"proactive\"\n ? \"extraction-proactive\"\n : \"extraction\";\n\n // Check for contradictions before writing (Phase 2B).\n // NOTE: This block was moved above the chunking branch so that the\n // pendingSemanticSkip guard (below) can also protect the chunking path.\n // Previously, contradiction detection only ran on the non-chunked path,\n // meaning chunked facts could be persisted even when semanticDecision was\n // \"skip\" (the deferred guard was bypassed by the chunking `continue`).\n let supersedes: string | undefined;\n let links: MemoryLink[] = [];\n // True when contradiction detection ran and confirmed a contradiction,\n // regardless of whether auto-resolve is enabled. Used by the\n // semantic-skip guard so that contradictory updates are never silently\n // dropped — even when `contradictionAutoResolve=false` (in which case\n // `supersedes` is intentionally left unset to avoid retiring the old\n // memory without user confirmation).\n let contradictionDetected = false;\n\n if (this.config.contradictionDetectionEnabled && this.qmd.isAvailable()) {\n const targetNamespace = this.namespaceFromStorageDir(targetStorage.dir);\n const contradiction = await this.checkForContradiction(\n fact.content,\n writeCategory,\n targetNamespace,\n );\n if (contradiction) {\n contradictionDetected = true;\n // When auto-resolve is enabled the existing memory has already been\n // marked superseded; set `supersedes` so the new write carries the\n // relationship. When auto-resolve is disabled we still record the\n // contradiction link (so the memory is annotated for manual review)\n // but do NOT set `supersedes` on the new write — the old memory\n // remains active until a human resolves it.\n if (this.config.contradictionAutoResolve) {\n supersedes = contradiction.supersededId;\n }\n links.push({\n targetId: contradiction.supersededId,\n linkType: \"contradicts\",\n strength: contradiction.confidence,\n reason: contradiction.reason,\n });\n // Deindex the superseded memory so stale paths don't remain in\n // index_time.json / index_tags.json after the incremental update.\n // Only applicable when auto-resolve is on and the old memory is\n // actually being retired; skip when manual review is required.\n if (\n this.config.contradictionAutoResolve &&\n this.config.queryAwareIndexingEnabled &&\n contradiction.supersededPath\n ) {\n deindexMemory(\n this.config.memoryDir,\n contradiction.supersededPath,\n contradiction.supersededCreated,\n contradiction.supersededTags,\n );\n }\n }\n }\n\n // Apply the deferred semantic-skip now that contradiction detection has\n // run. If a contradiction was found (contradictionDetected is true), the\n // candidate is a contradictory update and must be written — do not skip\n // it. Only drop it when there is no detected contradiction (true\n // near-duplicate). This check intentionally runs BEFORE the chunking\n // branch so that a fact flagged as a semantic near-duplicate cannot be\n // persisted (with its hash registered) simply because it was long enough\n // to trigger chunking.\n //\n // NOTE: We use `contradictionDetected` rather than `!!supersedes` here\n // so that facts are preserved even when `contradictionAutoResolve=false`.\n // When auto-resolve is disabled `supersedes` is intentionally unset, but\n // the write must still proceed so the user can manually reconcile the\n // two memories later.\n //\n // UUI1: correction category writes are NEVER suppressed by the semantic\n // skip fallback, regardless of whether supersedes is set. When contradiction\n // detection is disabled or QMD is unavailable, supersedes is never set —\n // without this exemption a high-similarity correction would be silently\n // dropped, leaving a stale fact active. writeCategory (not fact.category)\n // is used because routing rules may have overridden the raw category.\n const isCorrection = writeCategory === \"correction\";\n if (pendingSemanticSkip && !contradictionDetected && !isCorrection) {\n log.debug(\n `dedup: skipping semantic near-duplicate fact \"${fact.content\n .slice(0, 60)\n .replace(/\\s+/g, \" \")}…\" score=${pendingSemanticSkip.topScore.toFixed(\n 3,\n )} neighbor=${pendingSemanticSkip.topId}`,\n );\n dedupedCount++;\n // Do NOT add fact.content to contentHashIndex here. No memory was\n // persisted for this fact, so registering a synthetic hash would\n // permanently suppress exact-copy writes once the neighbor memory is\n // archived or deleted (the hash would linger with no backing record).\n continue;\n }\n\n // Check if chunking is enabled and content should be chunked.\n // When semanticChunkingEnabled is true, prefer the embedding-based\n // semantic chunker which produces more coherent topic-aligned segments.\n // Falls back to the recursive sentence-boundary chunker on failure.\n if (this.config.chunkingEnabled && writeCategory !== \"procedure\") {\n let chunkResult: { chunked: boolean; chunks: { content: string; index: number; tokenCount: number }[] };\n\n if (this.config.semanticChunkingEnabled) {\n try {\n const embedFn = this.embeddingFallback.embedTexts.bind(this.embeddingFallback);\n const semanticResult: SemanticChunkResult = await semanticChunkContent(\n fact.content,\n embedFn,\n this.config.semanticChunkingConfig,\n );\n chunkResult = semanticResult;\n } catch (err) {\n // Honor the fallbackToRecursive contract: when the user explicitly\n // disables fallback, re-throw so extraction fails fast instead of\n // silently using the recursive chunker. semanticChunkContent already\n // throws when fallback is disabled, but this outer catch swallowed\n // that signal. (PR #439 post-merge Finding 1.)\n if (this.config.semanticChunkingConfig?.fallbackToRecursive === false) {\n throw err;\n }\n log.debug(\n `semantic chunking failed, falling back to recursive chunker: ${err}`,\n );\n chunkResult = chunkContent(fact.content, chunkingConfig);\n }\n } else {\n chunkResult = chunkContent(fact.content, chunkingConfig);\n }\n\n if (chunkResult.chunked && chunkResult.chunks.length > 1) {\n // Classify memory kind (v8.0 Phase 2B: HiMem episode/note dual store)\n const memoryKind = this.config.episodeNoteModeEnabled\n ? classifyMemoryKind(fact.content, fact.tags ?? [], writeCategory)\n : undefined;\n\n // Write the parent memory first (with full content for reference).\n //\n // Compute the cited content once so that writeMemory and writeArtifact\n // (when verbatim artifacts are enabled) share the same citation timestamp.\n // See the normal write path comment for the full dedup rationale.\n //\n // Propagate supersedes/links from contradiction detection (round 6\n // fix): contradiction detection now runs BEFORE this branch so the\n // parent must carry the supersession relationship — without it the\n // old memory is deindexed but the new chunked parent has no link\n // back, leaving a dangling deindex with no replacement reference.\n // Child chunks intentionally do NOT carry supersedes; only the\n // parent represents the logical memory unit.\n //\n // Canonicalize contentHashSource before writing (Thread 3 — Codex P2,\n // issue #369). If fact.content already carries an inline citation\n // (e.g. re-processed or relayed fact), strip it so contentHashSource\n // records the raw un-cited body — matching what the dedup check hashes\n // via stripCitationForTemplate before calling hasFactContentHash.\n const rawChunkedContent =\n citationEnabled &&\n hasCitationForTemplate(fact.content, citationTemplate)\n ? stripCitationForTemplate(fact.content, citationTemplate)\n : fact.content;\n const citedChunkedContent = applyInlineCitation(rawChunkedContent);\n const parentId = await targetStorage.writeMemory(\n writeCategory,\n citedChunkedContent,\n {\n confidence: fact.confidence,\n tags: [...fact.tags, \"chunked\"],\n entityRef: fact.entityRef,\n source: extractionWriteSource,\n importance,\n supersedes,\n links: links.length > 0 ? links : undefined,\n intentGoal: inferredIntent?.goal,\n intentActionType: inferredIntent?.actionType,\n intentEntityTypes: inferredIntent?.entityTypes,\n memoryKind,\n structuredAttributes: fact.structuredAttributes,\n validAt: sourceContext?.validAt,\n contentHashSource: rawChunkedContent,\n },\n );\n try {\n // Write individual chunks with parent reference\n for (const chunk of chunkResult.chunks) {\n // Score each chunk's importance separately\n const chunkImportance = scoreImportance(\n chunk.content,\n writeCategory,\n fact.tags,\n );\n const chunkWriteSource =\n (fact as any).source === \"proactive\"\n ? \"chunking-proactive\"\n : \"chunking\";\n\n await targetStorage.writeChunk(\n parentId,\n chunk.index,\n chunkResult.chunks.length,\n writeCategory,\n // Each chunk carries its own inline citation so provenance\n // survives when a single chunk is quoted in isolation.\n applyInlineCitation(chunk.content),\n {\n confidence: fact.confidence,\n tags: fact.tags,\n entityRef: fact.entityRef,\n source: chunkWriteSource,\n importance: chunkImportance,\n intentGoal: inferredIntent?.goal,\n intentActionType: inferredIntent?.actionType,\n intentEntityTypes: inferredIntent?.entityTypes,\n memoryKind,\n validAt: sourceContext?.validAt,\n },\n );\n }\n } finally {\n // The parent memory is durable once writeMemory returns `parentId`.\n // Touch immediately around the chunk-write loop so a later chunk\n // failure still surfaces the partially durable parent/chunk files to\n // catalog-driven `writtenSince` maintenance. The final touch below\n // still refreshes `lastWriteAt` after later durable writes on success.\n this.markCatalogWrite(targetNamespaceName, targetStorage.dir);\n }\n\n if (routedRuleId) {\n log.debug(\n `routing applied for chunked memory ${parentId}: rule=${routedRuleId} category=${writeCategory} storage=${targetStorage.dir}`,\n );\n }\n log.debug(\n `chunked memory ${parentId} into ${chunkResult.chunks.length} chunks`,\n );\n trackPersistedId(targetStorage, parentId);\n if (\n threadEpisodeIdsForGraph &&\n !threadEpisodeIdsForGraph.includes(parentId)\n ) {\n threadEpisodeIdsForGraph.push(parentId);\n }\n await this.indexPersistedMemory(targetStorage, parentId);\n // PR #402 Thread 1 fix: run source-namespace temporal supersession for\n // chunked writes, matching the non-chunked path. Without this the\n // source namespace retains stale facts that should have been superseded.\n try {\n const supersessionEntityRef =\n typeof (fact as any).entityRef === \"string\"\n ? ((fact as any).entityRef as string)\n : undefined;\n await applyTemporalSupersession({\n storage: targetStorage,\n newMemoryId: parentId,\n entityRef: supersessionEntityRef,\n structuredAttributes: fact.structuredAttributes,\n createdAt: supersessionOrderingAt(sourceContext?.validAt),\n enabled: this.config.temporalSupersessionEnabled,\n });\n } catch (err) {\n log.warn(`temporal-supersession (chunked): unexpected error: ${err}`);\n }\n await promoteMemoryToShared({\n sourceStorage: targetStorage,\n category: writeCategory,\n content: fact.content,\n confidence: fact.confidence,\n tags: fact.tags,\n entityRef: fact.entityRef,\n structuredAttributes: fact.structuredAttributes,\n sourceMemoryId: parentId,\n importance,\n intentGoal: inferredIntent?.goal,\n intentActionType: inferredIntent?.actionType,\n intentEntityTypes: inferredIntent?.entityTypes,\n memoryKind,\n validAt: sourceContext?.validAt,\n source: extractionWriteSource,\n });\n // Register chunked content in the target storage hash index too.\n // Thread 3 fix: canonicalize by stripping any pre-existing citation\n // so the stored hash matches what the dedup check computes.\n try {\n const canonicalChunkedContent =\n citationEnabled &&\n hasCitationForTemplate(fact.content, citationTemplate)\n ? stripCitationForTemplate(fact.content, citationTemplate)\n : fact.content;\n await this.addContentHashDedup(targetStorage, canonicalChunkedContent);\n } catch (err) {\n log.warn(\n `content-hash dedup registration failed for chunked memory ${parentId}: ${err}`,\n );\n }\n\n for (const chunk of chunkResult.chunks) {\n const chunkId = `${parentId}-chunk-${chunk.index}`;\n // Do NOT push chunkId into persistedIds — chunk IDs must not leak\n // into boxBuilder.onExtraction() or threading.processTurn(), which\n // only expect canonical parent memory IDs. Call indexPersistedMemory\n // directly for embedding-fallback sync of each chunk document.\n await this.indexPersistedMemory(targetStorage, chunkId);\n }\n try {\n if (\n this.config.verbatimArtifactsEnabled &&\n this.config.verbatimArtifactCategories.includes(writeCategory) &&\n fact.confidence >= this.config.verbatimArtifactsMinConfidence\n ) {\n // Reuse citedChunkedContent so the artifact carries the same citation\n // timestamp as the parent memory write above (Fix #3 — duplicate-citation).\n await targetStorage.writeArtifact(citedChunkedContent, {\n confidence: fact.confidence,\n tags: [...fact.tags, \"artifact\", \"chunked-parent\"],\n artifactType: this.artifactTypeForCategory(writeCategory),\n sourceMemoryId: parentId,\n intentGoal: inferredIntent?.goal,\n intentActionType: inferredIntent?.actionType,\n intentEntityTypes: inferredIntent?.entityTypes,\n });\n }\n // v8.2: graph edge building for chunked memories\n if (this.config.multiGraphMemoryEnabled) {\n try {\n const graphContext = await ensureGraphContext(targetStorage);\n const entityRef =\n typeof (fact as any).entityRef === \"string\"\n ? (fact as any).entityRef\n : undefined;\n const parentRelPath = resolvePersistedMemoryRelativePath({\n memoryId: parentId,\n pathById: graphContext.memoryPathById,\n category: writeCategory,\n });\n graphContext.memoryPathById.set(parentId, parentRelPath);\n appendMemoryToGraphContext({\n allMemsForGraph: graphContext.allMemsForGraph,\n storageDir: targetStorage.dir,\n memoryRelPath: parentRelPath,\n memoryId: parentId,\n category: writeCategory,\n content: fact.content ?? \"\",\n entityRef,\n });\n await this.buildGraphEdge(\n targetStorage,\n parentRelPath,\n entityRef,\n parentId,\n fact.content ?? \"\",\n graphContext.allMemsForGraph,\n graphContext.memoryPathById,\n threadIdForExtraction ?? undefined,\n threadEpisodeIdsForGraph,\n graphContext.previousPersistedRelPath,\n );\n graphContext.previousPersistedRelPath = parentRelPath;\n } catch {\n /* fail-open */\n }\n }\n } finally {\n // Catalog touch (issue #1499): refresh AFTER later chunked\n // source-namespace durable mutations — temporal supersession, shared\n // promotion, optional artifact writes, and graph-edge writes — so\n // `lastWriteAt` cannot precede later file changes on successful\n // completion. Use the KNOWN routed name, not a dir-decoded guess.\n this.markCatalogWrite(targetNamespaceName, targetStorage.dir);\n }\n trackBehaviorSignals(\n targetStorage,\n buildBehaviorSignalsForMemory({\n memoryId: parentId,\n category: writeCategory,\n content: fact.content,\n namespace: this.namespaceFromStorageDir(targetStorage.dir),\n confidence: fact.confidence,\n source: \"extraction\",\n }),\n );\n continue; // Skip the normal write below\n }\n }\n\n // Suggest links for this memory (Phase 3A)\n if (this.config.memoryLinkingEnabled && this.qmd.isAvailable()) {\n const targetNamespace = this.namespaceFromStorageDir(targetStorage.dir);\n const suggestedLinks = await this.suggestLinksForMemory(\n fact.content,\n writeCategory,\n targetNamespace,\n );\n if (suggestedLinks.length > 0) {\n links.push(...suggestedLinks);\n }\n }\n\n // Classify memory kind (v8.0 Phase 2B: HiMem episode/note dual store)\n const memoryKind =\n writeCategory === \"procedure\"\n ? undefined\n : this.config.episodeNoteModeEnabled\n ? classifyMemoryKind(fact.content, fact.tags ?? [], writeCategory)\n : undefined;\n\n // Normal write (no chunking)\n //\n // Compute the cited content once so that writeMemory and writeArtifact\n // (when verbatim artifacts are enabled) share the same citation timestamp.\n // Calling applyInlineCitation twice on the same raw content would produce\n // two different timestamps, creating duplicate citations with divergent\n // provenance metadata on the memory and artifact copies of the same fact.\n //\n // Pass the RAW (pre-citation) fact as `contentHashSource` so the\n // fact-content hash index records the hash of the canonical fact text\n // rather than the citation-annotated variant. When inline attribution is\n // enabled, `applyInlineCitation` appends a timestamp-bearing marker, so\n // hashing the persisted body would produce a different hash on every\n // write and defeat cross-session dedup (see `findDuplicateExplicitCapture`\n // in explicit-capture.ts which calls `hasFactContentHash(candidate.content)`\n // on raw content).\n const rawPersistBody =\n writeCategory === \"procedure\"\n ? buildProcedurePersistBody(fact.content, fact.procedureSteps)\n : fact.content;\n const citedFactContent = applyInlineCitation(rawPersistBody);\n const memoryId = await targetStorage.writeMemory(\n writeCategory,\n citedFactContent,\n {\n confidence: fact.confidence,\n tags: fact.tags,\n entityRef:\n typeof (fact as any).entityRef === \"string\"\n ? (fact as any).entityRef\n : undefined,\n source: extractionWriteSource,\n importance,\n supersedes,\n links: links.length > 0 ? links : undefined,\n intentGoal: inferredIntent?.goal,\n intentActionType: inferredIntent?.actionType,\n intentEntityTypes: inferredIntent?.entityTypes,\n memoryKind,\n structuredAttributes: fact.structuredAttributes,\n validAt: sourceContext?.validAt,\n contentHashSource: writeCategory === \"fact\" ? fact.content : undefined,\n },\n );\n if (routedRuleId) {\n log.debug(\n `routing applied for memory ${memoryId}: rule=${routedRuleId} category=${writeCategory} storage=${targetStorage.dir}`,\n );\n }\n // Temporal supersession (issue #375): when the new fact has structured\n // attributes, retire any older fact with the same entity + attribute\n // key that has a conflicting value.\n try {\n const supersessionEntityRef =\n typeof (fact as any).entityRef === \"string\"\n ? ((fact as any).entityRef as string)\n : undefined;\n await applyTemporalSupersession({\n storage: targetStorage,\n newMemoryId: memoryId,\n entityRef: supersessionEntityRef,\n structuredAttributes: fact.structuredAttributes,\n createdAt: supersessionOrderingAt(sourceContext?.validAt),\n enabled: this.config.temporalSupersessionEnabled,\n });\n } catch (err) {\n log.warn(`temporal-supersession: unexpected error: ${err}`);\n }\n try {\n trackBehaviorSignals(\n targetStorage,\n buildBehaviorSignalsForMemory({\n memoryId,\n category: writeCategory,\n content: fact.content,\n namespace: this.namespaceFromStorageDir(targetStorage.dir),\n confidence: fact.confidence,\n source: \"extraction\",\n }),\n );\n trackPersistedId(targetStorage, memoryId);\n if (\n threadEpisodeIdsForGraph &&\n !threadEpisodeIdsForGraph.includes(memoryId)\n ) {\n threadEpisodeIdsForGraph.push(memoryId);\n }\n await this.indexPersistedMemory(targetStorage, memoryId);\n await promoteMemoryToShared({\n sourceStorage: targetStorage,\n category: writeCategory,\n content: fact.content,\n confidence: fact.confidence,\n tags: fact.tags,\n entityRef:\n typeof (fact as any).entityRef === \"string\"\n ? (fact as any).entityRef\n : undefined,\n structuredAttributes: fact.structuredAttributes,\n sourceMemoryId: memoryId,\n importance,\n intentGoal: inferredIntent?.goal,\n intentActionType: inferredIntent?.actionType,\n intentEntityTypes: inferredIntent?.entityTypes,\n memoryKind,\n validAt: sourceContext?.validAt,\n source: extractionWriteSource,\n });\n // v8.2: graph edge building (fail-open — errors caught inside GraphIndex)\n if (this.config.multiGraphMemoryEnabled) {\n try {\n const graphContext = await ensureGraphContext(targetStorage);\n const entityRef =\n typeof (fact as any).entityRef === \"string\"\n ? (fact as any).entityRef\n : undefined;\n const memoryRelPath = resolvePersistedMemoryRelativePath({\n memoryId,\n pathById: graphContext.memoryPathById,\n category: writeCategory,\n });\n graphContext.memoryPathById.set(memoryId, memoryRelPath);\n appendMemoryToGraphContext({\n allMemsForGraph: graphContext.allMemsForGraph,\n storageDir: targetStorage.dir,\n memoryRelPath: memoryRelPath,\n memoryId,\n category: writeCategory,\n content: fact.content ?? \"\",\n entityRef,\n });\n await this.buildGraphEdge(\n targetStorage,\n memoryRelPath,\n entityRef,\n memoryId,\n fact.content ?? \"\",\n graphContext.allMemsForGraph,\n graphContext.memoryPathById,\n threadIdForExtraction ?? undefined,\n threadEpisodeIdsForGraph,\n graphContext.previousPersistedRelPath,\n );\n graphContext.previousPersistedRelPath = memoryRelPath;\n } catch {\n /* fail-open */\n }\n }\n if (\n this.config.verbatimArtifactsEnabled &&\n this.config.verbatimArtifactCategories.includes(writeCategory) &&\n fact.confidence >= this.config.verbatimArtifactsMinConfidence\n ) {\n // Reuse citedFactContent so the artifact carries the same citation\n // timestamp as the memory write above (Fix #3 — duplicate-citation).\n await targetStorage.writeArtifact(citedFactContent, {\n confidence: fact.confidence,\n tags: [...fact.tags, \"artifact\"],\n artifactType: this.artifactTypeForCategory(writeCategory),\n sourceMemoryId: memoryId,\n intentGoal: inferredIntent?.goal,\n intentActionType: inferredIntent?.actionType,\n intentEntityTypes: inferredIntent?.entityTypes,\n });\n }\n // Register in the target storage content-hash index after successful\n // write. Thread 3 fix: canonicalize by stripping any pre-existing\n // citation so the stored hash matches what the dedup check computes.\n try {\n const canonicalFactContent =\n citationEnabled &&\n hasCitationForTemplate(fact.content, citationTemplate)\n ? stripCitationForTemplate(fact.content, citationTemplate)\n : fact.content;\n const hashRegisterKey =\n writeCategory === \"procedure\"\n ? buildProcedurePersistBody(fact.content, fact.procedureSteps)\n : canonicalFactContent;\n await this.addContentHashDedup(targetStorage, hashRegisterKey);\n } catch (err) {\n log.warn(\n `content-hash dedup registration failed for memory ${memoryId}: ${err}`,\n );\n }\n } finally {\n // Catalog touch (issue #1499): record AFTER every synchronous\n // source-namespace mutation in the non-chunked path: writeMemory,\n // temporal supersession, graph edges, and optional verbatim artifacts.\n // The `finally` preserves the write touch when post-write indexing or\n // promotion fails after the canonical memory is already durable. Use the\n // KNOWN routed name, not a dir-decoded guess (NCQI0).\n this.markCatalogWrite(targetNamespaceName, targetStorage.dir);\n }\n }\n\n // Tracks whether THIS extraction persisted any durable, non-fact output to the\n // BASE namespace's storage (entity / relationship / profile / question). The\n // per-fact `markCatalogWrite` only fires inside the fact write loop, so a\n // fact-less extraction that still persists durable data must record exactly one\n // base-namespace catalog touch after all writes complete (NHZEZ, codex P2).\n let durableNonFactWritten = false;\n let durableNonFactTouchRecorded = false;\n const touchBaseNonFactNamespace = () => {\n const baseTouchNamespace =\n baseNamespace && baseNamespace.length > 0\n ? baseNamespace\n : this.namespaceFromStorageDir(storage.dir);\n this.markCatalogWrite(baseTouchNamespace, storage.dir);\n };\n const recordDurableNonFactWrite = () => {\n durableNonFactWritten = true;\n if (durableNonFactTouchRecorded) return;\n durableNonFactTouchRecorded = true;\n touchBaseNonFactNamespace();\n };\n for (const entity of entities) {\n try {\n const name = (entity as any)?.name;\n const type = (entity as any)?.type;\n if (\n typeof name !== \"string\" ||\n !name.trim() ||\n typeof type !== \"string\" ||\n !type.trim()\n ) {\n continue;\n }\n const safeFacts = Array.isArray((entity as any)?.facts)\n ? (entity as any).facts.filter((f: any) => typeof f === \"string\")\n : [];\n const id = await storage.writeEntity(name, type, safeFacts, {\n source: typeof (entity as any)?.source === \"string\" ? (entity as any).source : \"extraction\",\n timestamp: sourceContext?.validAt,\n sessionKey: sourceContext?.sessionKey,\n principal: sourceContext?.principal,\n structuredSections: Array.isArray((entity as any)?.structuredSections)\n ? (entity as any).structuredSections\n : undefined,\n });\n if (id) {\n trackPersistedId(storage, id);\n recordDurableNonFactWrite();\n }\n } catch (err) {\n log.warn(`persistExtraction: entity write failed: ${err}`);\n }\n }\n\n // Persist entity relationships (v7.0)\n if (\n this.config.entityRelationshipsEnabled &&\n Array.isArray(result.relationships)\n ) {\n for (const rel of result.relationships.slice(0, 5)) {\n if (!rel.source || !rel.target || !rel.label) continue;\n try {\n // Add bidirectional relationship\n await storage.addEntityRelationship(rel.source, {\n target: rel.target,\n label: rel.label,\n });\n recordDurableNonFactWrite();\n await storage.addEntityRelationship(rel.target, {\n target: rel.source,\n label: `${rel.label} (reverse)`,\n });\n recordDurableNonFactWrite();\n } catch (err) {\n log.debug(`relationship persist failed: ${err}`);\n }\n }\n }\n\n // Persist entity activity (v7.0)\n if (this.config.entityActivityLogEnabled) {\n const today = new Date().toISOString().slice(0, 10);\n for (const entity of entities) {\n const name = (entity as any)?.name;\n const type = (entity as any)?.type;\n if (typeof name !== \"string\" || typeof type !== \"string\") continue;\n try {\n const normalized = storage.normalizeEntityName(name, type);\n await storage.addEntityActivity(\n normalized,\n { date: today, note: \"Mentioned in conversation\" },\n this.config.entityActivityLogMaxEntries,\n );\n } catch (err) {\n log.debug(`activity persist failed: ${err}`);\n }\n }\n }\n\n if (profileUpdates.length > 0) {\n await storage.appendToProfile(profileUpdates);\n recordDurableNonFactWrite();\n }\n\n // Persist questions\n for (const q of questions) {\n const id = await storage.writeQuestion(q.question, q.context, q.priority);\n if (id) {\n trackPersistedId(storage, id);\n recordDurableNonFactWrite();\n }\n }\n\n // Persist identity reflection. This writes durable namespace-local state, so\n // an identity-ONLY extraction (no facts/entities/profile/questions) still\n // counts as a durable non-fact write for the catalog touch below (NIIly).\n // Only count it when the write actually succeeds (best-effort write); the\n // touch is recorded AFTER this so a rolled-back/failed write never touches.\n if (this.config.identityEnabled && result.identityReflection) {\n try {\n await storage.appendIdentityReflection(result.identityReflection);\n recordDurableNonFactWrite();\n } catch (err) {\n log.debug(`identity reflection write failed: ${err}`);\n }\n }\n\n // Catalog touch for durable NON-FACT outputs (NHZEZ / NIIly, codex P2). The\n // per-fact `markCatalogWrite` above only fires inside the fact write loop, so\n // an extraction that persists ONLY entities, relationships, profile updates,\n // questions, or an identity reflection (no facts) would record durable data to\n // the BASE namespace's storage without ever touching the catalog — leaving that\n // namespace's `lastWriteAt` stale so `listNamespaces({writtenSince})` /\n // write-recency QMD maintenance miss the write. All of these are written to the\n // BASE `storage` (not the per-fact routed `targetStorage`), so we record ONE\n // base-namespace touch here, AFTER every non-fact write completes. Use the\n // KNOWN base namespace name, not a dir-decoded guess (NCQI0). One touch per\n // namespace per extraction — `markWrite` is idempotent, so if the fact path\n // already touched the base namespace this only refreshes `lastWriteAt`.\n // Best-effort and failure-tolerant (markCatalogWrite swallows errors).\n if (durableNonFactWritten) {\n touchBaseNonFactNamespace();\n }\n\n // Save any content-hash indexes touched during the batch.\n await this.saveContentHashIndexes().catch((err) =>\n log.warn(`content-hash index save failed: ${err}`),\n );\n\n for (const {\n storage: targetStorage,\n events,\n } of behaviorSignalsByStorage.values()) {\n const dedupedSignals = dedupeBehaviorSignalsByMemoryAndHash(events);\n if (dedupedSignals.length === 0) continue;\n await targetStorage\n .appendBehaviorSignals(dedupedSignals)\n .catch((err) =>\n log.warn(`appendBehaviorSignals failed (non-fatal): ${err}`),\n );\n }\n\n const dedupSuffix = dedupedCount > 0 ? ` (${dedupedCount} deduped)` : \"\";\n const gatedSuffix =\n importanceGatedCount > 0 ? ` (${importanceGatedCount} gated)` : \"\";\n const judgeSuffix =\n judgeGatedCount > 0 ? ` (${judgeGatedCount} judge-rejected)` : \"\";\n log.info(\n `persisted: ${facts.length - dedupedCount - importanceGatedCount - judgeGatedCount} facts${dedupSuffix}${gatedSuffix}${judgeSuffix}, ${entities.length} entities, ${questions.length} questions, ${profileUpdates.length} profile updates`,\n );\n\n // Update temporal + tag indexes (v8.1) — fire-and-forget, fail-open\n void (async () => {\n if (persistedIdsByStorage.size === 0) {\n await this.updateTemporalTagIndexes(storage, []);\n return;\n }\n for (const entry of persistedIdsByStorage.values()) {\n await this.updateTemporalTagIndexes(entry.storage, entry.ids);\n }\n })().catch((err) =>\n log.debug(`temporal-index update error (non-fatal): ${err}`),\n );\n\n // Return the persisted fact IDs for threading\n return persistedIds;\n }\n\n private async indexPersistedMemory(\n storage: StorageManager,\n memoryId: string,\n ): Promise<void> {\n if (!this.config.embeddingFallbackEnabled) return;\n if (!(await this.embeddingFallback.isAvailable())) return;\n const memory = await storage.getMemoryById(memoryId);\n if (!memory) return;\n await this.embeddingFallback.indexFile(\n memoryId,\n memory.content,\n memory.path,\n );\n }\n\n /**\n * Build a graph edge for a persisted memory (v8.2).\n * Shared helper used by both the chunked and non-chunked write paths to avoid duplication.\n * Fail-open: caller wraps in try/catch.\n */\n private async buildGraphEdge(\n storage: StorageManager,\n memoryRelPath: string,\n entityRef: string | undefined,\n memoryId: string,\n factContent: string,\n allMemsForGraph: import(\"./types.js\").MemoryFile[] | null | undefined,\n memoryPathById: Map<string, string>,\n threadIdForEdge: string | undefined,\n threadEpisodeIdsForGraph: string[] | undefined,\n fallbackCausalPredecessor: string | undefined,\n ): Promise<void> {\n // Entity siblings: other memories sharing the same entityRef\n const entitySiblings: string[] = [];\n if (entityRef) {\n try {\n const allMems = allMemsForGraph ?? [];\n for (const m of allMems) {\n if (m.frontmatter.entityRef === entityRef) {\n const rel = path.relative(storage.dir, m.path);\n if (rel !== memoryRelPath) entitySiblings.push(rel);\n }\n }\n } catch {\n /* fail-open */\n }\n }\n // Recent thread memories for time graph\n const recentInThread: string[] = [];\n if (threadIdForEdge && threadEpisodeIdsForGraph?.length) {\n try {\n recentInThread.push(\n ...resolveRecentThreadMemoryPaths({\n threadEpisodeIds: threadEpisodeIdsForGraph,\n currentMemoryId: memoryId,\n allMemsForGraph,\n pathById: memoryPathById,\n storageDir: storage.dir,\n maxRecent: 3,\n }),\n );\n } catch {\n /* fail-open */\n }\n }\n if (\n recentInThread.length === 0 &&\n this.config.graphWriteSessionAdjacencyEnabled !== false &&\n fallbackCausalPredecessor &&\n fallbackCausalPredecessor !== memoryRelPath\n ) {\n recentInThread.push(fallbackCausalPredecessor);\n }\n const causalPredecessor =\n recentInThread[recentInThread.length - 1] ?? fallbackCausalPredecessor;\n await this.graphIndexFor(storage).onMemoryWritten({\n memoryPath: memoryRelPath,\n entityRef,\n content: factContent,\n created: new Date().toISOString(),\n threadId: threadIdForEdge,\n recentInThread,\n entitySiblings,\n causalPredecessor,\n });\n }\n\n private graphIndexFor(storage: StorageManager): GraphIndex {\n const key = storage.dir;\n const existing = this.graphIndexes.get(key);\n if (existing) return existing;\n const created = new GraphIndex(key, this.config);\n this.graphIndexes.set(key, created);\n return created;\n }\n\n /**\n * Batch-update temporal and tag indexes after extraction (v8.1).\n * Reads each persisted memory's path + frontmatter and adds them to\n * state/index_time.json and state/index_tags.json.\n * Fail-open: any error is logged but does not abort extraction.\n */\n private async updateTemporalTagIndexes(\n storage: StorageManager,\n persistedIds: string[],\n ): Promise<void> {\n // Build temporal/tag indexes whenever either consumer is enabled:\n // - queryAwareIndexingEnabled: uses indexes for query-aware prefiltering in recall\n // - parallelRetrievalEnabled: temporal agent reads index_time.json for date-range lookup\n // Enabling only parallelRetrievalEnabled without queryAwareIndexingEnabled would silently\n // produce an empty temporal index, leaving the temporal agent with no data to work from.\n if (\n !this.config.queryAwareIndexingEnabled &&\n !this.config.parallelRetrievalEnabled\n )\n return;\n // Check for missing indexes BEFORE the early-return so first-time enablement\n // can bootstrap the full corpus even when this extraction turn persisted nothing.\n const needsFullRebuild = !indexesExist(this.config.memoryDir);\n if (!needsFullRebuild && persistedIds.length === 0) return;\n try {\n // Read the corpus once to avoid N separate full-corpus scans.\n // On full rebuild with namespaces enabled, span all configured namespaces so\n // memories written to other namespaces before the index existed are also captured.\n const allMemories =\n needsFullRebuild && this.config.namespacesEnabled\n ? await this.readAllMemoriesForNamespaces(\n Array.from(\n new Set<string>([\n this.config.defaultNamespace,\n this.config.sharedNamespace,\n ...this.config.namespacePolicies.map((p) => p.name),\n ]),\n ),\n )\n : await storage.readAllMemories();\n\n // Bootstrap: index only active (non-archived, non-superseded) memories.\n // Incremental: index only the newly persisted IDs.\n const pool = needsFullRebuild\n ? allMemories.filter((m) => isActiveMemoryStatus(m.frontmatter.status))\n : (() => {\n const idSet = new Set(persistedIds);\n return allMemories.filter((m) => idSet.has(m.frontmatter.id));\n })();\n\n const entries: Array<{\n path: string;\n createdAt: string;\n tags: string[];\n }> = [];\n for (const mem of pool) {\n if (mem.path && mem.frontmatter?.created) {\n entries.push({\n path: mem.path,\n createdAt: mem.frontmatter.created,\n tags: mem.frontmatter.tags ?? [],\n });\n }\n }\n if (needsFullRebuild) {\n // Always write empty indexes on full rebuild — even when the active pool\n // is empty (e.g. store contains only archived/superseded entries).\n // This marks bootstrap completion so indexesExist() returns true and\n // subsequent extractions skip the full-corpus scan.\n clearIndexes(this.config.memoryDir);\n if (entries.length > 0) {\n indexMemoriesBatch(this.config.memoryDir, entries);\n }\n log.info(\n `temporal-index: bootstrapped from ${entries.length} active memories`,\n );\n } else if (entries.length > 0) {\n indexMemoriesBatch(this.config.memoryDir, entries);\n }\n } catch (err) {\n log.debug(`temporal-index update failed (non-fatal): ${err}`);\n }\n }\n\n /** IDs of facts persisted in the last extraction */\n private lastPersistedIds: string[] = [];\n\n private async runConsolidation(): Promise<{\n memoriesProcessed: number;\n merged: number;\n invalidated: number;\n }> {\n log.info(\"running consolidation pass\");\n let merged = 0;\n let invalidated = 0;\n // Tracks whether any consolidation memory-item action (UPDATE / MERGE /\n // INVALIDATE) durably rewrote memory state. A consolidation pass that only\n // mutates memory items (no profile/entity updates) still changes the default\n // namespace's data, so its catalog `lastWriteAt` must refresh too (NIBOi).\n let memoryItemMutated = false;\n\n // Flush access tracking buffer first\n if (this.accessTrackingBuffer.size > 0) {\n await this.flushAccessTracking();\n }\n\n let allMemories = await this.storage.readAllMemories();\n if (allMemories.length < 5) {\n return { memoriesProcessed: allMemories.length, merged, invalidated };\n }\n\n const recent = allMemories\n .sort(\n (a, b) =>\n new Date(b.frontmatter.created).getTime() -\n new Date(a.frontmatter.created).getTime(),\n )\n .slice(0, 20);\n\n const older = allMemories.sort(\n (a, b) =>\n new Date(a.frontmatter.created).getTime() -\n new Date(b.frontmatter.created).getTime(),\n );\n\n const profile = await this.storage.readProfile();\n const result = await this.extraction.consolidate(recent, older, profile);\n\n // Build a lookup map from the already-loaded corpus to avoid repeated\n // readAllMemories() scans inside getMemoryById for pre-action deindex reads.\n const memoryLookup = this.config.queryAwareIndexingEnabled\n ? new Map(allMemories.map((m) => [m.frontmatter.id, m]))\n : null;\n\n for (const item of result.items) {\n switch (item.action) {\n case \"INVALIDATE\": {\n // Capture path/frontmatter before invalidation for index cleanup\n const toInvalidate = this.config.queryAwareIndexingEnabled\n ? (memoryLookup?.get(item.existingId) ?? null)\n : null;\n if (await this.storage.invalidateMemory(item.existingId)) {\n invalidated += 1;\n memoryItemMutated = true;\n await this.embeddingFallback.removeFromIndex(item.existingId);\n if (toInvalidate?.path && toInvalidate.frontmatter?.created) {\n deindexMemory(\n this.config.memoryDir,\n toInvalidate.path,\n toInvalidate.frontmatter.created,\n toInvalidate.frontmatter.tags ?? [],\n );\n }\n }\n break;\n }\n case \"UPDATE\":\n if (item.updatedContent) {\n await this.storage.updateMemory(\n item.existingId,\n item.updatedContent,\n {\n lineage: [item.existingId],\n },\n );\n memoryItemMutated = true;\n await this.indexPersistedMemory(this.storage, item.existingId);\n // updateMemory() only changes content/updated/lineage — path, created, and tags\n // are preserved, so the temporal/tag index entry is already correct; no reindex needed.\n }\n break;\n case \"MERGE\":\n if (item.updatedContent && item.mergeWith) {\n await this.storage.updateMemory(\n item.existingId,\n item.updatedContent,\n {\n supersedes: item.mergeWith,\n lineage: [item.existingId, item.mergeWith],\n },\n );\n memoryItemMutated = true;\n await this.indexPersistedMemory(this.storage, item.existingId);\n // updateMemory() only changes content/updated/supersedes/lineage — path, created, and tags\n // are preserved, so the temporal/tag index entry for the survivor is already correct.\n // Capture before invalidation for index cleanup\n const toMergeInvalidate = this.config.queryAwareIndexingEnabled\n ? (memoryLookup?.get(item.mergeWith) ?? null)\n : null;\n if (await this.storage.invalidateMemory(item.mergeWith)) {\n invalidated += 1;\n merged += 1;\n await this.embeddingFallback.removeFromIndex(item.mergeWith);\n if (\n toMergeInvalidate?.path &&\n toMergeInvalidate.frontmatter?.created\n ) {\n deindexMemory(\n this.config.memoryDir,\n toMergeInvalidate.path,\n toMergeInvalidate.frontmatter.created,\n toMergeInvalidate.frontmatter.tags ?? [],\n );\n }\n }\n }\n break;\n }\n }\n\n if (result.profileUpdates.length > 0) {\n await this.storage.appendToProfile(result.profileUpdates);\n }\n\n for (const entity of result.entityUpdates) {\n const safeFacts = Array.isArray((entity as any)?.facts)\n ? (entity as any).facts.filter((f: any) => typeof f === \"string\")\n : [];\n await this.storage.writeEntity(entity.name, entity.type, safeFacts, {\n source: \"consolidation\",\n structuredSections: Array.isArray((entity as any)?.structuredSections)\n ? (entity as any).structuredSections\n : undefined,\n });\n }\n\n // Catalog write touch accounting (issue #1499 sweep): consolidation persists\n // durable mutations directly to the default-namespace `this.storage`, bypassing\n // the extraction write path. We do NOT touch here — later maintenance steps in\n // this same function (entity-file merges, expired-commitment / TTL cleanup,\n // fact archival) can ALSO mutate the namespace on a run with no LLM outputs\n // (NIjwl). So we accumulate every durable mutation into `memoryItemMutated` and\n // record ONE consolidated touch AFTER all mutation-producing steps complete,\n // just before returning (rule #25: touch after the write commits). LLM\n // profile/entity updates and memory-item actions (UPDATE / MERGE / INVALIDATE)\n // count here (NIBOi).\n if (result.profileUpdates.length > 0 || result.entityUpdates.length > 0) {\n memoryItemMutated = true;\n }\n\n // Merge fragmented entity files\n const entitiesMerged = await this.storage.mergeFragmentedEntities();\n if (entitiesMerged > 0) {\n memoryItemMutated = true;\n log.info(`merged ${entitiesMerged} fragmented entity files`);\n }\n\n if (this.config.entitySummaryEnabled) {\n try {\n const synthesized = await this.processEntitySynthesisQueue(\n this.config.defaultNamespace,\n 5,\n );\n if (synthesized > 0) {\n // Entity synthesis rewrites entity files — a durable namespace mutation,\n // so record it for the catalog touch even when it is the only change in\n // the pass (codex). Otherwise lastWriteAt goes stale.\n memoryItemMutated = true;\n log.info(`refreshed ${synthesized} entity syntheses`);\n }\n } catch (err) {\n log.debug(`entity synthesis pass failed: ${err}`);\n }\n }\n\n // Clean expired commitments\n const deletedCommitments = await this.storage.cleanExpiredCommitments(\n this.config.commitmentDecayDays,\n );\n if (deletedCommitments.length > 0) {\n memoryItemMutated = true;\n log.info(`cleaned ${deletedCommitments.length} expired commitments`);\n if (this.config.queryAwareIndexingEnabled) {\n for (const m of deletedCommitments) {\n deindexMemory(\n this.config.memoryDir,\n m.path,\n m.frontmatter.created,\n m.frontmatter.tags ?? [],\n );\n }\n }\n }\n\n if (\n this.config.creationMemoryEnabled &&\n this.config.commitmentLedgerEnabled &&\n this.config.commitmentLifecycleEnabled\n ) {\n try {\n const lifecycle = await applyCommitmentLedgerLifecycle({\n memoryDir: this.config.memoryDir,\n commitmentLedgerDir: this.config.commitmentLedgerDir,\n enabled: true,\n decayDays: this.config.commitmentDecayDays,\n });\n if (\n lifecycle.transitionedToExpired.length > 0 ||\n lifecycle.deletedResolved.length > 0\n ) {\n memoryItemMutated = true;\n log.info(\n `commitment ledger lifecycle: expired ${lifecycle.transitionedToExpired.length}, cleaned ${lifecycle.deletedResolved.length}`,\n );\n }\n } catch (err) {\n log.debug(`commitment ledger lifecycle pass failed: ${err}`);\n }\n }\n\n // Clean memories past their TTL (speculative memories auto-expire)\n const deletedTTL = await this.storage.cleanExpiredTTL();\n if (deletedTTL.length > 0) {\n memoryItemMutated = true;\n log.info(`cleaned ${deletedTTL.length} TTL-expired memories`);\n if (this.config.queryAwareIndexingEnabled) {\n for (const m of deletedTTL) {\n deindexMemory(\n this.config.memoryDir,\n m.path,\n m.frontmatter.created,\n m.frontmatter.tags ?? [],\n );\n }\n }\n }\n\n // v8.3 Lifecycle policy pass — deterministic promotion/decay metadata\n if (this.config.lifecyclePolicyEnabled) {\n try {\n const lightSleepStartedAt = new Date().toISOString();\n const lifecycleCorpus = await this.storage.readAllMemories();\n // Lifecycle frontmatter writes count as durable mutations for the catalog\n // touch below (codex NR-tS), even when no other consolidation step set\n // memoryItemMutated.\n if ((await this.runLifecyclePolicyPass(lifecycleCorpus)) > 0) {\n memoryItemMutated = true;\n }\n await this.recordScheduledDreamsPhaseRun(\n \"lightSleep\",\n lifecycleCorpus.length,\n `scheduled lifecycle policy pass assessed ${lifecycleCorpus.length} memories`,\n {\n startedAt: lightSleepStartedAt,\n completedAt: new Date().toISOString(),\n },\n );\n } catch (err) {\n log.warn(`lifecycle policy pass failed (ignored): ${err}`);\n }\n }\n\n // v8.3 Compression guideline learning pass (default off, fail-open).\n await this.runCompressionGuidelineLearningPass();\n\n try {\n const deepSleepStartedAt = new Date().toISOString();\n // Tier migrations move/rewrite memory files; count them as durable\n // mutations for the catalog touch below (codex NThSW).\n const tierMigration = await this.runTierMigrationCycle(this.storage, \"maintenance\");\n if (tierMigration.migrated > 0) memoryItemMutated = true;\n allMemories = await this.storage.readAllMemories();\n\n // Fact archival pass (v6.0) — move old, low-importance, rarely-accessed facts to archive/\n if (this.config.factArchivalEnabled) {\n const archived = await this.runFactArchival(allMemories);\n if (archived > 0) {\n memoryItemMutated = true;\n log.info(`archived ${archived} old low-importance facts`);\n }\n }\n await this.recordScheduledDreamsPhaseRun(\n \"deepSleep\",\n allMemories.length,\n `scheduled deep-sleep maintenance assessed ${allMemories.length} memories`,\n {\n startedAt: deepSleepStartedAt,\n completedAt: new Date().toISOString(),\n },\n );\n } catch (err) {\n log.warn(`deep-sleep maintenance pass failed (ignored): ${err}`);\n try {\n allMemories = await this.storage.readAllMemories();\n } catch (readErr) {\n log.warn(`deep-sleep maintenance recovery read failed: ${readErr}`);\n throw err;\n }\n }\n\n // Semantic consolidation pass — find similar memories, synthesize canonical versions\n if (this.config.semanticConsolidationEnabled) {\n try {\n const stateFilePath = path.join(\n this.config.memoryDir,\n \"state\",\n \"semantic-consolidation-last-run.json\",\n );\n let shouldRun = true;\n try {\n const stateRaw = await readFile(stateFilePath, \"utf-8\");\n const stateData = JSON.parse(stateRaw) as { lastRunAt?: string };\n if (stateData.lastRunAt) {\n const lastRunMs = new Date(stateData.lastRunAt).getTime();\n const intervalMs =\n this.config.semanticConsolidationIntervalHours * 60 * 60 * 1000;\n if (Date.now() - lastRunMs < intervalMs) {\n shouldRun = false;\n log.debug(\n \"[semantic-consolidation] skipping — not enough time since last run\",\n );\n }\n }\n } catch {\n // No state file yet — first run\n }\n\n if (shouldRun) {\n const remStartedAt = new Date().toISOString();\n const semResult = await this.runSemanticConsolidation();\n let remItemsProcessed = allMemories.length;\n try {\n allMemories = await this.storage.readAllMemories();\n remItemsProcessed = allMemories.length;\n } catch (err) {\n log.warn(\n `[semantic-consolidation] post-run telemetry refresh failed (non-fatal): ${err}`,\n );\n }\n await this.recordScheduledDreamsPhaseRun(\n \"rem\",\n remItemsProcessed,\n `scheduled REM consolidation found ${semResult.clustersFound} clusters`,\n {\n startedAt: remStartedAt,\n completedAt: new Date().toISOString(),\n },\n );\n if (semResult.memoriesArchived > 0) {\n log.info(\n `[semantic-consolidation] archived ${semResult.memoriesArchived} memories during maintenance`,\n );\n }\n // Only persist last-run timestamp if the run succeeded (had no errors or made progress)\n if (semResult.errors === 0 || semResult.memoriesArchived > 0) {\n const stateDir = path.join(this.config.memoryDir, \"state\");\n await mkdir(stateDir, { recursive: true });\n await writeFile(\n stateFilePath,\n JSON.stringify({ lastRunAt: new Date().toISOString() }),\n \"utf-8\",\n );\n }\n }\n } catch (err) {\n log.warn(\n `[semantic-consolidation] maintenance pass failed (non-fatal): ${err}`,\n );\n }\n }\n\n // Auto-consolidate IDENTITY.md if it's getting large\n if (this.config.identityEnabled) {\n await this.autoConsolidateIdentity();\n }\n\n // Auto-consolidate profile.md if it exceeds max lines\n const profileSection = this.getRecallSectionEntry(\"profile\");\n const profileConsolidationTriggerLines =\n typeof profileSection?.consolidateTriggerLines === \"number\"\n ? Math.max(0, Math.floor(profileSection.consolidateTriggerLines))\n : undefined;\n const profileConsolidationTargetLines =\n typeof profileSection?.consolidateTargetLines === \"number\"\n ? Math.max(0, Math.floor(profileSection.consolidateTargetLines))\n : 50;\n if (\n await this.storage.profileNeedsConsolidation(\n profileConsolidationTriggerLines,\n )\n ) {\n log.info(\"profile.md exceeds max lines — running smart consolidation\");\n const currentProfile = await this.storage.readProfile();\n if (currentProfile) {\n const profileResult = await this.extraction.consolidateProfile(\n currentProfile,\n profileConsolidationTargetLines,\n );\n if (profileResult) {\n await this.storage.writeProfile(profileResult.consolidatedProfile);\n // Profile consolidation rewrites profile.md — a durable namespace\n // mutation; record it for the catalog touch even when it is the only\n // change in the pass (codex). Otherwise lastWriteAt goes stale.\n memoryItemMutated = true;\n log.info(\n `profile.md consolidated: removed ${profileResult.removedCount} items — ${profileResult.summary}`,\n );\n }\n }\n }\n\n // Memory Summarization (Phase 4A)\n if (this.config.summarizationEnabled) {\n await this.runSummarization(allMemories);\n }\n\n // Topic Extraction (Phase 4B)\n if (this.config.topicExtractionEnabled) {\n await this.runTopicExtraction(allMemories);\n }\n\n const meta = await this.storage.loadMeta();\n meta.lastConsolidationAt = new Date().toISOString();\n await this.storage.saveMeta(meta);\n\n // Temporal Memory Tree (v8.2) — rebuild nodes from all memories, fail-open\n if (this.config.temporalMemoryTreeEnabled) {\n try {\n const tmtEntries = allMemories\n .filter(\n (m) =>\n m.frontmatter.status !== \"superseded\" &&\n m.frontmatter.status !== \"archived\" &&\n m.frontmatter.status !== \"forgotten\",\n )\n .map((m) => ({\n path: m.path,\n id: m.frontmatter.id,\n created: m.frontmatter.created,\n content: m.content,\n }));\n await this.tmtBuilder.maybeRebuildNodes(\n tmtEntries,\n async (texts, level) => {\n const prompt = `You are a memory archivist. Summarize the following ${level}-level memories into 3–5 sentences, preserving key facts, decisions, and preferences.\\n\\n${texts.map((t, i) => `[${i + 1}] ${t}`).join(\"\\n\\n\")}`;\n const response = await this.fastChatCompletion(\n [\n {\n role: \"system\",\n content:\n \"Respond with a 3–5 sentence narrative summary. No JSON, just plain prose.\",\n },\n { role: \"user\", content: prompt },\n ],\n {\n temperature: 0.3,\n maxTokens: this.config.tmtSummaryMaxTokens,\n operation: \"tmt_summary\",\n priority: \"background\",\n },\n );\n return response?.content?.trim() || texts.slice(0, 3).join(\" \");\n },\n );\n } catch (err) {\n log.warn(`tmt: consolidation hook failed (ignored): ${err}`);\n }\n }\n\n if (this.consolidationObservers.size > 0) {\n const observation: ConsolidationObservation = {\n runAt: new Date().toISOString(),\n recentMemories: recent,\n existingMemories: older.slice(-50),\n profile,\n result,\n merged,\n invalidated,\n };\n for (const observer of this.consolidationObservers) {\n try {\n await observer(observation);\n } catch (err) {\n log.warn(`consolidation observer failed (ignored): ${err}`);\n }\n }\n }\n\n // Consolidated catalog write touch (issue #1499 sweep; NIBOi + NIjwl). One\n // touch covering EVERY durable namespace mutation this pass made — LLM\n // profile/entity/memory-item actions AND cleanup-only maintenance (entity-file\n // merges, expired-commitment / ledger-lifecycle / TTL cleanup, fact archival).\n // Recorded here, after all mutation-producing steps, so a cleanup-only run that\n // rewrote the store still refreshes `lastWriteAt` (rule #25). The default\n // namespace is always configured/cataloged; `markWrite` is idempotent so this\n // only refreshes recency. Best-effort and failure-tolerant.\n if (memoryItemMutated) {\n this.markCatalogWrite(\n this.namespaceFromStorageDir(this.storage.dir),\n this.storage.dir,\n );\n }\n\n log.info(\"consolidation complete\");\n return { memoriesProcessed: allMemories.length, merged, invalidated };\n }\n\n async optimizeCompressionGuidelines(options?: {\n dryRun?: boolean;\n eventLimit?: number;\n }): Promise<{\n enabled: boolean;\n dryRun: boolean;\n eventCount: number;\n previousGuidelineVersion: number | null;\n nextGuidelineVersion: number;\n changedRules: number;\n semanticRefinementApplied: boolean;\n persisted: boolean;\n draftContentHash: string | null;\n }> {\n const dryRun = options?.dryRun === true;\n const eventLimit =\n typeof options?.eventLimit === \"number\"\n ? Math.max(0, Math.floor(options.eventLimit))\n : 500;\n\n const [activeState, draftState] = await Promise.all([\n this.storage.readCompressionGuidelineOptimizerState(),\n this.storage.readCompressionGuidelineDraftState().catch(() => null),\n ]);\n const previousState =\n draftState &&\n ((activeState?.guidelineVersion ?? 0) < draftState.guidelineVersion ||\n (activeState?.guidelineVersion ?? 0) === draftState.guidelineVersion)\n ? draftState\n : activeState;\n\n if (!this.config.compressionGuidelineLearningEnabled) {\n return {\n enabled: false,\n dryRun,\n eventCount: 0,\n previousGuidelineVersion: previousState?.guidelineVersion ?? null,\n nextGuidelineVersion: previousState?.guidelineVersion ?? 0,\n changedRules: 0,\n semanticRefinementApplied: false,\n persisted: false,\n draftContentHash: null,\n };\n }\n\n let events = await this.storage.readMemoryActionEvents(eventLimit);\n if (eventLimit > 0) {\n let effectiveEvents = events.filter((event) => event.dryRun !== true);\n let fetchLimit = eventLimit;\n while (\n effectiveEvents.length < eventLimit &&\n events.length === fetchLimit\n ) {\n fetchLimit = Math.min(fetchLimit * 2, fetchLimit + 1000);\n if (fetchLimit <= events.length) break;\n events = await this.storage.readMemoryActionEvents(fetchLimit);\n effectiveEvents = events.filter((event) => event.dryRun !== true);\n }\n events = effectiveEvents.slice(-eventLimit);\n }\n const generatedAt = new Date().toISOString();\n const candidate = computeCompressionGuidelineCandidate(events, {\n generatedAtIso: generatedAt,\n previousState,\n });\n if (candidate.eventCounts.total === 0) {\n return {\n enabled: true,\n dryRun,\n eventCount: 0,\n previousGuidelineVersion: previousState?.guidelineVersion ?? null,\n nextGuidelineVersion: previousState?.guidelineVersion ?? 0,\n changedRules: 0,\n semanticRefinementApplied: false,\n persisted: false,\n draftContentHash: null,\n };\n }\n const refinedCandidate =\n await refineCompressionGuidelineCandidateSemantically(candidate, {\n enabled: this.config.compressionGuidelineSemanticRefinementEnabled,\n timeoutMs: this.config.compressionGuidelineSemanticTimeoutMs,\n runRefinement: async (baseline) => {\n const prompt = [\n \"You refine compression policy suggestions conservatively.\",\n \"Return JSON only in this shape:\",\n '{\"updates\":[{\"action\":\"summarize_node\",\"delta\":0.02,\"confidence\":\"medium\",\"note\":\"...\"}]}',\n \"Constraints:\",\n \"- Keep updates sparse and conservative.\",\n \"- delta must stay between -0.15 and 0.15.\",\n \"- Only include actions present in the input.\",\n \"Input candidate:\",\n JSON.stringify(baseline),\n ].join(\"\\n\");\n\n const response = await this.fastChatCompletion(\n [\n {\n role: \"system\",\n content: \"Respond with strict JSON only. No markdown.\",\n },\n { role: \"user\", content: prompt },\n ],\n {\n temperature: 0.1,\n maxTokens: 400,\n operation: \"compression_guideline_semantic_refinement\",\n priority: \"background\",\n },\n );\n\n return this.parseCompressionSemanticRefinement(\n response?.content ?? \"\",\n );\n },\n });\n\n const content = renderCompressionGuidelinesMarkdown(refinedCandidate);\n const contentHash = createHash(\"sha256\").update(content).digest(\"hex\");\n const semanticRefinementApplied =\n JSON.stringify(refinedCandidate.ruleUpdates) !==\n JSON.stringify(candidate.ruleUpdates);\n const changedRules = refinedCandidate.ruleUpdates.filter(\n (rule) => rule.delta !== 0,\n ).length;\n\n if (!dryRun) {\n await this.storage.writeCompressionGuidelineDraft(content);\n await this.storage.writeCompressionGuidelineDraftState({\n version: refinedCandidate.optimizerVersion,\n updatedAt: refinedCandidate.generatedAt,\n sourceWindow: refinedCandidate.sourceWindow,\n eventCounts: refinedCandidate.eventCounts,\n guidelineVersion: refinedCandidate.guidelineVersion,\n contentHash,\n activationState: \"draft\",\n actionSummaries: refinedCandidate.actionSummaries,\n ruleUpdates: refinedCandidate.ruleUpdates,\n });\n }\n\n return {\n enabled: true,\n dryRun,\n eventCount: candidate.eventCounts.total,\n previousGuidelineVersion: previousState?.guidelineVersion ?? null,\n nextGuidelineVersion: refinedCandidate.guidelineVersion,\n changedRules,\n semanticRefinementApplied,\n persisted: !dryRun,\n draftContentHash: dryRun ? null : contentHash,\n };\n }\n\n async activateCompressionGuidelineDraft(options?: {\n expectedContentHash?: string;\n expectedGuidelineVersion?: number;\n }): Promise<{\n enabled: boolean;\n activated: boolean;\n guidelineVersion: number | null;\n reason?:\n | \"disabled\"\n | \"missing_draft\"\n | \"expected_revision_required\"\n | \"content_hash_mismatch\"\n | \"guideline_version_mismatch\"\n | \"draft_changed\";\n }> {\n if (!this.config.compressionGuidelineLearningEnabled) {\n return {\n enabled: false,\n activated: false,\n guidelineVersion: null,\n reason: \"disabled\",\n };\n }\n\n const draftState = await this.storage.readCompressionGuidelineDraftState();\n if (!draftState) {\n return {\n enabled: true,\n activated: false,\n guidelineVersion: null,\n reason: \"missing_draft\",\n };\n }\n\n const expectedContentHash = options?.expectedContentHash?.trim();\n const expectedGuidelineVersion = options?.expectedGuidelineVersion;\n\n if (\n (!expectedContentHash || expectedContentHash.length === 0) &&\n typeof expectedGuidelineVersion !== \"number\"\n ) {\n return {\n enabled: true,\n activated: false,\n guidelineVersion: null,\n reason: \"expected_revision_required\",\n };\n }\n\n if (expectedContentHash && draftState.contentHash !== expectedContentHash) {\n return {\n enabled: true,\n activated: false,\n guidelineVersion: null,\n reason: \"content_hash_mismatch\",\n };\n }\n\n if (\n typeof expectedGuidelineVersion === \"number\" &&\n draftState.guidelineVersion !== expectedGuidelineVersion\n ) {\n return {\n enabled: true,\n activated: false,\n guidelineVersion: null,\n reason: \"guideline_version_mismatch\",\n };\n }\n\n const activated = await this.storage.activateCompressionGuidelineDraft({\n ...(expectedContentHash ? { expectedContentHash } : {}),\n ...(typeof expectedGuidelineVersion === \"number\"\n ? { expectedGuidelineVersion }\n : {}),\n });\n return {\n enabled: true,\n activated,\n guidelineVersion: activated ? draftState.guidelineVersion : null,\n ...(activated ? {} : { reason: \"draft_changed\" as const }),\n };\n }\n\n private async runCompressionGuidelineLearningPass(): Promise<void> {\n if (!this.config.compressionGuidelineLearningEnabled) return;\n try {\n const result = await this.optimizeCompressionGuidelines({\n dryRun: false,\n eventLimit: 500,\n });\n log.info(\n `compression guideline learning updated (${result.eventCount} events)`,\n );\n } catch (err) {\n log.warn(`compression guideline learning failed (ignored): ${err}`);\n }\n }\n\n private async buildCompressionGuidelineRecallSection(): Promise<\n string | null\n > {\n if (!this.config.contextCompressionActionsEnabled) return null;\n if (!this.config.compressionGuidelineLearningEnabled) return null;\n\n const state = await this.storage\n .readCompressionGuidelineOptimizerState()\n .catch(() => null);\n if (!state || state.guidelineVersion <= 0) return null;\n\n const raw = await this.storage\n .readCompressionGuidelines()\n .catch(() => null);\n const summary = raw ? formatCompressionGuidelinesForRecall(raw, 5) : null;\n if (!summary) return null;\n\n return [\n \"## Active Compression Guidelines\",\n \"\",\n `Guideline version: ${state.guidelineVersion}`,\n `Updated: ${state.updatedAt}`,\n \"\",\n summary,\n ].join(\"\\n\");\n }\n\n private parseCompressionSemanticRefinement(raw: string): {\n updates: Array<{\n action: MemoryActionType;\n delta?: number;\n confidence?: \"low\" | \"medium\" | \"high\";\n note?: string;\n }>;\n } | null {\n if (typeof raw !== \"string\" || raw.trim().length === 0) return null;\n const trimmed = raw.trim();\n const start = trimmed.indexOf(\"{\");\n const end = trimmed.lastIndexOf(\"}\");\n if (start === -1 || end === -1 || end <= start) return null;\n\n try {\n const parsed = JSON.parse(trimmed.slice(start, end + 1)) as {\n updates?: Array<{\n action?: unknown;\n delta?: unknown;\n confidence?: unknown;\n note?: unknown;\n }>;\n };\n if (!Array.isArray(parsed?.updates)) return null;\n\n const validActions = new Set<MemoryActionType>([\n \"store_episode\",\n \"store_note\",\n \"update_note\",\n \"create_artifact\",\n \"summarize_node\",\n \"discard\",\n \"link_graph\",\n ]);\n\n const updates = parsed.updates\n .filter(\n (item) =>\n item &&\n typeof item.action === \"string\" &&\n validActions.has(item.action as MemoryActionType),\n )\n .map((item) => {\n const confidence: \"low\" | \"medium\" | \"high\" | undefined =\n item.confidence === \"low\" ||\n item.confidence === \"medium\" ||\n item.confidence === \"high\"\n ? item.confidence\n : undefined;\n return {\n action: item.action as MemoryActionType,\n delta:\n typeof item.delta === \"number\" && Number.isFinite(item.delta)\n ? item.delta\n : undefined,\n confidence,\n note: typeof item.note === \"string\" ? item.note : undefined,\n };\n });\n\n return { updates };\n } catch {\n return null;\n }\n }\n\n private actionOutcomePriorDelta(event: MemoryActionEvent): number {\n if (event.outcome === \"failed\") return -0.3;\n if (event.policyDecision === \"deny\") return -0.22;\n if (event.policyDecision === \"defer\") return -0.14;\n if (event.outcome === \"skipped\") return -0.1;\n\n if (event.outcome !== \"applied\") return 0;\n switch (event.action) {\n case \"store_episode\":\n case \"store_note\":\n case \"update_note\":\n return 0.08;\n case \"create_artifact\":\n case \"summarize_node\":\n case \"link_graph\":\n return 0.04;\n case \"discard\":\n return -0.03;\n default:\n return 0;\n }\n }\n\n private async buildLifecycleActionPriors(\n storage: StorageManager = this.storage,\n ): Promise<Map<string, number>> {\n const events = await storage.readMemoryActionEvents(1200);\n if (events.length === 0) return new Map<string, number>();\n\n const nowMs = Date.now();\n const windowMs = 14 * 24 * 60 * 60 * 1000;\n const byMemory = new Map<\n string,\n Array<{ weightedDelta: number; weight: number }>\n >();\n\n for (const event of events) {\n if (\n typeof event.memoryId !== \"string\" ||\n event.memoryId.trim().length === 0\n )\n continue;\n const ts = Date.parse(event.timestamp);\n if (!Number.isFinite(ts)) continue;\n const ageMs = nowMs - ts;\n if (ageMs < 0 || ageMs > windowMs) continue;\n\n const delta = this.actionOutcomePriorDelta(event);\n if (delta === 0) continue;\n\n const recencyWeight = Math.max(0.2, 1 - ageMs / windowMs);\n const list = byMemory.get(event.memoryId) ?? [];\n if (list.length >= 8) list.shift();\n list.push({\n weightedDelta: delta * recencyWeight,\n weight: recencyWeight,\n });\n byMemory.set(event.memoryId, list);\n }\n\n const out = new Map<string, number>();\n for (const [memoryId, deltas] of byMemory.entries()) {\n if (deltas.length === 0) continue;\n const weightedSum = deltas.reduce(\n (sum, item) => sum + item.weightedDelta,\n 0,\n );\n const weightTotal = deltas.reduce((sum, item) => sum + item.weight, 0);\n if (weightTotal <= 0) continue;\n const score = weightedSum / weightTotal;\n out.set(memoryId, Math.max(-0.25, Math.min(0.15, score)));\n }\n return out;\n }\n\n private async recordScheduledDreamsPhaseRun(\n phase: \"lightSleep\" | \"rem\" | \"deepSleep\",\n itemsProcessed: number,\n notes: string,\n timing: { startedAt?: string; completedAt?: string } = {},\n ): Promise<void> {\n try {\n const { recordDreamsPhaseRun } = await import(\"./maintenance/dreams-ledger.js\");\n await recordDreamsPhaseRun({\n memoryDir: this.storage.dir,\n phase,\n trigger: \"scheduled\",\n itemsProcessed,\n notes,\n startedAt: timing.startedAt,\n completedAt: timing.completedAt,\n });\n } catch (error) {\n log.debug(`dreams ledger scheduled ${phase} write failed (non-fatal): ${error}`);\n }\n }\n\n async runLifecyclePolicyNow(storage: StorageManager = this.storage): Promise<{ memoriesAssessed: number }> {\n const lifecycleCorpus = await storage.readAllMemories();\n // Record the catalog write when the pass rewrote any frontmatter (codex NR-tS).\n if ((await this.runLifecyclePolicyPass(lifecycleCorpus, storage)) > 0) {\n this.markCatalogWrite(this.namespaceFromStorageDir(storage.dir), storage.dir);\n }\n return { memoriesAssessed: lifecycleCorpus.length };\n }\n\n private async runLifecyclePolicyPass(\n allMemories: MemoryFile[],\n storage: StorageManager = this.storage,\n ): Promise<number> {\n const now = new Date();\n const nowIso = now.toISOString();\n const countsByState: Record<LifecycleState, number> = {\n candidate: 0,\n validated: 0,\n active: 0,\n stale: 0,\n archived: 0,\n };\n const transitionCounts: Record<string, number> = {};\n let updatedCount = 0;\n let disputedCount = 0;\n let evaluatedCount = 0;\n\n const thresholds = this.effectiveLifecycleThresholds();\n const policy = {\n promoteHeatThreshold: thresholds.promoteHeatThreshold,\n staleDecayThreshold: thresholds.staleDecayThreshold,\n archiveDecayThreshold: thresholds.archiveDecayThreshold,\n protectedCategories: this.config.lifecycleProtectedCategories,\n };\n const actionPriors = await this.buildLifecycleActionPriors(storage);\n\n for (const memory of allMemories) {\n if (\n memory.frontmatter.status === \"superseded\" ||\n memory.frontmatter.status === \"forgotten\"\n ) {\n continue;\n }\n evaluatedCount += 1;\n const currentState = resolveLifecycleState(memory.frontmatter);\n const actionPriorScore = actionPriors.get(memory.frontmatter.id);\n const signals: LifecycleSignals | undefined =\n typeof actionPriorScore === \"number\" &&\n Number.isFinite(actionPriorScore)\n ? { actionPriorScore }\n : undefined;\n const decision = decideLifecycleTransition(memory, policy, now, signals);\n const nextState: LifecycleState =\n memory.frontmatter.status === \"archived\"\n ? \"archived\"\n : decision.nextState;\n\n countsByState[nextState] += 1;\n if (memory.frontmatter.verificationState === \"disputed\") {\n disputedCount += 1;\n }\n if (nextState !== currentState) {\n const key = `${currentState}->${nextState}`;\n transitionCounts[key] = (transitionCounts[key] ?? 0) + 1;\n }\n\n const prevHeat = memory.frontmatter.heatScore;\n const prevDecay = memory.frontmatter.decayScore;\n const scoreDelta =\n Math.abs((prevHeat ?? -1) - decision.heatScore) +\n Math.abs((prevDecay ?? -1) - decision.decayScore);\n const shouldPersist =\n memory.frontmatter.lifecycleState !== nextState ||\n memory.frontmatter.heatScore === undefined ||\n memory.frontmatter.decayScore === undefined ||\n memory.frontmatter.lastValidatedAt === undefined ||\n scoreDelta >= 0.01;\n\n if (!shouldPersist) continue;\n\n const wrote = await storage.writeMemoryFrontmatter(memory, {\n lifecycleState: nextState,\n heatScore: decision.heatScore,\n decayScore: decision.decayScore,\n lastValidatedAt: nowIso,\n });\n if (wrote) updatedCount += 1;\n }\n\n // Report how many memories had frontmatter rewritten so callers can record a\n // catalog write touch for lifecycle-only passes (codex NR-tS).\n if (!this.config.lifecycleMetricsEnabled) return updatedCount;\n\n const total = evaluatedCount;\n const metrics = {\n generatedAt: nowIso,\n memoriesEvaluated: total,\n memoriesUpdated: updatedCount,\n countsByLifecycleState: countsByState,\n transitionCounts,\n staleRatio: total > 0 ? countsByState.stale / total : 0,\n disputedRatio: total > 0 ? disputedCount / total : 0,\n policy: {\n promoteHeatThreshold: thresholds.promoteHeatThreshold,\n staleDecayThreshold: thresholds.staleDecayThreshold,\n archiveDecayThreshold: thresholds.archiveDecayThreshold,\n protectedCategories: this.config.lifecycleProtectedCategories,\n },\n };\n const metricsPath = path.join(\n storage.dir,\n \"state\",\n \"lifecycle-metrics.json\",\n );\n await mkdir(path.dirname(metricsPath), { recursive: true });\n await writeFile(metricsPath, JSON.stringify(metrics, null, 2), \"utf-8\");\n return updatedCount;\n }\n\n /**\n * Archive old, low-importance, rarely-accessed facts (v6.0).\n * Moves eligible facts from facts/ to archive/YYYY-MM-DD/.\n * Returns the number of archived facts.\n */\n private async runFactArchival(\n allMemories: import(\"./types.js\").MemoryFile[],\n ): Promise<number> {\n const now = Date.now();\n const ageCutoffMs = this.config.factArchivalAgeDays * 24 * 60 * 60 * 1000;\n const protectedCategories = new Set(\n this.config.factArchivalProtectedCategories,\n );\n let archivedCount = 0;\n\n for (const memory of allMemories) {\n const fm = memory.frontmatter;\n\n // Skip already-archived or superseded\n if (fm.status && fm.status !== \"active\") continue;\n\n // Skip protected categories\n if (protectedCategories.has(fm.category)) continue;\n\n // Skip corrections (always keep)\n if (fm.category === \"correction\") continue;\n\n // Check age requirement\n const createdMs = new Date(fm.created).getTime();\n if (now - createdMs < ageCutoffMs) continue;\n\n // Check importance (only archive low-importance facts)\n const importanceScore = fm.importance?.score ?? 0.5;\n if (importanceScore >= this.config.factArchivalMaxImportance) continue;\n\n // Check access count\n const accessCount = fm.accessCount ?? 0;\n if (accessCount > this.config.factArchivalMaxAccessCount) continue;\n\n // All criteria met — archive\n const result = await this.storage.archiveMemory(memory);\n if (result) {\n // Remove from the same storage-scoped content-hash index since it is\n // no longer in hot search.\n await this.removeContentHashForMemory(\n this.storage,\n memory,\n \"fact-archival\",\n );\n await this.embeddingFallback.removeFromIndex(memory.frontmatter.id);\n if (\n this.config.queryAwareIndexingEnabled &&\n memory.path &&\n memory.frontmatter?.created\n ) {\n deindexMemory(\n this.config.memoryDir,\n memory.path,\n memory.frontmatter.created,\n memory.frontmatter.tags ?? [],\n );\n }\n archivedCount++;\n }\n }\n\n // Save hash indexes if we removed any entries.\n if (archivedCount > 0) {\n await this.saveContentHashIndexes().catch((err) =>\n log.warn(`content-hash index save failed during archival: ${err}`),\n );\n }\n\n return archivedCount;\n }\n\n /**\n * Run memory summarization if memory count exceeds threshold (Phase 4A).\n */\n private async runSummarization(\n allMemories: import(\"./types.js\").MemoryFile[],\n ): Promise<void> {\n // Only active memories count toward the threshold\n const activeMemories = allMemories.filter(\n (m) => isActiveMemoryStatus(m.frontmatter.status),\n );\n\n if (activeMemories.length < this.config.summarizationTriggerCount) {\n return;\n }\n\n log.info(\n `memory count (${activeMemories.length}) exceeds threshold (${this.config.summarizationTriggerCount}) — running summarization`,\n );\n\n // Sort by creation date, oldest first\n const sorted = activeMemories.sort(\n (a, b) =>\n new Date(a.frontmatter.created).getTime() -\n new Date(b.frontmatter.created).getTime(),\n );\n\n // Keep recent memories, with explicit zero handling so `slice(-0)` does not\n // accidentally keep every memory out of the summarization candidate set.\n const recentToKeep = Math.max(0, this.config.summarizationRecentToKeep);\n const toSummarize = recentToKeep > 0 ? sorted.slice(0, -recentToKeep) : sorted;\n\n // Filter candidates for summarization\n const candidates = toSummarize.filter((m) => {\n // Skip if protected by entity reference\n if (m.frontmatter.entityRef) return false;\n\n // Skip if protected by tag\n const protectedTags = this.config.summarizationProtectedTags;\n if (m.frontmatter.tags.some((t) => protectedTags.includes(t)))\n return false;\n\n // Skip if importance is above threshold\n const importance = m.frontmatter.importance?.score ?? 0.5;\n if (importance >= this.config.summarizationImportanceThreshold)\n return false;\n\n return true;\n });\n\n if (candidates.length < 50) {\n log.debug(\n `only ${candidates.length} candidates for summarization — skipping`,\n );\n return;\n }\n\n // Summarize in batches of 50\n const batchSize = 50;\n for (let i = 0; i < candidates.length; i += batchSize) {\n const batch = candidates.slice(i, i + batchSize);\n const batchData = batch.map((m) => ({\n id: m.frontmatter.id,\n content: m.content,\n category: m.frontmatter.category,\n created: m.frontmatter.created,\n }));\n\n const result = await this.extraction.summarizeMemories(batchData);\n if (!result) continue;\n\n // Create summary\n const summary: MemorySummary = {\n id: `summary-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,\n createdAt: new Date().toISOString(),\n timeRangeStart: batch[0].frontmatter.created,\n timeRangeEnd: batch[batch.length - 1].frontmatter.created,\n summaryText: result.summaryText,\n keyFacts: result.keyFacts,\n keyEntities: result.keyEntities,\n sourceEpisodeIds: batch.map((m) => m.frontmatter.id),\n };\n\n await this.storage.writeSummary(summary);\n\n // Archive source memories\n const archived = await this.storage.archiveMemories(\n batch.map((m) => m.frontmatter.id),\n summary.id,\n );\n\n // Catalog write touch (issue #1499 sweep): summarization writes a durable\n // summary and then rewrites source-memory archive status, bypassing the\n // extraction write path. Record the touch after both mutations complete so\n // `lastWriteAt` covers the final archived-state write.\n this.markCatalogWrite(\n this.namespaceFromStorageDir(this.storage.dir),\n this.storage.dir,\n );\n\n log.info(\n `created summary ${summary.id} from ${batch.length} memories, archived ${archived}`,\n );\n }\n }\n\n /**\n * Run topic extraction on all memories (Phase 4B).\n */\n private async runTopicExtraction(\n allMemories: import(\"./types.js\").MemoryFile[],\n ): Promise<void> {\n // Only extract from active memories\n const activeMemories = allMemories.filter(\n (m) => isActiveMemoryStatus(m.frontmatter.status),\n );\n\n if (activeMemories.length === 0) return;\n\n const topics = extractTopics(\n activeMemories,\n this.config.topicExtractionTopN,\n );\n await this.storage.saveTopics(topics);\n\n log.debug(\n `extracted ${topics.length} topics from ${activeMemories.length} memories`,\n );\n }\n\n /** Threshold (bytes) at which IDENTITY.md reflections get auto-consolidated */\n private static readonly IDENTITY_CONSOLIDATE_THRESHOLD = 8_000;\n\n private async autoConsolidateIdentity(): Promise<void> {\n // Fan out over the catalog-union namespace set (issue #1499 sweep): a dynamic\n // namespace that accumulated IDENTITY.md reflections must also be eligible for\n // auto-consolidation, otherwise its identity file grows unbounded and is never\n // consolidated. Falls back to the configured set on any catalog read failure.\n const namespaces = this.config.namespacesEnabled\n ? await this.maintenanceNamespaces()\n : [this.config.defaultNamespace];\n\n for (const namespace of namespaces) {\n const storage = await this.storageRouter.storageFor(namespace);\n const identityNamespace =\n this.config.namespacesEnabled &&\n namespace !== this.config.defaultNamespace\n ? namespace\n : undefined;\n const reflectionsContent =\n (await storage.readIdentityReflections()) ?? \"\";\n\n const existingIdentity = await storage.readIdentity(\n this.config.workspaceDir,\n identityNamespace,\n );\n const headerEnd =\n existingIdentity.indexOf(\"## Learned Patterns\") !== -1\n ? existingIdentity.indexOf(\"## Learned Patterns\")\n : existingIdentity.indexOf(\"## Reflection\");\n const staticHeader =\n (headerEnd !== -1\n ? existingIdentity.slice(0, headerEnd)\n : existingIdentity\n ).trimEnd() || \"# IDENTITY\";\n const identityContent = `${staticHeader}\\n\\n${reflectionsContent.trim()}\\n`;\n if (identityContent.length < Orchestrator.IDENTITY_CONSOLIDATE_THRESHOLD)\n continue;\n\n log.info(\n `IDENTITY(${namespace}) is ${identityContent.length} chars — auto-consolidating reflections`,\n );\n const result = await this.extraction.consolidateIdentity(\n identityContent,\n \"## Reflection\",\n );\n\n if (!result || result.learnedPatterns.length === 0) {\n log.warn(\n `identity consolidation produced no patterns for namespace=${namespace}`,\n );\n continue;\n }\n\n const patternsSection = [\n \"## Learned Patterns (consolidated from reflections, \" +\n new Date().toISOString().slice(0, 10) +\n \")\",\n \"\",\n ...result.learnedPatterns.map((p) => `- ${p}`),\n \"\",\n ].join(\"\\n\");\n\n const newContent = staticHeader + \"\\n\\n\" + patternsSection + \"\\n\";\n\n await storage.writeIdentity(\n this.config.workspaceDir,\n newContent,\n identityNamespace,\n );\n await storage.writeIdentityReflections(\"\");\n // NRcCL (codex P2): record a per-namespace catalog write for THIS namespace\n // after the identity files are updated. This fan-out can mutate a dynamic\n // namespace via `writeIdentity`/`writeIdentityReflections`, but the\n // consolidation pass's only consolidated touch covers `this.storage` (the\n // default) and only fires when `memoryItemMutated` was set by OTHER work — so\n // a namespace whose sole mutation in the pass is identity consolidation would\n // otherwise keep a stale `lastWriteAt`, making `listNamespaces({ writtenSince })`\n // and catalog-recency consumers miss the write. Best-effort and\n // failure-tolerant (`markCatalogWrite` swallows errors, never crashing the\n // consolidation; gotcha #13, rule #40). No double-count with the consolidated\n // touch above: that one is gated on `memoryItemMutated` (which identity\n // consolidation does not set), and `markWrite` is idempotent regardless.\n this.markCatalogWrite(namespace, storage.dir);\n log.info(\n `IDENTITY(${namespace}) consolidated: ${identityContent.length} → ${newContent.length} chars, ${result.learnedPatterns.length} patterns`,\n );\n }\n }\n\n private formatQmdResults(title: string, results: QmdSearchResult[]): string {\n const lines = results.map((r, i) => {\n const snippet = r.snippet\n ? r.snippet.slice(0, 500).replace(/\\n/g, \" \")\n : \"(no preview)\";\n const source = typeof r.line === \"number\" ? `${r.path}:${r.line}` : r.path;\n return `[${i + 1}] ${source} (score: ${r.score.toFixed(3)})\\n${snippet}`;\n });\n return `## ${title}\\n\\n${lines.join(\"\\n\\n\")}`;\n }\n\n private formatObjectiveStateResults(\n results: ObjectiveStateSearchResult[],\n ): string {\n const lines = results.map(({ snapshot }, index) => {\n const parts = [\n snapshot.recordedAt.replace(\"T\", \" \").slice(0, 16),\n `${snapshot.kind}/${snapshot.changeKind}`,\n ];\n if (snapshot.outcome) parts.push(snapshot.outcome);\n const header = `[${index + 1}] ${parts.join(\" | \")} | ${snapshot.scope}`;\n const detailParts = [snapshot.summary];\n if (snapshot.command) detailParts.push(`command: ${snapshot.command}`);\n else if (snapshot.toolName)\n detailParts.push(`tool: ${snapshot.toolName}`);\n return `${header}\\n${detailParts.join(\" | \")}`;\n });\n return `## Objective State\\n\\n${lines.join(\"\\n\\n\")}`;\n }\n\n private formatCausalTrajectoryResults(\n results: CausalTrajectorySearchResult[],\n ): string {\n const lines = results.map(({ record, matchedFields }, index) => {\n const header = [\n `[${index + 1}] ${record.recordedAt.replace(\"T\", \" \").slice(0, 16)}`,\n record.outcomeKind,\n ].join(\" | \");\n const details = [\n `goal: ${record.goal}`,\n `action: ${record.actionSummary}`,\n `observation: ${record.observationSummary}`,\n `outcome: ${record.outcomeSummary}`,\n ];\n if (record.followUpSummary)\n details.push(`follow-up: ${record.followUpSummary}`);\n if (matchedFields.length > 0)\n details.push(`matched: ${matchedFields.join(\", \")}`);\n return `${header}\\n${details.join(\"\\n\")}`;\n });\n\n return `## Causal Trajectories\\n\\n${lines.join(\"\\n\\n\")}`;\n }\n\n private formatTrustZoneResults(results: TrustZoneSearchResult[]): string {\n const lines = results.map(({ record, matchedFields }, index) => {\n const header = [\n `[${index + 1}] ${record.recordedAt.replace(\"T\", \" \").slice(0, 16)}`,\n record.zone,\n record.kind,\n ].join(\" | \");\n const details = [\n record.summary,\n `provenance: ${record.provenance.sourceClass}`,\n ];\n if (record.entityRefs && record.entityRefs.length > 0) {\n details.push(`entities: ${record.entityRefs.join(\", \")}`);\n }\n if (record.tags && record.tags.length > 0) {\n details.push(`tags: ${record.tags.join(\", \")}`);\n }\n if (matchedFields.length > 0) {\n details.push(`matched: ${matchedFields.join(\", \")}`);\n }\n return `${header}\\n${details.join(\"\\n\")}`;\n });\n\n return `## Trust Zones\\n\\n${lines.join(\"\\n\\n\")}`;\n }\n\n private formatHarmonicRetrievalResults(\n results: HarmonicRetrievalResult[],\n ): string {\n const lines = results.map(\n (\n { node, matchedAnchors, matchedFields, nodeScore, anchorScore },\n index,\n ) => {\n const header = [\n `[${index + 1}] ${node.recordedAt.replace(\"T\", \" \").slice(0, 16)}`,\n `${node.kind}/${node.abstractionLevel}`,\n node.sessionKey,\n ].join(\" | \");\n const details = [\n node.title,\n node.summary,\n `scores: node=${nodeScore.toFixed(1)} anchor=${anchorScore.toFixed(1)}`,\n ];\n if (matchedAnchors.length > 0) {\n details.push(\n `anchors: ${matchedAnchors.map((anchor) => `${anchor.anchorType}:${anchor.anchorValue}`).join(\"; \")}`,\n );\n }\n if (matchedFields.length > 0) {\n details.push(`matched: ${matchedFields.join(\", \")}`);\n }\n return `${header}\\n${details.join(\"\\n\")}`;\n },\n );\n\n return `## Harmonic Retrieval\\n\\n${lines.join(\"\\n\\n\")}`;\n }\n\n private formatWorkProductResults(\n results: WorkProductLedgerSearchResult[],\n ): string {\n const lines = results.map(({ entry, matchedFields }, index) => {\n const header = [\n `[${index + 1}] ${entry.recordedAt.replace(\"T\", \" \").slice(0, 16)}`,\n `${entry.kind}/${entry.action}`,\n entry.sessionKey,\n ].join(\" | \");\n const details = [entry.summary, `scope: ${entry.scope}`];\n if (entry.artifactPath) details.push(`artifact: ${entry.artifactPath}`);\n if (entry.tags && entry.tags.length > 0)\n details.push(`tags: ${entry.tags.join(\", \")}`);\n if (matchedFields.length > 0)\n details.push(`matched: ${matchedFields.join(\", \")}`);\n return `${header}\\n${details.join(\"\\n\")}`;\n });\n\n return `## Work Products\\n\\n${lines.join(\"\\n\\n\")}`;\n }\n\n private formatVerifiedEpisodeResults(\n results: VerifiedEpisodeResult[],\n ): string {\n const lines = results.map(\n ({ box, verifiedEpisodeCount, matchedFields }, index) => {\n const header = [\n `[${index + 1}] ${box.sealedAt.replace(\"T\", \" \").slice(0, 16)}`,\n box.traceId ? `trace:${box.traceId.slice(0, 12)}` : \"trace:none\",\n ].join(\" | \");\n const details = [\n box.goal ?? `topics: ${box.topics.join(\", \")}`,\n `verified episodes: ${verifiedEpisodeCount}`,\n ];\n if (box.toolsUsed && box.toolsUsed.length > 0) {\n details.push(`tools: ${box.toolsUsed.join(\", \")}`);\n }\n if (matchedFields.length > 0) {\n details.push(`matched: ${matchedFields.join(\", \")}`);\n }\n return `${header}\\n${details.join(\"\\n\")}`;\n },\n );\n\n return `## Verified Episodes\\n\\n${lines.join(\"\\n\\n\")}`;\n }\n\n private formatVerifiedSemanticRuleResults(\n results: VerifiedSemanticRuleResult[],\n ): string {\n const lines = results.map(\n (\n {\n rule,\n sourceMemoryId,\n verificationStatus,\n effectiveConfidence,\n matchedFields,\n },\n index,\n ) => {\n const header = [\n `[${index + 1}] ${rule.frontmatter.updated.replace(\"T\", \" \").slice(0, 16)}`,\n verificationStatus,\n `confidence:${effectiveConfidence.toFixed(2)}`,\n ].join(\" | \");\n const details = [rule.content, `source memory: ${sourceMemoryId}`];\n if (matchedFields.length > 0) {\n details.push(`matched: ${matchedFields.join(\", \")}`);\n }\n return `${header}\\n${details.join(\"\\n\")}`;\n },\n );\n\n return `## Verified Rules\\n\\n${lines.join(\"\\n\\n\")}`;\n }\n\n private summarizeIdentityText(\n raw: string,\n maxLines: number,\n maxChars: number,\n ): string {\n const lines = raw\n .replace(/\\r/g, \"\")\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.length > 0 && !line.startsWith(\"#\"));\n const compact = lines.slice(0, Math.max(1, maxLines)).join(\" \");\n if (compact.length <= maxChars) return compact;\n return `${compact.slice(0, Math.max(0, maxChars - 1))}…`;\n }\n\n private formatOpenIncidentLine(\n incident: ContinuityIncidentRecord,\n includeDetails: boolean,\n ): string {\n const base = `[${incident.id}] ${incident.symptom.trim()}`;\n if (!includeDetails) return `- ${base}`;\n const parts = [base];\n if (incident.suspectedCause)\n parts.push(`cause: ${incident.suspectedCause.trim()}`);\n if (incident.triggerWindow)\n parts.push(`window: ${incident.triggerWindow.trim()}`);\n return `- ${parts.join(\" | \")}`;\n }\n\n private trimIdentitySection(\n content: string,\n maxChars: number,\n ): { text: string; truncated: boolean } {\n if (maxChars <= 0) return { text: \"\", truncated: false };\n if (content.length <= maxChars) return { text: content, truncated: false };\n const suffix = \"\\n\\n...(identity continuity trimmed)\";\n if (maxChars <= suffix.length) {\n return { text: content.slice(0, maxChars), truncated: true };\n }\n const headroom = Math.max(0, maxChars - suffix.length);\n return { text: `${content.slice(0, headroom)}${suffix}`, truncated: true };\n }\n\n private async buildIdentityContinuitySection(options: {\n storage: StorageManager;\n recallMode: RecallPlanMode;\n prompt: string;\n }): Promise<{\n section: string;\n mode: IdentityInjectionMode;\n injectedChars: number;\n truncated: boolean;\n } | null> {\n if (!this.config.identityContinuityEnabled) return null;\n if (this.config.identityMaxInjectChars <= 0) return null;\n\n const resolved = resolveEffectiveIdentityInjectionMode({\n configuredMode: this.config.identityInjectionMode,\n recallMode: options.recallMode,\n prompt: options.prompt,\n });\n if (!resolved.shouldInject) return null;\n\n const [anchorRaw, loopsRaw, incidents] = await Promise.all([\n options.storage.readIdentityAnchor(),\n options.storage.readIdentityImprovementLoops(),\n options.storage.readContinuityIncidents(200),\n ]);\n const openIncidents = incidents.filter(\n (incident) => incident.state === \"open\",\n );\n\n const lines: string[] = [];\n if (resolved.mode === \"full\") {\n lines.push(\"## Identity Continuity\");\n if (anchorRaw && anchorRaw.trim().length > 0) {\n lines.push(\"\", \"### Anchor\", \"\", anchorRaw.trim());\n }\n if (loopsRaw && loopsRaw.trim().length > 0) {\n lines.push(\"\", \"### Improvement Loops\", \"\", loopsRaw.trim());\n }\n lines.push(\"\", \"### Open Incidents\", \"\");\n if (openIncidents.length === 0) {\n lines.push(\"- none\");\n } else {\n lines.push(\n ...openIncidents\n .slice(0, 5)\n .map((incident) => this.formatOpenIncidentLine(incident, true)),\n );\n }\n } else {\n const anchorSummary = anchorRaw\n ? this.summarizeIdentityText(anchorRaw, 3, 320)\n : \"\";\n const loopsSummary = loopsRaw\n ? this.summarizeIdentityText(loopsRaw, 2, 240)\n : \"\";\n lines.push(\"## Identity Continuity Signals\", \"\");\n if (anchorSummary) lines.push(`- anchor: ${anchorSummary}`);\n if (loopsSummary) lines.push(`- loops: ${loopsSummary}`);\n if (openIncidents.length === 0) {\n lines.push(\"- incidents: 0 open\");\n } else {\n lines.push(`- incidents: ${openIncidents.length} open`);\n lines.push(\n ...openIncidents\n .slice(0, 2)\n .map((incident) => this.formatOpenIncidentLine(incident, false)),\n );\n }\n }\n\n const body = lines.join(\"\\n\").trim();\n if (!body) return null;\n\n const { text, truncated } = this.trimIdentitySection(\n body,\n this.config.identityMaxInjectChars,\n );\n if (!text) return null;\n\n return {\n section: text,\n mode: resolved.mode,\n injectedChars: text.length,\n truncated,\n };\n }\n\n private emitTrace(event: EngramTraceEvent): void {\n try {\n const cb = (globalThis as any).__openclawEngramTrace;\n if (typeof cb === \"function\") cb(event);\n } catch (err) {\n log.debug(`trace callback failed: ${err}`);\n }\n }\n\n private queueEvalShadowRecall(\n record: Omit<EvalShadowRecallRecord, \"schemaVersion\">,\n ): void {\n if (!this.config.evalHarnessEnabled || !this.config.evalShadowModeEnabled)\n return;\n this.evalShadowWriteChain = this.evalShadowWriteChain\n .catch(() => undefined)\n .then(async () => {\n try {\n await recordEvalShadowRecall({\n memoryDir: this.config.memoryDir,\n evalStoreDir: this.config.evalStoreDir,\n record: {\n schemaVersion: 1,\n ...record,\n },\n });\n } catch (err) {\n log.debug(`eval shadow recall write failed: ${err}`);\n }\n });\n }\n\n private publishRecallResults(options: {\n title: string;\n results: QmdSearchResult[];\n sectionBuckets: Map<string, string[]>;\n retrievalQuery: string;\n sessionKey: string | undefined;\n identityInjection?: {\n mode: IdentityInjectionMode | \"none\";\n injectedChars: number;\n truncated: boolean;\n };\n }): void {\n const sectionId = \"memories\";\n const memoryIds = this.extractMemoryIdsFromResults(options.results);\n this.trackMemoryAccess(memoryIds);\n\n this.appendRecallSection(\n options.sectionBuckets,\n sectionId,\n this.formatQmdResults(options.title, options.results),\n );\n }\n\n /**\n * Apply MMR over the pre-truncation recall candidate pool and then slice\n * the result to `limit`. This is the single place in the pipeline where\n * MMR runs, and it must be called *before* callers throw away candidates\n * that would otherwise sit below the final cutoff. Running MMR post-slice\n * is a no-op in the cases we care about — diverse candidates just below\n * the cutoff are already gone and can never be promoted.\n *\n * Callers must pass the full candidate pool (post-rerank, pre-slice).\n */\n private qmdCollectionNamespaceFromPrefix(collectionPrefix: string): string | null {\n const baseCollection = this.config.qmdCollection;\n if (collectionPrefix === baseCollection) return this.config.defaultNamespace;\n const namespaceSuffix = collectionPrefix.startsWith(`${baseCollection}--`)\n ? collectionPrefix.slice(baseCollection.length + 2)\n : \"\";\n if (!namespaceSuffix) return null;\n\n const decoded = namespaceIdentityFromToken(namespaceSuffix);\n if (decoded !== null) return decoded || this.config.defaultNamespace;\n if (namespaceSuffix.startsWith(\"ns--\")) {\n const legacyNamespace = namespaceSuffix.slice(\"ns--\".length).trim();\n return legacyNamespace || null;\n }\n return null;\n }\n\n private async readQmdResultMemory(\n resultPath: string,\n fallbackStorage: StorageManager,\n recallNamespaces: readonly string[] = [],\n ): Promise<MemoryFile | null> {\n const parts = qmdCollectionPathParts(resultPath);\n const storageDirFor = (storage: StorageManager): string | null =>\n typeof (storage as { dir?: unknown }).dir === \"string\" &&\n (storage as { dir?: string }).dir\n ? (storage as { dir: string }).dir\n : null;\n const fallbackStorageDir = storageDirFor(fallbackStorage);\n const coldCollection = this.config.qmdColdCollection ?? \"openclaw-engram-cold\";\n if (parts && parts.collection === coldCollection) {\n const storages: StorageManager[] = [];\n const seenStorageDirs = new Set<string>();\n const addStorage = (storage: StorageManager): void => {\n const storageDir = storageDirFor(storage);\n const storageKey = storageDir\n ? path.resolve(storageDir)\n : `storage-without-dir-${storages.length}`;\n if (seenStorageDirs.has(storageKey)) return;\n seenStorageDirs.add(storageKey);\n storages.push(storage);\n };\n\n const fallbackNamespace =\n fallbackStorageDir !== null\n ? this.namespaceFromStorageDir(fallbackStorageDir)\n : this.config.defaultNamespace;\n if (\n recallNamespaces.length === 0 ||\n !this.config.namespacesEnabled ||\n recallNamespaces.includes(fallbackNamespace)\n ) {\n addStorage(fallbackStorage);\n }\n\n if (recallNamespaces.length > 0) {\n for (const namespace of recallNamespaces) {\n try {\n addStorage(await this.storageRouter.storageFor(namespace));\n } catch (err) {\n log.debug(\"qmd cold result namespace storage lookup skipped\", {\n path: resultPath,\n namespace,\n error: (err as Error).message,\n });\n }\n }\n }\n\n for (const storage of storages) {\n const storageDir = storageDirFor(storage);\n if (!storageDir) {\n const memory = await storage.readMemoryByPath(resultPath);\n if (memory) return memory;\n continue;\n }\n try {\n const coldRoot = path.join(storageDir, \"cold\");\n for (const candidate of qmdResultPathCandidates(\n coldRoot,\n parts.relativePath,\n )) {\n const memory = await storage.readMemoryByPath(candidate);\n if (memory) return memory;\n }\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n log.debug(\"qmd cold result path lookup failed open\", {\n path: resultPath,\n collection: coldCollection,\n error: (err as Error).message,\n });\n }\n }\n return null;\n }\n const collectionNamespace = parts\n ? this.qmdCollectionNamespaceFromPrefix(parts.collection)\n : null;\n\n if (parts && collectionNamespace) {\n try {\n const collectionStorage =\n await this.storageRouter.storageFor(collectionNamespace);\n for (const candidate of qmdResultPathCandidates(\n collectionStorage.dir,\n parts.relativePath,\n )) {\n const memory = await collectionStorage.readMemoryByPath(candidate);\n if (memory) return memory;\n }\n return null;\n } catch (err) {\n if (err instanceof SecureStoreLockedError) throw err;\n log.debug(\"qmd result namespace path lookup failed open\", {\n path: resultPath,\n namespace: collectionNamespace,\n error: (err as Error).message,\n });\n return null;\n }\n }\n\n if (path.isAbsolute(resultPath)) {\n if (!fallbackStorageDir) {\n return await fallbackStorage.readMemoryByPath(resultPath);\n }\n const ownerStorage = await this.storageForAbsoluteQmdResultPath(\n resultPath,\n fallbackStorage,\n recallNamespaces,\n );\n if (!ownerStorage) return null;\n for (const candidate of qmdResultPathCandidates(\n ownerStorage.dir,\n resultPath,\n )) {\n const memory = await ownerStorage.storage.readMemoryByPath(candidate);\n if (memory) return memory;\n }\n return null;\n }\n\n if (!fallbackStorageDir) {\n return await fallbackStorage.readMemoryByPath(resultPath);\n }\n for (const candidate of qmdResultPathCandidates(\n fallbackStorageDir,\n resultPath,\n )) {\n const memory = await fallbackStorage.readMemoryByPath(candidate);\n if (memory) return memory;\n }\n return null;\n }\n\n private async resolveColdQmdResultForRecall(\n result: QmdSearchResult,\n fallbackStorage: StorageManager,\n recallNamespaces: readonly string[] = [],\n ): Promise<{ namespace: string; result: QmdSearchResult } | null> {\n const memory = await this.readQmdResultMemory(\n result.path,\n fallbackStorage,\n recallNamespaces,\n );\n if (!memory) return null;\n\n let ownerNamespace: string | null = null;\n if (path.isAbsolute(memory.path)) {\n const ownerStorage = await this.storageForAbsoluteQmdResultPath(\n memory.path,\n fallbackStorage,\n recallNamespaces,\n );\n ownerNamespace = ownerStorage?.namespace ?? null;\n if (!ownerNamespace && this.config.namespacesEnabled) return null;\n }\n ownerNamespace ??= this.namespaceFromPath(memory.path);\n if (\n recallNamespaces.length > 0 &&\n !recallNamespaces.includes(ownerNamespace)\n ) {\n return null;\n }\n\n return {\n namespace: ownerNamespace,\n result: {\n ...result,\n docid: result.docid || memory.frontmatter.id,\n path: memory.path,\n snippet: result.snippet || memory.content.slice(0, 400),\n },\n };\n }\n\n private async storageForAbsoluteQmdResultPath(\n resultPath: string,\n fallbackStorage: StorageManager,\n recallNamespaces: readonly string[] = [],\n ): Promise<{ storage: StorageManager; dir: string; namespace: string } | null> {\n const resolvedPath = path.resolve(resultPath);\n const memoryRoot = path.resolve(this.config.memoryDir);\n const namespacesRoot = path.join(memoryRoot, \"namespaces\");\n const fallbackStorageDir =\n typeof (fallbackStorage as { dir?: unknown }).dir === \"string\" &&\n (fallbackStorage as { dir?: string }).dir\n ? (fallbackStorage as { dir: string }).dir\n : null;\n const matches: Array<{ storage: StorageManager; dir: string; namespace: string }> = [];\n const seenDirs = new Set<string>();\n\n const maybeAddStorage = (storage: StorageManager, namespace: string) => {\n const storageDir =\n typeof (storage as { dir?: unknown }).dir === \"string\" &&\n (storage as { dir?: string }).dir\n ? (storage as { dir: string }).dir\n : null;\n if (!storageDir) return;\n const candidateRoot = path.resolve(storageDir);\n if (seenDirs.has(candidateRoot)) return;\n if (!isPathInsideStorageRoot(candidateRoot, resolvedPath)) return;\n if (\n candidateRoot === memoryRoot &&\n isPathInsideStorageRoot(namespacesRoot, resolvedPath)\n ) {\n return;\n }\n seenDirs.add(candidateRoot);\n matches.push({ storage, dir: candidateRoot, namespace });\n };\n\n const fallbackNamespace =\n fallbackStorageDir !== null\n ? this.namespaceFromStorageDir(fallbackStorageDir)\n : this.config.defaultNamespace;\n maybeAddStorage(fallbackStorage, fallbackNamespace);\n\n const candidateNamespaces = new Set<string>();\n candidateNamespaces.add(this.config.defaultNamespace);\n candidateNamespaces.add(this.config.sharedNamespace);\n for (const ns of recallNamespaces) {\n candidateNamespaces.add(ns);\n }\n if (isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {\n const relativeToNamespaces = path.relative(namespacesRoot, resolvedPath);\n const [namespaceSegment] = relativeToNamespaces.split(/[\\\\/]/);\n if (namespaceSegment) {\n candidateNamespaces.add(\n namespaceIdentityFromToken(namespaceSegment) ?? namespaceSegment,\n );\n }\n }\n for (const policy of this.config.namespacePolicies ?? []) {\n candidateNamespaces.add(policy.name);\n }\n\n for (const ns of candidateNamespaces) {\n if (!ns) continue;\n try {\n maybeAddStorage(await this.storageRouter.storageFor(ns), ns);\n } catch {\n continue;\n }\n }\n\n matches.sort((a, b) => b.dir.length - a.dir.length);\n return matches[0] ?? null;\n }\n\n private async applyMemoryWorthRerank(\n results: QmdSearchResult[],\n namespaces: string[],\n ): Promise<QmdSearchResult[]> {\n // Build the counter lookup. We union frontmatter counters across every\n // namespace the recall spans — the recall path itself already\n // aggregates candidates from multiple namespaces, so we must do the\n // same when looking up counters. Per-namespace results are cached with\n // a short TTL so interactive recall doesn't trigger a full\n // `readAllMemories` scan per query (addresses codex P2 on PR 4).\n const counters = new Map<string, MemoryWorthCounters>();\n const seenNamespaces = new Set<string>();\n const nowMs = Date.now();\n\n // Evict all expired entries on every call so long-running processes\n // touching a high-cardinality namespace set (coding/project overlays,\n // per-branch) don't grow the cache unboundedly. Without this, an entry\n // for a namespace that's never looked up again would pin its full\n // counter map forever.\n for (const [key, entry] of this.memoryWorthCounterCache) {\n if (nowMs - entry.at >= Orchestrator.MEMORY_WORTH_CACHE_TTL_MS) {\n this.memoryWorthCounterCache.delete(key);\n }\n }\n\n for (const ns of namespaces) {\n if (seenNamespaces.has(ns)) continue;\n seenNamespaces.add(ns);\n try {\n const cached = this.memoryWorthCounterCache.get(ns);\n let nsMap: ReadonlyMap<string, MemoryWorthCounters> | undefined;\n if (\n cached &&\n nowMs - cached.at < Orchestrator.MEMORY_WORTH_CACHE_TTL_MS\n ) {\n nsMap = cached.counters;\n } else {\n const storage = await this.getStorage(ns);\n const memories = await storage.readAllMemories();\n nsMap = buildMemoryWorthCounterMap(memories);\n this.memoryWorthCounterCache.set(ns, { at: nowMs, counters: nsMap });\n }\n for (const [path, c] of nsMap) counters.set(path, c);\n } catch (err) {\n log.debug(\"memory-worth: failed to read namespace, skipping\", {\n namespace: ns,\n error: (err as Error).message,\n });\n }\n }\n\n // For candidates whose path didn't show up in any hot-tier namespace\n // scan (typical of cold-tier / archive fallback), try a direct\n // per-path read. Without this, cold-tier candidates always stay at\n // multiplier 1.0 even when they have outcome history. Errors are\n // swallowed so a single unreadable archive entry can't break the\n // whole recall.\n const missing = results.filter((r) => !counters.has(r.path));\n if (missing.length > 0) {\n // Use the first-seen namespace's storage as the reader — all\n // StorageManagers share the same on-disk format, and\n // `readMemoryByPath` takes an absolute path so the baseDir doesn't\n // have to match.\n let reader: StorageManager | null = null;\n for (const ns of namespaces) {\n try {\n reader = await this.getStorage(ns);\n break;\n } catch {\n // try next namespace\n }\n }\n if (reader) {\n for (const r of missing) {\n try {\n const memory = await this.readQmdResultMemory(r.path, reader, namespaces);\n if (!memory) continue;\n const fm = memory.frontmatter;\n if (fm.mw_success === undefined && fm.mw_fail === undefined) continue;\n counters.set(r.path, {\n mw_success: fm.mw_success,\n mw_fail: fm.mw_fail,\n lastAccessed: fm.lastAccessed,\n });\n } catch (err) {\n log.debug(\"memory-worth: direct path lookup failed\", {\n path: r.path,\n error: (err as Error).message,\n });\n }\n }\n }\n }\n\n // If no memory in the candidate set has any counter data, the filter\n // would be a no-op — skip the reorder to avoid spurious log spam.\n if (counters.size === 0) return results;\n\n // Preserve upstream ordering (reranker, specialized tiers, etc.) for\n // neutral candidates. The upstream stages set `memoryResults` in their\n // intended order but often leave `r.score` as the raw QMD score. If we\n // sorted by `r.score * multiplier` directly, neutral candidates\n // (multiplier 1.0) would snap back to raw-QMD order and silently undo\n // the reranker. Feed the filter a synthetic monotone-decreasing rank\n // score so it uses input position as the baseline, then applies the\n // multiplier on top. Ties fall back to the stable secondary key in\n // `applyMemoryWorthFilter`.\n const rankedInputs = results.map((r, i) => ({\n path: r.path,\n // Large positive rank score so multiplier math stays well-scaled and\n // we never hit zero; descending so earlier items rank higher.\n score: results.length - i,\n }));\n const filtered = applyMemoryWorthFilter(rankedInputs, {\n counters,\n now: new Date(),\n halfLifeMs:\n this.config.recallMemoryWorthHalfLifeMs > 0\n ? this.config.recallMemoryWorthHalfLifeMs\n : undefined,\n });\n\n // Reconstruct the QmdSearchResult list in the new order. `.score` is\n // preserved from the upstream pipeline (rerank, tier scoring, etc.) —\n // we only reorder. Writing the synthetic rank-weighted score back\n // would contaminate downstream logic (telemetry, confidence gates)\n // that expects the original QMD/rerank score semantics.\n const byPath = new Map(results.map((r) => [r.path, r]));\n const reordered: QmdSearchResult[] = [];\n for (const item of filtered) {\n const original = byPath.get(item.path);\n if (original) reordered.push(original);\n }\n return reordered;\n }\n\n private diversifyAndLimitRecallResults(\n sectionId: string,\n results: QmdSearchResult[],\n limit: number,\n retrievalQuery?: string,\n ): QmdSearchResult[] {\n const safeLimit =\n typeof limit === \"number\" && Number.isFinite(limit)\n ? Math.max(0, Math.floor(limit))\n : 0;\n if (!Array.isArray(results) || results.length === 0) return [];\n // `recallResultLimit === 0` is a true zero limit (e.g. when\n // `memoriesSectionEnabled` is false) and must return an empty array so\n // the memories section is genuinely skipped. This mirrors the\n // `slice(0, 0)` semantics of every call site this helper replaced.\n if (safeLimit === 0) return [];\n // Issue #564 PR 3: when the feature flag is on, boost reasoning_trace\n // memories for problem-solving asks so they bubble up ahead of ordinary\n // facts/decisions before MMR picks the final section. No-op when the\n // flag is off or the query is not a problem-solving ask.\n const boosted =\n this.config.recallReasoningTraceBoostEnabled && typeof retrievalQuery === \"string\"\n ? applyReasoningTraceBoost(results, {\n enabled: true,\n query: retrievalQuery,\n })\n : results;\n const diversified = this.applyMmrToQmdResults(sectionId, boosted);\n return diversified.slice(0, safeLimit);\n }\n\n /**\n * Apply Maximal Marginal Relevance to a section's ordered candidate list.\n *\n * Operates per-section so one redundant cluster cannot dominate a section,\n * and so one section's MMR pass cannot starve other sections. Returns the\n * input unchanged when disabled, when there are fewer than 2 candidates, or\n * when no budget information is available.\n */\n private applyMmrToQmdResults(\n sectionId: string,\n results: QmdSearchResult[],\n ): QmdSearchResult[] {\n if (this.config.recallMmrEnabled === false) return results;\n if (!Array.isArray(results) || results.length < 2) return results;\n\n // Config is runtime API (see AGENTS.md §4): preserve `0` as a true zero\n // limit rather than coercing it to a non-zero value. A configured topN of\n // 0 means \"apply MMR over an empty window\" — i.e. skip the reorder and\n // return the upstream candidates unchanged. This keeps read-time\n // behavior symmetric with the write-time semantics parseConfig exposes.\n const configuredTopN = this.config.recallMmrTopN;\n const topN =\n typeof configuredTopN === \"number\" && Number.isFinite(configuredTopN)\n ? Math.max(0, Math.floor(configuredTopN))\n : 40;\n if (topN === 0) return results;\n const lambda = this.config.recallMmrLambda ?? 0.7;\n\n // Delegate to the pure helper so candidate keying (path-first, index\n // suffixed for uniqueness) and the head-of-list diversity metric are\n // exercised by the same code path that the unit tests cover.\n const { reordered, diversity } = reorderRecallResultsWithMmr(results, {\n lambda,\n topN,\n });\n\n try {\n log.info(\n `recall_mmr: section=${sectionId} kept=${diversity.kept}/${diversity.considered} ` +\n `headReorderCount=${diversity.headReorderCount} ` +\n `avgSimBefore=${diversity.avgPairwiseSimBefore.toFixed(3)} ` +\n `avgSimAfter=${diversity.avgPairwiseSimAfter.toFixed(3)} ` +\n `lambda=${lambda.toFixed(2)}`,\n );\n } catch {\n // Metrics must never break recall.\n }\n\n return reordered;\n }\n\n private buildLastRecallBudgetSummary(options: {\n requestedTopK?: number;\n recallResultLimit: number;\n qmdFetchLimit: number;\n qmdHybridFetchLimit: number;\n finalContextChars?: number;\n truncated?: boolean;\n includedSections?: string[];\n omittedSections?: string[];\n }): LastRecallBudgetSummary {\n return {\n requestedTopK: options.requestedTopK,\n appliedTopK: options.recallResultLimit,\n recallBudgetChars: this.getRecallBudgetChars(),\n maxMemoryTokens: this.config.maxMemoryTokens,\n qmdFetchLimit: options.qmdFetchLimit,\n qmdHybridFetchLimit: options.qmdHybridFetchLimit,\n finalContextChars: options.finalContextChars,\n truncated: options.truncated,\n includedSections: [...(options.includedSections ?? [])],\n omittedSections: [...(options.omittedSections ?? [])],\n };\n }\n\n private collectLastRecallSources(\n sectionBuckets: Map<string, string[]>,\n recallSource:\n | \"none\"\n | \"hot_qmd\"\n | \"hot_embedding\"\n | \"cold_fallback\"\n | \"recent_scan\",\n ): string[] {\n const used = new Set<string>();\n if (recallSource !== \"none\") {\n used.add(recallSource);\n }\n for (const [sectionId, chunks] of sectionBuckets.entries()) {\n if (chunks.length > 0) {\n used.add(sectionId);\n }\n }\n return [...used];\n }\n\n /**\n * Issue #373 — nearest-neighbor lookup for the write-time semantic dedup\n * guard. Returns the top-K embedding hits against the currently indexed\n * memories, or an empty array when the embedding backend is unavailable.\n * Intentionally does NOT throw; `decideSemanticDedup` treats both \"empty\"\n * and \"error\" outcomes as fail-open (keep the candidate).\n *\n * PR #399 P1 fix: when namespaces are enabled the lookup must be scoped\n * to the SAME namespace as the fact being written. Otherwise a\n * high-similarity memory from another namespace can suppress a write in\n * the target namespace — cross-tenant data loss. Callers pass the target\n * storage so we can translate its root directory into the correct index\n * path prefix (and, for the legacy default-namespace layout at\n * `memoryDir` root, an exclusion list for `namespaces/*`).\n */\n async semanticDedupLookup(\n content: string,\n limit: number,\n targetStorage: StorageManager,\n ): Promise<SemanticDedupHit[]> {\n // Round 6 fix (Finding 3): backend-unavailable conditions must THROW so\n // that `decideSemanticDedup`'s catch block can return\n // reason=\"backend_unavailable\". Previously all error/unavailable paths\n // returned [] — causing decideSemanticDedup to always report\n // reason=\"no_candidates\" even when the provider was actually down.\n //\n // Contract after this fix:\n // • embeddingFallbackEnabled=false → throw (feature not configured;\n // caller treats this as backend_unavailable and fails open).\n // • isAvailable() returns false → throw (provider is reachable but\n // reports itself unavailable; distinct from empty index).\n // • search() throws → re-throw (network/provider error).\n // • search() returns [] → return [] (empty index, not a\n // backend failure; decideSemanticDedup reports no_candidates).\n if (!this.config.embeddingFallbackEnabled) {\n throw new Error(\"semantic dedup: embedding backend not configured\");\n }\n if (!(await this.embeddingFallback.isAvailable())) {\n log.debug(\"semantic dedup: embedding backend unavailable, skipping\");\n throw new Error(\"semantic dedup: embedding backend unavailable\");\n }\n // search() may throw — let it propagate so decideSemanticDedup catches it\n // and returns reason=\"backend_unavailable\". Pass throwOnTimeout:true so\n // EmbeddingTimeoutError is re-thrown here (Round 10 fix, Ui1J+Ui1L: the\n // recall-path caller searchEmbeddingFallback does NOT pass this flag,\n // keeping its fail-open [] contract on timeout).\n const scope = this.semanticDedupScopeFor(targetStorage);\n const hits = await this.embeddingFallback.search(content, limit, { ...scope, throwOnTimeout: true });\n if (!Array.isArray(hits) || hits.length === 0) return [];\n return hits.map((hit) => ({\n id: hit.id,\n score: hit.score,\n path: hit.path,\n }));\n }\n\n /**\n * Resolve the namespace-scoped filter to pass into\n * `EmbeddingFallback.search()` for semantic dedup. Returns an empty\n * object (no filter) when namespaces are disabled, preserving the\n * pre-PR #399 behavior for single-tenant installs.\n *\n * Index entries are stored as paths relative to `config.memoryDir`, so:\n * - A non-default namespace `ns` lives under `namespaces/<ns>/…` and\n * we include exactly that prefix.\n * - The default namespace may live at `memoryDir` root (legacy) or at\n * `memoryDir/namespaces/<default>/…` (migrated). When it lives at\n * root we include everything but EXCLUDE all `namespaces/…` entries\n * so facts from non-default namespaces can't cross-match.\n */\n private semanticDedupScopeFor(targetStorage: StorageManager): {\n pathPrefix?: string;\n pathExcludePrefixes?: readonly string[];\n } {\n if (!this.config.namespacesEnabled) return {};\n const memoryDir = path.resolve(this.config.memoryDir);\n const storageDir = path.resolve(targetStorage.dir);\n if (storageDir === memoryDir) {\n // Default namespace at legacy root. Include everything that isn't\n // under `namespaces/*` (those belong to other namespaces).\n return { pathExcludePrefixes: [\"namespaces/\"] };\n }\n let rel = path.relative(memoryDir, storageDir);\n if (!rel || rel.startsWith(\"..\")) {\n // Round 12 fix (PR #399 thread PRRT_kwDORJXyws56U6Gj): when\n // targetStorage.dir is outside memoryDir (custom namespace routing),\n // toMemoryRelativePath() stores the absolute file path in the index\n // rather than a memoryDir-relative path. Return the absolute storageDir\n // as the pathPrefix so the search() filter still scopes the lookup to\n // the correct tenant's files. Previously this returned {} (no scoping),\n // which let high-similarity hits from other namespaces' absolute-path\n // entries suppress writes in the target namespace — a cross-tenant\n // dedup suppression path.\n log.debug(\n `semantic dedup: target storage dir ${storageDir} is outside memoryDir ${memoryDir}; scoping lookup to absolute path prefix`,\n );\n const absPrefix = storageDir.replace(/\\\\/g, \"/\");\n return { pathPrefix: absPrefix.endsWith(\"/\") ? absPrefix : `${absPrefix}/` };\n }\n rel = rel.replace(/\\\\/g, \"/\");\n if (!rel.endsWith(\"/\")) rel = `${rel}/`;\n return { pathPrefix: rel };\n }\n\n private async searchEmbeddingFallback(\n query: string,\n limit: number,\n ): Promise<QmdSearchResult[]> {\n if (!this.config.embeddingFallbackEnabled) return [];\n if (!(await this.embeddingFallback.isAvailable())) return [];\n const hits = await this.embeddingFallback.search(query, limit);\n if (hits.length === 0) return [];\n\n const results: QmdSearchResult[] = [];\n for (const hit of hits) {\n const fullPath = path.isAbsolute(hit.path)\n ? hit.path\n : path.join(this.config.memoryDir, hit.path);\n const memory = await this.storage.readMemoryByPath(fullPath);\n if (!memory) continue;\n results.push({\n docid: hit.id,\n path: fullPath,\n score: hit.score,\n snippet: memory.content.slice(0, 400).replace(/\\n/g, \" \"),\n });\n }\n return results;\n }\n\n /**\n * Long-term fallback retrieval.\n * Searches archived memories only, and is invoked only when hot recall returns zero hits.\n */\n private async searchLongTermArchiveFallback(\n prompt: string,\n recallNamespaces: string[],\n limit: number,\n queryAwarePrefilter?: QueryAwarePrefilter,\n abortSignal?: AbortSignal,\n ): Promise<QmdSearchResult[]> {\n throwIfRecallAborted(abortSignal);\n const cappedLimit = Math.max(0, limit);\n if (cappedLimit === 0) return [];\n if (queryAwarePrefilter?.candidatePaths?.size === 0) return [];\n\n const scopedSeedResults = queryAwarePrefilter?.candidatePaths?.size\n ? await this.searchScopedMemoryCandidates(\n queryAwarePrefilter.candidatePaths,\n prompt,\n cappedLimit,\n { allowArchived: true },\n )\n : [];\n if (scopedSeedResults.length >= cappedLimit) {\n return scopedSeedResults\n .filter((result) => !isArtifactMemoryPath(result.path))\n .slice(0, cappedLimit);\n }\n\n const tokens = Array.from(new Set(tokenizeRecallQuery(prompt)));\n if (tokens.length === 0) return scopedSeedResults;\n\n throwIfRecallAborted(abortSignal);\n const archivedMemories =\n await this.readArchivedMemoriesForNamespaces(recallNamespaces);\n if (archivedMemories.length === 0) return scopedSeedResults;\n\n const scored: QmdSearchResult[] = [];\n for (const memory of archivedMemories) {\n throwIfRecallAborted(abortSignal);\n const haystack = [\n memory.content,\n memory.frontmatter.category,\n ...(memory.frontmatter.tags ?? []),\n ]\n .join(\" \")\n .toLowerCase();\n let hits = 0;\n for (const token of tokens) {\n if (haystack.includes(token)) hits += 1;\n }\n if (hits === 0) continue;\n const normalized = hits / tokens.length;\n scored.push({\n docid: memory.frontmatter.id,\n path: memory.path,\n score: normalized,\n snippet: memory.content.slice(0, 400).replace(/\\n/g, \" \"),\n });\n }\n\n const mergedByPath = new Map<string, QmdSearchResult>();\n for (const result of [...scopedSeedResults, ...scored]) {\n const key = result.path || result.docid;\n const existing = mergedByPath.get(key);\n if (!existing || result.score > existing.score) {\n mergedByPath.set(key, {\n ...result,\n snippet: result.snippet || existing?.snippet || \"\",\n });\n }\n }\n\n return [...mergedByPath.values()]\n .filter((result) => !isArtifactMemoryPath(result.path))\n .sort((a, b) => b.score - a.score)\n .slice(0, cappedLimit);\n }\n\n private async applyColdFallbackPipeline(options: {\n prompt: string;\n recallNamespaces: string[];\n recallResultLimit: number;\n recallMode: RecallPlanMode;\n queryAwarePrefilter?: QueryAwarePrefilter;\n abortSignal?: AbortSignal;\n /** Issue #680 — historical recall point in ms-since-epoch. */\n asOfMs?: number;\n /**\n * Optional out-parameter that receives the pre-MMR / pre-truncation\n * pool size captured inside the pipeline (issue #570 PR 1). The\n * X-ray capture block in `recallInternal` passes a small sink so\n * the cold-fallback branch's pre-truncation pool size can be\n * attributed back to the branch when `recallSource === \"cold_fallback\"`.\n * Unset by default so existing call sites are unaffected.\n */\n xrayPoolSizeSink?: { size: number };\n deadlineAtMs?: number | null;\n /** Issue #681 — when true, bypass graphTraversalConfidenceFloor. */\n includeLowConfidence?: boolean;\n }): Promise<QmdSearchResult[]> {\n if (options.queryAwarePrefilter?.candidatePaths?.size === 0) {\n if (options.xrayPoolSizeSink) options.xrayPoolSizeSink.size = 0;\n return [];\n }\n const deadlineRemainingMs = (): number | null =>\n typeof options.deadlineAtMs === \"number\"\n ? Math.max(0, options.deadlineAtMs - Date.now())\n : null;\n const runColdStepWithinDeadline = async <T>(\n label: string,\n fallback: T,\n task: () => Promise<T>,\n ): Promise<T> => {\n throwIfRecallAborted(options.abortSignal);\n const remainingMs = deadlineRemainingMs();\n if (remainingMs === 0) {\n log.debug(`cold-tier recall ${label} skipped: shared assembly deadline expired`);\n return fallback;\n }\n if (remainingMs === null) return task();\n\n let timeoutHandle: NodeJS.Timeout | undefined;\n let timedOut = false;\n const taskPromise = task().catch((err) => {\n if (timedOut) {\n log.debug(`cold-tier recall ${label} failed after deadline: ${err}`);\n return fallback;\n }\n throw err;\n });\n\n try {\n return await Promise.race<T>([\n taskPromise,\n new Promise<T>((resolve) => {\n timeoutHandle = setTimeout(() => {\n timedOut = true;\n log.debug(\n `cold-tier recall ${label} skipped: shared assembly deadline expired`,\n );\n resolve(fallback);\n }, remainingMs);\n }),\n ]);\n } finally {\n if (timeoutHandle) clearTimeout(timeoutHandle);\n }\n };\n\n const coldQmdEnabled = this.config.qmdColdTierEnabled === true;\n const coldCollection =\n this.config.qmdColdCollection ?? \"openclaw-engram-cold\";\n const coldMaxResults =\n this.config.qmdColdMaxResults ?? this.config.qmdMaxResults;\n\n let longTerm: QmdSearchResult[] = [];\n if (coldQmdEnabled && this.qmd.isAvailable()) {\n const coldFetchLimit = Math.max(\n 0,\n Math.min(options.recallResultLimit, Math.max(0, coldMaxResults)),\n );\n if (coldFetchLimit > 0) {\n const coldHybridLimit = computeQmdHybridFetchLimit(\n coldFetchLimit,\n false,\n 0,\n );\n longTerm = await runColdStepWithinDeadline(\n \"qmd lookup\",\n [],\n () =>\n this.fetchQmdMemoryResultsWithArtifactTopUp(\n options.prompt,\n coldFetchLimit,\n coldHybridLimit,\n {\n namespacesEnabled: this.config.namespacesEnabled,\n recallNamespaces: options.recallNamespaces,\n resolveNamespace: (p) => this.namespaceFromPath(p),\n collection: coldCollection,\n queryAwarePrefilter: options.queryAwarePrefilter,\n searchOptions: this.buildConfiguredQmdSearchOptions(options.prompt),\n abortSignal: options.abortSignal,\n },\n ),\n );\n if (longTerm.length > 0) {\n log.debug(\n `cold-tier recall source=cold-qmd collection=${coldCollection} hits=${longTerm.length}`,\n );\n }\n }\n }\n if (longTerm.length === 0) {\n longTerm = await runColdStepWithinDeadline(\n \"archive scan\",\n [],\n () =>\n this.searchLongTermArchiveFallback(\n options.prompt,\n options.recallNamespaces,\n options.recallResultLimit,\n options.queryAwarePrefilter,\n options.abortSignal,\n ),\n );\n if (longTerm.length > 0) {\n log.debug(\"cold-tier recall source=archive-scan\");\n }\n }\n if (longTerm.length === 0) return [];\n\n let results = longTerm;\n if (this.config.namespacesEnabled) {\n const recallRoots: string[] = [];\n const seenRecallRoots = new Set<string>();\n for (const namespace of options.recallNamespaces) {\n try {\n const storage = await this.storageRouter.storageFor(namespace);\n const storageDir =\n typeof (storage as { dir?: unknown }).dir === \"string\" &&\n (storage as { dir?: string }).dir\n ? (storage as { dir: string }).dir\n : null;\n if (!storageDir) continue;\n const recallRoot = path.resolve(storageDir);\n if (seenRecallRoots.has(recallRoot)) continue;\n seenRecallRoots.add(recallRoot);\n recallRoots.push(recallRoot);\n } catch (err) {\n log.debug(\"cold-tier recall namespace root lookup skipped\", {\n namespace,\n error: (err as Error).message,\n });\n }\n }\n const scopedResults: QmdSearchResult[] = [];\n for (const result of results) {\n if (options.abortSignal?.aborted || deadlineRemainingMs() === 0) break;\n const parts = qmdCollectionPathParts(result.path);\n if (parts?.collection === coldCollection) {\n const resolvedCold = await this.resolveColdQmdResultForRecall(\n result,\n this.storage,\n options.recallNamespaces,\n );\n if (resolvedCold) scopedResults.push(resolvedCold.result);\n continue;\n }\n if (path.isAbsolute(result.path)) {\n const resolvedPath = path.resolve(result.path);\n if (\n recallRoots.some((recallRoot) =>\n isPathInsideStorageRoot(recallRoot, resolvedPath),\n )\n ) {\n scopedResults.push(result);\n }\n continue;\n }\n if (options.recallNamespaces.includes(this.namespaceFromPath(result.path))) {\n scopedResults.push(result);\n }\n }\n results = scopedResults;\n }\n // Artifact isolation contract: generic recall paths must exclude artifacts.\n results = results.filter((r) => !isArtifactMemoryPath(r.path));\n if (results.length === 0) return [];\n\n const isFullModeGraphAssist =\n this.config.qmdTierParityGraphEnabled &&\n this.config.multiGraphMemoryEnabled &&\n this.config.graphAssistInFullModeEnabled !== false &&\n options.recallMode === \"full\" &&\n results.length >= Math.max(1, this.config.graphAssistMinSeedResults ?? 3);\n const shouldRunGraphExpansion =\n this.config.qmdTierParityGraphEnabled &&\n (options.recallMode === \"graph_mode\" || isFullModeGraphAssist);\n\n if (shouldRunGraphExpansion) {\n const { merged } = await this.expandResultsViaGraph({\n memoryResults: results,\n recallNamespaces: options.recallNamespaces,\n recallResultLimit: options.recallResultLimit,\n deadlineAtMs: options.deadlineAtMs,\n ...(options.includeLowConfidence === true ? { includeLowConfidence: true } : {}),\n });\n results = merged;\n }\n\n const boostInput = await this.filterSearchResultsForRecall(\n results,\n undefined,\n {\n allowLifecycleFiltered: true,\n asOfMs: options.asOfMs,\n deadlineAtMs: options.deadlineAtMs,\n abortSignal: options.abortSignal,\n dropUnresolved: true,\n recallNamespaces: options.recallNamespaces,\n },\n );\n results = boostInput.results;\n const boostTimeoutMs =\n typeof options.deadlineAtMs === \"number\"\n ? Math.max(0, options.deadlineAtMs - Date.now())\n : null;\n if (boostTimeoutMs !== 0) {\n let timeoutHandle: NodeJS.Timeout | undefined;\n try {\n const boosted = await (boostTimeoutMs !== null\n ? Promise.race<QmdSearchResult[] | { status: \"timed_out\" }>([\n this.boostSearchResults(\n boostInput.results,\n options.recallNamespaces,\n options.prompt,\n boostInput.memoryByPath,\n { allowLifecycleFiltered: true, asOfMs: options.asOfMs },\n ),\n new Promise<{ status: \"timed_out\" }>((resolve) => {\n timeoutHandle = setTimeout(\n () => resolve({ status: \"timed_out\" }),\n boostTimeoutMs,\n );\n }),\n ])\n : this.boostSearchResults(\n boostInput.results,\n options.recallNamespaces,\n options.prompt,\n boostInput.memoryByPath,\n { allowLifecycleFiltered: true, asOfMs: options.asOfMs },\n ));\n if (\n typeof boosted === \"object\" &&\n boosted !== null &&\n \"status\" in boosted &&\n boosted.status === \"timed_out\"\n ) {\n log.debug(\"cold-tier recall boost skipped: shared assembly deadline expired\");\n } else if (Array.isArray(boosted)) {\n results = boosted;\n } else {\n results = boostInput.results;\n }\n } catch (err) {\n log.debug(`cold-tier recall boost failed open: ${err}`);\n } finally {\n if (timeoutHandle) clearTimeout(timeoutHandle);\n }\n } else {\n log.debug(\"cold-tier recall boost skipped: shared assembly deadline already expired\");\n }\n\n if (this.config.rerankEnabled && this.config.rerankProvider === \"local\") {\n const ranked = await rerankLocalOrNoop({\n query: options.prompt,\n candidates: results\n .slice(0, this.config.rerankMaxCandidates)\n .map((r) => ({\n id: r.path,\n snippet: r.snippet || r.path,\n })),\n local: this.fastLlmForRerank,\n enabled: true,\n timeoutMs: this.config.rerankTimeoutMs,\n maxCandidates: this.config.rerankMaxCandidates,\n cache: this.rerankCache,\n cacheEnabled: this.config.rerankCacheEnabled,\n cacheTtlMs: this.config.rerankCacheTtlMs,\n });\n if (ranked && ranked.length > 0) {\n const byPath = new Map(results.map((r) => [r.path, r]));\n const reordered: QmdSearchResult[] = [];\n for (const p of ranked) {\n const it = byPath.get(p);\n if (it) reordered.push(it);\n }\n const rankedSet = new Set(ranked);\n for (const r of results) {\n if (!rankedSet.has(r.path)) reordered.push(r);\n }\n results = reordered;\n }\n }\n if (this.config.rerankEnabled && this.config.rerankProvider === \"cloud\") {\n log.debug(\n \"rerankProvider=cloud is reserved/experimental in v2.2.0; skipping rerank\",\n );\n }\n\n // Memory Worth filter — must fire on the cold fallback path too, or the\n // feature flag produces divergent behavior by retrieval path (CLAUDE.md\n // rule 39). Fail-open on lookup errors.\n if (this.config.recallMemoryWorthFilterEnabled && results.length > 0) {\n try {\n results = await this.applyMemoryWorthRerank(results, options.recallNamespaces);\n } catch (err) {\n log.debug(\"memory-worth filter (cold) failed open\", {\n error: (err as Error).message,\n });\n }\n }\n\n // Apply MMR before final truncation so the cold fallback path mirrors\n // the diversification policy applied in the hot QMD/embedding/recent\n // paths. Running MMR post-slice would be unable to promote diverse\n // candidates sitting just below the cutoff.\n if (options.xrayPoolSizeSink) {\n options.xrayPoolSizeSink.size = Math.max(\n options.xrayPoolSizeSink.size,\n results.length,\n );\n }\n return this.diversifyAndLimitRecallResults(\n \"memories\",\n results,\n options.recallResultLimit,\n options.prompt,\n );\n }\n\n // ---------------------------------------------------------------------------\n // Access Tracking (Phase 1A)\n // ---------------------------------------------------------------------------\n\n /**\n * Record that memories were accessed (retrieved).\n * Updates are batched in memory and flushed during consolidation.\n */\n trackMemoryAccess(memoryIds: string[]): void {\n if (!this.config.accessTrackingEnabled) return;\n\n const now = new Date().toISOString();\n for (const id of memoryIds) {\n const existing = this.accessTrackingBuffer.get(id);\n this.accessTrackingBuffer.set(id, {\n count: (existing?.count ?? 0) + 1,\n lastAccessed: now,\n });\n }\n\n // Flush if buffer exceeds max size\n if (\n this.accessTrackingBuffer.size >= this.config.accessTrackingBufferMaxSize\n ) {\n this.flushAccessTracking().catch((err) =>\n log.debug(`background access tracking flush failed: ${err}`),\n );\n }\n }\n\n /**\n * Flush access tracking buffer to disk.\n * Called during consolidation or when buffer is full.\n */\n async flushAccessTracking(): Promise<void> {\n if (this.accessTrackingBuffer.size === 0) return;\n\n // Build entries from buffer, merging with existing counts\n const entries: AccessTrackingEntry[] = [];\n const namespaces = this.config.namespacesEnabled\n ? Array.from(\n new Set<string>([\n this.config.defaultNamespace,\n this.config.sharedNamespace,\n ...this.config.namespacePolicies.map((p) => p.name),\n ]),\n )\n : [this.config.defaultNamespace];\n const memories = await this.readAllMemoriesForNamespaces(namespaces);\n const memoryMap = new Map(memories.map((m) => [m.frontmatter.id, m]));\n\n for (const [memoryId, update] of this.accessTrackingBuffer) {\n const memory = memoryMap.get(memoryId);\n const existingCount = memory?.frontmatter.accessCount ?? 0;\n entries.push({\n memoryId,\n newCount: existingCount + update.count,\n lastAccessed: update.lastAccessed,\n });\n }\n\n const byNamespace = new Map<string, AccessTrackingEntry[]>();\n for (const e of entries) {\n const m = memoryMap.get(e.memoryId);\n if (!m) continue;\n const ns = this.namespaceFromPath(m.path);\n const list = byNamespace.get(ns) ?? [];\n list.push(e);\n byNamespace.set(ns, list);\n }\n for (const [ns, list] of byNamespace) {\n const sm = await this.storageRouter.storageFor(ns);\n await sm.flushAccessTracking(list);\n }\n this.accessTrackingBuffer.clear();\n log.debug(`flushed ${entries.length} access tracking entries`);\n }\n\n private async loadSearchResultMemoryMap(\n results: QmdSearchResult[],\n preloadedMemoryMap?: Map<string, MemoryFile>,\n options?: {\n deadlineAtMs?: number | null;\n abortSignal?: AbortSignal;\n recallNamespaces?: readonly string[];\n },\n ): Promise<{\n memoryByPath: Map<string, MemoryFile>;\n checkedPaths: Set<string>;\n unreadablePaths: Set<string>;\n completed: boolean;\n }> {\n const memoryByPath: Map<string, MemoryFile> = preloadedMemoryMap\n ? new Map(preloadedMemoryMap)\n : new Map();\n const checkedPaths = new Set<string>();\n const unreadablePaths = new Set<string>();\n\n const markChecked = (result: QmdSearchResult): void => {\n if (result.path) checkedPaths.add(result.path);\n };\n const markUnreadable = (result: QmdSearchResult, err: unknown): void => {\n if (!result.path) return;\n checkedPaths.add(result.path);\n unreadablePaths.add(result.path);\n log.warn(\"recall safety filter dropped unreadable secure-store candidate\", {\n path: result.path,\n error: (err as Error).message,\n });\n };\n const deadlineExpired = (): boolean =>\n typeof options?.deadlineAtMs === \"number\" &&\n Date.now() >= options.deadlineAtMs;\n\n if (options?.deadlineAtMs == null) {\n const batchSize = options?.abortSignal ? 16 : results.length;\n for (let offset = 0; offset < results.length; offset += batchSize) {\n if (options?.abortSignal?.aborted) {\n return {\n memoryByPath,\n checkedPaths,\n unreadablePaths,\n completed: false,\n };\n }\n await Promise.all(\n results.slice(offset, offset + batchSize).map(async (r) => {\n if (!r.path) return;\n if (memoryByPath.has(r.path)) {\n markChecked(r);\n return;\n }\n try {\n const mem = await this.readQmdResultMemory(\n r.path,\n this.storage,\n options?.recallNamespaces,\n );\n markChecked(r);\n if (mem) memoryByPath.set(r.path, mem);\n } catch (err) {\n if (err instanceof SecureStoreLockedError) {\n markUnreadable(r, err);\n return;\n }\n throw err;\n }\n }),\n );\n }\n\n return { memoryByPath, checkedPaths, unreadablePaths, completed: true };\n }\n\n for (const result of results) {\n if (!result.path) continue;\n if (memoryByPath.has(result.path)) {\n markChecked(result);\n continue;\n }\n if (options?.abortSignal?.aborted || deadlineExpired()) {\n return { memoryByPath, checkedPaths, unreadablePaths, completed: false };\n }\n try {\n const mem = await this.readQmdResultMemory(\n result.path,\n this.storage,\n options?.recallNamespaces,\n );\n markChecked(result);\n if (mem) memoryByPath.set(result.path, mem);\n } catch (err) {\n if (err instanceof SecureStoreLockedError) {\n markUnreadable(result, err);\n continue;\n }\n throw err;\n }\n }\n\n return { memoryByPath, checkedPaths, unreadablePaths, completed: true };\n }\n\n private filterSearchResultsByRecallSafety(\n results: QmdSearchResult[],\n memoryByPath: Map<string, MemoryFile>,\n options?: {\n allowLifecycleFiltered?: boolean;\n allowDedicatedSurface?: boolean;\n asOfMs?: number;\n blockedPaths?: Set<string>;\n },\n ): QmdSearchResult[] {\n let lifecycleFilteredCount = 0;\n let temporalSupersededFilteredCount = 0;\n let dedicatedSurfaceFilteredCount = 0;\n let forgottenFilteredCount = 0;\n let blockedPathFilteredCount = 0;\n const filtered: QmdSearchResult[] = [];\n for (const r of results) {\n if (r.path && options?.blockedPaths?.has(r.path)) {\n blockedPathFilteredCount += 1;\n continue;\n }\n const memory = memoryByPath.get(r.path);\n if (memory) {\n if (memory.frontmatter.status === \"forgotten\") {\n forgottenFilteredCount += 1;\n continue;\n }\n\n if (\n options?.allowLifecycleFiltered !== true &&\n shouldFilterLifecycleRecallCandidate(memory.frontmatter, {\n lifecyclePolicyEnabled: this.config.lifecyclePolicyEnabled,\n lifecycleFilterStaleEnabled:\n this.config.lifecycleFilterStaleEnabled,\n })\n ) {\n lifecycleFilteredCount += 1;\n continue;\n }\n\n // Historical recall (issue #680): when the caller pinned the\n // recall to a specific point in time, evaluate temporal validity\n // at that instant FIRST and bypass the supersession filter\n // entirely. A fact that is currently superseded but was valid\n // at `as_of` is exactly what historical recall should surface;\n // running supersession filtering before the as_of check would\n // drop it and break the worked example in docs/temporal-recall.md\n // (codex P1 / cursor High on PR #713).\n const asOfActive =\n typeof options?.asOfMs === \"number\" && Number.isFinite(options.asOfMs);\n if (asOfActive) {\n if (!isValidAsOf(memory.frontmatter, options!.asOfMs!)) {\n temporalSupersededFilteredCount += 1;\n continue;\n }\n } else if (\n // Temporal supersession filter (issue #375): drop memories that\n // a newer fact has retired, unless the caller opted in to history.\n // NOTE: This check is intentionally independent of\n // allowLifecycleFiltered (Finding A fix) — cold fallback sets\n // allowLifecycleFiltered=true to include archived/retired\n // candidates, but superseded memories must still be filtered\n // unless temporalSupersessionIncludeInRecall is set.\n // Skipped entirely when `as_of` is active (above branch); the\n // half-open `[valid_at, invalid_at)` evaluation in isValidAsOf\n // is the authoritative gate for historical recall.\n shouldFilterSupersededFromRecall(memory.frontmatter, {\n enabled: this.config.temporalSupersessionEnabled,\n includeInRecall: this.config.temporalSupersessionIncludeInRecall,\n })\n ) {\n temporalSupersededFilteredCount += 1;\n continue;\n }\n\n if (\n options?.allowDedicatedSurface !== true &&\n (memory.frontmatter.memoryKind === \"dream\" ||\n memory.frontmatter.memoryKind === \"procedural\")\n ) {\n dedicatedSurfaceFilteredCount += 1;\n continue;\n }\n }\n filtered.push(r);\n }\n if (lifecycleFilteredCount > 0) {\n log.debug(\n `lifecycle retrieval filter removed ${lifecycleFilteredCount} stale/archived candidates`,\n );\n }\n if (temporalSupersededFilteredCount > 0) {\n log.debug(\n `temporal supersession filter removed ${temporalSupersededFilteredCount} superseded candidates`,\n );\n }\n if (dedicatedSurfaceFilteredCount > 0) {\n log.debug(\n `dedicated surface filter removed ${dedicatedSurfaceFilteredCount} dream/procedural candidates from generic recall`,\n );\n }\n if (forgottenFilteredCount > 0) {\n log.debug(\n `forgotten status filter removed ${forgottenFilteredCount} candidates from recall`,\n );\n }\n if (blockedPathFilteredCount > 0) {\n log.debug(\n `unreadable-path filter removed ${blockedPathFilteredCount} candidates from recall`,\n );\n }\n return filtered;\n }\n\n private async filterSearchResultsForRecall(\n results: QmdSearchResult[],\n preloadedMemoryMap?: Map<string, MemoryFile>,\n options?: {\n allowLifecycleFiltered?: boolean;\n allowDedicatedSurface?: boolean;\n asOfMs?: number;\n deadlineAtMs?: number | null;\n abortSignal?: AbortSignal;\n dropUnresolved?: boolean;\n recallNamespaces?: readonly string[];\n },\n ): Promise<{ results: QmdSearchResult[]; memoryByPath: Map<string, MemoryFile> }> {\n if (results.length === 0) {\n return {\n results,\n memoryByPath: preloadedMemoryMap ? new Map(preloadedMemoryMap) : new Map(),\n };\n }\n const loaded = await this.loadSearchResultMemoryMap(\n results,\n preloadedMemoryMap,\n options,\n );\n const candidateResults = loaded.completed\n ? results\n : results.filter((result) => !result.path || loaded.checkedPaths.has(result.path));\n if (!loaded.completed) {\n log.debug(\n `recall safety filter stopped before validating all candidates (${candidateResults.length}/${results.length} eligible)`,\n );\n }\n const blockedPaths = new Set(loaded.unreadablePaths);\n if (options?.dropUnresolved === true) {\n for (const resultPath of loaded.checkedPaths) {\n if (!loaded.memoryByPath.has(resultPath)) {\n blockedPaths.add(resultPath);\n }\n }\n }\n return {\n results: this.filterSearchResultsByRecallSafety(\n candidateResults,\n loaded.memoryByPath,\n { ...options, blockedPaths },\n ),\n memoryByPath: loaded.memoryByPath,\n };\n }\n\n /**\n * Apply recency, access count, and importance boosting to QMD search results.\n * Returns re-ranked results.\n */\n private async boostSearchResults(\n results: QmdSearchResult[],\n _recallNamespaces: string[],\n prompt?: string,\n preloadedMemoryMap?: Map<string, MemoryFile>,\n options?: {\n allowLifecycleFiltered?: boolean;\n allowDedicatedSurface?: boolean;\n /**\n * Historical recall point in ms-since-epoch (issue #680). When\n * set, drops candidates that were not authoritative at this\n * instant per `temporal-validity.isValidAsOf`. Caller is\n * responsible for parsing/validating the user-supplied ISO\n * string at the input boundary (CLI / HTTP / MCP).\n */\n asOfMs?: number;\n },\n ): Promise<QmdSearchResult[]> {\n if (results.length === 0) return results;\n\n const safety = await this.filterSearchResultsForRecall(\n results,\n preloadedMemoryMap,\n { ...options, recallNamespaces: _recallNamespaces },\n );\n const safeResults = safety.results;\n const memoryByPath = safety.memoryByPath;\n if (safeResults.length === 0) return safeResults;\n\n const now = Date.now();\n\n // Determine temporal/tag query params before index I/O (pure computation).\n const resultPaths = new Set(\n safeResults.map((r) => r.path).filter(Boolean) as string[],\n );\n let temporalFromDate: string | null = null;\n let promptTags: string[] = [];\n if (this.config.queryAwareIndexingEnabled && prompt) {\n if (isTemporalQuery(prompt)) {\n temporalFromDate = recencyWindowFromPrompt(prompt, now);\n }\n promptTags = extractTagsFromPrompt(prompt);\n }\n\n const [rawTemporal, rawTags] = await Promise.all([\n temporalFromDate !== null\n ? queryByDateRangeAsync(this.config.memoryDir, temporalFromDate)\n : Promise.resolve<Set<string> | null>(null),\n promptTags.length > 0\n ? queryByTagsAsync(this.config.memoryDir, promptTags)\n : Promise.resolve<Set<string> | null>(null),\n ]);\n\n const queryIntent =\n this.config.intentRoutingEnabled && prompt\n ? inferIntentFromText(prompt)\n : null;\n\n // v8.1: Temporal + Tag prefilter candidate set\n // Scope to result paths first so cross-namespace paths don't consume the cap.\n let temporalCandidates: Set<string> | null = null;\n let tagCandidates: Set<string> | null = null;\n if (this.config.queryAwareIndexingEnabled && prompt) {\n const maxCandidates = this.config.queryAwareIndexingMaxCandidates;\n const capSet = (s: Set<string> | null): Set<string> | null => {\n if (!s) return null;\n // Intersect with result paths first so out-of-scope paths don't exhaust the budget\n const scoped = new Set(Array.from(s).filter((p) => resultPaths.has(p)));\n if (maxCandidates === 0 || scoped.size <= maxCandidates)\n return scoped;\n return new Set(Array.from(scoped).slice(0, maxCandidates));\n };\n if (temporalFromDate !== null) {\n temporalCandidates = capSet(rawTemporal);\n }\n if (promptTags.length > 0) {\n tagCandidates = capSet(rawTags);\n }\n }\n\n const boosted: QmdSearchResult[] = [];\n const recencyWeight = this.effectiveRecencyWeight();\n for (const r of safeResults) {\n const memory = memoryByPath.get(r.path);\n let score = r.score;\n\n if (memory) {\n // Recency boost: exponential decay over 7 days\n if (recencyWeight > 0) {\n const createdAt = new Date(memory.frontmatter.created).getTime();\n const ageMs = now - createdAt;\n const ageDays = ageMs / (1000 * 60 * 60 * 24);\n const halfLifeDays = 7;\n const recencyScore = Math.pow(0.5, ageDays / halfLifeDays);\n score = score * (1 - recencyWeight) + recencyScore * recencyWeight;\n }\n\n // Access count boost: log scale, capped\n if (this.config.boostAccessCount && memory.frontmatter.accessCount) {\n const accessBoost =\n Math.log10(memory.frontmatter.accessCount + 1) / 3;\n score += applyUtilityRankingRuntimeDelta(\n Math.min(accessBoost, 0.1),\n this.utilityRuntimeValues,\n \"boost\",\n );\n }\n\n // Importance boost (Phase 1B): higher importance = higher rank\n if (memory.frontmatter.importance) {\n const importanceScore = memory.frontmatter.importance.score;\n // Boost important memories, slightly penalize trivial ones\n // Scale: trivial (-0.05) to critical (+0.15)\n const importanceBoost = (importanceScore - 0.4) * 0.25;\n score += applyUtilityRankingRuntimeDelta(\n importanceBoost,\n this.utilityRuntimeValues,\n importanceBoost >= 0 ? \"boost\" : \"suppress\",\n );\n }\n\n // Feedback bias (v2.2): apply small user-provided up/down vote adjustments.\n if (this.config.feedbackEnabled) {\n const match = memory.path.match(/([^/]+)\\.md$/);\n const memoryId = match ? match[1] : null;\n if (memoryId) {\n const feedbackDelta = this.relevance.adjustment(memoryId);\n score += applyUtilityRankingRuntimeDelta(\n feedbackDelta,\n this.utilityRuntimeValues,\n feedbackDelta >= 0 ? \"boost\" : \"suppress\",\n );\n }\n }\n\n // Negative examples (v2.2): apply a small penalty for memories repeatedly marked \"not useful\".\n if (this.config.negativeExamplesEnabled) {\n const match = memory.path.match(/([^/]+)\\.md$/);\n const memoryId = match ? match[1] : null;\n if (memoryId) {\n const negativePenalty = this.negatives.penalty(memoryId, {\n perHit: this.config.negativeExamplesPenaltyPerHit,\n cap: this.config.negativeExamplesPenaltyCap,\n });\n score -= applyUtilityRankingRuntimeDelta(\n negativePenalty,\n this.utilityRuntimeValues,\n \"suppress\",\n );\n }\n }\n\n if (\n queryIntent &&\n memory.frontmatter.intentGoal &&\n memory.frontmatter.intentActionType\n ) {\n const compatibility = intentCompatibilityScore(queryIntent, {\n goal: memory.frontmatter.intentGoal,\n actionType: memory.frontmatter.intentActionType,\n entityTypes: memory.frontmatter.intentEntityTypes ?? [],\n });\n score += applyUtilityRankingRuntimeDelta(\n compatibility * this.config.intentRoutingBoost,\n this.utilityRuntimeValues,\n \"boost\",\n );\n }\n\n // v8.1: Temporal + Tag index boost\n // Results that match the detected temporal window or tag query get a small additive boost.\n if (this.config.queryAwareIndexingEnabled && r.path) {\n if (temporalCandidates?.has(r.path)) {\n score += applyUtilityRankingRuntimeDelta(\n 0.08,\n this.utilityRuntimeValues,\n \"boost\",\n );\n }\n if (tagCandidates?.has(r.path)) {\n score += applyUtilityRankingRuntimeDelta(\n 0.06,\n this.utilityRuntimeValues,\n \"boost\",\n );\n }\n }\n\n // v8.3: lifecycle retrieval weighting (fail-open on legacy memories).\n const lifecycleDelta = lifecycleRecallScoreAdjustment(\n memory.frontmatter,\n {\n lifecyclePolicyEnabled: this.config.lifecyclePolicyEnabled,\n },\n );\n score += applyUtilityRankingRuntimeDelta(\n lifecycleDelta,\n this.utilityRuntimeValues,\n lifecycleDelta >= 0 ? \"boost\" : \"suppress\",\n );\n\n // Reinforcement recall boost (issue #687 PR 3/4).\n // Applies an additive score bonus proportional to how many times the\n // pattern-reinforcement job has promoted this memory as a canonical.\n // Formula: min(reinforcement_count * weight, max).\n // Gated by reinforcementRecallBoostEnabled (default false).\n let reinforcementBoost = 0;\n if (\n this.config.reinforcementRecallBoostEnabled &&\n typeof memory.frontmatter.reinforcement_count === \"number\" &&\n memory.frontmatter.reinforcement_count > 0\n ) {\n reinforcementBoost = Math.min(\n memory.frontmatter.reinforcement_count *\n this.config.reinforcementRecallBoostWeight,\n this.config.reinforcementRecallBoostMax,\n );\n score += reinforcementBoost;\n }\n if (reinforcementBoost > 0) {\n boosted.push({\n ...r,\n score,\n explain: { ...(r.explain ?? {}), reinforcementBoost },\n });\n continue;\n }\n }\n\n boosted.push({ ...r, score });\n }\n\n // Re-sort by boosted score\n return boosted.sort((a, b) => b.score - a.score);\n }\n\n /**\n * Extract memory IDs from QMD search results for access tracking.\n */\n private extractMemoryIdsFromResults(results: QmdSearchResult[]): string[] {\n // QMD results have paths like /path/to/fact-123.md\n // Extract the ID from the filename\n return results\n .map((r) => {\n const match = r.path.match(/([^/]+)\\.md$/);\n return match ? match[1] : null;\n })\n .filter((id): id is string => id !== null);\n }\n\n // ---------------------------------------------------------------------------\n // Contradiction Detection (Phase 2B)\n // ---------------------------------------------------------------------------\n\n // ---------------------------------------------------------------------------\n // Feedback (v2.2)\n // ---------------------------------------------------------------------------\n\n async recordMemoryFeedback(\n memoryId: string,\n vote: \"up\" | \"down\",\n note?: string,\n ): Promise<void> {\n await this.relevance.record(memoryId, vote, note);\n }\n\n // Negative Examples (v2.2)\n async recordNotUsefulMemories(\n memoryIds: string[],\n note?: string,\n ): Promise<void> {\n await this.negatives.recordNotUseful(memoryIds, note);\n }\n\n getLastRecall(sessionKey: string): LastRecallSnapshot | null {\n return this.lastRecall.get(sessionKey);\n }\n\n /**\n * Check if a new memory contradicts an existing one.\n * Uses QMD to find similar memories, then LLM to verify contradiction.\n */\n private async checkForContradiction(\n content: string,\n category: string,\n namespaceScope: string,\n ): Promise<{\n supersededId: string;\n confidence: number;\n reason: string;\n supersededPath: string;\n supersededCreated: string;\n supersededTags: string[];\n } | null> {\n if (!this.isSearchAvailableForNamespaceRouting()) return null;\n\n // Search for similar memories\n const results = await this.searchAcrossNamespaces({\n query: content,\n namespaces: [namespaceScope],\n maxResults: 5,\n mode: \"search\",\n });\n\n for (const result of results) {\n // Check similarity threshold\n if (result.score < this.config.contradictionSimilarityThreshold) {\n continue;\n }\n\n // Get the existing memory\n const memoryId = this.extractMemoryIdsFromResults([result])[0];\n if (!memoryId) continue;\n\n const resultNamespace = this.namespaceFromPath(result.path);\n if (resultNamespace !== namespaceScope) continue;\n const resultStorage =\n await this.storageRouter.storageFor(resultNamespace);\n const existingMemory = await resultStorage.getMemoryById(memoryId);\n if (!existingMemory) continue;\n\n // Skip memories already resolved or explicitly forgotten. Other\n // non-active statuses remain valid contradiction candidates.\n if (\n existingMemory.frontmatter.status === \"superseded\" ||\n existingMemory.frontmatter.status === \"forgotten\"\n ) {\n continue;\n }\n\n // Verify contradiction with LLM\n const verification = await this.extraction.verifyContradiction(\n { content, category },\n {\n id: existingMemory.frontmatter.id,\n content: existingMemory.content,\n category: existingMemory.frontmatter.category,\n created: existingMemory.frontmatter.created,\n },\n );\n\n if (!verification) continue;\n\n // Check if it's a real contradiction with high confidence\n if (\n verification.isContradiction &&\n verification.confidence >= this.config.contradictionMinConfidence\n ) {\n // When the LLM says the existing memory is newer (whichIsNewer ===\n // \"first\") the incoming fact is the stale one in both resolve modes —\n // log and continue so the caller never marks contradictionDetected and\n // the semantic-skip gate can discard the outdated write normally.\n if (verification.whichIsNewer === \"first\") {\n log.info(\n `detected contradiction (confidence: ${verification.confidence}): ${existingMemory.frontmatter.id} vs new memory — existing is newer, incoming fact is stale`,\n );\n continue;\n }\n\n // The new fact is newer than the existing one. When auto-resolve is\n // enabled, immediately retire the old memory. When disabled, leave the\n // old memory active for manual review.\n if (this.config.contradictionAutoResolve) {\n await resultStorage.supersedeMemory(\n existingMemory.frontmatter.id,\n \"pending-new\", // Will be updated after the new memory is written\n verification.reasoning,\n );\n }\n\n // Return the contradiction info regardless of auto-resolve setting.\n // The caller uses this to set `contradictionDetected=true` which\n // prevents the semantic-skip guard from silently dropping a\n // legitimately contradictory update (the regression this fixes).\n log.info(\n `detected contradiction (confidence: ${verification.confidence}): ${existingMemory.frontmatter.id} vs new memory${this.config.contradictionAutoResolve ? \" (auto-resolved)\" : \" (queued for manual review)\"}`,\n );\n return {\n supersededId: existingMemory.frontmatter.id,\n confidence: verification.confidence,\n reason: verification.reasoning,\n supersededPath: existingMemory.path,\n supersededCreated: existingMemory.frontmatter.created,\n supersededTags: existingMemory.frontmatter.tags ?? [],\n };\n }\n }\n\n return null;\n }\n\n // ---------------------------------------------------------------------------\n // Memory Linking (Phase 3A)\n // ---------------------------------------------------------------------------\n\n /**\n * Suggest links for a new memory based on similar existing memories.\n */\n private async suggestLinksForMemory(\n content: string,\n category: string,\n namespaceScope: string,\n ): Promise<MemoryLink[]> {\n if (!this.isSearchAvailableForNamespaceRouting()) return [];\n\n // Search for related memories\n const results = await this.searchAcrossNamespaces({\n query: content,\n namespaces: [namespaceScope],\n maxResults: 5,\n mode: \"search\",\n });\n if (results.length === 0) return [];\n\n // Get full memory details for candidates\n const candidates: Array<{ id: string; content: string; category: string }> =\n [];\n for (const result of results) {\n const memoryId = this.extractMemoryIdsFromResults([result])[0];\n if (!memoryId) continue;\n\n const resultNamespace = this.namespaceFromPath(result.path);\n if (resultNamespace !== namespaceScope) continue;\n const resultStorage =\n await this.storageRouter.storageFor(resultNamespace);\n const memory = await resultStorage.getMemoryById(memoryId);\n if (\n memory &&\n memory.frontmatter.status !== \"superseded\" &&\n memory.frontmatter.status !== \"forgotten\"\n ) {\n candidates.push({\n id: memory.frontmatter.id,\n content: memory.content,\n category: memory.frontmatter.category,\n });\n }\n }\n\n if (candidates.length === 0) return [];\n\n // Ask LLM for link suggestions\n const suggestions = await this.extraction.suggestLinks(\n { content, category },\n candidates,\n );\n\n if (!suggestions || suggestions.links.length === 0) return [];\n\n // Convert to MemoryLink format\n return suggestions.links.map((link) => ({\n targetId: link.targetId,\n linkType: link.linkType,\n strength: link.strength,\n reason: link.reason || undefined,\n }));\n }\n\n private async graphSeedPathRelativeToStorage(\n storage: StorageManager,\n result: QmdSearchResult,\n recallNamespaces: readonly string[] = [],\n ): Promise<string | null> {\n const parts = qmdCollectionPathParts(result.path);\n if (parts) {\n const memory = await this.readQmdResultMemory(\n result.path,\n storage,\n recallNamespaces,\n );\n return memory\n ? graphPathRelativeToStorage(storage.dir, memory.path)\n : null;\n }\n return graphPathRelativeToStorage(storage.dir, result.path);\n }\n\n private async graphSeedPathsWithinDeadline(\n storage: StorageManager,\n results: QmdSearchResult[],\n deadlineAtMs: number,\n recallNamespaces: readonly string[] = [],\n ): Promise<string[]> {\n const resolved: string[] = [];\n for (const result of results) {\n if (Date.now() >= deadlineAtMs) break;\n const seedPath = await this.graphSeedPathRelativeToStorage(\n storage,\n result,\n recallNamespaces,\n );\n if (Date.now() >= deadlineAtMs) break;\n if (seedPath) resolved.push(seedPath);\n }\n return resolved;\n }\n\n private namespaceFromPath(p: string): string {\n if (!this.config.namespacesEnabled) return this.config.defaultNamespace;\n const parts = qmdCollectionPathParts(p);\n const collectionNamespace = parts\n ? this.qmdCollectionNamespaceFromPrefix(parts.collection)\n : null;\n if (collectionNamespace) return collectionNamespace;\n const m = p.match(/[\\\\/]+namespaces[\\\\/]+([^\\\\/]+)(?:[\\\\/]|$)/);\n if (!m?.[1]) return this.config.defaultNamespace;\n return namespaceIdentityFromToken(m[1]) ?? m[1];\n }\n\n private namespaceFromStorageDir(storageDir: string): string {\n if (!this.config.namespacesEnabled) return this.config.defaultNamespace;\n const resolvedStorageDir = path.resolve(storageDir);\n const resolvedMemoryDir = path.resolve(this.config.memoryDir);\n if (resolvedStorageDir === resolvedMemoryDir)\n return this.config.defaultNamespace;\n const m = resolvedStorageDir.match(/[\\\\/]namespaces[\\\\/]([^\\\\/]+)$/);\n if (!m?.[1]) return this.config.defaultNamespace;\n const dirName = m[1];\n // Token-shaped raw names (round 6, codex P2 — NBsFz): a dir name might be a\n // tokenized identity OR a literal raw namespace name that merely LOOKS like a\n // token (e.g. a configured or dynamic name `ns-616c706861`). The round-trip check below\n // (`namespaceIdentityToken(decoded) === dirName`) is TAUTOLOGICAL for a\n // canonical token string, so it cannot tell a tokenized dir for `alpha` apart\n // from the legacy raw root of a namespace literally named `ns-616c706861`\n // (codex NRCve). A dir name that is itself a KNOWN namespace (configured or\n // catalog-owned at this exact storage root) is therefore preserved as the\n // literal namespace BEFORE attempting to decode it.\n if (this.configuredNamespaces().includes(dirName)) {\n return dirName;\n }\n this.loadNamespaceStorageDirHintsFromCatalog();\n const hintedNamespaces = this.namespaceStorageDirHints.get(resolvedStorageDir);\n if (hintedNamespaces?.has(dirName)) {\n return dirName;\n }\n if (hintedNamespaces?.size === 1) {\n const [hintedNamespace] = hintedNamespaces;\n if (hintedNamespace) return hintedNamespace;\n }\n const decoded = namespaceIdentityFromToken(dirName);\n if (decoded && namespaceIdentityToken(decoded) === dirName) {\n return decoded;\n }\n return dirName;\n }\n\n /**\n * Record a namespace write in the catalog (issue #1499). Best-effort and\n * failure-tolerant: a catalog write error MUST NOT crash the primary memory\n * write (CLAUDE.md gotcha #13, rule #40). Fire-and-forget by design.\n */\n private markCatalogWrite(namespace: string, storageDir?: string): void {\n if (!this.namespaceCatalog.enabled) return;\n this.rememberNamespaceStorageDirHint(namespace, storageDir);\n void this.namespaceCatalog\n .markWrite(namespace, { discoveredBy: \"write\", storageDir })\n .catch(() => undefined);\n }\n\n /**\n * Public best-effort catalog write touch (issue #1499). User-facing explicit\n * captures (`memory_store`) and review-queue approvals persist via\n * `persistExplicitCapture()` → `storage.writeMemory()`, which bypasses the\n * extraction write path that calls `markCatalogWrite`. Without this their\n * namespaces never record `lastWriteAt`, so the catalog under-reports write\n * recency (round 5, codex P2). Fire-and-forget and failure-tolerant — a\n * catalog error must never affect the explicit write (gotcha #13, rule #40).\n *\n * An undefined/empty `namespace` means the write targeted the DEFAULT namespace\n * (`getStorage(undefined)` routes there), so we record it under the configured\n * default rather than skipping it (round 6, codex P2 — default `memory_store`\n * and inline-note writes were missing from `writtenSince`/maintenance).\n */\n recordCatalogWrite(namespace?: string, storageDir?: string): void {\n const ns = namespace && namespace.trim().length > 0 ? namespace : this.config.defaultNamespace;\n if (!ns) return;\n this.markCatalogWrite(ns, storageDir);\n }\n\n /** Record a namespace read in the catalog. Best-effort, failure-tolerant. */\n private markCatalogRead(namespace: string, storageDir?: string): void {\n if (!this.namespaceCatalog.enabled) return;\n this.rememberNamespaceStorageDirHint(namespace, storageDir);\n void this.namespaceCatalog\n .markRead(namespace, { discoveredBy: \"read\", storageDir })\n .catch(() => undefined);\n }\n\n private async readAllMemoriesForNamespaces(\n namespaces: string[],\n ): Promise<MemoryFile[]> {\n const uniq = Array.from(new Set(namespaces.filter(Boolean)));\n const lists = await Promise.all(\n uniq.map(async (ns) => {\n const sm = await this.storageRouter.storageFor(ns);\n return sm.readAllMemories();\n }),\n );\n return lists.flat();\n }\n\n private async readArchivedMemoriesForNamespaces(\n namespaces: string[],\n ): Promise<MemoryFile[]> {\n const uniq = Array.from(new Set(namespaces.filter(Boolean)));\n const lists = await Promise.all(\n uniq.map(async (ns) => {\n const sm = await this.storageRouter.storageFor(ns);\n return sm.readArchivedMemories();\n }),\n );\n return lists.flat();\n }\n}\n","/**\n * Intent-gated recall for active procedure memories (issue #519).\n */\n\nimport type { MemoryFile, PluginConfig } from \"../types.js\";\nimport type { StorageManager } from \"../storage.js\";\nimport { inferIntentFromText, intentCompatibilityScore, isTaskInitiationIntent } from \"../intent.js\";\nimport { isActiveMemoryStatus } from \"../memory-lifecycle-ledger-utils.js\";\n\nfunction tokenOverlapScore(prompt: string, memoryText: string): number {\n const norm = (s: string) =>\n s\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter((t) => t.length > 2);\n const promptTokens = new Set(norm(prompt));\n const memTokens = new Set(norm(memoryText));\n if (promptTokens.size === 0 || memTokens.size === 0) return 0;\n let inter = 0;\n for (const t of promptTokens) {\n if (memTokens.has(t)) inter++;\n }\n const union = new Set([...promptTokens, ...memTokens]);\n return inter / Math.max(1, union.size);\n}\n\nfunction scoreProcedureForPrompt(\n m: MemoryFile,\n prompt: string,\n queryIntent: ReturnType<typeof inferIntentFromText>,\n): number {\n const memText = `${m.content}\\n${(m.frontmatter.tags ?? []).join(\" \")}`;\n const jaccard = tokenOverlapScore(prompt, memText);\n const memIntent = inferIntentFromText(m.content.slice(0, 2000));\n const intentScore = intentCompatibilityScore(queryIntent, memIntent);\n return jaccard * 0.55 + intentScore * 0.45;\n}\n\n/**\n * Build markdown for the recall pipeline when procedural memory is enabled and\n * the prompt looks like task initiation.\n */\nexport async function buildProcedureRecallSection(\n storage: StorageManager,\n prompt: string,\n config: PluginConfig,\n): Promise<string | null> {\n if (config.procedural?.enabled !== true) return null;\n const trimmed = typeof prompt === \"string\" ? prompt.trim() : \"\";\n if (!trimmed) return null;\n\n const queryIntent = inferIntentFromText(trimmed);\n if (!isTaskInitiationIntent(queryIntent)) return null;\n\n const maxN = Math.min(\n 10,\n Math.max(\n 1,\n typeof config.procedural.recallMaxProcedures === \"number\" &&\n Number.isFinite(config.procedural.recallMaxProcedures)\n ? Math.floor(config.procedural.recallMaxProcedures)\n // Safer-by-default fallback (issue #567 PR 3/5): must match\n // config.ts's canonical default (2). Cursor review on PR #607:\n // divergent fallbacks silently regressed the safer cap whenever\n // the config value was missing or non-finite at this call site.\n : 2,\n ),\n );\n\n const all = await storage.readAllMemories();\n const scored = all\n .filter(\n (m) =>\n m.frontmatter.category === \"procedure\" &&\n isActiveMemoryStatus(m.frontmatter.status),\n )\n .map((m) => ({ m, score: scoreProcedureForPrompt(m, trimmed, queryIntent) }))\n .filter((x) => x.score > 0.04)\n .sort((a, b) => b.score - a.score)\n .slice(0, maxN);\n\n if (scored.length === 0) return null;\n\n const blocks = scored.map(({ m, score }) => {\n const id = m.frontmatter.id;\n const flat = m.content.replace(/\\s+/g, \" \").trim();\n const preview = flat.slice(0, 320);\n const suffix = flat.length > 320 ? \"…\" : \"\";\n return `### ${id} (match ${score.toFixed(2)})\\n\\n${preview}${suffix}`;\n });\n\n return `## Relevant procedures\\n\\n${blocks.join(\"\\n\\n\")}`;\n}\n","/**\n * Pattern-reinforcement maintenance job (issue #687 PR 2/4).\n *\n * Reads all memories via `StorageManager.readAllMemories()`, clusters\n * non-procedural memories by normalized content, and reinforces the\n * most-recent member of each large-enough cluster:\n *\n * 1. Cluster across active AND already-superseded members. This is\n * load-bearing: after the first reinforcement pass, older\n * duplicates are marked `superseded`, so on the next pass the\n * \"active count\" alone would be just `canonical + N-new`. By\n * keeping superseded members in the cluster for the threshold\n * check, an established canonical (count >= minCount) keeps\n * growing as soon as a single new duplicate arrives.\n * `forgotten` / `archived` / `quarantined` / `pending_review` /\n * `rejected` stay excluded per CLAUDE.md rule 53.\n * 2. Pick the most-recent ACTIVE member of each cluster as the\n * canonical. Stamp it with `reinforcement_count` (total cluster\n * size including superseded members) and `last_reinforced_at`.\n * Record provenance: `derived_from = [...source-ids...]` and\n * `derived_via = \"pattern-reinforcement\"`.\n * 3. Mark any still-active duplicates with `status: \"superseded\"`\n * and point `supersededBy` at the canonical id.\n *\n * The job is idempotent: re-running on the same corpus does not\n * double-bump `reinforcement_count` (the bump-only-on-change guard\n * compares cluster size to the canonical's previous counter), and\n * already-superseded duplicates simply pass through.\n *\n * Recall integration (boost from `reinforcement_count`) and the CLI\n * surface ship in PR 3/4 and PR 4/4 respectively — this PR only wires\n * the maintenance job and storage plumbing.\n */\n\nimport { clusterByKey } from \"../procedural/reinforcement-core.js\";\nimport type {\n MemoryFile,\n MemoryFrontmatter,\n MemoryStatus,\n} from \"../types.js\";\n\n/**\n * Storage surface the job needs. Defined as a structural interface so\n * tests can pass an in-memory stub without booting a full\n * `StorageManager` (mirrors the pattern in `forget.ts`).\n */\nexport interface PatternReinforcementStorage {\n readAllMemories(): Promise<MemoryFile[]>;\n writeMemoryFrontmatter(\n memory: MemoryFile,\n patch: Partial<MemoryFrontmatter>,\n ): Promise<boolean>;\n}\n\nexport interface PatternReinforcementOptions {\n /** Categories the job considers (e.g. [\"preference\", \"fact\", \"decision\"]). */\n categories: readonly string[];\n /** Minimum cluster size required to promote a canonical. */\n minCount: number;\n /** ISO 8601 timestamp source. Defaults to `Date.now()`. */\n now?: () => Date;\n}\n\nexport interface PatternReinforcementClusterResult {\n /** Memory id of the canonical (most-recent) member. */\n canonicalId: string;\n /** Cluster size at run time (mirrors `reinforcement_count`). */\n count: number;\n /** IDs of the source memories that contributed (canonical + duplicates). */\n sourceIds: readonly string[];\n /** IDs of the older duplicates that were marked superseded. */\n supersededIds: readonly string[];\n /**\n * `true` when the canonical's `reinforcement_count` actually\n * changed during this run. False when the job converged\n * idempotently (same cluster size as the previous run).\n */\n reinforcementBumped: boolean;\n}\n\nexport interface PatternReinforcementResult {\n /** Number of clusters that met the `minCount` threshold. */\n clustersFound: number;\n /** Number of canonical memories whose reinforcement counter changed. */\n canonicalsUpdated: number;\n /** Total duplicate memories newly marked `status: \"superseded\"`. */\n duplicatesSuperseded: number;\n /** Per-cluster details for tests / observability. */\n clusters: PatternReinforcementClusterResult[];\n}\n\n/**\n * Cluster key derivation: lowercase + collapse whitespace + truncate to\n * 200 chars. Pure helper so callers and tests can compute the same key\n * without re-implementing the rule.\n *\n * Truncation is intentional — long-form content with a stable opening\n * still clusters together even when the tail differs slightly. 200\n * chars matches the spec.\n *\n * @deprecated Prefer `patternReinforcementClusterKey(category, content)`\n * which partitions by memory category so identical text in different\n * categories does not get cross-superseded (PR #730 review feedback,\n * Codex P2). This bare helper is kept exported for backward\n * compatibility with callers that already partition by category\n * upstream.\n */\nexport function patternReinforcementKey(content: string): string {\n return content.trim().toLowerCase().replace(/\\s+/g, \" \").slice(0, 200);\n}\n\n/**\n * Cluster key derivation that includes the memory category as a prefix\n * so identical text under different categories (e.g. `fact` and\n * `decision`) does not collapse into one cluster. Without this,\n * pattern reinforcement would silently supersede a fact when a\n * decision happens to share the same canonical text — distorting\n * downstream category-scoped retrieval and governance behavior (PR\n * #730 review feedback, Codex P2).\n */\nexport function patternReinforcementClusterKey(category: string, content: string): string {\n // Use a `::` separator that cannot appear in either component so\n // a category like `fact` plus content starting with `decision:...`\n // cannot collide with category `decision`.\n return `${category}::${patternReinforcementKey(content)}`;\n}\n\n/**\n * Compare two memories by their effective timestamp.\n *\n * Parses each timestamp to an *instant* (epoch ms) via `Date.parse`\n * rather than lexicographic `localeCompare` so ISO-8601 variants with\n * non-`Z` offsets (e.g. `2026-04-26T10:00:00+02:00`) and mixed\n * millisecond precision compare by actual time rather than by raw\n * string (PR #730 review feedback, Codex P2). Imported / hand-edited\n * memory files routinely use such variants.\n *\n * Falls back to the raw string when an instant is unparseable (a\n * corrupt frontmatter is rare but possible) and tie-breaks on memory\n * id for stable ordering.\n */\nfunction pickCanonical(memories: MemoryFile[]): MemoryFile {\n let best = memories[0];\n let bestInstant = memoryInstant(best);\n let bestStamp = memoryStamp(best);\n for (let i = 1; i < memories.length; i += 1) {\n const candidate = memories[i];\n const instant = memoryInstant(candidate);\n const stamp = memoryStamp(candidate);\n let cmp: number;\n if (instant !== null && bestInstant !== null) {\n cmp = instant - bestInstant;\n } else {\n // One side is unparseable — fall back to lexicographic compare\n // on raw strings. This keeps ordering deterministic even when\n // a corrupt timestamp slipped past the parser.\n cmp = stamp.localeCompare(bestStamp);\n }\n if (cmp > 0 || (cmp === 0 && candidate.frontmatter.id > best.frontmatter.id)) {\n best = candidate;\n bestInstant = instant;\n bestStamp = stamp;\n }\n }\n return best;\n}\n\nfunction memoryStamp(memory: MemoryFile): string {\n // Prefer `updated`, fall back to `created`. Both are ISO-8601 and\n // present on every well-formed memory; the parser default-fills them\n // when absent.\n return memory.frontmatter.updated || memory.frontmatter.created || \"\";\n}\n\n/**\n * Parse a memory's effective timestamp to epoch milliseconds. Returns\n * `null` for an unparseable / empty stamp so callers can fall back to\n * a string compare without observing `NaN` propagation.\n */\nfunction memoryInstant(memory: MemoryFile): number | null {\n const stamp = memoryStamp(memory);\n if (stamp.length === 0) return null;\n const parsed = Date.parse(stamp);\n return Number.isFinite(parsed) ? parsed : null;\n}\n\nconst ACTIVE_STATUS: MemoryStatus = \"active\";\n\n/**\n * Run pattern reinforcement across the configured categories.\n *\n * The function is intentionally pure (modulo the storage handle): no\n * cron scheduling, no telemetry side effects, no logging. Callers\n * (orchestrator cron path / CLI surface in PR 4) own those concerns.\n */\nexport async function runPatternReinforcement(\n storage: PatternReinforcementStorage,\n options: PatternReinforcementOptions,\n): Promise<PatternReinforcementResult> {\n const minCount = Math.max(2, Math.floor(options.minCount));\n const targetCategories = new Set(options.categories);\n const now = options.now ?? (() => new Date());\n const nowIso = now().toISOString();\n\n // No-op fast paths so unconfigured callers get a clean result rather\n // than walking the entire corpus.\n if (targetCategories.size === 0) {\n return emptyResult();\n }\n\n const memories = await storage.readAllMemories();\n\n // Cluster across BOTH active and already-superseded memories so a\n // canonical that has previously absorbed duplicates still gets\n // reinforced when a single new duplicate arrives (Codex P1).\n // Without this, the post-first-pass active set is just\n // `canonical + N-new`, which falls below `minCount` for any\n // realistic cadence. CLAUDE.md rule 53 still applies — forgotten,\n // archived, quarantined, pending_review, and rejected memories\n // remain excluded.\n const eligible = memories.filter((m) => {\n if (!targetCategories.has(m.frontmatter.category)) return false;\n const status = m.frontmatter.status ?? ACTIVE_STATUS;\n return status === ACTIVE_STATUS || status === \"superseded\";\n });\n\n if (eligible.length === 0) return emptyResult();\n\n // Cluster by `<category> <content>` so identical text in different\n // categories does not get cross-superseded (PR #730 review feedback,\n // Codex P2).\n const clusters = clusterByKey(eligible, (m) =>\n patternReinforcementClusterKey(m.frontmatter.category, m.content),\n );\n\n const result: PatternReinforcementResult = {\n clustersFound: 0,\n canonicalsUpdated: 0,\n duplicatesSuperseded: 0,\n clusters: [],\n };\n\n for (const cluster of clusters.values()) {\n // The cluster represents the full historical pattern — its size\n // is the threshold the user configured against.\n if (cluster.length < minCount) continue;\n\n // Active members are the only ones we can write to (or pick as\n // canonical). If every member is already superseded — e.g. a\n // prior canonical was archived externally — there's nothing to\n // do for this cluster on this pass.\n const activeMembers = cluster.filter((m) => {\n const status = m.frontmatter.status ?? ACTIVE_STATUS;\n return status === ACTIVE_STATUS;\n });\n if (activeMembers.length === 0) continue;\n\n result.clustersFound += 1;\n\n const canonical = pickCanonical(activeMembers);\n const activeDuplicates = activeMembers.filter((m) => m !== canonical);\n\n // Source-id provenance: include the canonical + every member\n // that contributed to the cluster (active and superseded), so\n // the lineage is fully reconstructible. Sort ids\n // deterministically (CLAUDE.md rule 38) so re-runs produce\n // stable on-disk output.\n const sourceIds = [...cluster]\n .map((m) => m.frontmatter.id)\n .filter((id): id is string => typeof id === \"string\" && id.length > 0)\n .sort();\n\n // Use `sourceIds.length` (the filtered, valid-ID set) as the\n // canonical cluster count for both the reinforcement bump guard\n // and the on-disk `reinforcement_count` field. Using the raw\n // `cluster.length` would inflate the metric whenever any member\n // lacks a valid string ID, causing telemetry to diverge from\n // what is actually being reinforced (PR #730 review, Cursor).\n const previousCount = canonical.frontmatter.reinforcement_count ?? 0;\n const newCount = sourceIds.length;\n const reinforcementBumped = newCount > previousCount;\n\n // Refresh provenance on the canonical whenever cluster membership\n // changes — even if the cluster size happens to stay constant\n // (e.g. one older member archived externally while a new\n // duplicate arrived). Without this, `derived_from` would\n // silently fall out of sync with the actual contributors and\n // diagnostics would surface false-positive \"missing source\"\n // signals (PR #730 review feedback, Codex P2).\n const previousDerivedFrom = Array.isArray(canonical.frontmatter.derived_from)\n ? [...canonical.frontmatter.derived_from].sort()\n : [];\n const sortedSourceIds = [...sourceIds].sort();\n const membershipChanged =\n previousDerivedFrom.length !== sortedSourceIds.length ||\n previousDerivedFrom.some((id, i) => id !== sortedSourceIds[i]);\n const previousVia = canonical.frontmatter.derived_via;\n const viaChanged = previousVia !== \"pattern-reinforcement\";\n const canonicalNeedsRefresh =\n reinforcementBumped || membershipChanged || viaChanged;\n\n // Patch the canonical when the cluster grew, the cluster\n // membership rotated, or the canonical was previously stamped by\n // a different operator. Idempotent re-runs on a stable corpus\n // (same size, same members, same operator) still produce zero\n // writes.\n //\n // On a provenance-only refresh (membership rotated but count\n // unchanged), preserve the existing `reinforcement_count` and\n // `last_reinforced_at` so they remain monotonic and only advance\n // on genuine reinforcement events (PR #730 review, Codex P2).\n if (canonicalNeedsRefresh) {\n const patch: Partial<MemoryFrontmatter> = {\n derived_from: sourceIds,\n derived_via: \"pattern-reinforcement\",\n updated: nowIso,\n };\n if (reinforcementBumped) {\n patch.reinforcement_count = newCount;\n patch.last_reinforced_at = nowIso;\n } else {\n // Carry forward the existing values so a provenance-only\n // refresh does not reset or re-timestamp the counter.\n patch.reinforcement_count =\n canonical.frontmatter.reinforcement_count ?? newCount;\n patch.last_reinforced_at =\n canonical.frontmatter.last_reinforced_at ?? nowIso;\n }\n await storage.writeMemoryFrontmatter(canonical, patch);\n result.canonicalsUpdated += 1;\n }\n\n // Supersede any still-active duplicates. Already-superseded\n // members were filtered out above, which doubles as our\n // crash-recovery guard: a previous run that died mid-supersede\n // simply re-runs the active half on the next pass.\n const supersededIds: string[] = [];\n for (const dup of activeDuplicates) {\n const patch: Partial<MemoryFrontmatter> = {\n status: \"superseded\",\n supersededBy: canonical.frontmatter.id,\n supersededAt: nowIso,\n updated: nowIso,\n };\n await storage.writeMemoryFrontmatter(dup, patch);\n supersededIds.push(dup.frontmatter.id);\n result.duplicatesSuperseded += 1;\n }\n\n result.clusters.push({\n canonicalId: canonical.frontmatter.id,\n count: newCount,\n sourceIds,\n supersededIds,\n reinforcementBumped,\n });\n }\n\n return result;\n}\n\nfunction emptyResult(): PatternReinforcementResult {\n return {\n clustersFound: 0,\n canonicalsUpdated: 0,\n duplicatesSuperseded: 0,\n clusters: [],\n };\n}\n","/**\n * @remnic/core — Write-time semantic dedup guard\n *\n * Complements the exact content-hash check in the orchestrator's write path\n * by detecting near-duplicate candidate facts via embedding cosine similarity.\n *\n * The module intentionally has no dependency on the EmbeddingFallback or QMD\n * classes directly — callers pass in a `lookup` function that returns the\n * top-K nearest neighbors with their cosine scores. This keeps the decision\n * logic pure and trivially testable with synthetic fixtures, and lets the\n * orchestrator reuse whichever backend it already has wired up.\n *\n * Related issue: joshuaswarren/remnic#373\n */\n\n// ── Public types ──────────────────────────────────────────────────────────────\n\n/** A single nearest-neighbor hit from the embedding backend. */\nexport interface SemanticDedupHit {\n /** Memory id of the existing neighbor. */\n id: string;\n /** Cosine similarity score in [0, 1]. */\n score: number;\n /** Optional source path, purely informational. */\n path?: string;\n}\n\n/**\n * Lookup function passed by the caller. Must return an array of hits sorted\n * descending by score. Implementations must throw when the embedding backend\n * is unavailable or the provider call fails, and return an empty array only\n * when a reachable backend successfully reports no hits. The decision function\n * fail-opens on thrown lookup errors while preserving a distinct\n * \"backend_unavailable\" reason for telemetry.\n */\nexport type SemanticDedupLookup = (\n content: string,\n limit: number,\n) => Promise<SemanticDedupHit[]>;\n\nexport interface SemanticDedupOptions {\n /** Master switch. When false, `decideSemanticDedup` always returns `keep`. */\n enabled: boolean;\n /** Cosine similarity threshold (0-1). ≥ threshold ⇒ treat as duplicate. */\n threshold: number;\n /** How many nearest neighbors to compare against. */\n candidates: number;\n}\n\nexport type SemanticDedupDecision =\n | {\n action: \"keep\";\n reason:\n | \"disabled\"\n | \"backend_unavailable\"\n | \"no_candidates\"\n | \"no_near_duplicate\";\n topScore?: number;\n topId?: string;\n }\n | {\n action: \"skip\";\n reason: \"near_duplicate\";\n topScore: number;\n topId: string;\n topPath?: string;\n };\n\n// ── Pure decision function ────────────────────────────────────────────────────\n\nconst DEFAULT_SEMANTIC_THRESHOLD = 0.92;\nconst DEFAULT_SEMANTIC_CANDIDATES = 5;\n\nfunction normalizeSemanticThreshold(value: number): number {\n return Number.isFinite(value)\n ? Math.min(1, Math.max(0, value))\n : DEFAULT_SEMANTIC_THRESHOLD;\n}\n\nfunction normalizeSemanticCandidates(value: number): number {\n if (!Number.isFinite(value) || value < 0) {\n return DEFAULT_SEMANTIC_CANDIDATES;\n }\n const normalized = Math.floor(value);\n return value > 0 && normalized === 0 ? 1 : normalized;\n}\n\n/**\n * Pure decision function: given a lookup callback and options, decide whether\n * the candidate content should be written or skipped as a near-duplicate.\n *\n * Contract:\n * - When `options.enabled` is false → always keep, reason=\"disabled\".\n * - When the lookup throws (provider down / network error) → keep,\n * reason=\"backend_unavailable\". Fail-open: a lookup failure must not block\n * writes.\n * - When the lookup succeeds but returns 0 hits (empty index or no\n * neighbors above the score floor) → keep, reason=\"no_candidates\".\n * This is distinct from backend_unavailable so telemetry dashboards can\n * correctly distinguish \"provider is down\" from \"index is empty\".\n * - When the top hit's score ≥ threshold → skip with reason=\"near_duplicate\".\n * - Otherwise → keep with reason=\"no_near_duplicate\".\n */\nexport async function decideSemanticDedup(\n content: string,\n lookup: SemanticDedupLookup,\n options: SemanticDedupOptions,\n): Promise<SemanticDedupDecision> {\n if (!options.enabled) {\n return { action: \"keep\", reason: \"disabled\" };\n }\n const threshold = normalizeSemanticThreshold(options.threshold);\n const candidates = normalizeSemanticCandidates(options.candidates);\n // Zero candidates means the operator has disabled the embedding lookup.\n // Treat it identically to enabled=false so no backend call is made.\n if (candidates === 0) {\n return { action: \"keep\", reason: \"disabled\" };\n }\n const trimmed = typeof content === \"string\" ? content.trim() : \"\";\n if (!trimmed) {\n return { action: \"keep\", reason: \"no_near_duplicate\" };\n }\n let hits: SemanticDedupHit[] = [];\n try {\n hits = await lookup(trimmed, candidates);\n } catch {\n // Fail-open: a lookup error must not block writes.\n return { action: \"keep\", reason: \"backend_unavailable\" };\n }\n if (!Array.isArray(hits) || hits.length === 0) {\n // Provider responded (no throw) but returned no hits: the embedding index\n // is empty or contains no neighbors above the score floor. Use a distinct\n // reason so callers and telemetry can differentiate this from a genuine\n // backend failure.\n return { action: \"keep\", reason: \"no_candidates\" };\n }\n\n // Defensive: callers ought to return sorted, but don't trust it.\n let top: SemanticDedupHit | undefined;\n for (const hit of hits) {\n if (\n !hit ||\n typeof hit.id !== \"string\" ||\n hit.id.trim().length === 0 ||\n typeof hit.score !== \"number\" ||\n !Number.isFinite(hit.score)\n ) {\n continue;\n }\n if (!top || hit.score > top.score) {\n top = hit;\n }\n }\n if (!top) {\n return { action: \"keep\", reason: \"no_near_duplicate\" };\n }\n\n if (top.score >= threshold) {\n return {\n action: \"skip\",\n reason: \"near_duplicate\",\n topScore: top.score,\n topId: top.id,\n topPath: top.path,\n };\n }\n\n return {\n action: \"keep\",\n reason: \"no_near_duplicate\",\n topScore: top.score,\n topId: top.id,\n };\n}\n","/**\n * Default MECE taxonomy that maps every existing MemoryCategory value\n * to exactly one taxonomy category, ordered by priority.\n */\n\nimport type { Taxonomy } from \"./types.js\";\n\nexport const DEFAULT_TAXONOMY: Taxonomy = {\n version: 1,\n categories: [\n {\n id: \"corrections\",\n name: \"Corrections\",\n description: \"Corrections to previously stored information\",\n filingRules: [\"Any update that supersedes a prior fact\"],\n priority: 10,\n memoryCategories: [\"correction\"],\n },\n {\n id: \"principles\",\n name: \"Principles\",\n description: \"Rules, guidelines, and recurring patterns\",\n filingRules: [\"A guiding principle, rule, or skill\"],\n priority: 20,\n memoryCategories: [\"principle\", \"rule\", \"skill\"],\n },\n {\n id: \"procedures\",\n name: \"Procedures\",\n description: \"Ordered multi-step workflows the user repeats\",\n filingRules: [\"A repeatable sequence of steps or commands for a task\"],\n priority: 25,\n memoryCategories: [\"procedure\"],\n },\n {\n id: \"entities\",\n name: \"Entities\",\n description: \"People, organizations, places, projects\",\n filingRules: [\"Named entity with attributes\"],\n priority: 30,\n memoryCategories: [\"entity\", \"relationship\"],\n },\n {\n id: \"decisions\",\n name: \"Decisions\",\n description: \"Choices made and their rationale\",\n filingRules: [\"A decision or commitment with reasoning\"],\n priority: 35,\n memoryCategories: [\"decision\", \"commitment\"],\n },\n {\n id: \"preferences\",\n name: \"Preferences\",\n description: \"User likes, dislikes, and style choices\",\n filingRules: [\"Anything expressing a preference or taste\"],\n priority: 40,\n memoryCategories: [\"preference\"],\n },\n {\n id: \"facts\",\n name: \"Facts\",\n description: \"Objective statements about the world\",\n filingRules: [\"Any factual claim or piece of information\"],\n priority: 50,\n memoryCategories: [\"fact\"],\n },\n {\n id: \"moments\",\n name: \"Moments\",\n description: \"Significant events or experiences\",\n filingRules: [\"A specific event worth remembering\"],\n priority: 60,\n memoryCategories: [\"moment\"],\n },\n {\n id: \"reasoning-traces\",\n name: \"Reasoning Traces\",\n description:\n \"Stored intermediate reasoning / solution chains for a problem the agent previously solved\",\n filingRules: [\n \"A multi-step reasoning chain or solution walkthrough the agent can replay for a similar problem\",\n ],\n priority: 55,\n memoryCategories: [\"reasoning_trace\"],\n },\n ],\n};\n","/**\n * Generates a markdown decision-tree document (RESOLVER.md) from a\n * taxonomy definition.\n *\n * The document walks a user through filing a new piece of knowledge\n * by checking each category in priority order (lowest number first).\n */\n\nimport type { Taxonomy } from \"./types.js\";\n\n/**\n * Produce a markdown decision tree for the given taxonomy.\n *\n * Categories are listed in priority order (lowest number = checked first).\n * Each step asks whether the knowledge fits the category and, if so,\n * instructs the reader to file it there.\n */\nexport function generateResolverDocument(taxonomy: Taxonomy): string {\n const sorted = [...taxonomy.categories].sort((a, b) => {\n if (a.priority !== b.priority) return a.priority - b.priority;\n return a.id.localeCompare(b.id);\n });\n\n const lines: string[] = [\n \"# Memory Filing Resolver\",\n \"\",\n \"Given a new piece of knowledge, follow this tree to determine where it belongs.\",\n \"\",\n ];\n\n let step = 1;\n for (const cat of sorted) {\n lines.push(`## Step ${step}: ${cat.description}?`);\n lines.push(\"\");\n for (const rule of cat.filingRules) {\n lines.push(`- ${rule}`);\n }\n lines.push(\"\");\n lines.push(\n `> YES: File under **${cat.id}/** (priority ${cat.priority})`,\n );\n lines.push(\"\");\n step++;\n }\n\n lines.push(\"## Tie-breaking\");\n lines.push(\"\");\n lines.push(\n \"If a fact could go in multiple categories, file under the one with the **lowest priority number**.\",\n );\n lines.push(\"\");\n lines.push(`---`);\n lines.push(`*Generated from taxonomy v${taxonomy.version}*`);\n lines.push(\"\");\n\n return lines.join(\"\\n\");\n}\n","/**\n * Loads and validates a user-customized taxonomy from disk, merging\n * with the built-in defaults.\n *\n * User taxonomies are stored at `<memoryDir>/.taxonomy/taxonomy.json`.\n */\n\nimport { readFile, mkdir, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { Taxonomy, TaxonomyCategory } from \"./types.js\";\nimport { DEFAULT_TAXONOMY } from \"./default-taxonomy.js\";\n\nconst TAXONOMY_DIR = \".taxonomy\";\nconst TAXONOMY_FILE = \"taxonomy.json\";\n\n/** Maximum allowed slug length */\nconst MAX_SLUG_LENGTH = 32;\n\n/** Regex for valid slug: lowercase letters, digits, hyphens */\nconst SLUG_RE = /^[a-z][a-z0-9-]*$/;\nconst VALID_MEMORY_CATEGORIES = new Set([\n \"fact\",\n \"preference\",\n \"correction\",\n \"entity\",\n \"decision\",\n \"relationship\",\n \"principle\",\n \"commitment\",\n \"moment\",\n \"skill\",\n \"rule\",\n \"procedure\",\n \"reasoning_trace\",\n]);\n\n/**\n * Validate a taxonomy category slug.\n * Throws if the slug is invalid.\n */\nexport function validateSlug(slug: string): void {\n if (slug.length === 0) {\n throw new Error(\"Taxonomy category ID must not be empty\");\n }\n if (slug.length > MAX_SLUG_LENGTH) {\n throw new Error(\n `Taxonomy category ID \"${slug}\" exceeds ${MAX_SLUG_LENGTH} characters`,\n );\n }\n if (!SLUG_RE.test(slug)) {\n throw new Error(\n `Taxonomy category ID \"${slug}\" is invalid: must be lowercase letters, digits, and hyphens, starting with a letter`,\n );\n }\n}\n\n/**\n * Validate an entire taxonomy for structural correctness.\n * Throws on the first error found.\n */\nexport function validateTaxonomy(taxonomy: Taxonomy): void {\n if (typeof taxonomy.version !== \"number\" || taxonomy.version < 1) {\n throw new Error(\"Taxonomy version must be a positive integer\");\n }\n if (!Array.isArray(taxonomy.categories)) {\n throw new Error(\"Taxonomy categories must be an array\");\n }\n\n const seenIds = new Set<string>();\n for (const cat of taxonomy.categories) {\n validateSlug(cat.id);\n if (seenIds.has(cat.id)) {\n throw new Error(`Duplicate taxonomy category ID: \"${cat.id}\"`);\n }\n seenIds.add(cat.id);\n\n if (typeof cat.name !== \"string\" || cat.name.trim().length === 0) {\n throw new Error(`Taxonomy category \"${cat.id}\" must have a non-empty name`);\n }\n if (typeof cat.description !== \"string\" || cat.description.trim().length === 0) {\n throw new Error(`Taxonomy category \"${cat.id}\" must have a non-empty description`);\n }\n if (!Array.isArray(cat.filingRules)) {\n throw new Error(`Taxonomy category \"${cat.id}\" filingRules must be an array`);\n }\n for (const [index, rule] of cat.filingRules.entries()) {\n if (typeof rule !== \"string\" || rule.trim().length === 0) {\n throw new Error(\n `Taxonomy category \"${cat.id}\" filingRules[${index}] must be a non-empty string`,\n );\n }\n }\n if (typeof cat.priority !== \"number\" || !Number.isFinite(cat.priority)) {\n throw new Error(`Taxonomy category \"${cat.id}\" must have a finite numeric priority`);\n }\n if (!Array.isArray(cat.memoryCategories)) {\n throw new Error(`Taxonomy category \"${cat.id}\" memoryCategories must be an array`);\n }\n for (const [index, memoryCategory] of cat.memoryCategories.entries()) {\n if (typeof memoryCategory !== \"string\" || memoryCategory.trim().length === 0) {\n throw new Error(\n `Taxonomy category \"${cat.id}\" memoryCategories[${index}] must be a non-empty string`,\n );\n }\n if (!VALID_MEMORY_CATEGORIES.has(memoryCategory)) {\n throw new Error(\n `Taxonomy category \"${cat.id}\" memoryCategories[${index}] is unknown: \"${memoryCategory}\"`,\n );\n }\n }\n if (cat.parentId !== undefined) {\n if (typeof cat.parentId !== \"string\") {\n throw new Error(`Taxonomy category \"${cat.id}\" parentId must be a string if set`);\n }\n }\n }\n\n // Validate parentId references\n for (const cat of taxonomy.categories) {\n if (cat.parentId !== undefined && !seenIds.has(cat.parentId)) {\n throw new Error(\n `Taxonomy category \"${cat.id}\" references unknown parentId \"${cat.parentId}\"`,\n );\n }\n }\n}\n\n/**\n * Load a taxonomy from the user's memory directory.\n *\n * If `<memoryDir>/.taxonomy/taxonomy.json` exists, loads it, validates\n * it, and merges with the defaults (user categories override defaults\n * by ID). If the file does not exist, returns the defaults.\n */\nexport async function loadTaxonomy(memoryDir: string): Promise<Taxonomy> {\n const taxonomyPath = path.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);\n let raw: string;\n try {\n raw = await readFile(taxonomyPath, \"utf-8\");\n } catch (err: unknown) {\n // Only fall back to defaults for missing file; rethrow permission / I/O errors\n if (err instanceof Error && (err as NodeJS.ErrnoException).code === \"ENOENT\") {\n return structuredClone(DEFAULT_TAXONOMY);\n }\n throw err;\n }\n\n const parsed: unknown = JSON.parse(raw);\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n throw new Error(\"taxonomy.json must be a JSON object\");\n }\n\n const obj = parsed as Record<string, unknown>;\n if (typeof obj.version !== \"number\") {\n throw new Error(\"taxonomy.json version must be a number\");\n }\n if (!Array.isArray(obj.categories)) {\n throw new Error(\"taxonomy.json categories must be an array\");\n }\n\n const userVersion = obj.version;\n const userCategories = obj.categories as TaxonomyCategory[];\n\n // Validate: reject duplicate IDs in user categories before merging.\n // Without this check, duplicates are silently collapsed with last-write-wins\n // semantics when inserted into the Map.\n const userIdCounts = new Map<string, number>();\n for (const cat of userCategories) {\n const id = typeof cat.id === \"string\" ? cat.id : String(cat.id);\n userIdCounts.set(id, (userIdCounts.get(id) ?? 0) + 1);\n }\n const duplicateIds = [...userIdCounts.entries()]\n .filter(([, count]) => count > 1)\n .map(([id]) => id);\n if (duplicateIds.length > 0) {\n throw new Error(\n `Duplicate category IDs in taxonomy.json: ${duplicateIds.map((id) => `\"${id}\"`).join(\", \")}`,\n );\n }\n\n // Merge: user categories override defaults by ID\n const mergedMap = new Map<string, TaxonomyCategory>();\n for (const cat of DEFAULT_TAXONOMY.categories) {\n mergedMap.set(cat.id, { ...cat });\n }\n for (const cat of userCategories) {\n mergedMap.set(cat.id, cat);\n }\n\n const merged: Taxonomy = {\n version: userVersion,\n categories: [...mergedMap.values()],\n };\n\n validateTaxonomy(merged);\n return merged;\n}\n\n/**\n * Save a taxonomy to the user's memory directory.\n */\nexport async function saveTaxonomy(\n memoryDir: string,\n taxonomy: Taxonomy,\n): Promise<void> {\n validateTaxonomy(taxonomy);\n const dir = path.join(memoryDir, TAXONOMY_DIR);\n await mkdir(dir, { recursive: true });\n const filePath = path.join(dir, TAXONOMY_FILE);\n await writeFile(filePath, JSON.stringify(taxonomy, null, 2) + \"\\n\", \"utf-8\");\n}\n\n/**\n * Get the taxonomy directory path for a given memory directory.\n */\nexport function getTaxonomyDir(memoryDir: string): string {\n return path.join(memoryDir, TAXONOMY_DIR);\n}\n\n/**\n * Get the taxonomy file path for a given memory directory.\n */\nexport function getTaxonomyFilePath(memoryDir: string): string {\n return path.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);\n}\n","/**\n * Wearable connector registry.\n *\n * Concrete connectors live in optional à-la-carte packages and register\n * a factory here (directly, or via the built-in loader below which\n * dynamic-imports the known packages with computed specifiers so\n * bundlers and the dts resolver never require them at build time).\n */\n\nimport { log } from \"../logger.js\";\nimport type {\n WearableSourceConnector,\n WearableSourceSettings,\n} from \"./types.js\";\n\nexport interface WearableConnectorFactoryOptions {\n settings: WearableSourceSettings;\n /** IANA timezone transcripts are bucketed in. */\n timezone: string;\n}\n\nexport type WearableConnectorFactory = (\n options: WearableConnectorFactoryOptions,\n) => WearableSourceConnector;\n\nexport interface WearableConnectorRegistration {\n id: string;\n displayName: string;\n factory: WearableConnectorFactory;\n}\n\nconst registrations = new Map<string, WearableConnectorRegistration>();\n\nexport function registerWearableConnector(\n registration: WearableConnectorRegistration,\n): void {\n if (!registration || typeof registration !== \"object\") {\n throw new Error(\"wearable connector registration must be an object\");\n }\n if (\n typeof registration.id !== \"string\" ||\n registration.id.trim().length === 0\n ) {\n throw new Error(\"wearable connector id must be a non-empty string\");\n }\n if (typeof registration.factory !== \"function\") {\n throw new Error(\n `wearable connector '${registration.id}' must provide a factory function`,\n );\n }\n const key = registration.id.trim();\n if (registrations.has(key)) {\n throw new Error(`wearable connector '${key}' is already registered`);\n }\n registrations.set(key, { ...registration, id: key });\n}\n\nexport function getWearableConnector(\n id: string,\n): WearableConnectorRegistration | undefined {\n if (typeof id !== \"string\") return undefined;\n const key = id.trim();\n if (key.length === 0) return undefined;\n return registrations.get(key);\n}\n\nexport function listWearableConnectors(): string[] {\n return [...registrations.keys()];\n}\n\n/** Test-only: reset the registry between cases. */\nexport function clearWearableConnectors(): void {\n registrations.clear();\n}\n\n/**\n * Built-in connector packages, tried in order. Each entry is loaded via\n * a computed-specifier dynamic import (see optional-bench.ts in\n * @remnic/cli for the canonical à-la-carte pattern); a missing package\n * is silently skipped, any other load error is logged once and skipped\n * so one broken connector never takes down the others.\n */\nconst BUILT_IN_CONNECTOR_PACKAGES: Array<{ id: string; suffix: string }> = [\n { id: \"limitless\", suffix: \"connector-limitless\" },\n { id: \"bee\", suffix: \"connector-bee\" },\n { id: \"omi\", suffix: \"connector-omi\" },\n];\n\nconst loadFailuresWarned = new Set<string>();\n\nexport async function ensureBuiltInWearableConnectors(): Promise<void> {\n for (const entry of BUILT_IN_CONNECTOR_PACKAGES) {\n if (registrations.has(entry.id)) continue;\n const specifier = \"@remnic/\" + entry.suffix;\n let mod: { wearableConnectorRegistration?: WearableConnectorRegistration };\n try {\n mod = (await import(specifier)) as {\n wearableConnectorRegistration?: WearableConnectorRegistration;\n };\n } catch (err) {\n if (isModuleNotFound(err, specifier)) continue;\n if (!loadFailuresWarned.has(specifier)) {\n loadFailuresWarned.add(specifier);\n log.warn(\n `wearables: failed to load optional connector package ${specifier}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n continue;\n }\n const registration = mod.wearableConnectorRegistration;\n if (!registration) continue;\n try {\n registerWearableConnector(registration);\n } catch {\n // Already registered by a direct import — fine.\n }\n }\n}\n\nfunction isModuleNotFound(err: unknown, specifier: string): boolean {\n if (!err || typeof err !== \"object\") return false;\n const code = (err as { code?: unknown }).code;\n if (code !== \"ERR_MODULE_NOT_FOUND\" && code !== \"MODULE_NOT_FOUND\") {\n return false;\n }\n const message = (err as { message?: unknown }).message;\n // Only treat the failure as \"optional package absent\" when the error\n // names the specifier we asked for — a transitive resolution failure\n // inside an installed connector is a broken install worth surfacing.\n return typeof message === \"string\" && message.includes(specifier);\n}\n","/**\n * WearablesService — the single implementation behind every wearables\n * access surface (CLI, MCP tools, HTTP routes). Surfaces stay thin and\n * delegate here; formatting differences live with the surface, behavior\n * lives here (same renderer-sharing rule as recall explain/xray).\n */\n\nimport {\n correctionsFilePath,\n loadCorrectionsFile,\n saveCorrectionsFile,\n compileCorrectionRule,\n} from \"./corrections.js\";\nimport { describeErrorForOperator, WearablesInputError } from \"./errors.js\";\nimport { inferMemoryStatus } from \"../memory-lifecycle-ledger-utils.js\";\nimport { isValidTranscriptDate, parseDayTranscript } from \"./day-store.js\";\nimport { stripAttributesSuffix } from \"../storage.js\";\nimport type { MemoryFrontmatter } from \"../types.js\";\nimport type { WearableMemoryGenDeps } from \"./memory-gen.js\";\nimport { WEARABLE_SOURCE_PREFIX, wearableSourceLabel } from \"./memory-gen.js\";\nimport {\n defaultTimezone,\n syncWearableSource,\n type WearableSyncOptions,\n} from \"./pipeline.js\";\nimport {\n ensureBuiltInWearableConnectors,\n getWearableConnector,\n listWearableConnectors,\n} from \"./registry.js\";\nimport {\n loadSpeakerRegistry,\n saveSpeakerRegistry,\n speakerRegistryKey,\n type SpeakerRegistry,\n} from \"./speakers.js\";\nimport { loadSyncState } from \"./sync-state.js\";\nimport type {\n WearableCorrectionRule,\n WearableDayTranscript,\n WearableSourceSettings,\n WearableSourceStatus,\n WearableSyncSummary,\n WearablesConfig,\n} from \"./types.js\";\n\n/** Storage capabilities the service needs (satisfied by StorageManager). */\nexport interface WearableStorageIo {\n readonly dir: string;\n writeWearableDayTranscript(\n sourceId: string,\n date: string,\n serialized: string,\n ): Promise<void>;\n readWearableDayTranscript(\n sourceId: string,\n date: string,\n ): Promise<string | null>;\n listWearableTranscriptDays(\n sourceId?: string,\n ): Promise<Array<{ source: string; date: string }>>;\n readAllMemories(): Promise<\n Array<{\n path: string;\n frontmatter: {\n id: string;\n source: string;\n created: string;\n tags: string[];\n status?: string;\n /** Archival timestamp — rows with this set are not support. */\n archivedAt?: string;\n structuredAttributes?: Record<string, string>;\n };\n content: string;\n }>\n >;\n writeMemory: WearableMemoryGenDeps[\"writer\"][\"writeMemory\"];\n hasFactContentHash(content: string): Promise<boolean>;\n findWearableMemoryByContent(\n content: string,\n ): Promise<{ id: string; status: string | undefined } | null>;\n promoteWearableMemory(\n id: string,\n attributeUpdates: Record<string, string>,\n confidence?: number,\n ): Promise<boolean>;\n demoteWearableMemory(\n id: string,\n attributeUpdates: Record<string, string>,\n ): Promise<boolean>;\n}\n\nexport interface WearableSearchBackend {\n /** Full-text search over the memory dir; null when unavailable. */\n search(\n query: string,\n maxResults: number,\n ): Promise<Array<{ path: string; score: number; preview: string }> | null>;\n}\n\nexport interface WearablesServiceDeps {\n config: WearablesConfig;\n getStorage(): Promise<WearableStorageIo>;\n /** Extraction hook; null when no engine is available. */\n extract: WearableMemoryGenDeps[\"extract\"] | null;\n /**\n * LLM-as-judge hook for smart memoryMode (the orchestrator wires the\n * existing extraction judge here). Absent degrades smart mode to\n * confidence x sourceTrust + corroboration scoring.\n */\n judgeFacts?: WearableMemoryGenDeps[\"judgeFacts\"];\n /** Search backend (QMD); null disables indexed search. */\n searchBackend: WearableSearchBackend | null;\n /** Fired after transcript writes so the search index refreshes. */\n reindexSearch?: () => Promise<void>;\n}\n\nexport interface WearableTranscriptSearchResult {\n source: string;\n date: string;\n score: number;\n snippet: string;\n /** \"indexed\" (QMD) or \"scan\" (substring fallback). */\n backend: \"indexed\" | \"scan\";\n}\n\nexport interface WearableMemorySearchResult {\n id: string;\n source: string;\n date?: string;\n conversationId?: string;\n status?: string;\n content: string;\n created: string;\n}\n\nexport interface WearableDayTranscriptView {\n source: string;\n date: string;\n meta: WearableDayTranscript[\"meta\"] | null;\n body: string;\n /** Other sources that also recorded during this day (overlap hint). */\n overlapsWith: string[];\n}\n\n/**\n * Build the memory writer used by wearable syncs. The storage fact\n * hash index only covers category \"fact\", so dedup for the other\n * categories wearables write (moment digests, decisions, preferences,\n * commitments) additionally scans existing wearable-tagged memories for\n * an exact content match — without this, a forced or retried day\n * re-writes identical digests and candidates (Codex P2 on PR #1458).\n * The scan is bounded to wearable-sourced memories and sits on the\n * cached readAllMemories() path.\n */\nexport function createWearableMemoryWriter(\n storage: WearableStorageIo,\n): WearableMemoryGenDeps[\"writer\"] {\n return {\n writeMemory: storage.writeMemory.bind(storage),\n findWearableMemoryByContent: async (content: string) =>\n (await storage.findWearableMemoryByContent(content)) as\n | { id: string; status: import(\"../types.js\").MemoryStatus | undefined }\n | null,\n promoteWearableMemory: storage.promoteWearableMemory.bind(storage),\n demoteWearableMemory: storage.demoteWearableMemory.bind(storage),\n hasFactContentHash: async (content: string) => {\n if (await storage.hasFactContentHash(content)) return true;\n // Compare with the \"[Attributes: ...]\" enrichment suffix removed\n // on BOTH sides — stored wearable bodies carry it, callers pass\n // raw fact text. Without the strip, digest/candidate dedup never\n // matched attribute-bearing memories.\n const needle = stripAttributesSuffix(content);\n const memories = await storage.readAllMemories();\n return memories.some(\n (memory) =>\n typeof memory.frontmatter.source === \"string\" &&\n memory.frontmatter.source.startsWith(`${WEARABLE_SOURCE_PREFIX}:`) &&\n stripAttributesSuffix(memory.content) === needle,\n );\n },\n };\n}\n\n/** Mirrors the storage-layer guard so surface inputs fail as 400s. */\nconst SOURCE_ID_PATTERN = /^[a-z][a-z0-9-]{0,63}$/;\n\nfunction assertValidSourceId(source: string): void {\n if (!SOURCE_ID_PATTERN.test(source)) {\n throw new WearablesInputError(\n `invalid source id '${source}' — expected lowercase letters, digits, and dashes`,\n );\n }\n}\n\nconst TRANSCRIPT_SEARCH_DEFAULT_LIMIT = 10;\nconst TRANSCRIPT_SEARCH_MAX_LIMIT = 50;\nconst MEMORY_LIST_DEFAULT_LIMIT = 50;\nconst MEMORY_LIST_MAX_LIMIT = 200;\n\nexport class WearablesService {\n constructor(private readonly deps: WearablesServiceDeps) {}\n\n get enabled(): boolean {\n return this.deps.config.enabled;\n }\n\n private assertEnabled(): void {\n if (!this.deps.config.enabled) {\n throw new WearablesInputError(\n \"wearables are not enabled — set `wearables.enabled: true` (and configure at least one source) in the plugin config\",\n );\n }\n }\n\n private timezone(): string {\n return this.deps.config.timezone ?? defaultTimezone();\n }\n\n private enabledSources(): Array<[string, WearableSourceSettings]> {\n return Object.entries(this.deps.config.sources).filter(\n ([, settings]) => settings.enabled,\n );\n }\n\n /** Status for every configured source (and connector availability). */\n async status(): Promise<{\n enabled: boolean;\n timezone: string;\n sources: WearableSourceStatus[];\n connectorsInstalled: string[];\n }> {\n await ensureBuiltInWearableConnectors();\n const storage = await this.deps.getStorage();\n const syncState = await loadSyncState(storage.dir);\n const sources: WearableSourceStatus[] = [];\n for (const [sourceId, settings] of Object.entries(this.deps.config.sources)) {\n const registration = getWearableConnector(sourceId);\n const days = await storage.listWearableTranscriptDays(sourceId).catch(() => []);\n const state = syncState.sources[sourceId];\n sources.push({\n source: sourceId,\n displayName: registration?.displayName ?? sourceId,\n enabled: settings.enabled,\n connectorInstalled: registration !== undefined,\n memoryMode: settings.memoryMode,\n lastSyncAt: state?.lastSyncAt ?? null,\n lastDateSynced: state?.lastDateSynced ?? null,\n transcriptDays: days.length,\n });\n }\n return {\n enabled: this.deps.config.enabled,\n timezone: this.timezone(),\n sources,\n connectorsInstalled: listWearableConnectors(),\n };\n }\n\n /** Run a sync for one source or all enabled sources. */\n async sync(\n options: WearableSyncOptions & { source?: string },\n ): Promise<WearableSyncSummary[]> {\n this.assertEnabled();\n await ensureBuiltInWearableConnectors();\n const storage = await this.deps.getStorage();\n\n let targets: Array<[string, WearableSourceSettings]>;\n if (options.source !== undefined) {\n assertValidSourceId(options.source);\n const settings = this.deps.config.sources[options.source];\n if (!settings) {\n throw new WearablesInputError(\n `unknown wearable source '${options.source}' — configured sources: ${\n Object.keys(this.deps.config.sources).join(\", \") || \"(none)\"\n }`,\n );\n }\n if (!settings.enabled) {\n throw new WearablesInputError(\n `wearable source '${options.source}' is configured but disabled — set wearables.sources.${options.source}.enabled: true`,\n );\n }\n targets = [[options.source, settings]];\n } else {\n targets = this.enabledSources();\n if (targets.length === 0) {\n throw new WearablesInputError(\n \"no wearable sources are enabled — configure wearables.sources.<id>.enabled: true\",\n );\n }\n }\n\n const memoryGen: WearableMemoryGenDeps | null = this.deps.extract\n ? {\n extract: this.deps.extract,\n writer: createWearableMemoryWriter(storage),\n ...(this.deps.judgeFacts !== undefined\n ? { judgeFacts: this.deps.judgeFacts }\n : {}),\n }\n : null;\n\n const summaries: WearableSyncSummary[] = [];\n for (const [sourceId, settings] of targets) {\n const registration = getWearableConnector(sourceId);\n if (!registration) {\n throw new WearablesInputError(\n `wearable source '${sourceId}' is enabled but its connector package is not installed.\\n` +\n `Install it alongside Remnic:\\n npm install @remnic/connector-${sourceId}`,\n );\n }\n const connector = registration.factory({\n settings,\n timezone: this.timezone(),\n });\n const summary = await syncWearableSource(\n connector,\n settings,\n this.deps.config,\n options,\n {\n memoryDir: storage.dir,\n readDayContentHash: async (source, date) => {\n const raw = await storage.readWearableDayTranscript(source, date);\n if (raw === null) return null;\n return parseDayTranscript(raw)?.meta.contentHash ?? null;\n },\n writeDayTranscript: (source, date, serialized) =>\n storage.writeWearableDayTranscript(source, date, serialized),\n afterWrites: this.deps.reindexSearch,\n memoryGen,\n // Cross-device corroboration evidence (smart mode): other\n // sources' stored transcripts for the same day...\n readOtherSourceDayBodies: async (date, excludeSource) => {\n const bodies = new Map<string, string>();\n const days = await storage.listWearableTranscriptDays();\n for (const entry of days) {\n if (entry.date !== date || entry.source === excludeSource) continue;\n if (bodies.size >= 4) break;\n const raw = await storage.readWearableDayTranscript(entry.source, entry.date);\n if (raw === null) continue;\n bodies.set(entry.source, parseDayTranscript(raw)?.body ?? raw);\n }\n return bodies;\n },\n // ...and existing memories for the support boost. Status\n // resolves through the canonical inferMemoryStatus so rows\n // archived via `archivedAt` (or an archive/ path) without an\n // explicit status never count. Explicit allow-list: active\n // rows AND pending_review rows — a borderline fact observed\n // again on a later day is repetition signal and the support\n // boost is how it earns promotion. Rejected/quarantined/\n // superseded/archived/forgotten rows never count (CLAUDE.md\n // rule 53). Bodies feed token matching with the\n // \"[Attributes: ...]\" enrichment suffix stripped — attribute\n // metadata must never grant corroboration.\n listSupportMemories: async () => {\n const memories = await storage.readAllMemories();\n const support: Array<{ id: string; content: string }> = [];\n for (const memory of memories) {\n // WearableStorageIo narrows MemoryFrontmatter for\n // testability; production hands us the real thing.\n const status = inferMemoryStatus(\n memory.frontmatter as MemoryFrontmatter,\n memory.path,\n );\n if (status !== \"active\" && status !== \"pending_review\") {\n continue;\n }\n support.push({\n id: memory.frontmatter.id,\n content: stripAttributesSuffix(memory.content),\n });\n }\n return support;\n },\n },\n );\n summaries.push(summary);\n }\n return summaries;\n }\n\n /** Verify connectivity/credentials for one source. */\n async checkAuth(sourceId: string): Promise<{ ok: boolean; detail?: string }> {\n this.assertEnabled();\n await ensureBuiltInWearableConnectors();\n assertValidSourceId(sourceId);\n const settings = this.deps.config.sources[sourceId];\n if (!settings) {\n throw new WearablesInputError(`unknown wearable source '${sourceId}'`);\n }\n const registration = getWearableConnector(sourceId);\n if (!registration) {\n return {\n ok: false,\n detail: `connector package @remnic/connector-${sourceId} is not installed`,\n };\n }\n const connector = registration.factory({\n settings,\n timezone: this.timezone(),\n });\n try {\n // Connector detail strings are authored guidance (plus\n // name+errno network summaries) — safe to pass through verbatim.\n return await connector.verifyAuth();\n } catch (err) {\n return {\n ok: false,\n detail: describeErrorForOperator(err),\n };\n }\n }\n\n /**\n * Full transcript(s) for a day. Without `source`, returns every\n * source that recorded that day, annotated with overlap hints.\n */\n async dayTranscript(\n date: string,\n sourceId?: string,\n ): Promise<WearableDayTranscriptView[]> {\n if (!isValidTranscriptDate(date)) {\n throw new WearablesInputError(`invalid date '${date}' — expected YYYY-MM-DD`);\n }\n if (sourceId !== undefined) assertValidSourceId(sourceId);\n const storage = await this.deps.getStorage();\n const targets =\n sourceId !== undefined\n ? [sourceId]\n : (await storage.listWearableTranscriptDays())\n .filter((entry) => entry.date === date)\n .map((entry) => entry.source);\n const views: WearableDayTranscriptView[] = [];\n for (const source of [...new Set(targets)]) {\n const raw = await storage.readWearableDayTranscript(source, date);\n if (raw === null) continue;\n const parsed = parseDayTranscript(raw);\n views.push({\n source,\n date,\n meta: parsed?.meta ?? null,\n body: parsed?.body ?? raw,\n overlapsWith: [],\n });\n }\n for (const view of views) {\n view.overlapsWith = views\n .map((other) => other.source)\n .filter((other) => other !== view.source);\n }\n return views;\n }\n\n /** List days that have stored transcripts. */\n async listDays(\n sourceId?: string,\n ): Promise<Array<{ source: string; date: string }>> {\n if (sourceId !== undefined) assertValidSourceId(sourceId);\n const storage = await this.deps.getStorage();\n return storage.listWearableTranscriptDays(sourceId);\n }\n\n /**\n * Search stored transcripts. Uses the indexed backend when available\n * and falls back to a bounded substring scan otherwise — the two\n * paths are distinguishable in the result (`backend`) so callers can\n * tell \"no hits\" from \"weaker search ran\".\n */\n async searchTranscripts(\n query: string,\n options: {\n source?: string;\n from?: string;\n to?: string;\n limit?: number;\n } = {},\n ): Promise<WearableTranscriptSearchResult[]> {\n const trimmed = query.trim();\n if (trimmed.length === 0) {\n throw new WearablesInputError(\"transcript search requires a non-empty query\");\n }\n if (options.source !== undefined) assertValidSourceId(options.source);\n for (const [name, value] of [\n [\"from\", options.from],\n [\"to\", options.to],\n ] as const) {\n if (value !== undefined && !isValidTranscriptDate(value)) {\n throw new WearablesInputError(`invalid ${name} date '${value}' — expected YYYY-MM-DD`);\n }\n }\n const limit = clampLimit(\n options.limit,\n TRANSCRIPT_SEARCH_DEFAULT_LIMIT,\n TRANSCRIPT_SEARCH_MAX_LIMIT,\n \"limit\",\n );\n\n const matchesScope = (source: string, date: string): boolean => {\n if (options.source !== undefined && source !== options.source) return false;\n if (options.from !== undefined && date < options.from) return false;\n // Half-open scan semantics aren't meaningful for whole-day files;\n // `to` is inclusive of the named day.\n if (options.to !== undefined && date > options.to) return false;\n return true;\n };\n\n if (this.deps.searchBackend) {\n const hits = await this.deps.searchBackend.search(trimmed, limit * 5);\n if (hits !== null) {\n const results: WearableTranscriptSearchResult[] = [];\n for (const hit of hits) {\n const located = locateTranscriptPath(hit.path);\n if (!located) continue;\n if (!matchesScope(located.source, located.date)) continue;\n results.push({\n source: located.source,\n date: located.date,\n score: hit.score,\n snippet: hit.preview,\n backend: \"indexed\",\n });\n if (results.length >= limit) break;\n }\n // The index spans the whole memory dir, so ordinary memory\n // files can crowd transcripts out of the top hits entirely.\n // Zero in-scope hits therefore doesn't mean \"no transcript\n // matches\" — fall through to the bounded scan in that case\n // (Codex P2 on PR #1458). Partial result sets stay indexed-only\n // so the two backends never interleave in one response.\n if (results.length > 0) {\n return results;\n }\n }\n }\n\n // Fallback scan: newest days first, bounded, case-insensitive.\n const storage = await this.deps.getStorage();\n const days = await storage.listWearableTranscriptDays(options.source);\n const needle = trimmed.toLowerCase();\n const results: WearableTranscriptSearchResult[] = [];\n for (const { source, date } of days) {\n if (!matchesScope(source, date)) continue;\n const raw = await storage.readWearableDayTranscript(source, date);\n if (raw === null) continue;\n const body = parseDayTranscript(raw)?.body ?? raw;\n const lower = body.toLowerCase();\n const index = lower.indexOf(needle);\n if (index === -1) continue;\n results.push({\n source,\n date,\n score: 0,\n snippet: extractSnippet(body, index, needle.length),\n backend: \"scan\",\n });\n if (results.length >= limit) break;\n }\n return results;\n }\n\n /**\n * Memories created from wearable transcripts, filterable by source\n * and/or day. Includes pending_review candidates — the whole point of\n * review mode is seeing what's queued.\n */\n async transcriptMemories(\n options: {\n source?: string;\n date?: string;\n limit?: number;\n } = {},\n ): Promise<WearableMemorySearchResult[]> {\n if (options.date !== undefined && !isValidTranscriptDate(options.date)) {\n throw new WearablesInputError(`invalid date '${options.date}' — expected YYYY-MM-DD`);\n }\n if (options.source !== undefined) assertValidSourceId(options.source);\n const limit = clampLimit(\n options.limit,\n MEMORY_LIST_DEFAULT_LIMIT,\n MEMORY_LIST_MAX_LIMIT,\n \"limit\",\n );\n const storage = await this.deps.getStorage();\n const memories = await storage.readAllMemories();\n const results: WearableMemorySearchResult[] = [];\n for (const memory of memories) {\n const source = memory.frontmatter.source;\n if (typeof source !== \"string\" || !source.startsWith(`${WEARABLE_SOURCE_PREFIX}:`)) {\n continue;\n }\n const attrs = memory.frontmatter.structuredAttributes ?? {};\n const sourceId = attrs.wearableSource;\n if (options.source !== undefined) {\n if (\n sourceId !== options.source &&\n source !== wearableSourceLabel(options.source) &&\n source !== `${wearableSourceLabel(options.source)}:native`\n ) {\n continue;\n }\n }\n if (options.date !== undefined && attrs.wearableDate !== options.date) {\n continue;\n }\n results.push({\n id: memory.frontmatter.id,\n source: sourceId ?? source,\n date: attrs.wearableDate,\n conversationId: attrs.wearableConversationId,\n status: memory.frontmatter.status,\n content: memory.content,\n created: memory.frontmatter.created,\n });\n }\n results.sort((a, b) => {\n if (a.created > b.created) return -1;\n if (a.created < b.created) return 1;\n if (a.id < b.id) return -1;\n if (a.id > b.id) return 1;\n return 0;\n });\n return results.slice(0, limit);\n }\n\n // -- speakers -------------------------------------------------------------\n\n async listSpeakers(): Promise<SpeakerRegistry> {\n const storage = await this.deps.getStorage();\n return loadSpeakerRegistry(storage.dir);\n }\n\n async setSpeaker(\n sourceId: string,\n speakerKey: string,\n name: string,\n opts: { isSelf?: boolean } = {},\n ): Promise<SpeakerRegistry> {\n if (typeof name !== \"string\" || name.trim().length === 0) {\n throw new WearablesInputError(\"speaker name must be a non-empty string\");\n }\n if (typeof speakerKey !== \"string\" || speakerKey.trim().length === 0) {\n throw new WearablesInputError(\"speaker key must be a non-empty string\");\n }\n const storage = await this.deps.getStorage();\n const registry = await loadSpeakerRegistry(storage.dir);\n registry.speakers[speakerRegistryKey(sourceId, speakerKey.trim())] = {\n name: name.trim(),\n ...(opts.isSelf === true ? { isSelf: true } : {}),\n updatedAt: new Date().toISOString(),\n };\n await saveSpeakerRegistry(storage.dir, registry);\n return registry;\n }\n\n async setSelfName(name: string): Promise<SpeakerRegistry> {\n if (typeof name !== \"string\" || name.trim().length === 0) {\n throw new WearablesInputError(\"self name must be a non-empty string\");\n }\n const storage = await this.deps.getStorage();\n const registry = await loadSpeakerRegistry(storage.dir);\n registry.selfName = name.trim();\n await saveSpeakerRegistry(storage.dir, registry);\n return registry;\n }\n\n async removeSpeaker(\n sourceId: string,\n speakerKey: string,\n ): Promise<SpeakerRegistry> {\n const storage = await this.deps.getStorage();\n const registry = await loadSpeakerRegistry(storage.dir);\n const key = speakerRegistryKey(sourceId, speakerKey.trim());\n if (!(key in registry.speakers)) {\n throw new WearablesInputError(`no speaker override stored for '${key}'`);\n }\n delete registry.speakers[key];\n await saveSpeakerRegistry(storage.dir, registry);\n return registry;\n }\n\n // -- corrections ----------------------------------------------------------\n\n async listCorrections(): Promise<{\n fromConfig: WearableCorrectionRule[];\n fromState: WearableCorrectionRule[];\n stateFilePath: string;\n }> {\n const storage = await this.deps.getStorage();\n return {\n fromConfig: this.deps.config.corrections,\n fromState: await loadCorrectionsFile(storage.dir),\n stateFilePath: correctionsFilePath(storage.dir),\n };\n }\n\n async addCorrection(rule: WearableCorrectionRule): Promise<void> {\n // Validate before persisting so a bad rule fails the command, not\n // the next sync.\n compileCorrectionRule(rule, \"correction\");\n const storage = await this.deps.getStorage();\n const rules = await loadCorrectionsFile(storage.dir);\n const duplicate = rules.some(\n (existing) =>\n existing.match === rule.match &&\n existing.replace === rule.replace &&\n (existing.regex === true) === (rule.regex === true),\n );\n if (duplicate) {\n throw new WearablesInputError(\n `an identical correction rule already exists (match: ${JSON.stringify(rule.match)})`,\n );\n }\n rules.push(rule);\n await saveCorrectionsFile(storage.dir, rules);\n }\n\n async removeCorrection(index: number): Promise<WearableCorrectionRule> {\n if (!Number.isInteger(index) || index < 0) {\n throw new WearablesInputError(`invalid correction index '${index}'`);\n }\n const storage = await this.deps.getStorage();\n const rules = await loadCorrectionsFile(storage.dir);\n if (index >= rules.length) {\n throw new WearablesInputError(\n `correction index ${index} is out of range (have ${rules.length} state rule${rules.length === 1 ? \"\" : \"s\"})`,\n );\n }\n const [removed] = rules.splice(index, 1);\n await saveCorrectionsFile(storage.dir, rules);\n return removed;\n }\n}\n\nfunction clampLimit(\n value: number | undefined,\n fallback: number,\n max: number,\n label: string,\n): number {\n if (value === undefined) return fallback;\n if (!Number.isFinite(value) || !Number.isInteger(value) || value < 1 || value > max) {\n throw new WearablesInputError(\n `invalid ${label} '${value}' — expected an integer between 1 and ${max}`,\n );\n }\n return value;\n}\n\n/** Map an indexed-search hit path back to (source, date), or null. */\nexport function locateTranscriptPath(\n hitPath: string,\n): { source: string; date: string } | null {\n const normalized = hitPath.replace(/\\\\/g, \"/\");\n const match = normalized.match(\n /(?:^|\\/)wearables\\/([a-z][a-z0-9-]{0,63})\\/(\\d{4}-\\d{2}-\\d{2})\\.md$/,\n );\n if (!match) return null;\n if (!isValidTranscriptDate(match[2])) return null;\n return { source: match[1], date: match[2] };\n}\n\nfunction extractSnippet(body: string, index: number, matchLength: number): string {\n const start = Math.max(0, index - 80);\n const end = Math.min(body.length, index + matchLength + 80);\n const prefix = start > 0 ? \"…\" : \"\";\n const suffix = end < body.length ? \"…\" : \"\";\n return `${prefix}${body.slice(start, end).replace(/\\s+/g, \" \").trim()}${suffix}`;\n}\n","import path from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\nimport type { Dirent } from \"node:fs\";\nimport {\n appendFile,\n lstat,\n mkdir,\n open,\n readdir,\n readFile,\n realpath,\n rename,\n stat,\n unlink,\n utimes,\n writeFile,\n} from \"node:fs/promises\";\nimport type { PluginConfig } from \"../types.js\";\nimport { isSafeRouteNamespace } from \"../routing/engine.js\";\nimport { namespaceIdentityFromToken, namespaceIdentityToken, normalizeNamespaceIdentity } from \"./identity.js\";\nimport { resolveDefaultNamespaceRoot, resolveNamespaceStorageRoot } from \"./storage.js\";\nimport { ALL_CATEGORY_DIRS } from \"../utils/category-dir.js\";\n\n/**\n * Rebuildable namespace catalog (issue #1499).\n *\n * Purpose: a downstream, rebuildable metadata index that lets Remnic ENUMERATE\n * the configured and dynamically-created namespaces that exist or should be\n * maintained. Filesystem memory remains the single source of truth; the catalog\n * is derived metadata and can always be reconstructed from disk.\n *\n * Storage format: `<memoryDir>/state/namespaces.jsonl` — an append-and-compact\n * JSON-lines log. We chose this over per-namespace sidecar files because:\n * - touches (markRead/markWrite/markMaintenance) are cheap single appends;\n * - it is naturally audit-friendly (the raw log preserves touch history);\n * - a single file makes enumeration trivial (no directory walk per call);\n * - last-record-wins compaction folds the log into the current state on read,\n * and `rebuildFromDisk` rewrites it atomically (temp file + rename).\n *\n * SECURITY:\n * - The catalog stores ONLY metadata (namespace names, kinds, timestamps,\n * resolved storage dirs). It NEVER holds raw memory content or secrets.\n * - Catalog presence grants NO authorization. Read/write access still flows\n * through the namespace policies in `principal.ts`; this module never makes\n * an access decision.\n * - All namespace tokens are validated with `isSafeRouteNamespace` (except the\n * configured default namespace, which is exempt at the routing layer) and\n * every storage dir is contained under `<memoryDir>/namespaces`.\n * - `rebuildFromDisk` rejects/reports symlinked roots that escape the memory\n * root rather than trusting them.\n *\n * LIFECYCLE: catalog write failures must NEVER crash a primary memory op.\n * Callers should wrap touch calls in try/catch (or rely on the internal\n * failure-tolerant append). The internal serialized write chain recovers from\n * rejection so one failed append cannot poison subsequent writes.\n */\n\nexport type NamespaceKind =\n | \"default\"\n | \"self\"\n | \"shared\"\n | \"project\"\n | \"branch\"\n | \"team-project\"\n | \"explicit\"\n | \"legacy\";\n\nexport type NamespaceDiscoverySource = \"config\" | \"write\" | \"read\" | \"scan\" | \"migration\";\n\nexport interface NamespaceRecord {\n namespace: string;\n identityToken: string;\n kind: NamespaceKind;\n principal?: string;\n projectId?: string;\n branch?: string;\n parentNamespace?: string;\n createdAt: string;\n lastReadAt?: string;\n lastWriteAt?: string;\n lastMaintenanceAt?: Record<string, string>;\n storageDir: string;\n discoveredBy: NamespaceDiscoverySource;\n}\n\nexport interface NamespaceCatalogFilter {\n kind?: NamespaceKind;\n discoveredBy?: NamespaceDiscoverySource;\n /** Only include namespaces written since this instant (inclusive lower bound). */\n writtenSince?: Date;\n}\n\nexport interface NamespaceTouchMetadata {\n discoveredBy?: NamespaceDiscoverySource;\n kind?: NamespaceKind;\n principal?: string;\n projectId?: string;\n branch?: string;\n parentNamespace?: string;\n /** Explicit storage dir (when the caller already resolved it). */\n storageDir?: string;\n /** Override the touch timestamp (mainly for tests / migration replay). */\n at?: Date;\n}\n\nexport interface NamespaceCatalogSkippedRoot {\n token: string;\n reason: \"symlink\" | \"escape\" | \"unsafe\" | \"error\";\n detail?: string;\n}\n\nexport interface NamespaceCatalogRebuildResult {\n dryRun: boolean;\n records: NamespaceRecord[];\n /** Roots reported as ambiguous/unsafe rather than silently misclassified. */\n skipped: NamespaceCatalogSkippedRoot[];\n /**\n * Whether the rebuild actually rewrote the on-disk catalog (round 6, codex P2\n * / cursor Medium — NBn3n/NBsGG). `false` for a dry-run, AND for an `--apply`\n * that could NOT acquire the cross-process rebuild lock within the bounded wait\n * (it ran compute-only to avoid clobbering a concurrent lock holder). Callers\n * (CLI) must NOT report unqualified success when `applied` is false for a\n * non-dry-run — the catalog was left unchanged and a retry is needed.\n */\n applied: boolean;\n}\n\nconst NAMESPACE_KINDS: readonly NamespaceKind[] = [\n \"default\",\n \"self\",\n \"shared\",\n \"project\",\n \"branch\",\n \"team-project\",\n \"explicit\",\n \"legacy\",\n];\n\nconst NAMESPACE_DISCOVERY_SOURCES: readonly NamespaceDiscoverySource[] = [\n \"config\",\n \"write\",\n \"read\",\n \"scan\",\n \"migration\",\n];\n\nconst CATALOG_FILE = \"namespaces.jsonl\";\nconst STATE_DIR = \"state\";\nconst REBUILD_LOCK_FILE = \"namespaces.rebuild.lock\";\n// A held lock older than this is treated as stale (a crashed rebuild) and broken.\nconst REBUILD_LOCK_STALE_MS = 30_000;\n// Bounded acquisition: poll briefly, then proceed best-effort rather than block\n// a CLI rebuild forever behind a busy gateway.\nconst REBUILD_LOCK_MAX_WAIT_MS = 5_000;\nconst REBUILD_LOCK_POLL_MS = 50;\n// Heartbeat: while a rebuild holds the lock it refreshes the lock file's mtime\n// on this interval so a long (>STALE_MS) scan is NOT mistaken for a crashed\n// holder and broken out from under it (round 5, cursor/codex Medium/P2). Must be\n// comfortably below STALE_MS so at least a couple of beats land per stale window.\nconst REBUILD_LOCK_HEARTBEAT_MS = 10_000;\n\n// Children that indicate a directory holds Remnic memory data (used for legacy\n// default-root detection and to skip empty/non-data roots during rebuild).\n//\n// `state` is included to MATCH the router's storage-presence check\n// (`NamespaceStorageRouter` counts the `state` runtime child via\n// `includeRuntimeState: true`). Without it (round 3, cursor Medium) a namespace\n// the router actively resolves because it has only a `state/` dir would be\n// treated as absent by rebuild and vanish from the catalog after `--apply`.\nconst MEMORY_DATA_CHILDREN = [\n ...ALL_CATEGORY_DIRS,\n \"entities\",\n \"artifacts\",\n \"identity\",\n \"config\",\n \"summaries\",\n \"profile.md\",\n \"state\",\n] as const;\n\nfunction isCatalogEnabled(config: PluginConfig): boolean {\n // Inert unless namespaces are enabled. namespaceCatalogEnabled defaults to\n // true (undefined => enabled) but is only honored when namespacesEnabled.\n if (config.namespacesEnabled !== true) return false;\n return (config as { namespaceCatalogEnabled?: boolean }).namespaceCatalogEnabled !== false;\n}\n\n// Marker children that MUST be a regular file rather than a directory. Everything\n// else in MEMORY_DATA_CHILDREN is a category/data DIRECTORY that downstream\n// indexers (`scanMemoryDir`) read — and which they reject when it is a symlink or\n// a non-directory. `profile.md` is the sole file marker.\nconst FILE_MEMORY_DATA_CHILDREN = new Set<string>([\"profile.md\"]);\n\ntype MemoryDataMarkerStatus =\n | { state: \"absent\" }\n | { state: \"valid\" }\n | { state: \"invalid\"; detail: string };\n\ntype MemoryDataRootStatus = {\n hasData: boolean;\n invalidMarker?: string;\n};\n\nfunction isNotFoundError(err: unknown): boolean {\n return (\n typeof err === \"object\" &&\n err !== null &&\n \"code\" in err &&\n (err as { code?: string }).code === \"ENOENT\"\n );\n}\n\n/**\n * Inspect `child` under `rootDir` as a memory-data marker (NIw0F / PR #1506).\n * Existence alone is not enough: a bogus marker — e.g. `facts` as a symlink or a\n * regular file instead of a real directory — passes `lstat` but makes\n * `scanMemoryDir` throw on the symlinked/non-directory category root. Returning\n * a distinct `invalid` status lets root scans reject a namespace when ANY known\n * marker is malformed, even if a sibling marker such as `state/` is valid.\n */\nasync function inspectMemoryDataMarker(rootDir: string, child: string): Promise<MemoryDataMarkerStatus> {\n const childPath = path.join(rootDir, child);\n let entry;\n try {\n entry = await lstat(childPath);\n } catch (err) {\n return isNotFoundError(err)\n ? { state: \"absent\" }\n : { state: \"invalid\", detail: `${child}: ${err instanceof Error ? err.message : String(err)}` };\n }\n // Reject symlinked markers outright (scan parity — never follow them).\n if (entry.isSymbolicLink()) return { state: \"invalid\", detail: `${child}: symlink` };\n if (FILE_MEMORY_DATA_CHILDREN.has(child)) {\n // `profile.md` must be a regular file.\n return entry.isFile()\n ? { state: \"valid\" }\n : { state: \"invalid\", detail: `${child}: expected file` };\n }\n // Category/data markers must be real directories whose realpath stays inside\n // the namespace root (no escape via a symlinked ancestor).\n if (!entry.isDirectory()) return { state: \"invalid\", detail: `${child}: expected directory` };\n try {\n const rootReal = await realpath(rootDir);\n const childReal = await realpath(childPath);\n return isPathInside(rootReal, childReal)\n ? { state: \"valid\" }\n : { state: \"invalid\", detail: `${child}: escapes namespace root` };\n } catch (err) {\n return { state: \"invalid\", detail: `${child}: ${err instanceof Error ? err.message : String(err)}` };\n }\n}\n\nasync function inspectMemoryDataRoot(rootDir: string): Promise<MemoryDataRootStatus> {\n let hasData = false;\n for (const child of MEMORY_DATA_CHILDREN) {\n const marker = await inspectMemoryDataMarker(rootDir, child);\n if (marker.state === \"invalid\") {\n return { hasData: false, invalidMarker: marker.detail };\n }\n if (marker.state === \"valid\") {\n hasData = true;\n }\n }\n return { hasData };\n}\n\nexport async function hasMemoryData(rootDir: string): Promise<boolean> {\n return (await inspectMemoryDataRoot(rootDir)).hasData;\n}\n\nfunction isValidIsoTimestamp(value: string): boolean {\n const ms = Date.parse(value);\n return Number.isFinite(ms);\n}\n\nfunction isNamespaceKind(value: unknown): value is NamespaceKind {\n return typeof value === \"string\" && (NAMESPACE_KINDS as readonly string[]).includes(value);\n}\n\nfunction isNamespaceDiscoverySource(value: unknown): value is NamespaceDiscoverySource {\n return typeof value === \"string\" && (NAMESPACE_DISCOVERY_SOURCES as readonly string[]).includes(value);\n}\n\n/**\n * Validate a JSONL line parsed value as a usable NamespaceRecord.\n * Rejects null / non-object / missing-field records (CLAUDE.md rule #18).\n * Persisted enum and timestamp fields are also validated here so a syntactically\n * valid but tampered/pre-fix line cannot surface impossible record states.\n */\nfunction coerceRecord(value: unknown): NamespaceRecord | null {\n if (typeof value !== \"object\" || value === null) return null;\n const v = value as Record<string, unknown>;\n if (typeof v.namespace !== \"string\") return null;\n const namespace = normalizeNamespaceIdentity(v.namespace);\n if (namespace.length === 0) return null;\n if (typeof v.identityToken !== \"string\" || v.identityToken.length === 0) return null;\n const expectedIdentityToken = namespaceIdentityToken(namespace);\n if (v.identityToken !== expectedIdentityToken) return null;\n if (typeof v.storageDir !== \"string\" || v.storageDir.length === 0) return null;\n if (typeof v.createdAt !== \"string\" || v.createdAt.length === 0) return null;\n if (!isValidIsoTimestamp(v.createdAt)) return null;\n const kind = v.kind === undefined ? \"explicit\" : isNamespaceKind(v.kind) ? v.kind : null;\n if (!kind) return null;\n const discoveredBy =\n v.discoveredBy === undefined\n ? \"scan\"\n : isNamespaceDiscoverySource(v.discoveredBy)\n ? v.discoveredBy\n : null;\n if (!discoveredBy) return null;\n const record: NamespaceRecord = {\n namespace,\n identityToken: expectedIdentityToken,\n kind,\n createdAt: v.createdAt,\n storageDir: v.storageDir,\n discoveredBy,\n };\n if (typeof v.principal === \"string\") record.principal = v.principal;\n if (typeof v.projectId === \"string\") record.projectId = v.projectId;\n if (typeof v.branch === \"string\") record.branch = v.branch;\n if (typeof v.parentNamespace === \"string\") record.parentNamespace = v.parentNamespace;\n if (typeof v.lastReadAt === \"string\" && isValidIsoTimestamp(v.lastReadAt)) {\n record.lastReadAt = v.lastReadAt;\n }\n if (typeof v.lastWriteAt === \"string\" && isValidIsoTimestamp(v.lastWriteAt)) {\n record.lastWriteAt = v.lastWriteAt;\n }\n if (v.lastMaintenanceAt && typeof v.lastMaintenanceAt === \"object\") {\n const out: Record<string, string> = {};\n for (const [k, val] of Object.entries(v.lastMaintenanceAt as Record<string, unknown>)) {\n if (typeof val === \"string\" && isValidIsoTimestamp(val)) out[k] = val;\n }\n if (Object.keys(out).length > 0) record.lastMaintenanceAt = out;\n }\n return record;\n}\n\n/** Later of two optional ISO timestamps (undefined-safe). */\nfunction laterIso(a: string | undefined, b: string | undefined): string | undefined {\n if (!a) return b;\n if (!b) return a;\n const am = Date.parse(a);\n const bm = Date.parse(b);\n if (!Number.isFinite(am)) return b;\n if (!Number.isFinite(bm)) return a;\n return bm > am ? b : a;\n}\n\n/**\n * Fold the touch fields (lastReadAt / lastWriteAt / lastMaintenanceAt) from a\n * freshly re-read on-disk record into the rebuilt record, taking the LATER\n * timestamp per field (round 5 cross-process re-merge). Disk-derived fields\n * (storageDir, kind, discoveredBy, createdAt, principal hints) are owned by the\n * rebuilt record and left untouched — we only recover touch recency that a\n * concurrent (possibly cross-process) writer recorded after our initial load.\n */\nfunction mergeNewerTouchFields(base: NamespaceRecord, fresh: NamespaceRecord): NamespaceRecord {\n const merged: NamespaceRecord = { ...base };\n const lr = laterIso(base.lastReadAt, fresh.lastReadAt);\n if (lr) merged.lastReadAt = lr;\n const lw = laterIso(base.lastWriteAt, fresh.lastWriteAt);\n if (lw) merged.lastWriteAt = lw;\n if (base.lastMaintenanceAt || fresh.lastMaintenanceAt) {\n const jobs: Record<string, string> = { ...(base.lastMaintenanceAt ?? {}) };\n for (const [job, ts] of Object.entries(fresh.lastMaintenanceAt ?? {})) {\n const latest = laterIso(jobs[job], ts);\n if (latest) jobs[job] = latest;\n }\n if (Object.keys(jobs).length > 0) merged.lastMaintenanceAt = jobs;\n }\n return merged;\n}\n\n/**\n * Serialize a record with sorted keys (CLAUDE.md rule #38) so byte output is\n * stable across runs — required for idempotent rebuilds.\n */\nfunction serializeRecord(record: NamespaceRecord): string {\n const ordered: Record<string, unknown> = {};\n const source = record as unknown as Record<string, unknown>;\n for (const key of Object.keys(source).sort()) {\n const value = source[key];\n if (value === undefined) continue;\n if (key === \"lastMaintenanceAt\" && value && typeof value === \"object\") {\n const sortedJobs: Record<string, string> = {};\n for (const jobKey of Object.keys(value as Record<string, string>).sort()) {\n sortedJobs[jobKey] = (value as Record<string, string>)[jobKey]!;\n }\n ordered[key] = sortedJobs;\n continue;\n }\n ordered[key] = value;\n }\n return JSON.stringify(ordered);\n}\n\n/**\n * Infer the namespace kind from its name/structure using the same conventions\n * as `coding-namespace.ts` (project-*, *-branch-*, team-*-project-*). Returns\n * `explicit` when no structural signal is present. The caller can override.\n */\nfunction inferKind(namespace: string, config: PluginConfig): NamespaceKind {\n // Compare against NORMALIZED config names (NGnek, codex P2): the catalog seeds\n // normalized namespace identities, so a configured name with surrounding\n // whitespace (e.g. `sharedNamespace: \"shared \"`) must still classify the\n // normalized `\"shared\"` as `shared`, not fall through to `explicit`.\n if (namespace === normalizeNamespaceIdentity(config.defaultNamespace)) return \"default\";\n if (namespace === normalizeNamespaceIdentity(config.sharedNamespace)) return \"shared\";\n if (config.namespacePolicies.some((p) => normalizeNamespaceIdentity(p.name) === namespace)) {\n return \"explicit\";\n }\n // Branch overlays embed \"-branch-\" (project-<id>-branch-<name>).\n if (/-branch-|^project-[^-]+-branch-/.test(namespace) || namespace.includes(\"-branch-\")) {\n return \"branch\";\n }\n // Team-project promotions are prefixed team-*-project-*.\n if (/^team-.*-project-/.test(namespace) || /^team-.*project-/.test(namespace)) {\n return \"team-project\";\n }\n // Project overlays are \"project-*\" or \"<principal>-project-*\".\n if (/^project-/.test(namespace) || /-project-/.test(namespace)) {\n return \"project\";\n }\n return \"explicit\";\n}\n\nexport class NamespaceCatalog {\n private readonly memoryDir: string;\n private readonly stateDir: string;\n private readonly catalogPath: string;\n private readonly rebuildLockPath: string;\n // Per-INSTANCE lock owner id (round 6, codex P2 — NBsGP). The rebuild lock\n // file records this id, not just `process.pid`, so two NamespaceCatalog\n // instances in the SAME process sharing a memoryDir are NOT mistaken for each\n // other: a touch on instance B must still wait for instance A's rebuild lock\n // (different owner id, same PID) instead of skipping as \"self-held\".\n private readonly lockOwnerId: string = randomUUID();\n // Serialized write chain that recovers from rejection (CLAUDE.md rule #40)\n // so a single failed append cannot permanently poison subsequent writes.\n private writeChain: Promise<void> = Promise.resolve();\n // Test-only seam (round 7 — NEZkA): fires inside a touch's HELD-lock critical\n // section, after the lock is acquired but BEFORE the read→merge→append. A\n // deterministic concurrency test installs a hook here to widen the (otherwise\n // microscopic) window and prove that a cross-process rebuild CANNOT run its\n // load→rename while a touch holds the lock. Never set in production code.\n protected onTouchCriticalSectionForTest?: () => Promise<void>;\n // Test-only seam (round 7 — NEZkA): fires inside a mutating rebuild's HELD-lock\n // critical section, after the final cross-process re-merge `loadCompacted()` and\n // BEFORE the atomic `rename()`. This is the EXACT window in which a check-then-\n // append touch (the old bug) would clobber its append. A deterministic test\n // installs a hook here to attempt a cross-instance touch in this window and\n // assert the held mutex blocks it. Never set in production code.\n protected onRebuildBeforeRenameForTest?: () => Promise<void>;\n // Test-only seam (NFgCT, codex P2): fires AFTER the lockless disk scan but\n // BEFORE the rebuild acquires the cross-process file lock for its final\n // load→merge→rename window. A deterministic test installs a hook here to attempt\n // a cross-instance touch DURING the scan window and assert it is NOT blocked or\n // dropped — proving the scan no longer holds the mutex. Never set in production.\n protected onRebuildAfterScanForTest?: () => Promise<void>;\n // Test-only seam (NG7Bg, codex P2): fires inside `breakStaleRebuildLock` AFTER it\n // has judged the lock stale and captured its identity, but BEFORE the final\n // re-validation+unlink. A deterministic test installs a hook here to REPLACE the\n // lock file (a fresh holder created a new lock in the race window) and assert the\n // break is skipped — the replacement's active lock is not deleted. Never set in\n // production.\n protected onBeforeBreakStaleUnlinkForTest?: () => Promise<void>;\n\n // Normalized (trimmed) default namespace identity (NH-FH, cursor Medium).\n // Catalog records key namespaces by their NORMALIZED identity\n // (`normalizeNamespaceIdentity`), but several default-namespace exemptions and\n // memoryDir-ownership checks compared against the RAW `config.defaultNamespace`.\n // If the configured default name carries surrounding whitespace the record key\n // is trimmed while the comparison string is not, so the default row is\n // misclassified, dropped at read time, or given the wrong storage root. Compare\n // against this normalized form everywhere instead.\n private readonly defaultNamespaceIdentity: string;\n\n constructor(private readonly config: PluginConfig) {\n this.memoryDir = config.memoryDir;\n this.stateDir = path.join(this.memoryDir, STATE_DIR);\n this.catalogPath = path.join(this.stateDir, CATALOG_FILE);\n this.rebuildLockPath = path.join(this.stateDir, REBUILD_LOCK_FILE);\n this.defaultNamespaceIdentity = normalizeNamespaceIdentity(config.defaultNamespace);\n }\n\n /** Whether the catalog is active (namespaces enabled and catalog not opted out). */\n get enabled(): boolean {\n return isCatalogEnabled(this.config);\n }\n\n // ── Public enumeration API ──────────────────────────────────────────────\n\n /**\n * Sanitize a record at the enumeration boundary (round 5, cursor Medium + codex\n * P2; round 6 — NDXHe). Reads return whatever is in `namespaces.jsonl` after\n * schema checks only, so a tampered or pre-fix row could surface unsafe data to\n * maintenance/QMD until a rewrite occurs. Two distinct defenses:\n *\n * 1. UNSAFE NAMESPACE NAME (NGZqr, codex P2): an unsafe non-default namespace\n * (e.g. `../evil`, a name with separators, or >64 chars) is REJECTED outright\n * — return `null` so the caller drops it. The disk SCAN and the hot touch\n * path both reject such names with the SAME default-exempt `isSafeRouteNamespace`\n * gate, so the read boundary MUST agree, or `listNamespaces()`/`getNamespaceRecord()`\n * would expose a namespace those paths reject (note `isStorageDirForNamespace`\n * can still build a tokenized root even for `../evil`, so storageDir sanitation\n * alone does not catch it). The default namespace is exempt (it may be a\n * non-route literal), matching every other validation site.\n *\n * 2. UNSAFE storageDir: for an otherwise-valid namespace, apply the SAME contract\n * as the write path — full containment (`isContainedStorageDir`: lexical +\n * symlink/realpath) AND namespace ownership (`isStorageDirForNamespace`). When\n * a record fails EITHER check we substitute the trusted resolved-and-safe root\n * for that namespace (rule 42: read and write stay symmetric).\n */\n private async sanitizeRecordForRead(record: NamespaceRecord): Promise<NamespaceRecord | null> {\n // Defense 1: drop an unsafe non-default namespace name entirely. Compare\n // against the NORMALIZED default identity — record keys are trimmed, so a raw\n // whitespace-padded config default would never match the default row (NH-FH).\n if (record.namespace !== this.defaultNamespaceIdentity && !isSafeRouteNamespace(record.namespace)) {\n return null;\n }\n // Defense 2: keep the record but substitute a safe storageDir when needed.\n if (\n (await this.isContainedStorageDir(record.storageDir)) &&\n (await this.isStorageDirForNamespace(record.namespace, record.storageDir))\n ) {\n return record;\n }\n const safe = await this.resolveSafeStorageDir(record.namespace);\n return { ...record, storageDir: safe };\n }\n\n private storageRootOwnershipRank(\n record: NamespaceRecord,\n resolvedStorageDir: string,\n configured: Set<string>,\n ): number {\n if (resolvedStorageDir === path.resolve(this.memoryDir)) {\n return record.namespace === this.defaultNamespaceIdentity ? 0 : 3;\n }\n\n const leaf = path.basename(resolvedStorageDir);\n const tokenOwnsRoot = namespaceIdentityToken(record.namespace) === leaf;\n if (tokenOwnsRoot && configured.has(record.namespace)) {\n return 0;\n }\n if (record.namespace === leaf) return 1;\n if (tokenOwnsRoot) return 2;\n return 3;\n }\n\n private configuredNamespaceIdentities(): Set<string> {\n return new Set(\n [\n this.config.defaultNamespace,\n this.config.sharedNamespace,\n ...this.config.namespacePolicies.map((p) => p.name),\n ]\n .map((n) => normalizeNamespaceIdentity(n))\n .filter((n) => n.length > 0),\n );\n }\n\n private preferStorageRootOwner(\n current: NamespaceRecord,\n candidate: NamespaceRecord,\n resolvedStorageDir: string,\n configured: Set<string>,\n ): NamespaceRecord {\n const currentRank = this.storageRootOwnershipRank(current, resolvedStorageDir, configured);\n const candidateRank = this.storageRootOwnershipRank(candidate, resolvedStorageDir, configured);\n if (candidateRank < currentRank) return candidate;\n if (candidateRank > currentRank) return current;\n\n const byName = candidate.namespace.localeCompare(current.namespace);\n if (byName < 0) return candidate;\n if (byName > 0) return current;\n return candidate.identityToken.localeCompare(current.identityToken) < 0 ? candidate : current;\n }\n\n private dropDuplicateStorageRootAliases(records: NamespaceRecord[]): NamespaceRecord[] {\n const byStorageDir = new Map<string, NamespaceRecord>();\n const configured = this.configuredNamespaceIdentities();\n for (const record of records) {\n const resolvedStorageDir = path.resolve(record.storageDir);\n const current = byStorageDir.get(resolvedStorageDir);\n if (!current) {\n byStorageDir.set(resolvedStorageDir, record);\n continue;\n }\n const owner = this.preferStorageRootOwner(current, record, resolvedStorageDir, configured);\n const alias = owner === current ? record : current;\n byStorageDir.set(resolvedStorageDir, mergeNewerTouchFields(owner, alias));\n }\n return [...byStorageDir.values()];\n }\n\n private async loadSanitizedRecords(): Promise<NamespaceRecord[]> {\n const records = await this.loadCompacted();\n const sanitized = await Promise.all(\n [...records.values()].map((r) => this.sanitizeRecordForRead(r)),\n );\n // Drop unsafe-namespace rows (sanitizer returned null) at the read boundary.\n // Then collapse duplicate root aliases so maintenance/QMD see exactly one\n // namespace owner for a physical storage root, matching rebuild ownership,\n // while preserving touch recency from every alias row.\n return this.dropDuplicateStorageRootAliases(\n sanitized.filter((r): r is NamespaceRecord => r !== null),\n );\n }\n\n async listNamespaces(filter?: NamespaceCatalogFilter): Promise<NamespaceRecord[]> {\n if (!this.enabled) return [];\n let out = await this.loadSanitizedRecords();\n if (filter?.kind) out = out.filter((r) => r.kind === filter.kind);\n if (filter?.discoveredBy) out = out.filter((r) => r.discoveredBy === filter.discoveredBy);\n if (filter?.writtenSince) {\n const sinceMs = filter.writtenSince.getTime();\n out = out.filter((r) => {\n if (!r.lastWriteAt) return false;\n const ms = Date.parse(r.lastWriteAt);\n return Number.isFinite(ms) && ms >= sinceMs;\n });\n }\n // Stable sort: namespace asc, identityToken as deterministic tiebreaker\n // (CLAUDE.md rule #19 — comparator returns 0 only for truly-equal items).\n return out.sort((a, b) => {\n const byName = a.namespace.localeCompare(b.namespace);\n if (byName !== 0) return byName;\n return a.identityToken.localeCompare(b.identityToken);\n });\n }\n\n async getNamespaceRecord(namespace: string): Promise<NamespaceRecord | null> {\n if (!this.enabled) return null;\n const ns = normalizeNamespaceIdentity(namespace);\n return (await this.loadSanitizedRecords()).find((record) => record.namespace === ns) ?? null;\n }\n\n // ── Touch API (cheap, failure-tolerant) ─────────────────────────────────\n\n async markRead(namespace: string, metadata?: NamespaceTouchMetadata): Promise<void> {\n await this.touch(namespace, \"read\", metadata);\n }\n\n async markWrite(namespace: string, metadata?: NamespaceTouchMetadata): Promise<void> {\n await this.touch(namespace, \"write\", metadata);\n }\n\n async markMaintenance(namespace: string, jobName: string, at?: Date): Promise<void> {\n if (typeof jobName !== \"string\" || jobName.trim().length === 0) {\n throw new Error(\"markMaintenance requires a non-empty jobName\");\n }\n await this.touch(namespace, \"maintenance\", { at }, jobName.trim());\n }\n\n /**\n * Register namespaces known purely from config (default, shared, explicit\n * policies). Source `config`. Cheap and idempotent.\n */\n async registerConfiguredNamespaces(): Promise<void> {\n if (!this.enabled) return;\n const names = new Set<string>([\n this.config.defaultNamespace,\n this.config.sharedNamespace,\n ...this.config.namespacePolicies.map((p) => p.name),\n ]);\n for (const ns of names) {\n if (!ns) continue;\n // Skip unsafe configured names (e.g. a `sharedNamespace`/policy name like\n // `../evil`) consistently with `rebuildFromDisk` (round 6, cursor Low —\n // NBn3w). `register`→`validateNamespace` THROWS on unsafe tokens; without\n // this guard one bad name would abort registration of all the rest. The\n // default namespace is exempt (it may be a non-route literal). Each call is\n // also wrapped so a single failure never blocks the remaining names.\n // `names` carries RAW config values, so normalize before the default-exempt\n // check — a whitespace-padded default must still be recognized (NH-FH).\n if (normalizeNamespaceIdentity(ns) !== this.defaultNamespaceIdentity && !isSafeRouteNamespace(ns)) {\n continue;\n }\n try {\n await this.register(ns, { discoveredBy: \"config\" });\n } catch {\n // Best-effort: a single bad/unsafe name must not abort the batch.\n }\n }\n }\n\n /**\n * Register a namespace whose storage was just resolved by the router. Used as\n * the router's integration hook (`discoveredBy: config`). Storage dir is\n * provided so we do not re-resolve it. Failure-tolerant. Returns whether the\n * registration actually APPENDED (round 6, codex P2 — NEFoX), so the router's\n * resolve-hook dedup only marks a namespace notified when it truly persisted —\n * a dropped append (disabled catalog or rebuild-lock-timeout drop) returns\n * `false` and is retried on the next resolve.\n */\n async registerResolved(namespace: string, storageDir: string): Promise<boolean> {\n if (!this.enabled) return false;\n return this.register(namespace, { discoveredBy: \"config\", storageDir });\n }\n\n /**\n * Generic register/touch without changing read/write timestamps unless the\n * source implies it. Validates the namespace and resolves a storage dir.\n * Returns whether the touch actually appended.\n */\n private async register(namespace: string, metadata: NamespaceTouchMetadata): Promise<boolean> {\n return this.touch(namespace, \"register\", metadata);\n }\n\n private validateNamespace(namespace: string): string {\n const ns = normalizeNamespaceIdentity(namespace);\n if (ns.length === 0) throw new Error(\"empty namespace\");\n // The configured default namespace is exempt from isSafeRouteNamespace at\n // the routing layer; honor the same exemption here, but everything still\n // resolves through the contained storage-dir helper below.\n if (ns !== this.defaultNamespaceIdentity && !isSafeRouteNamespace(ns)) {\n throw new Error(`unsafe namespace: ${ns}`);\n }\n return ns;\n }\n\n /**\n * Resolve the on-disk storage dir for a namespace WITHOUT trusting caller\n * input. The default namespace may use the legacy memoryDir root; everything\n * else lives under `<memoryDir>/namespaces/<token>`. Containment is enforced\n * by rejecting separators/parent-refs in the token.\n */\n private resolveStorageDir(namespace: string): string {\n if (normalizeNamespaceIdentity(namespace) === this.defaultNamespaceIdentity) {\n // Default may resolve to the legacy memoryDir root OR a tokenized dir; we\n // report memoryDir here as the canonical default root for the catalog.\n // rebuildFromDisk refines this when a tokenized default dir holds data.\n return this.memoryDir;\n }\n const token = namespaceIdentityToken(namespace);\n return this.namespaceTokenDir(token);\n }\n\n private namespaceTokenDir(token: string): string {\n if (\n token.length === 0 ||\n token.includes(\"/\") ||\n token.includes(\"\\\\\") ||\n token.includes(\"..\") ||\n path.isAbsolute(token)\n ) {\n throw new Error(`unsafe namespace token: ${token}`);\n }\n return path.join(this.memoryDir, \"namespaces\", token);\n }\n\n /**\n * Whether a candidate storage dir is LEXICALLY contained: it is either the\n * legacy default root (`memoryDir`) or a strict descendant of\n * `<memoryDir>/namespaces/`. The router legitimately resolves a namespace to\n * EITHER the tokenized dir or a legacy raw-name dir under `namespaces/`, so we\n * accept any contained child rather than a single exact token path. This is a\n * pure string check — symlink escape is checked separately via realpath.\n */\n private isLexicallyContained(candidate: string): boolean {\n const resolved = path.resolve(candidate);\n if (resolved === path.resolve(this.memoryDir)) return true;\n const nsBase = path.resolve(path.join(this.memoryDir, \"namespaces\"));\n const rel = path.relative(nsBase, resolved);\n // Must be a strict descendant of namespaces/ (non-empty, no parent escape).\n return rel.length > 0 && !rel.startsWith(\"..\") && !path.isAbsolute(rel);\n }\n\n /**\n * Whether a candidate storage dir satisfies the catalog containment contract,\n * including SYMLINK-escape rejection (round 5, codex P2). A lexically-contained\n * path that is actually a symlink to an outside directory would let maintenance\n * or QMD follow it outside `memoryDir`. We mirror `rebuildFromDisk`'s posture:\n * the path must be lexically contained AND, if it exists on disk, neither the\n * path itself a symlink nor its realpath escaping the memory root. Non-existent\n * paths pass the realpath stage (nothing to follow yet) but still must be\n * lexically contained.\n */\n private async isContainedStorageDir(candidate: string): Promise<boolean> {\n if (!this.isLexicallyContained(candidate)) return false;\n // The default/legacy memoryDir root is trusted as-is.\n if (path.resolve(candidate) === path.resolve(this.memoryDir)) return true;\n let memoryReal: string;\n try {\n memoryReal = await realpath(this.memoryDir);\n } catch {\n memoryReal = path.resolve(this.memoryDir);\n }\n // Reject a candidate beneath any SYMLINKED ancestor (codex NVuq5): even when\n // the symlink currently resolves back inside memoryDir, the disk scanner\n // rejects such a root, and a later retarget of the link would let\n // maintenance/QMD follow the persisted path outside memoryDir. Mirror the\n // scanner so touch/config seeding cannot persist a root under a symlinked\n // namespace ancestor (the leaf itself is symlink-checked below).\n if (await this.hasSymlinkedAncestor(candidate)) return false;\n try {\n const stat = await lstat(candidate);\n if (stat.isSymbolicLink()) return false;\n // Reject an EXISTING non-directory root (NF21i, codex P2; CLAUDE.md rule\n // #24). A regular file (or socket/fifo) at `<memoryDir>/namespaces/<token>`\n // is lexically contained and its realpath stays inside memoryDir, so the\n // realpath check below would ACCEPT it — but a storage root must be a\n // directory. Recording a file as a namespace root yields a broken install\n // that only fails later when maintenance/QMD/mkdir treat it as a dir. The\n // disk scan already skips non-directory entries; mirror that here so every\n // containment consumer (resolve/touch/fallback/live-recheck) agrees.\n if (!stat.isDirectory()) return false;\n } catch {\n // The leaf does not exist yet. Lexical containment is NOT sufficient: an\n // EXISTING ancestor (e.g. `<memoryDir>/namespaces`) could be a symlink to\n // outside memoryDir, so a future mkdir/maintenance/QMD op would follow the\n // persisted root outside the root (round 6, codex P2 — NDo79). Verify the\n // nearest EXISTING ancestor's realpath still resolves inside memoryDir.\n return this.isNearestExistingAncestorContained(candidate, memoryReal);\n }\n try {\n const real = await realpath(candidate);\n return isPathInside(memoryReal, real);\n } catch {\n return false;\n }\n }\n\n /**\n * Reject a candidate whose path crosses a SYMLINKED ancestor strictly between\n * memoryDir and the leaf (codex NVuq5). `realpath`-based containment accepts a\n * symlinked `<memoryDir>/namespaces` that currently resolves back inside\n * memoryDir, but the disk scanner rejects such a root and a later retarget would\n * escape the memory tree — so refuse it here too. The leaf itself is\n * symlink-checked by the caller; this walks only the intermediate ancestors.\n */\n private async hasSymlinkedAncestor(candidate: string): Promise<boolean> {\n const stopAt = path.resolve(this.memoryDir);\n let dir = path.dirname(path.resolve(candidate));\n const root = path.parse(dir).root;\n while (dir !== stopAt && dir !== root && dir !== path.dirname(dir)) {\n try {\n if ((await lstat(dir)).isSymbolicLink()) return true;\n } catch {\n // Ancestor does not exist yet — it cannot be a symlink; keep walking up.\n }\n dir = path.dirname(dir);\n }\n return false;\n }\n\n /**\n * Walk up from a not-yet-existing candidate to the nearest ancestor that exists\n * on disk and verify its realpath stays inside `memoryReal` (round 6, codex P2\n * — NDo79). Rejects a non-existent leaf whose existing parent chain escapes\n * memoryDir via a symlink. Stops at memoryDir's resolved root.\n *\n * The nearest existing ancestor must also be a DIRECTORY (NHIdt, codex P2): if\n * an existing parent such as `<memoryDir>/namespaces` is a regular FILE (or\n * socket/fifo), `realpath(parent)` still succeeds and resolves inside memoryDir,\n * so a containment-only check would ACCEPT a leaf that can never be created — you\n * cannot mkdir a child under a file. We `lstat` the nearest existing ancestor and\n * reject when it is not a directory, mirroring the leaf non-directory rejection\n * (NF21i) and the disk scan, so every containment consumer agrees.\n */\n private async isNearestExistingAncestorContained(\n candidate: string,\n memoryReal: string,\n ): Promise<boolean> {\n let dir = path.resolve(candidate);\n const root = path.parse(dir).root;\n for (;;) {\n const parent = path.dirname(dir);\n // Reached the filesystem root without finding an existing ancestor.\n if (parent === dir || dir === root) return false;\n let real: string;\n try {\n real = await realpath(parent);\n } catch {\n // Parent does not exist yet either — keep walking up.\n dir = parent;\n continue;\n }\n // The nearest EXISTING ancestor must resolve inside the memory root...\n if (!(isPathInside(memoryReal, real) || real === memoryReal)) return false;\n // ...AND be a directory: a non-directory ancestor (e.g. a file occupying\n // `namespaces`) cannot hold the not-yet-created leaf (NHIdt).\n try {\n const stat = await lstat(real);\n return stat.isDirectory();\n } catch {\n // The ancestor vanished between realpath and lstat — treat as not usable.\n return false;\n }\n }\n }\n\n /**\n * Resolve the storage dir to persist for a touch, validating any caller-\n * provided `metadata.storageDir` against the catalog containment contract\n * (round 4 + round 5, codex P2). `markWrite`/`registerResolved` accept an\n * explicit storageDir, but persisting it verbatim would let a bad hook or\n * external consumer write an arbitrary path — including one outside `memoryDir`\n * or a symlink that escapes it — into the catalog, handing maintenance/QMD an\n * unsafe root. We accept an explicit (or previously-stored) dir ONLY when it\n * stays contained under memoryDir (lexically AND via realpath); otherwise we\n * drop it and fall back to the trusted resolved dir.\n */\n private async resolveTouchStorageDir(\n namespace: string,\n explicit: string | undefined,\n existingDir: string | undefined,\n ): Promise<string> {\n // An explicit storageDir is accepted ONLY when it is both contained AND\n // actually belongs to THIS namespace (round 6, codex P2 — NDATT). Containment\n // alone let a caller pass another namespace's tree (e.g.\n // `markWrite(\"project-a\", { storageDir: \".../namespaces/<project-b-token>\" })`)\n // or `memoryDir` for a non-default namespace; `listNamespaces()` would then\n // tell maintenance/QMD that `project-a` lives in another namespace's (or the\n // default) tree — a cross-namespace root confusion. We reject a mismatched\n // explicit root and fall back to the namespace's own resolved root.\n if (\n explicit !== undefined &&\n (await this.isContainedStorageDir(explicit)) &&\n (await this.isStorageDirForNamespace(namespace, explicit))\n ) {\n return explicit;\n }\n // Don't let a record poisoned by a pre-fix out-of-containment write keep an\n // unsafe dir alive across touches — only preserve a contained existing dir\n // that also belongs to this namespace.\n if (\n existingDir !== undefined &&\n (await this.isContainedStorageDir(existingDir)) &&\n (await this.isStorageDirForNamespace(namespace, existingDir))\n ) {\n return existingDir;\n }\n return this.resolveSafeStorageDir(namespace);\n }\n\n /**\n * Whether `candidate` is a legitimate storage root FOR `namespace` (round 6,\n * codex P2 — NDATT). Accepts the namespace's router-resolved root, its canonical\n * lexical tokenized dir, and (for the default namespace only) memoryDir. This\n * prevents a contained-but-CROSS-NAMESPACE path — another namespace's tree, or\n * memoryDir for a non-default namespace — from being persisted as this\n * namespace's root. Compared on resolved (absolute) paths.\n */\n private async isStorageDirForNamespace(namespace: string, candidate: string): Promise<boolean> {\n const resolvedCandidate = path.resolve(candidate);\n const valid = new Set<string>();\n // The namespace's canonical lexical TOKENIZED dir is always a valid root.\n try {\n valid.add(path.resolve(this.namespaceTokenDir(namespaceIdentityToken(namespace))));\n } catch {\n // Unsafe token cannot build a lexical dir; fall through to other roots.\n }\n // The namespace's legacy RAW-NAME dir (`namespaces/<rawname>`) is also a\n // valid root — the router serves data from it when present, even before any\n // dir exists on disk. Both forms belong to THIS namespace, never another's.\n try {\n valid.add(path.resolve(this.namespaceTokenDir(namespace)));\n } catch {\n // Unsafe raw name cannot build a lexical dir; rely on the other roots.\n }\n // The router-resolved root (whichever of the above it currently serves, a\n // migrated default, etc.).\n try {\n valid.add(path.resolve(await resolveNamespaceStorageRoot(this.config, namespace)));\n } catch {\n // Router resolution failed; rely on the lexical/default roots below.\n }\n // memoryDir is a valid root ONLY for the default namespace.\n if (normalizeNamespaceIdentity(namespace) === this.defaultNamespaceIdentity) {\n valid.add(path.resolve(this.memoryDir));\n try {\n valid.add(path.resolve(await resolveDefaultNamespaceRoot(this.config)));\n } catch {\n // ignore; memoryDir already covers the common default case.\n }\n }\n return valid.has(resolvedCandidate);\n }\n\n /**\n * Resolve the canonical storage dir for a namespace as the LIVE ROUTER would,\n * but NEVER return a path that escapes the memory root.\n *\n * Router alignment (round 4, cursor Medium): a read/register touch with no\n * explicit storageDir previously used the lexical `resolveStorageDir`, which\n * always picks `<memoryDir>/namespaces/<token>` (or `memoryDir` for the\n * default). That diverges from `NamespaceStorageRouter`, which can route to a\n * legacy raw-name dir or a migrated default root — so a recall touch could\n * record a contained-but-WRONG root that maintenance/rebuild then targets. We\n * now delegate to the shared `resolveNamespaceStorageRoot` (the very helper the\n * router uses) so the catalog records the same on-disk root the router serves.\n *\n * Containment (round 5, codex P2): the resolved path can still be a symlink\n * escaping memoryDir, so we run the full (lexical + realpath) containment\n * contract. When it FAILS we fall back to a NAMESPACE-SPECIFIC safe root, NOT\n * a blanket `memoryDir`. Recording `memoryDir` for a non-default namespace\n * would point enumeration/maintenance at the DEFAULT namespace's tree (round 5,\n * cursor/codex Medium/P2) — a cross-namespace fanout error. The correct safe\n * root is the namespace's own lexical tokenized dir\n * (`<memoryDir>/namespaces/<token>`), which is always contained and is that\n * namespace's canonical location (we record the lexical PATH as metadata; we do\n * not follow the escaping symlink). Only the default namespace — or a token so\n * unsafe even the lexical dir cannot be built — falls back to `memoryDir`.\n */\n private async resolveSafeStorageDir(namespace: string): Promise<string> {\n let resolved: string;\n try {\n resolved = await resolveNamespaceStorageRoot(this.config, namespace);\n } catch {\n return this.safeFallbackStorageDir(namespace);\n }\n if (await this.isContainedStorageDir(resolved)) return resolved;\n return this.safeFallbackStorageDir(namespace);\n }\n\n /**\n * The namespace-specific contained fallback root, used when the router-resolved\n * root fails containment (round 5, cursor/codex Medium/P2).\n *\n * Preference order:\n * 1. The namespace's OWN lexical tokenized dir (`namespaces/<token>`) — so a\n * non-default namespace is NOT pointed at the DEFAULT namespace's `memoryDir`\n * tree (which would misdirect maintenance fanout). Returned only when the\n * token dir itself stays CONTAINED (it is not a symlink, and its realpath\n * does not escape memoryDir — e.g. via a symlinked `namespaces/` parent).\n * 2. `memoryDir` as a LAST resort — for the default namespace, an unsafe token\n * that cannot build a contained path, OR the irreparable case where the\n * token dir's realpath escapes the root (so even its lexical path resolves\n * outside). NF21m note (codex P2): we deliberately do NOT record the lexical\n * token dir in that irreparable case — its realpath escapes memoryDir, and\n * the NDo79 contract REQUIRES that an escaping path is never persisted (a\n * later mkdir/maintenance/QMD op would follow it outside the root). Since no\n * contained namespace-specific path exists, containment wins: `memoryDir` is\n * the only safe root left. A namespace whose token dir's realpath escapes is\n * an irreparable on-disk state; recording the contained default root is\n * strictly safer than persisting an escaping one. The common case where the\n * token dir IS contained is handled by branch 1, so a healthy non-default\n * namespace never reaches `memoryDir`.\n */\n private async safeFallbackStorageDir(namespace: string): Promise<string> {\n if (normalizeNamespaceIdentity(namespace) === this.defaultNamespaceIdentity) return this.memoryDir;\n let tokenDir: string;\n try {\n tokenDir = this.namespaceTokenDir(namespaceIdentityToken(namespace));\n } catch {\n return this.memoryDir;\n }\n if (await this.isContainedStorageDir(tokenDir)) return tokenDir;\n return this.memoryDir;\n }\n\n /**\n * Re-check, NOW, whether a namespace's storage root currently EXISTS on disk\n * with the SAME safety the directory scan uses (NFJV8, codex P2).\n *\n * The rebuild's final re-merge runs under the held lock and folds the freshly\n * re-read log (`latest`) into the scanned `rebuilt` set. A namespace present in\n * `latest` (a live touch row) but ABSENT from `rebuilt` is normally PURGED as\n * deleted (the NATqU \"disk scan is authoritative\" rule). But there is a TOCTOU\n * window: a dynamic namespace can be CREATED on disk AFTER `rebuildFromDisk()`\n * already enumerated `namespaces/` but BEFORE this re-merge. The scan snapshot\n * missed its new root, yet a gateway `markWrite` already appended a row for it.\n * Blindly purging that row would rewrite the catalog WITHOUT a live namespace\n * that now has data on disk, so `writtenSince`/maintenance/QMD consumers miss\n * it until another touch or rebuild.\n *\n * So before purging, we re-resolve the namespace's safe storage root (the same\n * router-aligned, containment-checked path the scan would have catalogued) and\n * confirm it is a real, contained, non-symlink directory that actually holds\n * memory data RIGHT NOW. If so the namespace was created-after-scan and is LIVE\n * — KEEP its row. This is the precise inverse of NATqU and does NOT reintroduce\n * it: a touch on a REMOVED root re-checks as ABSENT (no data on disk) and is\n * still purged; only a root that EXISTS on a fresh re-check is kept.\n *\n * Mirrors the per-entry scan checks (symlink rejection + realpath containment +\n * `hasMemoryData`) so a symlinked/escaping root is never resurrected.\n */\n private async liveStorageRootExistsForRebuild(\n namespace: string,\n memoryReal: string | null,\n ): Promise<boolean> {\n let root: string;\n try {\n // Use the SAME router-aligned, containment-enforcing resolver the catalog\n // uses everywhere else. It never returns an escaping path (falls back to a\n // namespace-specific contained root on containment failure).\n root = await this.resolveSafeStorageDir(namespace);\n } catch {\n return false;\n }\n // NH3Xy (codex P2): for a NON-default namespace, a generic fallback root is\n // NOT proof of liveness. When the namespace's own token root was skipped by\n // the scan as a symlink/escape, `resolveSafeStorageDir` can fall back to the\n // DEFAULT namespace's `memoryDir`; `hasMemoryData()` on that shared default\n // tree then returns true whenever the default namespace has any data, which\n // would wrongly KEEP a stale project row now pointing at the default tree\n // instead of purging the skipped namespace. Only the namespace's OWN root may\n // attest its liveness — so if a non-default namespace resolved to `memoryDir`,\n // it has no independent contained root and must be treated as absent (purge).\n if (\n normalizeNamespaceIdentity(namespace) !== this.defaultNamespaceIdentity &&\n path.resolve(root) === path.resolve(this.memoryDir)\n ) {\n return false;\n }\n let stat;\n try {\n stat = await lstat(root);\n } catch {\n // Root does not exist on disk → genuinely absent → allow the purge.\n return false;\n }\n // Reject a symlinked root rather than resurrecting it (scan parity).\n if (stat.isSymbolicLink()) return false;\n if (!stat.isDirectory()) return false;\n // Realpath must stay inside the memory root (scan parity).\n try {\n const real = await realpath(root);\n if (memoryReal && !isPathInside(memoryReal, real)) return false;\n } catch {\n return false;\n }\n // Only treat the root as a live namespace when it actually holds memory data,\n // exactly as the scan does (empty shells are not catalogued).\n return hasMemoryData(root);\n }\n\n /**\n * Record a namespace touch. Returns whether the touch actually APPENDED to the\n * log (round 6, codex P2 — NEFoX): a disabled catalog or a dropped append (the\n * NAUf7 rebuild-lock-timeout drop) returns `false`, so callers (e.g. the router\n * resolve-hook dedup) can avoid marking a dropped registration as completed and\n * suppressing its retry.\n */\n private async touch(\n namespace: string,\n kind: \"read\" | \"write\" | \"maintenance\" | \"register\",\n metadata?: NamespaceTouchMetadata,\n jobName?: string,\n ): Promise<boolean> {\n if (!this.enabled) return false;\n // Validate up front (outside the chain) so caller-facing rejections — e.g.\n // an unsafe namespace token — surface immediately and deterministically,\n // not interleaved with serialized I/O.\n const ns = this.validateNamespace(namespace);\n const nowIso = (metadata?.at ?? new Date()).toISOString();\n\n // Run the read → merge → append as a single serialized critical section so\n // two concurrent touches for the same namespace cannot both observe the same\n // stale record and then have the later append win compaction while dropping\n // the earlier touch's fields (CLAUDE.md rule #40 — the chain also recovers\n // from rejection). Reading inside the chain guarantees each touch sees the\n // most recent appended state, including any concurrent read/write/register.\n // Cross-process serialization (round 7, codex P2 — NEZkA: HELD MUTEX). A CLI\n // `rebuild --apply` holds the rebuild lock across its final `loadCompacted()`\n // → atomic `rename`. Previously a touch only POLLED (`waitForRebuildLockClear`)\n // for the lock before reading/appending WITHOUT holding it — a check-then-act\n // gap: a touch could see no lock, a rebuild could then acquire the lock + run\n // its final `loadCompacted()`, and the touch's later append would be clobbered\n // by the rebuild's `rename()`. We now make the touch HOLD the SAME advisory\n // lock for the WHOLE read → merge → append window. While the touch holds the\n // lock, a rebuild in another process blocks on it (and vice-versa), so no\n // append can land between a rebuild's final load and its rename. `queueCritical`\n // serializes this within ONE process (so the OS lock is never self-contended in\n // process); the file lock adds the missing CROSS-process exclusion. If the touch\n // cannot ACQUIRE the lock within the bounded wait (another process's rebuild is\n // mid-flight), it DROPS the append: the catalog is rebuildable best-effort\n // metadata, so skipping one touch is acceptable; it NEVER blocks forever, NEVER\n // appends without the lock, and NEVER crashes the primary memory op.\n return this.queueCritical(async () =>\n this.withHeldCatalogLock(async (acquired) => {\n // Could not hold the lock (a cross-process rebuild is in its load→rename\n // window). DROP rather than append into that window (the lost-append race\n // this lock exists to prevent). Returning false also lets the router's\n // resolve-hook dedup retry a dropped registration later.\n if (!acquired) return false;\n\n // Test-only seam: widen the held-lock window so a concurrency test can\n // attempt a cross-process rebuild here and assert it is BLOCKED by this\n // held lock (no-op in production).\n if (this.onTouchCriticalSectionForTest) {\n await this.onTouchCriticalSectionForTest();\n }\n\n const records = await this.loadCompacted();\n const existing = records.get(ns);\n\n // Containment-check any explicit storageDir before persisting it (round 4\n // + round 5, codex P2). Never trust a caller-provided path verbatim;\n // reject lexical escapes AND symlinks that escape via realpath.\n const storageDir = await this.resolveTouchStorageDir(\n ns,\n metadata?.storageDir,\n existing?.storageDir,\n );\n // Provenance (discoveredBy) and createdAt are CREATION-ONLY fields. Once a\n // record exists they are preserved, so a routine routing/recall touch (or\n // the router's `config` register hook firing on a cache hit) can never\n // clobber the original discovery source — e.g. a `write`-discovered record\n // is not reset to `config` by a later resolve. Touch fields (lastReadAt /\n // lastWriteAt / lastMaintenanceAt) still update on every touch below.\n const record: NamespaceRecord = existing\n ? { ...existing }\n : {\n namespace: ns,\n identityToken: namespaceIdentityToken(ns),\n kind: metadata?.kind ?? inferKind(ns, this.config),\n createdAt: nowIso,\n storageDir,\n discoveredBy:\n metadata?.discoveredBy ??\n (kind === \"register\" ? \"config\" : kind === \"maintenance\" ? \"scan\" : kind),\n };\n\n // Update mutable fields. storageDir, kind, and the principal/project hints\n // may legitimately change over a namespace's lifetime, so they upsert.\n record.storageDir = storageDir;\n if (metadata?.kind) record.kind = metadata.kind;\n if (metadata?.principal !== undefined) record.principal = metadata.principal;\n if (metadata?.projectId !== undefined) record.projectId = metadata.projectId;\n if (metadata?.branch !== undefined) record.branch = metadata.branch;\n if (metadata?.parentNamespace !== undefined)\n record.parentNamespace = metadata.parentNamespace;\n // PROVENANCE (creation-only, with one upgrade — round 6, codex P2 NBPmT):\n // `discoveredBy` is otherwise preserved for existing records (a routine\n // read/register/resolve never relabels it). The single exception is a real\n // WRITE upgrading a record that was only PRE-REGISTERED by the router's\n // `onResolve` hook (`discoveredBy: \"config\"`) before any data was written.\n // Without this upgrade, `listNamespaces({ discoveredBy: \"write\" })` misses\n // namespaces that were genuinely written, because `storageFor()` fires\n // `registerResolved()` (config) before `recordCatalogWrite()` runs. We\n // upgrade ONLY config→write — never downgrade write/read, never relabel a\n // read-discovered record — so the authoritative \"this namespace has been\n // written\" signal is recorded.\n if (kind === \"write\" && existing && record.discoveredBy === \"config\") {\n record.discoveredBy = \"write\";\n }\n\n if (kind === \"read\") record.lastReadAt = nowIso;\n if (kind === \"write\") record.lastWriteAt = nowIso;\n if (kind === \"maintenance\" && jobName) {\n record.lastMaintenanceAt = { ...(record.lastMaintenanceAt ?? {}), [jobName]: nowIso };\n }\n\n await this.appendUnchained(record);\n return true;\n }),\n );\n }\n\n // ── Rebuild from disk ────────────────────────────────────────────────────\n\n async rebuildFromDisk(\n options?: { dryRun?: boolean },\n ): Promise<NamespaceCatalogRebuildResult> {\n const dryRun = options?.dryRun === true;\n if (!this.enabled) {\n return { dryRun, records: [], skipped: [], applied: false };\n }\n\n // CONCURRENCY (Issue A — round 2): the entire scan → merge → rewrite runs\n // inside ONE serialized critical section on the shared write chain. This\n // closes the round-1 residual risk where a hot-path markRead/markWrite/\n // registerResolved append could land AFTER the snapshot but BEFORE the\n // atomic rewrite and then be discarded by the rewrite. Because touches also\n // run through `queueCritical`, no append can interleave between the load\n // (which now reads the latest persisted state, including touches that\n // landed before this section started) and the rewrite. A `--dry-run` still\n // takes the section for a consistent read but performs no mutation.\n //\n // Deadlock note: the rewrite inside this section uses the unchained\n // `rewriteUnchained` helper (mirroring `appendUnchained`) rather than a\n // helper that re-enters `queueCritical` — re-entering the chain from inside\n // a held turn would await the very entry this section holds.\n //\n // CROSS-PROCESS (round 5, codex P2): `queueCritical` only serializes this\n // process's instance. A CLI `rebuild --apply` and the live gateway are\n // SEPARATE processes with independent write chains, so a gateway append can\n // still land between the CLI's load and its atomic rename. For the mutating\n // path we additionally take a cross-process file lock AND re-merge the latest\n // on-disk touches under that lock immediately before the rewrite (see\n // `rebuildInsideChain`). A dry-run never mutates, so it skips the lock.\n if (dryRun) {\n return this.queueCritical(async () => this.rebuildInsideChain(dryRun, false));\n }\n // A mutating rebuild HOLDS the same advisory lock that touches now hold (round\n // 7, codex P2 — NEZkA). Because the touch path acquires this lock across its\n // read→append window and the rebuild holds it across its final\n // `loadCompacted()` → `rename()`, the two are mutually exclusive cross-process:\n // no touch append can land between a rebuild's final load and its rename.\n //\n // SCOPED MUTEX (NFgCT, codex P2): the lock is acquired ONLY around the final\n // load→merge→rename window, NOT the (potentially long) disk scan. The scan does\n // not mutate, so holding the lock across it merely forces concurrent gateway\n // touches to wait — and they DROP their append after `REBUILD_LOCK_MAX_WAIT_MS`,\n // losing real `lastWriteAt`/new-namespace data the rewrite then misses. Keeping\n // the scan lockless shrinks the window in which a touch must contend with the\n // rebuild to just the final critical section, which is brief. `rebuildInsideChain`\n // acquires `withHeldCatalogLock` itself, immediately before its re-merge+rewrite.\n //\n // LOCK ORDERING (round 7 — NEZkA): the file lock is acquired INSIDE\n // `queueCritical`, identically to the touch path (`queueCritical` → file lock),\n // NOT around it. A consistent acquire order is what prevents an in-process\n // deadlock between a same-instance touch and rebuild: `queueCritical` fully\n // serializes the two turns in this process, so when one turn holds the file\n // lock the other is not even running — the OS lock is never self-contended\n // in-process and a same-instance touch never stalls/drops behind its own\n // rebuild. The file lock therefore adds ONLY the missing cross-process\n // exclusion. `rebuildInsideChain` still runs entirely inside `queueCritical`;\n // it just narrows the cross-process file lock to the final rewrite window.\n return this.queueCritical(async () => this.rebuildInsideChain(dryRun, true));\n }\n\n /**\n * Body of `rebuildFromDisk`, run inside a single `queueCritical` turn. MUST\n * only be invoked from within the serialized chain so the load and the\n * rewrite are atomic with respect to concurrent touches (in-process).\n *\n * `wantMutate` is true for an `--apply` (the caller intends to rewrite). The\n * cross-process file lock is acquired LATE — only around the final\n * load→merge→rename window (NFgCT, codex P2) — never across the disk scan, so a\n * long scan does not force concurrent gateway touches to wait (and drop their\n * append). Whether the rewrite actually happened is reported via the result's\n * `applied`: true only when `wantMutate` AND the lock was acquired.\n */\n private async rebuildInsideChain(\n dryRun: boolean,\n wantMutate: boolean,\n ): Promise<NamespaceCatalogRebuildResult> {\n // Read the LATEST persisted state inside the chain so any touch that landed\n // before this turn is folded in (and re-merged into the rewrite below).\n const existing = await this.loadCompacted();\n const skipped: NamespaceCatalogSkippedRoot[] = [];\n const rebuilt = new Map<string, NamespaceRecord>();\n const nowIso = new Date().toISOString();\n\n let memoryReal: string | null = null;\n try {\n memoryReal = await realpath(this.memoryDir);\n } catch {\n memoryReal = this.memoryDir;\n }\n\n // 1) Configured namespaces always belong in the catalog.\n //\n // NORMALIZE FIRST (NGnek, codex P2): the live router normalizes every namespace\n // via `normalizeNamespaceIdentity` (a trim) in `storageFor()` before resolving\n // storage, and `isSafeRouteNamespace` also trims before validating. So a\n // configured name with harmless surrounding whitespace (e.g.\n // `sharedNamespace: \"shared \"` or a policy name copied with a trailing space)\n // would otherwise seed a catalog row for the RAW string and resolve a\n // `namespaces/shared ` root the live reads/writes never use — pointing\n // maintenance/QMD at the wrong directory after `rebuild --apply`. We normalize\n // configured names here so the catalog seeds the SAME identity the router uses\n // (rule #42: read/write resolve through the same normalization). The default\n // namespace is normalized too and compared via its normalized form (`defaultNs`)\n // wherever a configured/scanned name is matched against it below.\n const defaultNs = normalizeNamespaceIdentity(this.config.defaultNamespace);\n const configured = new Set<string>(\n [\n this.config.defaultNamespace,\n this.config.sharedNamespace,\n ...this.config.namespacePolicies.map((p) => p.name),\n ]\n .map((n) => normalizeNamespaceIdentity(n))\n .filter((n) => n.length > 0),\n );\n\n // 2) Default-root alignment (Issue C — round 2): the catalog's default\n // record MUST point at the SAME root the runtime router resolves, or\n // maintenance/QMD consumers would read a different default root than\n // live reads. We delegate to the shared `resolveDefaultNamespaceRoot`\n // (the very helper the router uses) instead of reimplementing divergent\n // \"prefer tokenized dir if it has data\" logic — while legacy data lives\n // directly under memoryDir, this returns memoryDir, matching runtime.\n const resolvedDefaultRoot = await resolveDefaultNamespaceRoot(this.config);\n // CONTAINMENT (round 6, codex P2 — NEOFS): `resolveDefaultNamespaceRoot()` can\n // return a `namespaces/<default-token>` symlink escaping memoryDir when the\n // legacy default root is empty. The default record must never carry an\n // escaping `storageDir`; fall back to the trusted `memoryDir` root when the\n // resolved one fails containment. Computed ONCE so every later use (the\n // configured-seeding step and the scan's default-dir re-apply) stays safe.\n const defaultStorageDir = (await this.isContainedStorageDir(resolvedDefaultRoot))\n ? resolvedDefaultRoot\n : this.memoryDir;\n const legacyDefaultHasData = defaultStorageDir === this.memoryDir;\n\n for (const ns of configured) {\n if (!ns) continue;\n // SAFETY (round 6, codex P2 — NBPmO): `parseConfig` intentionally preserves\n // unsafe namespace strings (e.g. a `sharedNamespace`/`namespacePolicies[]`\n // name like `../evil`) so sinks reject them. The hot touch/scan paths\n // already reject via `isSafeRouteNamespace`; rebuild must NOT be the path\n // that admits an unsafe configured namespace into the catalog. The default\n // namespace is exempt (it may be a non-route literal), matching the scan\n // loop's exemption below.\n if (ns !== defaultNs && !isSafeRouteNamespace(ns)) {\n let token: string;\n try {\n token = namespaceIdentityToken(ns);\n } catch {\n token = ns;\n }\n skipped.push({ token, reason: \"unsafe\", detail: ns });\n continue;\n }\n // ROUTER ALIGNMENT (round 6, codex P2 — NDxiS): seed a configured\n // non-default namespace with the SAME root the runtime router resolves, not\n // a blanket tokenized dir. `resolveNamespaceStorageRoot` returns the legacy\n // RAW root when it exists and only prefers the tokenized root when that has\n // storage markers — so a configured namespace with an empty legacy raw root\n // (e.g. `namespaces/shared`) is catalogued at the runtime path, keeping\n // maintenance/QMD aligned with live reads. Falls back to the lexical token\n // dir if router resolution fails.\n let storageDir: string;\n if (ns === defaultNs) {\n storageDir = defaultStorageDir;\n } else {\n try {\n storageDir = await resolveNamespaceStorageRoot(this.config, ns);\n } catch {\n storageDir = this.namespaceTokenDir(namespaceIdentityToken(ns));\n }\n }\n // CONTAINMENT (round 6, codex P2 — NCzT4/NEOFS): verify the seeded path does\n // not ESCAPE memoryDir before recording it. The scan below rejects\n // escaping/symlinked roots, but this seeding runs FIRST, so without this\n // check rebuild would persist an escaping `storageDir`. `isContainedStorageDir`\n // enforces the full lexical + symlink + realpath contract and allows a\n // not-yet-created path (a brand-new configured namespace seeds its canonical\n // root). The DEFAULT namespace is also checked (NEOFS): if\n // `resolveDefaultNamespaceRoot()` returns a `namespaces/<default-token>`\n // symlink escaping memoryDir, we must NOT persist it. The default cannot be\n // \"skipped\" (it must always exist), so it falls back to the trusted\n // `memoryDir` root; a non-default namespace is skipped (escape).\n if (!(await this.isContainedStorageDir(storageDir))) {\n if (ns === defaultNs) {\n storageDir = this.memoryDir;\n } else {\n skipped.push({ token: namespaceIdentityToken(ns), reason: \"escape\", detail: storageDir });\n continue;\n }\n }\n rebuilt.set(\n ns,\n this.mergeForRebuild(existing.get(ns), {\n namespace: ns,\n identityToken: namespaceIdentityToken(ns),\n kind: inferKind(ns, this.config),\n createdAt: existing.get(ns)?.createdAt ?? nowIso,\n storageDir,\n discoveredBy: \"config\",\n }),\n );\n }\n\n // 3) Scan the namespaces/ directory for tokenized roots.\n const namespacesDir = path.join(this.memoryDir, \"namespaces\");\n let entries: Dirent[] = [];\n // CONTAINMENT (round 8, codex P2 — NE9K_): check the `namespaces` ROOT itself\n // BEFORE `readdir` follows it. If `<memoryDir>/namespaces` is a symlink (or its\n // realpath escapes memoryDir), `readdir()` would enumerate an arbitrary outside\n // tree — leaking names or spending time on a huge directory — even though the\n // catalog rejects symlinked/escaping per-entry roots. The per-entry lstat/realpath\n // checks below run AFTER the readdir, so they cannot prevent following an\n // escaping ROOT. We lstat the root: if it is a symlink, OR its realpath escapes\n // memoryDir, we DO NOT read it and report it as a single unsafe scan root.\n let namespacesDirSafe = true;\n try {\n const rootStat = await lstat(namespacesDir);\n if (rootStat.isSymbolicLink()) {\n namespacesDirSafe = false;\n } else {\n const realNamespacesDir = await realpath(namespacesDir);\n if (memoryReal && !isPathInside(memoryReal, realNamespacesDir)) {\n namespacesDirSafe = false;\n }\n }\n } catch {\n // The `namespaces` dir does not exist yet (or lstat failed): nothing to scan,\n // and there is no symlink to follow. Treat as an empty, safe scan.\n namespacesDirSafe = true;\n }\n if (!namespacesDirSafe) {\n skipped.push({ token: \"namespaces\", reason: \"symlink\", detail: namespacesDir });\n } else {\n try {\n entries = await readdir(namespacesDir, { withFileTypes: true });\n } catch {\n entries = [];\n }\n }\n\n // Dual-root alignment (round 5, cursor Medium): when both a legacy raw-name\n // dir and a tokenized dir hold data for the SAME namespace, the router\n // prefers the tokenized root. Track which scanned namespaces were already\n // sourced from their tokenized dir so a later legacy-named `readdir` entry\n // cannot overwrite the tokenized record (and vice-versa: a tokenized entry\n // always wins over a previously-set legacy one).\n const scannedFromTokenized = new Set<string>();\n\n for (const entry of entries) {\n const token = entry.name;\n const fullPath = path.join(namespacesDir, token);\n // Reject symlinks / escaping roots rather than trusting them.\n let stat;\n try {\n stat = await lstat(fullPath);\n } catch (err) {\n skipped.push({ token, reason: \"error\", detail: err instanceof Error ? err.message : String(err) });\n continue;\n }\n if (stat.isSymbolicLink()) {\n skipped.push({ token, reason: \"symlink\", detail: fullPath });\n continue;\n }\n if (!stat.isDirectory()) continue;\n // Containment: realpath must stay inside the memory root.\n try {\n const real = await realpath(fullPath);\n if (memoryReal && !isPathInside(memoryReal, real)) {\n skipped.push({ token, reason: \"escape\", detail: real });\n continue;\n }\n } catch (err) {\n skipped.push({ token, reason: \"error\", detail: err instanceof Error ? err.message : String(err) });\n continue;\n }\n\n // Decode the namespace from the dir name. A configured dir name is used\n // verbatim. Otherwise decode a genuine tokenized dir back to its identity,\n // falling back to the raw dir name when it is not a decodable token.\n //\n // NDATN note (round 6, codex P2): a raw dir literally named like a CANONICAL\n // token (e.g. `namespaces/ns-616c706861`, the canonical token of `alpha`) is\n // inherently ambiguous from disk alone — the bytes are identical whether the\n // namespace is `alpha` (in its tokenized dir) or the literal `ns-616c706861`\n // (in a raw dir). Decoding a canonical token is the correct default. The\n // unambiguous fix lives on the WRITE path, where the caller knows the true\n // namespace and records it verbatim (NCQI0); the scanner cannot recover a\n // name the encoding cannot distinguish, so we keep the canonical decode.\n //\n // NRcCD (round 9, codex P2 — same class as namespaceFromStorageDir/NRCve):\n // the canonical decode is WRONG when a namespace LITERALLY named like the\n // token already OWNS this root. A dynamic namespace served from a legacy raw\n // root `namespaces/ns-616c706861` (named verbatim `ns-616c706861`) records a\n // catalog row from the write path; that row is in `existing` (the prior\n // load) here. If we still decoded to `alpha`, this scan would emit an `alpha`\n // row at `fullPath`, and the final live-row remerge in `finishRebuild` would\n // re-add the literal `ns-616c706861` row (its root still has data) — leaving\n // TWO catalog rows at the SAME `storageDir`, fanning QMD/maintenance out under\n // the wrong namespace. So, mirroring `namespaceFromStorageDir`'s \"config/catalog\n // match before decode\" rule, prefer the LITERAL dir name when it is already a\n // KNOWN namespace — configured OR present as a live/cataloged row in `existing`\n // — and DO NOT also emit the decoded alias for that same root. A genuine\n // tokenized dir with no literal owner (no `existing` row keyed by the raw\n // token) still decodes as before.\n // Root ownership (codex r3499938974): preserving the literal must be\n // ROOT-based, not just key-based. A STALE cataloged row merely NAMED like\n // the token (but whose storageDir is NOT this `fullPath`) must NOT win — a\n // real dynamic `alpha` write served from this tokenized root would then be\n // rebuilt under the stale literal name and the fresh `alpha` row dropped by\n // the owned-by-other guard. So only prefer the literal when a CONFIGURED\n // name matches OR an existing cataloged row named `token` actually OWNS this\n // `fullPath`. A genuine tokenized root with no literal owner decodes.\n const literalRecord = existing.get(token);\n const literalOwnsRoot =\n configured.has(token) ||\n (literalRecord !== undefined &&\n path.resolve(literalRecord.storageDir) === path.resolve(fullPath));\n // Match `storageFor()`'s canonical namespace identity. A raw root whose\n // spelling trims to another namespace (for example `namespaces/shared `)\n // is not a routeable live root and must not be catalogued from disk.\n const tokenDecoded = literalOwnsRoot ? null : namespaceIdentityFromToken(token);\n const rawDecoded = tokenDecoded && tokenDecoded.length > 0 ? tokenDecoded : token;\n const decoded = normalizeNamespaceIdentity(rawDecoded);\n if (decoded.length === 0 || rawDecoded !== decoded) {\n skipped.push({ token, reason: \"unsafe\", detail: rawDecoded });\n continue;\n }\n if (decoded !== defaultNs && !isSafeRouteNamespace(decoded)) {\n skipped.push({ token, reason: \"unsafe\", detail: decoded });\n continue;\n }\n // Only catalog roots that actually hold memory data (skip empty shells).\n // A malformed PRESENT marker is different from an absent marker: if\n // `facts/` is a file/symlink but `state/` is valid, cataloging the root\n // would later make catalog-driven QMD scan the bad category directory and\n // throw. Reject the whole root on the first malformed known marker.\n const memoryData = await inspectMemoryDataRoot(fullPath);\n if (memoryData.invalidMarker) {\n skipped.push({\n token,\n reason: \"unsafe\",\n detail: `invalid memory marker: ${memoryData.invalidMarker}`,\n });\n continue;\n }\n if (!memoryData.hasData) continue;\n\n // Default-root alignment (Issue C): never let a tokenized default dir\n // overwrite the configured default's storageDir with `fullPath`. The\n // default record's root is owned by `resolveDefaultNamespaceRoot` above,\n // which mirrors the router. We still keep the default record (set in\n // step 1) but skip clobbering its root here.\n if (decoded === defaultNs) {\n const def = rebuilt.get(defaultNs);\n if (def) {\n def.storageDir = defaultStorageDir;\n def.kind = \"default\";\n }\n continue;\n }\n\n // Dual-root preference: mirror the router, which uses the tokenized root\n // over a legacy raw-name root when the tokenized one has data. `entry.name`\n // is the on-disk dir name; it is the tokenized dir iff it equals the\n // namespace's identity token. If we already recorded this namespace from\n // its tokenized dir, a later legacy-named entry must not clobber it.\n const isTokenizedEntry = token === namespaceIdentityToken(decoded);\n if (rebuilt.has(decoded) && scannedFromTokenized.has(decoded) && !isTokenizedEntry) {\n continue;\n }\n if (isTokenizedEntry) scannedFromTokenized.add(decoded);\n\n const prior = existing.get(decoded);\n rebuilt.set(\n decoded,\n this.mergeForRebuild(prior, {\n namespace: decoded,\n identityToken: namespaceIdentityToken(decoded),\n kind: inferKind(decoded, this.config),\n createdAt: prior?.createdAt ?? nowIso,\n storageDir: fullPath,\n // Configured-and-present namespaces keep config provenance; purely\n // discovered ones are scan.\n discoveredBy: configured.has(decoded) ? \"config\" : prior?.discoveredBy ?? \"scan\",\n }),\n );\n }\n\n // Mark legacy default root explicitly when applicable.\n if (legacyDefaultHasData && defaultStorageDir === this.memoryDir) {\n const def = rebuilt.get(defaultNs);\n if (def) def.kind = \"default\";\n }\n\n // ── Final critical section (SCOPED MUTEX — NFgCT, codex P2) ──────────────\n // The disk scan above ran LOCKLESS (it only reads). Now, for a mutating\n // rebuild, acquire the cross-process file lock ONLY for the\n // load→merge→rename window — the brief section a concurrent touch must be\n // excluded from. `canMutate` is true iff we ACTUALLY hold the lock: if\n // acquisition timed out (`acquired === false`) we run compute-only and never\n // re-merge+rewrite unlocked (which would race a concurrent lock holder and\n // recreate the lost-append window). A dry-run skips the lock entirely.\n if (!wantMutate) {\n return this.finishRebuild(rebuilt, skipped, dryRun, false, memoryReal, nowIso);\n }\n // Test-only seam: the SCAN is now complete but the cross-process lock has NOT\n // yet been acquired (NFgCT). A concurrency test attempts a cross-instance touch\n // here and asserts it is NOT blocked/dropped — proving the scan is lockless.\n if (this.onRebuildAfterScanForTest) {\n await this.onRebuildAfterScanForTest();\n }\n return this.withHeldCatalogLock((acquired) =>\n this.finishRebuild(rebuilt, skipped, dryRun, acquired, memoryReal, nowIso),\n );\n }\n\n /**\n * Final load→merge→rename window of a rebuild, factored out so the caller can\n * run it WITHIN the cross-process file lock (NFgCT, codex P2) without holding\n * that lock across the preceding disk scan. Re-reads the latest on-disk state,\n * folds concurrent touches, then (when `canMutate`) atomically rewrites the log.\n *\n * `canMutate` records that the cross-process lock was actually held. The\n * re-merge + rewrite run only when it is true — a dry-run, or an unlocked apply\n * (lock-acquisition timeout), computes records but does NOT rename, so it can\n * never clobber a concurrent lock holder's window. `applied` mirrors `canMutate`.\n */\n private async finishRebuild(\n rebuilt: Map<string, NamespaceRecord>,\n skipped: NamespaceCatalogSkippedRoot[],\n dryRun: boolean,\n canMutate: boolean,\n memoryReal: string | null,\n nowIso: string,\n ): Promise<NamespaceCatalogRebuildResult> {\n if (canMutate) {\n // CROSS-PROCESS re-merge (round 5, codex P2): under the rebuild lock,\n // re-read the on-disk log ONE more time and fold any touch fields that\n // landed AFTER our initial `loadCompacted()` (e.g. a gateway markWrite in\n // another process) into the rebuilt records — last-write-wins per touch\n // field. This recovers cross-process appends that completed during the\n // scan, which the in-process `queueCritical` alone cannot see. Only runs\n // when we hold the lock (round 6, codex P2 — NBPmY): an unlocked rebuild\n // must not re-merge then rename, or it races a concurrent lock holder.\n const latest = await this.loadCompacted();\n for (const [ns, fresh] of latest) {\n const current = rebuilt.get(ns);\n if (!current) {\n // AUTHORITATIVE PURGE (round 6, cursor Medium — NATqU): the disk scan\n // is the single source of truth for which namespaces EXIST. A namespace\n // absent from `rebuilt` was NOT discovered on disk (its root is\n // empty/deleted) and is NOT configured, so the rebuild is purging it.\n // We must NOT resurrect it from the log — not even when a CONCURRENT\n // best-effort `markRead`/`markWrite` touched it after our snapshot. A\n // touch on a dynamic namespace whose on-disk root was removed only\n // bumps a timestamp; re-inserting that row (with its stale `storageDir`)\n // would defeat the purge the rebuild is meant to perform.\n //\n // CREATED-AFTER-SCAN RE-CHECK (NFJV8, codex P2): there is a TOCTOU\n // window where a dynamic namespace is CREATED on disk AFTER the scan\n // enumerated `namespaces/` but BEFORE this re-merge. Its new root was\n // missed by the snapshot, yet a gateway `markWrite` already landed a row\n // in `latest`. Purging that row would drop a LIVE namespace that now has\n // data on disk. So before purging, re-check the namespace's storage root\n // RIGHT NOW (with the same symlink/realpath/containment + memory-data\n // safety the scan uses). If it currently EXISTS with data, the namespace\n // was created-after-scan and is live — KEEP its row. This is the precise\n // inverse of NATqU, not a regression of it: a touch on a REMOVED root\n // re-checks as absent and is still purged below; only a root that EXISTS\n // on a fresh re-check is kept.\n //\n // SAFETY REVALIDATION (NGLz5, codex P2): the `ns` key comes from the\n // UNTRUSTED log (`latest`), which may carry an unsafe namespace row from a\n // pre-fix or tampered catalog. The disk SCAN validates every decoded\n // namespace with `isSafeRouteNamespace` (default exempt) and SKIPS unsafe\n // ones — so an unsafe namespace is absent from `rebuilt` by design, NOT\n // because it was deleted. Without re-applying that exact check here, a\n // matching tokenized dir on disk would let this branch RESURRECT the\n // unsafe row, and `--apply` would rewrite the catalog with a namespace the\n // hot touch/config/scan paths all reject — leaving maintenance/QMD able to\n // enumerate an unsafe namespace after a rebuild that appeared to skip it.\n // Apply the SAME default-exempt safety gate before the live-root recheck;\n // an unsafe row is dropped (fall through to purge), never kept.\n if (ns !== this.defaultNamespaceIdentity && !isSafeRouteNamespace(ns)) {\n continue;\n }\n if (await this.liveStorageRootExistsForRebuild(ns, memoryReal)) {\n // Created-after-scan: keep the live row. Re-resolve its storageDir to\n // the safe (router-aligned, contained) root so we never persist a\n // touch's stale/escaping `storageDir`.\n const safeDir = await this.resolveSafeStorageDir(ns);\n // DUAL-ROOT GUARD (codex NR-td): if another rebuilt row already OWNS\n // this exact storageDir (e.g. the decoded/configured owner of a\n // token-shaped root that the disk scan resolved), do NOT also resurrect\n // this stale alias from the untrusted log — that leaves TWO catalog rows\n // pointing at one root and fans maintenance/QMD out over the wrong\n // namespace. Enforce at most one row per storageDir: the scan's owner\n // wins, the alias is dropped (falls through to purge) after folding\n // its touch fields into the owner so recency filters/maintenance do\n // not miss a real write.\n const resolvedSafe = path.resolve(safeDir);\n let owningNamespace: string | null = null;\n for (const [otherNs, otherRec] of rebuilt) {\n if (otherNs !== ns && path.resolve(otherRec.storageDir) === resolvedSafe) {\n owningNamespace = otherNs;\n break;\n }\n }\n if (owningNamespace) {\n const owner = rebuilt.get(owningNamespace);\n if (owner) rebuilt.set(owningNamespace, mergeNewerTouchFields(owner, fresh));\n continue;\n }\n rebuilt.set(ns, {\n ...fresh,\n storageDir: safeDir,\n identityToken: namespaceIdentityToken(ns),\n kind: fresh.kind ?? inferKind(ns, this.config),\n createdAt: fresh.createdAt ?? nowIso,\n });\n continue;\n }\n // Confirmed absent on disk. Losing a touch timestamp for a deleted root\n // is acceptable (the catalog is rebuildable best-effort metadata);\n // resurrecting a purged record is not. Drop it.\n continue;\n }\n // SURVIVING namespace (still present in the authoritative disk scan):\n // fold in any newer touch fields that landed cross-process after our\n // initial snapshot so a concurrent gateway markWrite is not lost.\n rebuilt.set(ns, mergeNewerTouchFields(current, fresh));\n }\n }\n\n const records = [...rebuilt.values()].sort((a, b) => {\n const byName = a.namespace.localeCompare(b.namespace);\n if (byName !== 0) return byName;\n return a.identityToken.localeCompare(b.identityToken);\n });\n\n // Only rewrite when we actually hold the cross-process lock (round 6, codex\n // P2 — NBPmY). A dry-run never mutates; an unlocked rebuild (acquisition\n // timed out) returns the computed records WITHOUT renaming over the log, so\n // it can never clobber a concurrent lock holder's window.\n if (canMutate) {\n // Test-only seam: the load→rename window where the old check-then-append\n // touch could be clobbered. A concurrency test attempts a cross-instance\n // touch here and asserts the held lock blocks it (no-op in production).\n if (this.onRebuildBeforeRenameForTest) {\n await this.onRebuildBeforeRenameForTest();\n }\n await this.rewriteUnchained(records);\n }\n\n // `applied` is true only when we actually rewrote the log: never for a\n // dry-run, and never for an `--apply` that ran compute-only because it could\n // not acquire the lock (canMutate=false). Surfaces the real mutation state so\n // the CLI does not report success on a skipped rewrite (NBn3n/NBsGG).\n return { dryRun, records, skipped, applied: canMutate };\n }\n\n // ── Cross-process catalog write lock (held mutex) ────────────────────────\n\n /**\n * Run `fn` while HOLDING the shared cross-process advisory lock (round 5, codex\n * P2; generalized round 7 — NEZkA). This is the SINGLE mutex shared by BOTH the\n * touch read→merge→append window AND the rebuild final load→merge→rename window,\n * so a touch and a rebuild in different processes are mutually exclusive over\n * their respective critical sections — closing the check-then-append gap where a\n * polled-only touch could append into a rebuild's load→rename window.\n *\n * Acquisition is atomic via `open(..., \"wx\")`. A lock older than\n * `REBUILD_LOCK_STALE_MS` is treated as a crashed holder and broken. After\n * `REBUILD_LOCK_MAX_WAIT_MS` of contention we proceed best-effort WITHOUT the\n * lock rather than block forever. The lock is always released in `finally`.\n *\n * IN-PROCESS SAFETY: every caller invokes this from inside (or wrapping) the\n * per-process `queueCritical` chain, which serializes all catalog mutations in\n * THIS process. So within one process only one logical holder attempts OS-lock\n * acquisition at a time — the file lock is never self-contended in-process, and\n * the lock is acquired and released within a single in-process turn. The file\n * lock adds only the missing CROSS-process exclusion.\n *\n * HEARTBEAT (round 5, cursor/codex Medium/P2): while WE hold the lock a timer\n * refreshes its mtime every `REBUILD_LOCK_HEARTBEAT_MS`, so a legitimately long\n * holder (> `REBUILD_LOCK_STALE_MS`) is not treated as a crashed holder and\n * unlinked by another process — which would let overlapping windows lose\n * appends. Heartbeat failures are swallowed; the timer is always cleared in\n * `finally`.\n *\n * ACQUISITION RESULT (round 6, codex P2 — NBPmY): `fn` receives whether WE\n * actually hold the lock. When acquisition TIMED OUT (another holder is active),\n * a MUTATING rebuild must NOT perform its load/rename window unlocked, and a\n * touch must NOT append unlocked — both would recreate the lost-append race. The\n * caller uses `acquired` to run compute-only (rebuild) or DROP the append\n * (touch) when unlocked.\n */\n private async withHeldCatalogLock<T>(fn: (acquired: boolean) => Promise<T>): Promise<T> {\n const acquired = await this.acquireRebuildLock();\n let heartbeat: ReturnType<typeof setInterval> | undefined;\n if (acquired) {\n heartbeat = setInterval(() => {\n const now = new Date();\n // Refresh mtime so age-based stale detection sees an active holder.\n utimes(this.rebuildLockPath, now, now).catch(() => undefined);\n }, REBUILD_LOCK_HEARTBEAT_MS);\n // Don't keep the event loop alive solely for the heartbeat.\n heartbeat.unref?.();\n }\n try {\n return await fn(acquired);\n } finally {\n if (heartbeat) clearInterval(heartbeat);\n if (acquired) {\n try {\n // Release ONLY the lock still owned by THIS instance (round 6, codex\n // P2 — NCzT6). If this rebuild paused long enough that another process\n // treated our lock as stale, unlinked it, and acquired a REPLACEMENT,\n // an unconditional unlink here would delete that other holder's active\n // lock — letting writers/another rebuild proceed during its load/rename\n // window and recreating the lost-append race. Verify ownership first.\n if (await this.rebuildLockHeldBySelf()) {\n await unlink(this.rebuildLockPath);\n }\n } catch {\n // Best-effort release; a stale lock will be broken on next rebuild.\n }\n }\n }\n }\n\n /** Try to acquire the rebuild lock; returns true if WE created it. */\n private async acquireRebuildLock(): Promise<boolean> {\n const deadline = Date.now() + REBUILD_LOCK_MAX_WAIT_MS;\n await mkdir(this.stateDir, { recursive: true });\n for (;;) {\n try {\n const handle = await open(this.rebuildLockPath, \"wx\");\n try {\n // Record PID, this instance's owner id, and a timestamp. The owner id\n // distinguishes same-process instances (NBsGP).\n await handle.writeFile(\n `${process.pid} ${this.lockOwnerId} ${new Date().toISOString()}\\n`,\n \"utf8\",\n );\n } catch {\n // Ignore write failures — the exclusive create already gave us the lock.\n } finally {\n await handle.close();\n }\n return true;\n } catch (err) {\n if ((err as NodeJS.ErrnoException)?.code !== \"EEXIST\") {\n // Unexpected FS error — proceed best-effort without the lock.\n return false;\n }\n // Lock exists: break it if stale, otherwise wait briefly.\n await this.breakStaleRebuildLock();\n if (Date.now() >= deadline) return false;\n await new Promise((r) => setTimeout(r, REBUILD_LOCK_POLL_MS));\n }\n }\n }\n\n /**\n * Remove the lock file if its mtime is older than the stale threshold.\n *\n * REPLACEMENT-SAFE (NG7Bg, codex P2): a plain `stat` → `unlink` has a TOCTOU\n * window — two processes can both observe the SAME stale lock; one removes it and\n * creates a FRESH lock, and the other's later `unlink` then deletes that fresh\n * holder's ACTIVE lock based on the stale identity it read earlier, leaving the\n * fresh holder running its critical section with no visible lock and reopening the\n * lost-update race the mutex prevents. We therefore capture the lock's IDENTITY\n * (its full content line: `<pid> <owner-uuid> <iso>`) when we judge it stale, then\n * RE-READ immediately before unlinking and only remove it when the content is\n * byte-identical AND still stale. A replacement lock has a different owner id /\n * timestamp, so its content differs and we leave it untouched. We never unlink a\n * lock whose mtime is now fresh (a heartbeat refreshed it) or whose identity\n * changed (a replacement was created). This is best-effort: any mismatch/vanish\n * simply skips the break and the caller polls again.\n */\n private async breakStaleRebuildLock(): Promise<void> {\n let staleIdentity: string;\n try {\n const info = await stat(this.rebuildLockPath);\n if (Date.now() - info.mtimeMs <= REBUILD_LOCK_STALE_MS) {\n // Not stale (e.g. a live holder's heartbeat keeps it fresh) — leave it.\n return;\n }\n // Capture the exact identity we judged stale, so we can confirm it has not\n // been replaced before we unlink.\n staleIdentity = await readFile(this.rebuildLockPath, \"utf8\");\n } catch {\n // Lock vanished (released by holder) or stat/read failed — nothing to do.\n return;\n }\n // Test-only seam: simulate a replacement lock being created in the race window\n // between the staleness judgment and the unlink (NG7Bg). No-op in production.\n if (this.onBeforeBreakStaleUnlinkForTest) {\n await this.onBeforeBreakStaleUnlinkForTest();\n }\n try {\n // Re-validate immediately before unlinking: the lock must still carry the\n // SAME identity AND still be stale. If a replacement lock was created in the\n // window (different owner/timestamp) or a heartbeat refreshed the mtime, do\n // NOT unlink — that would delete another process's ACTIVE lock.\n const current = await readFile(this.rebuildLockPath, \"utf8\");\n if (current !== staleIdentity) return; // replaced — leave the fresh lock\n const recheck = await stat(this.rebuildLockPath);\n if (Date.now() - recheck.mtimeMs <= REBUILD_LOCK_STALE_MS) return; // refreshed\n await unlink(this.rebuildLockPath).catch(() => undefined);\n } catch {\n // The lock changed/vanished between checks — another process handled it.\n }\n }\n\n /**\n * Whether the rebuild lock file was written by THIS instance (round 6, codex\n * P2 — NBsGP). Matches the per-instance owner id, NOT just `process.pid`: two\n * NamespaceCatalog instances in the same process share a PID, so a PID-only\n * check would wrongly treat instance A's lock as self-held by instance B and\n * let B's touch skip the wait and append into A's rebuild window. Falls back to\n * the legacy PID-only form for lock files written before owner ids existed.\n */\n private async rebuildLockHeldBySelf(): Promise<boolean> {\n try {\n const body = await readFile(this.rebuildLockPath, \"utf8\");\n const parts = body.trim().split(/\\s+/);\n const pid = Number.parseInt(parts[0] ?? \"\", 10);\n const ownerId = parts[1];\n // New format: \"<pid> <uuid> <iso>\". A UUID at parts[1] uniquely identifies\n // the writing INSTANCE; only the same instance is self. The strict UUID\n // shape avoids mistaking a legacy \"<pid> <iso>\" timestamp (also hyphenated)\n // for an owner id.\n const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n if (ownerId && UUID_RE.test(ownerId)) {\n return ownerId === this.lockOwnerId;\n }\n // Legacy format: \"<pid> <iso>\" (no owner id). Best-effort PID match.\n return Number.isFinite(pid) && pid === process.pid;\n } catch {\n return false;\n }\n }\n\n /**\n * Merge a prior record's preserved metadata (timestamps, principal hints)\n * onto a freshly-discovered record. Disk-derived fields (storageDir, kind)\n * take precedence from the new record.\n *\n * PROVENANCE (round 3, cursor Low): `discoveredBy` and `createdAt` are\n * CREATION-ONLY — identical to the touch path's invariant. A rebuild must NOT\n * reset a namespace first seen via a `write`/`read` touch back to `config`\n * just because it is also listed in policies. So when a prior record exists we\n * carry its `discoveredBy` forward; only brand-new records keep the fresh\n * (config/scan) provenance.\n */\n private mergeForRebuild(prior: NamespaceRecord | undefined, fresh: NamespaceRecord): NamespaceRecord {\n if (!prior) return fresh;\n const merged: NamespaceRecord = {\n ...fresh,\n createdAt: prior.createdAt ?? fresh.createdAt,\n discoveredBy: prior.discoveredBy ?? fresh.discoveredBy,\n };\n if (prior.lastReadAt) merged.lastReadAt = prior.lastReadAt;\n if (prior.lastWriteAt) merged.lastWriteAt = prior.lastWriteAt;\n if (prior.lastMaintenanceAt) merged.lastMaintenanceAt = { ...prior.lastMaintenanceAt };\n if (prior.principal !== undefined) merged.principal = prior.principal;\n if (prior.projectId !== undefined) merged.projectId = prior.projectId;\n if (prior.branch !== undefined) merged.branch = prior.branch;\n if (prior.parentNamespace !== undefined) merged.parentNamespace = prior.parentNamespace;\n return merged;\n }\n\n // ── Persistence ──────────────────────────────────────────────────────────\n\n /** Load the JSONL log and fold it into current state (last-record-wins). */\n private async loadCompacted(): Promise<Map<string, NamespaceRecord>> {\n const records = new Map<string, NamespaceRecord>();\n let raw: string;\n try {\n raw = await readFile(this.catalogPath, \"utf8\");\n } catch {\n return records;\n }\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (trimmed.length === 0) continue;\n let parsed: unknown;\n try {\n parsed = JSON.parse(trimmed);\n } catch {\n // Skip corrupt lines (CLAUDE.md rule #18 robustness).\n continue;\n }\n const record = coerceRecord(parsed);\n if (!record) continue;\n // Field-level touch merge during compaction (round 6, codex P2 — ND6Cz).\n // Touches run on PER-PROCESS write chains, so two processes (a gateway write\n // racing a CLI/second-server read or maintenance touch) can each load the\n // same prior record and append a full snapshot. Plain last-record-wins\n // compaction would then discard the earlier snapshot's `lastReadAt` /\n // `lastWriteAt` / `lastMaintenanceAt`, erasing a real touch and skewing\n // `writtenSince`. We instead take the LATER record as the base (most recent\n // identity/disk-derived state) and fold in the MAX of each touch field from\n // both, so no cross-process touch recency is lost without locking the hot\n // touch path. A destructive overwrite of real memory is never at stake here\n // — only best-effort recency metadata.\n const prior = records.get(record.namespace);\n records.set(record.namespace, prior ? mergeNewerTouchFields(record, prior) : record);\n }\n return records;\n }\n\n /**\n * Serialize an arbitrary read-modify-write critical section through the single\n * write chain. Every catalog mutation (touch read+merge+append, full rewrite)\n * runs through this so they are mutually exclusive: a touch always reads the\n * latest persisted state before appending, and a rebuild rewrite cannot\n * interleave with a touch's append. The chain recovers from rejection\n * (CLAUDE.md rule #40) — one failed section never poisons subsequent ones —\n * while still surfacing the error to that section's awaited promise.\n */\n private queueCritical<T>(fn: () => Promise<T>): Promise<T> {\n const run = this.writeChain.then(fn);\n // Keep the chain alive after a rejection so later sections still run.\n this.writeChain = run.then(\n () => undefined,\n () => undefined,\n );\n return run;\n }\n\n /**\n * Append a single record to the JSONL log WITHOUT re-serializing through the\n * write chain. MUST only be called from inside a `queueCritical(...)` section\n * (which already holds the serialized turn); calling it directly would bypass\n * the read-before-append ordering that prevents lost-field races.\n */\n private async appendUnchained(record: NamespaceRecord): Promise<void> {\n const line = serializeRecord(record) + \"\\n\";\n await mkdir(this.stateDir, { recursive: true });\n await appendFile(this.catalogPath, line, \"utf8\");\n }\n\n /**\n * Atomic temp-file + rename rewrite (CLAUDE.md rule #54: write temp, then\n * rename — never delete-before-write) WITHOUT re-entering the write chain.\n * MUST only be called from inside a `queueCritical(...)` turn (e.g. the\n * rebuild critical section, which already holds the serialized turn so its\n * load and rewrite are atomic against concurrent touches). Re-entering the\n * chain from within a held turn would deadlock.\n */\n private async rewriteUnchained(records: NamespaceRecord[]): Promise<void> {\n const body = records.map((r) => serializeRecord(r)).join(\"\\n\") + (records.length > 0 ? \"\\n\" : \"\");\n await mkdir(this.stateDir, { recursive: true });\n const tmp = `${this.catalogPath}.${process.pid}.${Date.now()}.tmp`;\n await writeFile(tmp, body, \"utf8\");\n await rename(tmp, this.catalogPath);\n }\n}\n\nfunction isPathInside(root: string, child: string): boolean {\n const relative = path.relative(root, child);\n return relative === \"\" || (!relative.startsWith(\"..\") && !path.isAbsolute(relative));\n}\n","import { createHash, randomUUID } from \"node:crypto\";\nimport type { Dirent } from \"node:fs\";\nimport { lstat, mkdir, open, readFile, readdir, rename, rm, rmdir, stat, utimes, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { NamespaceCatalog, NamespaceKind, NamespaceRecord } from \"../namespaces/catalog.js\";\nimport { hasMemoryData } from \"../namespaces/catalog.js\";\nimport { namespaceIdentityToken } from \"../namespaces/identity.js\";\nimport { resolveNamespaceStorageRoot } from \"../namespaces/storage.js\";\nimport { displayErrorDetail } from \"../runtime/better-sqlite.js\";\nimport type { PluginConfig } from \"../types.js\";\n\nexport type NamespaceMaintenanceJobName = string;\n\nexport type NamespaceMaintenanceSkipReason =\n | \"fanout_disabled\"\n | \"empty_root\"\n | \"branch_disabled\"\n | \"project_disabled\"\n | \"team_project_disabled\"\n | \"catalog_read_failed\"\n | \"unsafe_or_stale_root\"\n | \"budget_exhausted\"\n | \"lock_held\"\n | \"batch_lock_incomplete\"\n | \"throttled\"\n | \"job_failed\";\n\nexport interface NamespaceMaintenancePlannerOptions {\n jobName: NamespaceMaintenanceJobName;\n catalog?: NamespaceCatalog;\n now?: Date;\n budgetMode?: \"cycle\" | \"unbounded\";\n}\n\nexport interface NamespaceMaintenanceCandidate {\n namespace: string;\n kind: NamespaceKind;\n storageDir?: string;\n source: \"configured\" | \"catalog\";\n lastWriteAt?: string;\n lastMaintenanceAt?: string;\n}\n\nexport interface NamespaceMaintenancePlan {\n jobName: NamespaceMaintenanceJobName;\n generatedAt: string;\n namespaces: NamespaceMaintenanceCandidate[];\n skipped: NamespaceMaintenanceSkippedNamespace[];\n budget: {\n maxNamespacesPerCycle: number;\n selected: number;\n };\n}\n\nexport interface NamespaceMaintenanceSkippedNamespace {\n namespace: string;\n kind?: NamespaceKind;\n reason: NamespaceMaintenanceSkipReason;\n detail?: string;\n}\n\nexport interface NamespaceMaintenanceRunStatus {\n namespace: string;\n jobName: NamespaceMaintenanceJobName;\n state: \"ran\" | \"skipped\" | \"failed\";\n reason?: NamespaceMaintenanceSkipReason;\n startedAt: string;\n completedAt: string;\n itemCount?: number;\n error?: string;\n}\n\nexport interface NamespaceMaintenanceSummary {\n jobName: NamespaceMaintenanceJobName;\n generatedAt: string;\n ran: number;\n skipped: number;\n failed: number;\n statuses: NamespaceMaintenanceRunStatus[];\n}\n\nexport interface NamespaceMaintenanceBatchRunResult {\n itemCount?: number;\n itemCounts?: Record<string, number> | Map<string, number>;\n}\n\nexport interface NamespaceMaintenanceBatchRunOptions {\n requireAllLocks?: boolean;\n skipReasonForError?: (error: unknown) => NamespaceMaintenanceSkipReason | null | undefined;\n}\n\ninterface LockHandle {\n path: string;\n touch(): Promise<void>;\n release(): Promise<void>;\n}\n\nconst DEFAULT_MAX_NAMESPACES_PER_CYCLE = 20;\nconst DEFAULT_LOCK_STALE_MS = 10 * 60_000;\nconst LOCK_BASE = \"maintenance-locks\";\nconst STATUS_BASE = \"namespace-maintenance-status\";\nconst namespaceMaintenanceFs = { open, rm };\n\nexport function __setNamespaceMaintenanceFsForTest(overrides: Partial<typeof namespaceMaintenanceFs>): () => void {\n const previous = { ...namespaceMaintenanceFs };\n Object.assign(namespaceMaintenanceFs, overrides);\n return () => {\n Object.assign(namespaceMaintenanceFs, previous);\n };\n}\n\nfunction configuredNamespaces(config: PluginConfig): string[] {\n return Array.from(\n new Set(\n [config.defaultNamespace, config.sharedNamespace, ...config.namespacePolicies.map((policy) => policy.name)]\n .map((value) => value.trim())\n .filter(Boolean)\n )\n );\n}\n\nfunction inferConfiguredKind(config: PluginConfig, namespace: string): NamespaceKind {\n if (namespace === config.defaultNamespace.trim()) return \"default\";\n if (namespace === config.sharedNamespace.trim()) return \"shared\";\n return \"explicit\";\n}\n\nfunction maxNamespacesPerCycle(config: PluginConfig): number {\n return Math.max(\n 1,\n Math.floor(\n typeof config.maintenanceMaxNamespacesPerCycle === \"number\" &&\n Number.isFinite(config.maintenanceMaxNamespacesPerCycle)\n ? config.maintenanceMaxNamespacesPerCycle\n : DEFAULT_MAX_NAMESPACES_PER_CYCLE\n )\n );\n}\n\nfunction namespaceKindAllowed(config: PluginConfig, kind: NamespaceKind): boolean {\n switch (kind) {\n case \"branch\":\n return config.maintenanceIncludeBranchNamespaces === true;\n case \"project\":\n return config.maintenanceIncludeProjectNamespaces !== false;\n case \"team-project\":\n return config.maintenanceIncludeTeamProjectNamespaces !== false;\n default:\n return true;\n }\n}\n\nfunction disabledReasonForKind(kind: NamespaceKind): NamespaceMaintenanceSkipReason {\n if (kind === \"branch\") return \"branch_disabled\";\n if (kind === \"project\") return \"project_disabled\";\n if (kind === \"team-project\") return \"team_project_disabled\";\n return \"fanout_disabled\";\n}\n\nasync function catalogRootIsLive(config: PluginConfig, record: NamespaceRecord): Promise<boolean> {\n if (typeof record.storageDir !== \"string\" || record.storageDir.length === 0) {\n return false;\n }\n try {\n const liveRoot = await resolveNamespaceStorageRoot(config, record.namespace);\n if (path.resolve(liveRoot) !== path.resolve(record.storageDir)) return false;\n return hasMemoryData(liveRoot);\n } catch {\n return false;\n }\n}\n\nfunction candidateSortKey(candidate: NamespaceMaintenanceCandidate): string {\n const write = candidate.lastWriteAt ?? \"\";\n return `${write}\\u0000${candidate.namespace}`;\n}\n\nfunction candidatePriority(candidate: NamespaceMaintenanceCandidate): number {\n if (candidate.kind === \"default\") return 0;\n if (candidate.kind === \"shared\") return 1;\n if (candidate.source === \"configured\") return 2;\n if (candidate.kind === \"team-project\") return 3;\n if (candidate.kind === \"project\") return 4;\n if (candidate.kind === \"self\") return 5;\n if (candidate.kind === \"legacy\") return 6;\n if (candidate.kind === \"branch\") return 8;\n return 7;\n}\n\nfunction sortCandidates(a: NamespaceMaintenanceCandidate, b: NamespaceMaintenanceCandidate): number {\n const priority = candidatePriority(a) - candidatePriority(b);\n if (priority !== 0) return priority;\n const am = Date.parse(a.lastMaintenanceAt ?? \"\");\n const bm = Date.parse(b.lastMaintenanceAt ?? \"\");\n const aMaintained = Number.isFinite(am);\n const bMaintained = Number.isFinite(bm);\n if (aMaintained && bMaintained && am !== bm) return am - bm;\n if (aMaintained !== bMaintained) return aMaintained ? 1 : -1;\n const aw = Date.parse(a.lastWriteAt ?? \"\");\n const bw = Date.parse(b.lastWriteAt ?? \"\");\n const aValid = Number.isFinite(aw);\n const bValid = Number.isFinite(bw);\n if (aValid && bValid && aw !== bw) return bw - aw;\n if (aValid !== bValid) return aValid ? -1 : 1;\n const byKey = candidateSortKey(a).localeCompare(candidateSortKey(b));\n if (byKey !== 0) return byKey;\n return a.namespace.localeCompare(b.namespace);\n}\n\nexport async function planNamespaceMaintenance(\n config: PluginConfig,\n options: NamespaceMaintenancePlannerOptions\n): Promise<NamespaceMaintenancePlan> {\n const generatedAt = (options.now ?? new Date()).toISOString();\n const configured = configuredNamespaces(config);\n const byNamespace = new Map<string, NamespaceMaintenanceCandidate>();\n const skipped: NamespaceMaintenanceSkippedNamespace[] = [];\n\n for (const namespace of configured) {\n const kind = inferConfiguredKind(config, namespace);\n byNamespace.set(namespace, {\n namespace,\n kind,\n source: \"configured\",\n });\n }\n\n if (config.namespacesEnabled && config.maintenanceNamespaceFanoutEnabled !== false) {\n const configuredSet = new Set(configured);\n try {\n const records = options.catalog?.enabled ? await options.catalog.listNamespaces() : [];\n for (const record of records) {\n const namespace = record.namespace.trim();\n if (!namespace) continue;\n const isConfigured = configuredSet.has(namespace);\n const kind = isConfigured ? inferConfiguredKind(config, namespace) : record.kind;\n if (!namespaceKindAllowed(config, kind)) {\n skipped.push({\n namespace,\n kind,\n reason: disabledReasonForKind(kind),\n });\n continue;\n }\n if (!isConfigured && !(await catalogRootIsLive(config, record))) {\n skipped.push({\n namespace,\n kind,\n reason: \"unsafe_or_stale_root\",\n });\n continue;\n }\n byNamespace.set(namespace, {\n namespace,\n kind,\n storageDir: record.storageDir,\n source: isConfigured ? \"configured\" : \"catalog\",\n lastWriteAt: record.lastWriteAt,\n lastMaintenanceAt: record.lastMaintenanceAt?.[options.jobName],\n });\n }\n } catch (error) {\n skipped.push({\n namespace: \"*\",\n reason: \"catalog_read_failed\",\n detail: error instanceof Error ? error.message : String(error),\n });\n }\n } else if (config.namespacesEnabled) {\n skipped.push({\n namespace: \"*\",\n reason: \"fanout_disabled\",\n });\n }\n\n if (options.budgetMode !== \"unbounded\") {\n const latestStatusAtByNamespace = await readLatestStatusAtByNamespace(config, options.jobName);\n for (const candidate of byNamespace.values()) {\n if (!candidate.lastMaintenanceAt) {\n candidate.lastMaintenanceAt = latestStatusAtByNamespace.get(candidate.namespace);\n }\n }\n }\n\n const candidates = [...byNamespace.values()]\n .filter((candidate) => namespaceKindAllowed(config, candidate.kind))\n .sort(sortCandidates);\n\n const max = maxNamespacesPerCycle(config);\n const applyCycleBudget = options.budgetMode !== \"unbounded\";\n const selected = applyCycleBudget ? candidates.slice(0, max) : candidates;\n if (applyCycleBudget) {\n for (const candidate of candidates.slice(max)) {\n skipped.push({\n namespace: candidate.namespace,\n kind: candidate.kind,\n reason: \"budget_exhausted\",\n });\n }\n }\n\n return {\n jobName: options.jobName,\n generatedAt,\n namespaces: selected,\n skipped,\n budget: {\n maxNamespacesPerCycle: max,\n selected: selected.length,\n },\n };\n}\n\nfunction stablePathSegment(value: string): string {\n const sanitized = value.replace(/[^a-zA-Z0-9._-]/g, \"_\").slice(0, 128) || \"unnamed\";\n if (sanitized.length <= 128 && sanitized === value) return sanitized;\n return `${sanitized.slice(0, 80)}-${createHash(\"sha256\").update(value).digest(\"hex\").slice(0, 16)}`;\n}\n\nfunction namespacePathSegment(namespace: string): string {\n const token = namespaceIdentityToken(namespace);\n if (token.length <= 160) return token;\n return `ns-${createHash(\"sha256\").update(namespace).digest(\"hex\")}`;\n}\n\nfunction lockPath(config: PluginConfig, jobName: string, namespace: string): string {\n return path.join(\n config.memoryDir,\n \"state\",\n LOCK_BASE,\n stablePathSegment(jobName),\n `${namespacePathSegment(namespace)}.lock`\n );\n}\n\nfunction namespaceMaintenanceLockStaleMs(config: PluginConfig): number {\n if (\n typeof config.maintenanceNamespaceLockStaleMs === \"number\" &&\n Number.isFinite(config.maintenanceNamespaceLockStaleMs) &&\n config.maintenanceNamespaceLockStaleMs > 0\n ) {\n return Math.floor(config.maintenanceNamespaceLockStaleMs);\n }\n return DEFAULT_LOCK_STALE_MS;\n}\n\nfunction namespaceMaintenanceLockHeartbeatMs(config: PluginConfig): number {\n const staleMs = namespaceMaintenanceLockStaleMs(config);\n return Math.max(1, Math.min(30_000, Math.floor(staleMs / 3) || 1));\n}\n\nfunction errorCode(error: unknown): string | undefined {\n return typeof error === \"object\" && error !== null && \"code\" in error\n ? (error as { code?: string }).code\n : undefined;\n}\n\nasync function withNamespaceMaintenanceLockHeartbeat<T>(\n config: PluginConfig,\n locks: LockHandle | LockHandle[],\n task: () => Promise<T>,\n): Promise<T> {\n const activeLocks = Array.isArray(locks) ? locks : [locks];\n const interval = setInterval(() => {\n for (const lock of activeLocks) {\n void lock.touch().catch(() => undefined);\n }\n }, namespaceMaintenanceLockHeartbeatMs(config));\n interval.unref?.();\n try {\n return await task();\n } finally {\n clearInterval(interval);\n }\n}\n\nasync function removeStaleLockDirectory(filePath: string): Promise<void> {\n let entries: Dirent[];\n try {\n entries = await readdir(filePath, { withFileTypes: true });\n } catch (error) {\n if (errorCode(error) === \"ENOENT\") return;\n throw error;\n }\n for (const entry of entries) {\n if (!entry.isFile()) continue;\n await namespaceMaintenanceFs.rm(path.join(filePath, entry.name), { force: true });\n }\n try {\n await rmdir(filePath);\n } catch (error) {\n if (errorCode(error) === \"ENOENT\") return;\n throw error;\n }\n}\n\nasync function tryAcquireNamespaceMaintenanceLock(\n config: PluginConfig,\n jobName: string,\n namespace: string\n): Promise<LockHandle | null> {\n const filePath = lockPath(config, jobName, namespace);\n await mkdir(path.dirname(filePath), { recursive: true });\n try {\n const lockId = randomUUID();\n await mkdir(filePath);\n const ownerPath = path.join(filePath, `${lockId}.json`);\n let handle: Awaited<ReturnType<typeof open>> | undefined;\n try {\n handle = await namespaceMaintenanceFs.open(ownerPath, \"wx\");\n await handle.writeFile(\n `${JSON.stringify({\n lockId,\n pid: process.pid,\n jobName,\n namespace,\n acquiredAt: new Date().toISOString(),\n })}\\n`,\n \"utf8\"\n );\n await handle.close();\n } catch (setupError) {\n await handle?.close().catch(() => undefined);\n await namespaceMaintenanceFs.rm(ownerPath, { force: true }).catch(() => undefined);\n await rmdir(filePath).catch(() => undefined);\n throw setupError;\n }\n return {\n path: filePath,\n async touch() {\n try {\n const parsed = JSON.parse(await readFile(ownerPath, \"utf8\")) as { lockId?: unknown };\n if (parsed.lockId === lockId) {\n const now = new Date();\n await utimes(ownerPath, now, now);\n await utimes(filePath, now, now);\n }\n } catch {}\n },\n async release() {\n try {\n const parsed = JSON.parse(await readFile(ownerPath, \"utf8\")) as { lockId?: unknown };\n if (parsed.lockId === lockId) {\n await namespaceMaintenanceFs.rm(ownerPath, { force: true });\n await rmdir(filePath).catch(() => undefined);\n }\n } catch {}\n },\n };\n } catch (error) {\n if (errorCode(error) === \"EEXIST\") {\n const staleMs =\n namespaceMaintenanceLockStaleMs(config);\n try {\n const s = await lstat(filePath);\n if (s.isSymbolicLink()) {\n return null;\n }\n if ((s.isFile() || s.isDirectory()) && Date.now() - s.mtimeMs > staleMs) {\n try {\n if (s.isDirectory()) {\n await removeStaleLockDirectory(filePath);\n } else {\n await namespaceMaintenanceFs.rm(filePath, { force: true });\n }\n } catch (removeError) {\n if (errorCode(removeError) === \"ENOENT\") {\n return tryAcquireNamespaceMaintenanceLock(config, jobName, namespace);\n }\n if (errorCode(removeError) === \"ENOTEMPTY\") {\n return null;\n }\n throw removeError;\n }\n return tryAcquireNamespaceMaintenanceLock(config, jobName, namespace);\n }\n } catch (statError) {\n if (errorCode(statError) === \"ENOENT\") {\n return tryAcquireNamespaceMaintenanceLock(config, jobName, namespace);\n }\n throw statError;\n }\n return null;\n }\n throw error;\n }\n}\n\nfunction statusBasePath(config: PluginConfig): string {\n return path.join(config.memoryDir, \"state\", STATUS_BASE);\n}\n\nfunction statusPath(config: PluginConfig, jobName: string, namespace: string): string {\n return path.join(statusBasePath(config), stablePathSegment(jobName), `${namespacePathSegment(namespace)}.json`);\n}\n\nfunction lastRanStatusPath(config: PluginConfig, jobName: string, namespace: string): string {\n return path.join(statusBasePath(config), stablePathSegment(jobName), `${namespacePathSegment(namespace)}.last-ran.json`);\n}\n\nfunction parseStatus(value: unknown): NamespaceMaintenanceRunStatus | null {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return null;\n const v = value as Partial<NamespaceMaintenanceRunStatus>;\n if (\n typeof v.namespace === \"string\" &&\n typeof v.jobName === \"string\" &&\n (v.state === \"ran\" || v.state === \"skipped\" || v.state === \"failed\") &&\n typeof v.startedAt === \"string\" &&\n typeof v.completedAt === \"string\"\n ) {\n return v as NamespaceMaintenanceRunStatus;\n }\n return null;\n}\n\nasync function readLatestStatusAtByNamespace(config: PluginConfig, jobName: string): Promise<Map<string, string>> {\n const latest = new Map<string, string>();\n const latestMs = new Map<string, number>();\n for (const status of [...(await readStatusFiles(config)), ...(await readLastRanStatusFiles(config))]) {\n if (status.state !== \"ran\") continue;\n if (status.jobName !== jobName) continue;\n const completedAtMs = Date.parse(status.completedAt);\n if (!Number.isFinite(completedAtMs)) continue;\n const previousMs = latestMs.get(status.namespace);\n if (previousMs !== undefined && previousMs >= completedAtMs) continue;\n latestMs.set(status.namespace, completedAtMs);\n latest.set(status.namespace, status.completedAt);\n }\n return latest;\n}\n\nasync function readStatusFile(filePath: string): Promise<NamespaceMaintenanceRunStatus | null> {\n try {\n const parsed = JSON.parse(await readFile(filePath, \"utf8\")) as unknown;\n return parseStatus(parsed);\n } catch {\n return null;\n }\n}\n\nasync function readStatusFiles(config: PluginConfig): Promise<NamespaceMaintenanceRunStatus[]> {\n if (typeof config.memoryDir !== \"string\" || config.memoryDir.length === 0) {\n return [];\n }\n const root = statusBasePath(config);\n const statuses: NamespaceMaintenanceRunStatus[] = [];\n let jobDirs: Dirent[];\n try {\n jobDirs = await readdir(root, { withFileTypes: true });\n } catch {\n return statuses;\n }\n for (const jobDir of jobDirs) {\n if (!jobDir.isDirectory()) continue;\n let files: Dirent[];\n try {\n files = await readdir(path.join(root, jobDir.name), { withFileTypes: true });\n } catch {\n continue;\n }\n for (const file of files) {\n if (!file.isFile() || !file.name.endsWith(\".json\")) continue;\n if (file.name.endsWith(\".last-ran.json\")) continue;\n const status = await readStatusFile(path.join(root, jobDir.name, file.name));\n if (status) statuses.push(status);\n }\n }\n return statuses;\n}\n\nasync function readLastRanStatusFiles(config: PluginConfig): Promise<NamespaceMaintenanceRunStatus[]> {\n if (typeof config.memoryDir !== \"string\" || config.memoryDir.length === 0) {\n return [];\n }\n const root = statusBasePath(config);\n const statuses: NamespaceMaintenanceRunStatus[] = [];\n let jobDirs: Dirent[];\n try {\n jobDirs = await readdir(root, { withFileTypes: true });\n } catch {\n return statuses;\n }\n for (const jobDir of jobDirs) {\n if (!jobDir.isDirectory()) continue;\n let files: Dirent[];\n try {\n files = await readdir(path.join(root, jobDir.name), { withFileTypes: true });\n } catch {\n continue;\n }\n for (const file of files) {\n if (!file.isFile() || !file.name.endsWith(\".last-ran.json\")) continue;\n const status = await readStatusFile(path.join(root, jobDir.name, file.name));\n if (status) statuses.push(status);\n }\n }\n return statuses;\n}\n\nasync function writeStatusPayload(target: string, status: NamespaceMaintenanceRunStatus): Promise<void> {\n const dir = path.dirname(target);\n await mkdir(dir, { recursive: true });\n const temp = `${target}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;\n const payload = {\n version: 1,\n ...status,\n };\n await writeFile(temp, `${JSON.stringify(payload, null, 2)}\\n`, \"utf8\");\n await rename(temp, target);\n}\n\nasync function writeStatusFile(config: PluginConfig, status: NamespaceMaintenanceRunStatus): Promise<void> {\n await writeStatusPayload(statusPath(config, status.jobName, status.namespace), status);\n if (status.state === \"ran\") {\n await writeStatusPayload(lastRanStatusPath(config, status.jobName, status.namespace), status);\n }\n}\n\nasync function recordNamespaceMaintenanceStatusSafely(\n config: PluginConfig,\n status: NamespaceMaintenanceRunStatus\n): Promise<void> {\n try {\n await writeStatusFile(config, status);\n } catch {\n // Observability must not fail the maintenance operation.\n }\n}\n\nfunction maintenanceErrorDetail(error: unknown): string {\n return displayErrorDetail(error) || \"Error\";\n}\n\nexport async function readNamespaceMaintenanceStatuses(config: PluginConfig): Promise<NamespaceMaintenanceRunStatus[]> {\n return (await readStatusFiles(config)).sort((a, b) => {\n const byJob = a.jobName.localeCompare(b.jobName);\n if (byJob !== 0) return byJob;\n return a.namespace.localeCompare(b.namespace);\n });\n}\n\nexport async function runNamespaceMaintenancePlan(\n config: PluginConfig,\n plan: NamespaceMaintenancePlan,\n runner: (candidate: NamespaceMaintenanceCandidate) => Promise<{ itemCount?: number } | undefined>,\n catalog?: NamespaceCatalog\n): Promise<NamespaceMaintenanceSummary> {\n const statuses: NamespaceMaintenanceRunStatus[] = [];\n\n for (const skipped of plan.skipped) {\n if (skipped.namespace === \"*\") continue;\n const now = new Date().toISOString();\n const status: NamespaceMaintenanceRunStatus = {\n namespace: skipped.namespace,\n jobName: plan.jobName,\n state: \"skipped\",\n reason: skipped.reason,\n startedAt: now,\n completedAt: now,\n };\n statuses.push(status);\n await recordNamespaceMaintenanceStatusSafely(config, status);\n }\n\n for (const candidate of plan.namespaces) {\n const startedAt = new Date().toISOString();\n const lock = await tryAcquireNamespaceMaintenanceLock(config, plan.jobName, candidate.namespace);\n if (!lock) {\n const completedAt = new Date().toISOString();\n const status: NamespaceMaintenanceRunStatus = {\n namespace: candidate.namespace,\n jobName: plan.jobName,\n state: \"skipped\",\n reason: \"lock_held\",\n startedAt,\n completedAt,\n };\n statuses.push(status);\n await recordNamespaceMaintenanceStatusSafely(config, status);\n continue;\n }\n try {\n const result = await withNamespaceMaintenanceLockHeartbeat(config, lock, () => runner(candidate));\n const completedAt = new Date().toISOString();\n const status: NamespaceMaintenanceRunStatus = {\n namespace: candidate.namespace,\n jobName: plan.jobName,\n state: \"ran\",\n startedAt,\n completedAt,\n itemCount: result?.itemCount,\n };\n statuses.push(status);\n await recordNamespaceMaintenanceStatusSafely(config, status);\n try {\n await catalog?.markMaintenance(candidate.namespace, plan.jobName, new Date(completedAt));\n } catch {\n // Catalog maintenance touches are best-effort status metadata.\n }\n } catch (error) {\n const completedAt = new Date().toISOString();\n const status: NamespaceMaintenanceRunStatus = {\n namespace: candidate.namespace,\n jobName: plan.jobName,\n state: \"failed\",\n reason: \"job_failed\",\n startedAt,\n completedAt,\n error: maintenanceErrorDetail(error),\n };\n statuses.push(status);\n await recordNamespaceMaintenanceStatusSafely(config, status);\n } finally {\n await lock.release().catch(() => undefined);\n }\n }\n\n return {\n jobName: plan.jobName,\n generatedAt: new Date().toISOString(),\n ran: statuses.filter((s) => s.state === \"ran\").length,\n skipped: statuses.filter((s) => s.state === \"skipped\").length,\n failed: statuses.filter((s) => s.state === \"failed\").length,\n statuses,\n };\n}\n\nexport async function runNamespaceMaintenanceBatchPlan(\n config: PluginConfig,\n plan: NamespaceMaintenancePlan,\n runner: (candidates: NamespaceMaintenanceCandidate[]) => Promise<NamespaceMaintenanceBatchRunResult | undefined>,\n catalog?: NamespaceCatalog,\n options: NamespaceMaintenanceBatchRunOptions = {}\n): Promise<NamespaceMaintenanceSummary> {\n const statuses: NamespaceMaintenanceRunStatus[] = [];\n\n for (const skipped of plan.skipped) {\n if (skipped.namespace === \"*\") continue;\n const now = new Date().toISOString();\n const status: NamespaceMaintenanceRunStatus = {\n namespace: skipped.namespace,\n jobName: plan.jobName,\n state: \"skipped\",\n reason: skipped.reason,\n startedAt: now,\n completedAt: now,\n };\n statuses.push(status);\n await recordNamespaceMaintenanceStatusSafely(config, status);\n }\n\n const acquired: Array<{\n candidate: NamespaceMaintenanceCandidate;\n lock: LockHandle;\n startedAt: string;\n }> = [];\n\n try {\n for (const candidate of plan.namespaces) {\n const startedAt = new Date().toISOString();\n const lock = await tryAcquireNamespaceMaintenanceLock(config, plan.jobName, candidate.namespace);\n if (!lock) {\n const completedAt = new Date().toISOString();\n const status: NamespaceMaintenanceRunStatus = {\n namespace: candidate.namespace,\n jobName: plan.jobName,\n state: \"skipped\",\n reason: \"lock_held\",\n startedAt,\n completedAt,\n };\n statuses.push(status);\n await recordNamespaceMaintenanceStatusSafely(config, status);\n continue;\n }\n acquired.push({ candidate, lock, startedAt });\n }\n } catch (error) {\n await Promise.all(acquired.map(({ lock }) => lock.release().catch(() => undefined)));\n throw error;\n }\n\n if (options.requireAllLocks && acquired.length > 0 && acquired.length < plan.namespaces.length) {\n for (const { candidate, startedAt } of acquired) {\n const completedAt = new Date().toISOString();\n const status: NamespaceMaintenanceRunStatus = {\n namespace: candidate.namespace,\n jobName: plan.jobName,\n state: \"skipped\",\n reason: \"batch_lock_incomplete\",\n startedAt,\n completedAt,\n };\n statuses.push(status);\n await recordNamespaceMaintenanceStatusSafely(config, status);\n }\n await Promise.all(acquired.map(({ lock }) => lock.release().catch(() => undefined)));\n return {\n jobName: plan.jobName,\n generatedAt: new Date().toISOString(),\n ran: statuses.filter((s) => s.state === \"ran\").length,\n skipped: statuses.filter((s) => s.state === \"skipped\").length,\n failed: statuses.filter((s) => s.state === \"failed\").length,\n statuses,\n };\n }\n\n if (acquired.length === 0) {\n return {\n jobName: plan.jobName,\n generatedAt: new Date().toISOString(),\n ran: statuses.filter((s) => s.state === \"ran\").length,\n skipped: statuses.filter((s) => s.state === \"skipped\").length,\n failed: statuses.filter((s) => s.state === \"failed\").length,\n statuses,\n };\n }\n\n try {\n const result = await withNamespaceMaintenanceLockHeartbeat(\n config,\n acquired.map(({ lock }) => lock),\n () => runner(acquired.map(({ candidate }) => candidate)),\n );\n for (const { candidate, startedAt } of acquired) {\n const completedAt = new Date().toISOString();\n const status: NamespaceMaintenanceRunStatus = {\n namespace: candidate.namespace,\n jobName: plan.jobName,\n state: \"ran\",\n startedAt,\n completedAt,\n itemCount: itemCountForNamespace(result, candidate.namespace),\n };\n statuses.push(status);\n await recordNamespaceMaintenanceStatusSafely(config, status);\n try {\n await catalog?.markMaintenance(candidate.namespace, plan.jobName, new Date(completedAt));\n } catch {\n // Catalog maintenance touches are best-effort status metadata.\n }\n }\n } catch (error) {\n const skipReason = options.skipReasonForError?.(error);\n for (const { candidate, startedAt } of acquired) {\n const completedAt = new Date().toISOString();\n const status: NamespaceMaintenanceRunStatus = skipReason\n ? {\n namespace: candidate.namespace,\n jobName: plan.jobName,\n state: \"skipped\",\n reason: skipReason,\n startedAt,\n completedAt,\n }\n : {\n namespace: candidate.namespace,\n jobName: plan.jobName,\n state: \"failed\",\n reason: \"job_failed\",\n startedAt,\n completedAt,\n error: maintenanceErrorDetail(error),\n };\n statuses.push(status);\n await recordNamespaceMaintenanceStatusSafely(config, status);\n }\n } finally {\n await Promise.all(acquired.map(({ lock }) => lock.release().catch(() => undefined)));\n }\n\n return {\n jobName: plan.jobName,\n generatedAt: new Date().toISOString(),\n ran: statuses.filter((s) => s.state === \"ran\").length,\n skipped: statuses.filter((s) => s.state === \"skipped\").length,\n failed: statuses.filter((s) => s.state === \"failed\").length,\n statuses,\n };\n}\n\nfunction itemCountForNamespace(\n result: NamespaceMaintenanceBatchRunResult | undefined,\n namespace: string,\n): number | undefined {\n const itemCounts = result?.itemCounts;\n if (itemCounts instanceof Map) return itemCounts.get(namespace);\n if (itemCounts && Object.prototype.hasOwnProperty.call(itemCounts, namespace)) {\n return itemCounts[namespace];\n }\n return result?.itemCount;\n}\n"],"mappings":"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","names":["path","createHash","mkdir","readdir","readFile","stat","unlink","writeFile","results","path","mkdir","readFile","writeFile","path","stat","mkdir","readFile","writeFile","randomUUID","lstat","mkdir","open","readFile","readdir","rename","utimes","writeFile","path","open","path","readdir","mkdir","randomUUID","readFile","utimes","lstat","writeFile","rename","createHash","path","buildCompressionGuidelinesMarkdown","result","readdir","stat","unlink","displayErrorDetail","readFile","writeFile","mkdir","FallbackLlmClient","gatewayTaskChainOptions","llm","capped","profile","outcome","throwIfAborted","options","memoryKind"]}
|