@remnic/core 9.3.719 → 9.3.721
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-boundary.d.ts +10 -7
- package/dist/access-boundary.js +37 -34
- package/dist/access-cli.js +71 -66
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +11 -8
- package/dist/access-http.js +44 -41
- package/dist/access-mcp.d.ts +11 -8
- package/dist/access-mcp.js +40 -37
- package/dist/access-operations-batch.js +38 -35
- package/dist/access-operations.d.ts +11 -8
- package/dist/access-operations.js +39 -36
- package/dist/access-schema.d.ts +19 -19
- package/dist/access-schema.js +3 -3
- package/dist/{access-service-CZbnt0t2.d.ts → access-service-Dj3I-VBS.d.ts} +3 -3
- package/dist/access-service.d.ts +11 -8
- package/dist/access-service.js +36 -33
- package/dist/access-surface-catalog.d.ts +10 -7
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +4 -2
- package/dist/active-recall.js.map +1 -1
- package/dist/adapters/index.js +7 -7
- package/dist/adapters/registry.js +3 -3
- package/dist/{auto-sync-24NNS3GU.js → auto-sync-F3KCSQFJ.js} +5 -5
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +11 -8
- package/dist/briefing.d.ts +1 -1
- package/dist/briefing.js +12 -10
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer.d.ts +1 -1
- package/dist/calibration.d.ts +1 -1
- package/dist/calibration.js +2 -2
- package/dist/capabilities.d.ts +30 -2
- package/dist/capabilities.js +3 -1
- package/dist/{catalog-CEYlMs9X.d.ts → catalog-F-OEVbRQ.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-behavior.js +2 -2
- package/dist/causal-chain.js +2 -2
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +15 -13
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-retrieval.js +2 -2
- package/dist/causal-trajectory-graph.d.ts +4 -0
- package/dist/causal-trajectory-graph.js +2 -2
- package/dist/causal-trajectory.js +1 -1
- package/dist/{chunk-TH7WMHVK.js → chunk-3NN73CM7.js} +2 -2
- package/dist/{chunk-A5TUPZ3N.js → chunk-4SF232E6.js} +60 -30
- package/dist/chunk-4SF232E6.js.map +1 -0
- package/dist/{chunk-DGTDRIUO.js → chunk-4T3BMHKD.js} +2 -2
- package/dist/{chunk-EH27LHML.js → chunk-5O42UKXI.js} +2 -2
- package/dist/{chunk-KRGC4EDX.js → chunk-6FAMMBQ3.js} +2 -2
- package/dist/{chunk-FEB7W5JG.js → chunk-6OIDDKAA.js} +27 -6
- package/dist/chunk-6OIDDKAA.js.map +1 -0
- package/dist/{chunk-67HG7KFE.js → chunk-6YKIYQU7.js} +2 -2
- package/dist/{chunk-LXSG4L55.js → chunk-7CTNUVHZ.js} +2 -2
- package/dist/{chunk-UCJ5CDTK.js → chunk-A5XNBK2D.js} +22 -14
- package/dist/chunk-A5XNBK2D.js.map +1 -0
- package/dist/{chunk-7EEVXW7X.js → chunk-A7TJZLPK.js} +2 -2
- package/dist/{chunk-P5IPFZVH.js → chunk-B7WISIAJ.js} +5 -5
- package/dist/chunk-BCDKBDSY.js +173 -0
- package/dist/chunk-BCDKBDSY.js.map +1 -0
- package/dist/{chunk-JAKYZGV4.js → chunk-BXEOHV7K.js} +3 -3
- package/dist/chunk-C4X4QGIO.js +60 -0
- package/dist/chunk-C4X4QGIO.js.map +1 -0
- package/dist/{chunk-S3OPGGZB.js → chunk-D7EBTQ24.js} +2 -2
- package/dist/{chunk-IO5NQEGZ.js → chunk-DKT3X5C3.js} +2 -2
- package/dist/{chunk-PBH4JUAB.js → chunk-DVRHLN2O.js} +18 -3
- package/dist/chunk-DVRHLN2O.js.map +1 -0
- package/dist/{chunk-S35FX6MU.js → chunk-EBDA5TYA.js} +2 -2
- package/dist/{chunk-2PTBLS2S.js → chunk-EDOQM4E4.js} +2 -2
- package/dist/{chunk-YTZLBBEB.js → chunk-EEJMD2L2.js} +3 -3
- package/dist/{chunk-YGKUAX2B.js → chunk-EHQ5HO5T.js} +11 -11
- package/dist/chunk-EHQ5HO5T.js.map +1 -0
- package/dist/{chunk-JIZGYQYH.js → chunk-EM2LDXJ2.js} +4 -4
- package/dist/{chunk-YYOK4GVF.js → chunk-EVPNWN7Z.js} +10 -10
- package/dist/{chunk-HLIR3RJ7.js → chunk-EXUCUPV2.js} +2 -2
- package/dist/{chunk-F3PVXKHP.js → chunk-GDUOCHCD.js} +27 -21
- package/dist/chunk-GDUOCHCD.js.map +1 -0
- package/dist/{chunk-L5ASZA2F.js → chunk-GJSL4WG2.js} +17 -2
- package/dist/chunk-GJSL4WG2.js.map +1 -0
- package/dist/{chunk-2SXMCQEQ.js → chunk-GZQXOQQ2.js} +3 -3
- package/dist/{chunk-2KAYTPPT.js → chunk-HCVWF657.js} +12 -12
- package/dist/{chunk-N3DUH6OO.js → chunk-ILFSEIRT.js} +1 -1
- package/dist/chunk-ILFSEIRT.js.map +1 -0
- package/dist/{chunk-4KZGLDJJ.js → chunk-J3JPB7ZI.js} +2 -2
- package/dist/{chunk-3JJWNZTT.js → chunk-L2B3EE7B.js} +102 -42
- package/dist/chunk-L2B3EE7B.js.map +1 -0
- package/dist/{chunk-NFRBADNR.js → chunk-LA3HZKES.js} +610 -369
- package/dist/chunk-LA3HZKES.js.map +1 -0
- package/dist/{chunk-LQ6JI4VH.js → chunk-LD53WPMU.js} +4 -4
- package/dist/{chunk-URM3HW2R.js → chunk-LLUGAZ3B.js} +2 -2
- package/dist/{chunk-RVLB4E6N.js → chunk-MDBZTH7N.js} +5 -32
- package/dist/chunk-MDBZTH7N.js.map +1 -0
- package/dist/{chunk-U5H7WHTS.js → chunk-N77ELJ2D.js} +4 -4
- package/dist/{chunk-2VHMVWPU.js → chunk-NXRUUDUF.js} +2 -2
- package/dist/{chunk-DIFU33GU.js → chunk-OHTOPFRF.js} +2 -2
- package/dist/{chunk-74MYJSKB.js → chunk-ORAK3LNZ.js} +2 -2
- package/dist/{chunk-REWQAFSA.js → chunk-PD42EYQN.js} +2 -2
- package/dist/chunk-PHK3HARR.js +32 -0
- package/dist/chunk-PHK3HARR.js.map +1 -0
- package/dist/{chunk-773DPI6T.js → chunk-PKMQK2WY.js} +4 -4
- package/dist/{chunk-72VDBALG.js → chunk-QD6QP5P6.js} +63 -54
- package/dist/chunk-QD6QP5P6.js.map +1 -0
- package/dist/{chunk-CTOQEZSN.js → chunk-QR67FU5G.js} +2 -2
- package/dist/{chunk-AU7Q3LSC.js → chunk-RKNJBZ55.js} +7 -7
- package/dist/{chunk-YI7RZO7Y.js → chunk-SQNED75R.js} +1 -1
- package/dist/{chunk-5CEJH5ZN.js → chunk-TAPSNIMA.js} +4 -4
- package/dist/{chunk-IF362TF6.js → chunk-TQT3USCG.js} +2 -2
- package/dist/chunk-TQT3USCG.js.map +1 -0
- package/dist/{chunk-5RHM43BJ.js → chunk-TXQCG6SE.js} +3 -3
- package/dist/{chunk-ANI5DUAE.js → chunk-UIXXE6NI.js} +7 -7
- package/dist/{chunk-2COL35PK.js → chunk-UO5ZHIIH.js} +2 -2
- package/dist/{chunk-OJU73BUX.js → chunk-VCLGUIFM.js} +2 -2
- package/dist/{chunk-5J4OL7TJ.js → chunk-VUA4S7P6.js} +4 -4
- package/dist/{chunk-A66YRSOS.js → chunk-WQYSDPMA.js} +2 -2
- package/dist/chunk-XGTBNVIU.js +79 -0
- package/dist/chunk-XGTBNVIU.js.map +1 -0
- package/dist/{chunk-OZ2KQ7HF.js → chunk-YEE5KJQQ.js} +2 -2
- package/dist/chunk-YN2UN7N3.js +217 -0
- package/dist/chunk-YN2UN7N3.js.map +1 -0
- package/dist/{chunk-WRFKZEO6.js → chunk-YQGHW5ML.js} +4 -4
- package/dist/{chunk-APUJIMDM.js → chunk-Z4RU5VPM.js} +2 -2
- package/dist/{chunk-DCWIQFNA.js → chunk-ZUDM75KG.js} +4 -4
- package/dist/{cli-1orcdXOY.d.ts → cli-P_GaYcCY.d.ts} +3 -3
- package/dist/cli.d.ts +9 -6
- package/dist/cli.js +67 -63
- package/dist/compounding/engine.d.ts +1 -1
- package/dist/compounding/engine.js +12 -10
- package/dist/compounding/preference-consolidator.d.ts +1 -1
- package/dist/compression-optimizer.d.ts +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +4 -2
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +12 -10
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +13 -11
- package/dist/consolidation-provenance-check.d.ts +1 -1
- package/dist/consolidation-undo.d.ts +1 -1
- package/dist/contradiction/index.d.ts +1 -1
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/backend.js +2 -2
- package/dist/conversation-index/chunker.d.ts +1 -1
- package/dist/conversation-index/faiss-adapter.d.ts +1 -1
- package/dist/conversation-index/indexer.d.ts +1 -1
- package/dist/conversation-index/search.d.ts +1 -1
- package/dist/day-summary.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +1 -1
- package/dist/entity-retrieval.js +12 -10
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +11 -8
- package/dist/extraction-faithfulness.d.ts +8 -2
- package/dist/extraction-faithfulness.js +4 -3
- package/dist/extraction-judge-telemetry.d.ts +1 -1
- package/dist/extraction-judge-training.d.ts +1 -1
- package/dist/extraction-judge.d.ts +1 -1
- package/dist/extraction-judge.js +3 -3
- package/dist/extraction.d.ts +1 -1
- package/dist/extraction.js +5 -4
- package/dist/faithfulness-config.d.ts +55 -0
- package/dist/faithfulness-config.js +11 -0
- package/dist/faithfulness-config.js.map +1 -0
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/fallback-llm.js +2 -2
- package/dist/{forget-U66KPDPY.js → forget-OEE5OELK.js} +2 -2
- package/dist/graph-dashboard-diff.d.ts +4 -0
- package/dist/graph-dashboard-key.d.ts +4 -0
- package/dist/graph-dashboard-parser.d.ts +4 -0
- package/dist/{graph-edge-decay-JLOF3YW4.js → graph-edge-decay-QPRJQ7DL.js} +3 -3
- package/dist/graph-edge-reinforcement.d.ts +4 -0
- package/dist/graph-snapshot.d.ts +7 -3
- package/dist/graph-snapshot.js +3 -3
- package/dist/graph.d.ts +7 -1
- package/dist/graph.js +2 -2
- package/dist/identity-continuity.d.ts +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/index.d.ts +571 -570
- package/dist/index.js +104 -99
- package/dist/index.js.map +1 -1
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/engine.js +2 -2
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/index.js +4 -4
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +1 -1
- package/dist/local-model-endpoint.d.ts +96 -0
- package/dist/local-model-endpoint.js +12 -0
- package/dist/local-model-endpoint.js.map +1 -0
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +12 -10
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +12 -10
- package/dist/maintenance/rebuild-memory-projection.js +13 -11
- package/dist/mcp-memory-inspector-app.d.ts +11 -8
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-worth-outcomes.d.ts +1 -1
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +2 -2
- package/dist/namespaces/migrate.js +22 -20
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +9 -9
- package/dist/namespaces/storage.d.ts +2 -2
- package/dist/namespaces/storage.js +12 -10
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +3 -2
- package/dist/operator-toolkit.js +32 -28
- package/dist/orchestration/maintenance.d.ts +2 -2
- package/dist/orchestration/maintenance.js +14 -12
- package/dist/{orchestrator-kOxredSr.d.ts → orchestrator-f5xv19kp.d.ts} +178 -81
- package/dist/orchestrator.d.ts +8 -5
- package/dist/orchestrator.js +56 -52
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/provenance.d.ts +1 -1
- package/dist/provenance.js +2 -1
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +1 -1
- package/dist/recall-disclosure-escalation.d.ts +1 -1
- package/dist/recall-explain-renderer.d.ts +1 -1
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-planner-llm.js +2 -2
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +18 -1
- package/dist/recall-xray.js +2 -2
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +5 -3
- package/dist/retrieval-agents.d.ts +1 -1
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/routing/engine.d.ts +1 -1
- package/dist/routing/store.d.ts +1 -1
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/factory.js +8 -8
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +14 -14
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/lancedb-backend.js +2 -2
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.js +2 -2
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/orama-backend.js +2 -2
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-consolidation-B58v3S-a.d.ts → semantic-consolidation-BQm1e1Pn.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +13 -11
- package/dist/semantic-rule-promotion.js +12 -10
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +12 -10
- package/dist/session-observer-bands.d.ts +1 -1
- package/dist/session-observer-state.d.ts +1 -1
- package/dist/shared-context/manager.d.ts +1 -1
- package/dist/signal.d.ts +1 -1
- package/dist/storage.d.ts +45 -1
- package/dist/storage.js +11 -9
- package/dist/summarizer.d.ts +1 -1
- package/dist/summarizer.js +3 -3
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/temporal-supersession.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +1 -1
- package/dist/tier-routing.d.ts +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transfer/backup.js +2 -2
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/transfer/capsule-import.js +1 -1
- package/dist/trust-score-stage.d.ts +178 -0
- package/dist/trust-score-stage.js +18 -0
- package/dist/trust-score-stage.js.map +1 -0
- package/dist/trust-score.d.ts +164 -0
- package/dist/trust-score.js +22 -0
- package/dist/trust-score.js.map +1 -0
- package/dist/{types-ACmDOScJ.d.ts → types-DwO1Ot4n.d.ts} +56 -2
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.js +12 -10
- package/package.json +2 -2
- package/src/access-service.ts +8 -5
- package/src/capabilities-cluster-b.test.ts +78 -0
- package/src/capabilities.test.ts +11 -1
- package/src/capabilities.ts +58 -0
- package/src/cli/research-status-commands.ts +7 -3
- package/src/cli.ts +11 -6
- package/src/config.ts +60 -30
- package/src/extraction-faithfulness.test.ts +175 -0
- package/src/extraction-faithfulness.ts +53 -1
- package/src/faithfulness-config.test.ts +96 -0
- package/src/faithfulness-config.ts +138 -0
- package/src/graph-snapshot.ts +3 -3
- package/src/graph.ts +8 -7
- package/src/lifecycle/tombstones.test.ts +242 -1
- package/src/lifecycle/tombstones.ts +157 -70
- package/src/local-model-endpoint.test.ts +155 -0
- package/src/local-model-endpoint.ts +189 -0
- package/src/operator-toolkit.ts +24 -7
- package/src/orchestration/tier-migration-coordinator.ts +286 -0
- package/src/orchestrator.ts +331 -222
- package/src/recall-xray.test.ts +62 -0
- package/src/recall-xray.ts +34 -0
- package/src/trust-score-recall-paths.test.ts +157 -0
- package/src/trust-score-stage.test.ts +350 -0
- package/src/trust-score-stage.ts +398 -0
- package/src/trust-score.test.ts +282 -0
- package/src/trust-score.ts +449 -0
- package/src/types.ts +61 -1
- package/dist/chunk-3JJWNZTT.js.map +0 -1
- package/dist/chunk-72VDBALG.js.map +0 -1
- package/dist/chunk-A5TUPZ3N.js.map +0 -1
- package/dist/chunk-F3PVXKHP.js.map +0 -1
- package/dist/chunk-FEB7W5JG.js.map +0 -1
- package/dist/chunk-IF362TF6.js.map +0 -1
- package/dist/chunk-L5ASZA2F.js.map +0 -1
- package/dist/chunk-N3DUH6OO.js.map +0 -1
- package/dist/chunk-NFRBADNR.js.map +0 -1
- package/dist/chunk-PBH4JUAB.js.map +0 -1
- package/dist/chunk-RVLB4E6N.js.map +0 -1
- package/dist/chunk-UCJ5CDTK.js.map +0 -1
- package/dist/chunk-YGKUAX2B.js.map +0 -1
- /package/dist/{auto-sync-24NNS3GU.js.map → auto-sync-F3KCSQFJ.js.map} +0 -0
- /package/dist/{chunk-TH7WMHVK.js.map → chunk-3NN73CM7.js.map} +0 -0
- /package/dist/{chunk-DGTDRIUO.js.map → chunk-4T3BMHKD.js.map} +0 -0
- /package/dist/{chunk-EH27LHML.js.map → chunk-5O42UKXI.js.map} +0 -0
- /package/dist/{chunk-KRGC4EDX.js.map → chunk-6FAMMBQ3.js.map} +0 -0
- /package/dist/{chunk-67HG7KFE.js.map → chunk-6YKIYQU7.js.map} +0 -0
- /package/dist/{chunk-LXSG4L55.js.map → chunk-7CTNUVHZ.js.map} +0 -0
- /package/dist/{chunk-7EEVXW7X.js.map → chunk-A7TJZLPK.js.map} +0 -0
- /package/dist/{chunk-P5IPFZVH.js.map → chunk-B7WISIAJ.js.map} +0 -0
- /package/dist/{chunk-JAKYZGV4.js.map → chunk-BXEOHV7K.js.map} +0 -0
- /package/dist/{chunk-S3OPGGZB.js.map → chunk-D7EBTQ24.js.map} +0 -0
- /package/dist/{chunk-IO5NQEGZ.js.map → chunk-DKT3X5C3.js.map} +0 -0
- /package/dist/{chunk-S35FX6MU.js.map → chunk-EBDA5TYA.js.map} +0 -0
- /package/dist/{chunk-2PTBLS2S.js.map → chunk-EDOQM4E4.js.map} +0 -0
- /package/dist/{chunk-YTZLBBEB.js.map → chunk-EEJMD2L2.js.map} +0 -0
- /package/dist/{chunk-JIZGYQYH.js.map → chunk-EM2LDXJ2.js.map} +0 -0
- /package/dist/{chunk-YYOK4GVF.js.map → chunk-EVPNWN7Z.js.map} +0 -0
- /package/dist/{chunk-HLIR3RJ7.js.map → chunk-EXUCUPV2.js.map} +0 -0
- /package/dist/{chunk-2SXMCQEQ.js.map → chunk-GZQXOQQ2.js.map} +0 -0
- /package/dist/{chunk-2KAYTPPT.js.map → chunk-HCVWF657.js.map} +0 -0
- /package/dist/{chunk-4KZGLDJJ.js.map → chunk-J3JPB7ZI.js.map} +0 -0
- /package/dist/{chunk-LQ6JI4VH.js.map → chunk-LD53WPMU.js.map} +0 -0
- /package/dist/{chunk-URM3HW2R.js.map → chunk-LLUGAZ3B.js.map} +0 -0
- /package/dist/{chunk-U5H7WHTS.js.map → chunk-N77ELJ2D.js.map} +0 -0
- /package/dist/{chunk-2VHMVWPU.js.map → chunk-NXRUUDUF.js.map} +0 -0
- /package/dist/{chunk-DIFU33GU.js.map → chunk-OHTOPFRF.js.map} +0 -0
- /package/dist/{chunk-74MYJSKB.js.map → chunk-ORAK3LNZ.js.map} +0 -0
- /package/dist/{chunk-REWQAFSA.js.map → chunk-PD42EYQN.js.map} +0 -0
- /package/dist/{chunk-773DPI6T.js.map → chunk-PKMQK2WY.js.map} +0 -0
- /package/dist/{chunk-CTOQEZSN.js.map → chunk-QR67FU5G.js.map} +0 -0
- /package/dist/{chunk-AU7Q3LSC.js.map → chunk-RKNJBZ55.js.map} +0 -0
- /package/dist/{chunk-YI7RZO7Y.js.map → chunk-SQNED75R.js.map} +0 -0
- /package/dist/{chunk-5CEJH5ZN.js.map → chunk-TAPSNIMA.js.map} +0 -0
- /package/dist/{chunk-5RHM43BJ.js.map → chunk-TXQCG6SE.js.map} +0 -0
- /package/dist/{chunk-ANI5DUAE.js.map → chunk-UIXXE6NI.js.map} +0 -0
- /package/dist/{chunk-2COL35PK.js.map → chunk-UO5ZHIIH.js.map} +0 -0
- /package/dist/{chunk-OJU73BUX.js.map → chunk-VCLGUIFM.js.map} +0 -0
- /package/dist/{chunk-5J4OL7TJ.js.map → chunk-VUA4S7P6.js.map} +0 -0
- /package/dist/{chunk-A66YRSOS.js.map → chunk-WQYSDPMA.js.map} +0 -0
- /package/dist/{chunk-OZ2KQ7HF.js.map → chunk-YEE5KJQQ.js.map} +0 -0
- /package/dist/{chunk-WRFKZEO6.js.map → chunk-YQGHW5ML.js.map} +0 -0
- /package/dist/{chunk-APUJIMDM.js.map → chunk-Z4RU5VPM.js.map} +0 -0
- /package/dist/{chunk-DCWIQFNA.js.map → chunk-ZUDM75KG.js.map} +0 -0
- /package/dist/{forget-U66KPDPY.js.map → forget-OEE5OELK.js.map} +0 -0
- /package/dist/{graph-edge-decay-JLOF3YW4.js.map → graph-edge-decay-QPRJQ7DL.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
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"],"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 lstat,\n mkdir,\n readdir,\n readFile,\n realpath,\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 { detectPassiveCorrections } from \"./correction/passive-correction-detector.js\";\nimport { capturePassiveCorrections, type PassiveCaptureConfig } from \"./correction/passive-capture.js\";\nimport { createCorrectionService } from \"./correction/correction-access-wiring.js\";\nimport type { CorrectionService } from \"./correction/correction-service.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 applyFaithfulnessVerdict,\n createFaithfulnessCounters,\n runFaithfulnessGateBatch,\n} from \"./extraction-faithfulness.js\";\nimport type { FaithfulnessGateCounters } from \"./extraction-faithfulness.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 SearchDegradation,\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 { MaintenanceScheduler } from \"./orchestration/maintenance.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, isValidityExpiredNow } from \"./temporal-validity.js\";\nimport { resolveFactEventTime } from \"./event-time.js\";\nimport { RelevanceStore } from \"./relevance.js\";\nimport { NegativeExampleStore } from \"./negative.js\";\nimport {\n LastRecallStore,\n RecallHandleHistoryStore,\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 buildHandleIndexForResults,\n MEMORY_ID_PATTERN,\n parseIdOrHandle,\n resolveHandle,\n stripHandles,\n type RecallSnapshotIds,\n} from \"./recall-handles.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 \"./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 {\n resolveCapabilities,\n resolveGraphConstructionCapabilities,\n type CapabilitySet,\n type GraphConstructionCapabilitySet,\n} from \"./capabilities.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 type NamespaceMaintenanceSummary,\n} from \"./maintenance/namespace-planner.js\";\nimport {\n runNamespaceMaintenanceFanout,\n summarizeNamespaceMaintenanceHealth,\n type NamespaceMaintenanceFanoutRunnerContext,\n type NamespaceMaintenanceHealthSummary,\n} from \"./maintenance/namespace-maintenance-fanout.js\";\nimport {\n namespaceIdentityFromToken,\n namespaceIdentityToken,\n normalizeNamespaceIdentity,\n} from \"./namespaces/identity.js\";\nimport {\n canReadNamespace,\n canWriteNamespace,\n defaultNamespaceForPrincipal,\n recallNamespacesForPrincipal,\n resolvePrincipal,\n} from \"./namespaces/principal.js\";\nimport {\n getConfiguredNamespaces,\n resolveNamespaceFromStorageDir,\n resolveScopePlan,\n} from \"./scopes/scope-plan.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, ProvenanceSource } 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\";\nimport { categoryDirName, RECALL_FALLBACK_DIRS } from \"./utils/category-dir.js\";\nimport { assertPathInsideRoot } from \"./utils/path-containment.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 /**\n * Recall-operation capability gates (issue #1523). REQUIRED: the recall\n * orchestrator always passes a resolved set — the LLM planner gate reads\n * `caps.recallPlannerLlm`, never re-derives from config.\n */\n caps: CapabilitySet;\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 // Read the resolved capability (issue #1523) — never re-derive from config.\n const plannerLlmEnabled = options.caps.recallPlannerLlm;\n if (!options.plannerEnabled || !plannerLlmEnabled) {\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.caps,\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 // #1635 (defensive): skip pending_review ids from legacy episode sets.\n const pendingReviewIds = new Set<string>(\n (options.allMemsForGraph ?? [])\n .filter((m) => m.frontmatter.status === \"pending_review\" && m.frontmatter.id)\n .map((m) => m.frontmatter.id as string),\n );\n\n return options.threadEpisodeIds\n .filter((id) => id !== options.currentMemoryId)\n .filter((id) => !pendingReviewIds.has(id))\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. Routing goes through\n // the shared categoryDirName() chokepoint (utils/category-dir.ts) so\n // every category — decisions/, preferences/, reasoning-traces/, ... —\n // resolves to the same dir the writer used; otherwise graph edges point\n // at the wrong subtree and graph expansion silently drops those nodes\n // when readMemoryByPath cannot resolve them (issue #564 PR 3 / #1546).\n const subtree = categoryDirName(options.category);\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\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 /**\n * Maintenance scheduler (issue #1526 PR1). Owns cron auto-registration,\n * debounced QMD index maintenance, and consolidation scheduling. Job\n * runners (consolidation/pattern-reinforcement/governance) stay here.\n */\n readonly maintenanceScheduler: MaintenanceScheduler;\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 * Faithfulness gate distribution counters (issue #1576). Per-orchestrator\n * running tally surfaced via console_state telemetry. No module-level state\n * (rule 11) — these hang off the orchestrator instance.\n */\n private faithfulnessCounters: FaithfulnessGateCounters = createFaithfulnessCounters();\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 /**\n * Side-channel (#1635): pending_review persisted ids from the last\n * persistExtraction; runExtraction excludes them from the thread episode set.\n */\n private lastPersistExtractionPendingReviewIds: string[] = [];\n private readonly _fastGatewayLlm: FallbackLlmClient | null;\n\n get fastGatewayLlm(): FallbackLlmClient | null {\n return this._fastGatewayLlm;\n }\n\n /**\n * Faithfulness gate verdict distribution (issue #1576). Consumed by the\n * console-state aggregator so `remnic doctor` can render how the gate is\n * performing. Returns a fresh object so callers cannot mutate the\n * internal counters. Returns `undefined` when the gate is off so the\n * console-state snapshot omits the faithfulness block entirely (cursor\n * review: an all-zero block would otherwise always be truthy and leak\n * into snapshots that document it as absent-when-off).\n */\n getConsoleFaithfulnessDistribution(): FaithfulnessGateCounters | undefined {\n if (this.config.extractionFaithfulnessGate === \"off\") return undefined;\n return { ...this.faithfulnessCounters };\n }\n readonly modelRegistry: ModelRegistry;\n readonly relevance: RelevanceStore;\n readonly negatives: NegativeExampleStore;\n readonly lastRecall: LastRecallStore;\n readonly handleHistory: RecallHandleHistoryStore;\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 // Passive correction capture (issue #1581) — dedup state + lazy service.\n private passiveCorrectionDedup: Set<string> = new Set();\n private _passiveCorrectionService: CorrectionService | null = null;\n private passiveCorrectionTelemetry: {\n detected: number;\n queued: number;\n autoApplied: number;\n suppressedReasonCounts: Record<string, number>;\n } = { detected: 0, queued: 0, autoApplied: 0, suppressedReasonCounts: {} };\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 readonly consolidationObservers = new Set<\n (observation: ConsolidationObservation) => Promise<void> | void\n >();\n private wearablesServiceInstance: WearablesService | null = null;\n private wearablesAutoSyncHandle: { stop(): Promise<void> } | null = null;\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 this.maintenanceScheduler.dispose();\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 configuredNamespaceList(): string[] {\n // #1521: delegates to the scope-module resolver. The inline derivation is\n // retired so the adHocNamespaceResolutions ratchet no longer counts this\n // site.\n return getConfiguredNamespaces(this.config);\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.configuredNamespaceList().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 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 /**\n * Fan out a maintenance job across all maintained namespaces (issue #1500).\n *\n * Delegates to the namespace-maintenance-fanout coordinator, which plans\n * namespace discovery (configured + catalog), applies the cycle budget,\n * acquires per-job+namespace locks, records status files, and touches the\n * catalog's `lastMaintenanceAt`. The runner receives a per-namespace\n * candidate and a storage resolver wired to `this.getStorage(namespace)`.\n *\n * When namespaces are disabled the planner returns only the default\n * namespace, so the job runs exactly once — preserving single-user behavior.\n */\n async runNamespaceMaintenanceFanoutForJob(\n jobName: string,\n runner: (ctx: NamespaceMaintenanceFanoutRunnerContext) => Promise<{ itemCount?: number } | undefined>,\n options: { enabled?: boolean } = {},\n ): Promise<NamespaceMaintenanceSummary> {\n return runNamespaceMaintenanceFanout({\n config: this.config,\n catalog: this.namespaceCatalog,\n jobName,\n runner,\n resolveStorage: (namespace) => this.getStorage(namespace),\n enabled: options.enabled,\n });\n }\n\n /**\n * Read-only namespace maintenance health summary for doctor / dashboard /\n * CLI (issue #1500). Aggregates all per-namespace maintenance status files\n * into one report without running any maintenance.\n */\n async readNamespaceMaintenanceHealth(): Promise<NamespaceMaintenanceHealthSummary> {\n return summarizeNamespaceMaintenanceHealth(this.config);\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.configuredNamespaceList()\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 }, this.namespaceCatalog);\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 // #1522: bind the post-write catalog touch at the storage chokepoint.\n if (config.defaultNamespace) this.storageRouter.bindCatalogWriteHook(this.storage, config.defaultNamespace);\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 the tombstone non-resurrection invariant (issue #1579) on the\n // primary default-namespace storage. Router-created namespace storages\n // get the same config via NamespaceStorageRouter.bindTombstonesConfig\n // (installed below) so every write path funnels through the chokepoint.\n const { tombstonesEnabled, tombstonesSemanticMatch, tombstonesSemanticThreshold } = config;\n this.storage.setTombstonesConfig({\n enabled: tombstonesEnabled,\n semanticMatch: tombstonesSemanticMatch,\n semanticThreshold: tombstonesSemanticThreshold,\n namespace: config.defaultNamespace,\n });\n this.storageRouter.bindTombstonesConfig(this.storage, config.defaultNamespace, {\n enabled: tombstonesEnabled,\n semanticMatch: tombstonesSemanticMatch,\n semanticThreshold: tombstonesSemanticThreshold,\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 this.maintenanceScheduler = new MaintenanceScheduler({\n config,\n // Live accessor: the orchestrator reassigns this.qmd to NoopSearchBackend\n // after construction when the collection is missing (initialize /\n // startupSearchSync); the scheduler must read the current backend so\n // debounced maintenance never runs against a stale/disposed one.\n getQmd: () => this.qmd,\n namespaceSearchRouter: this.namespaceSearchRouter,\n namespaceCatalog: this.namespaceCatalog,\n });\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.handleHistory = new RecallHandleHistoryStore(config.memoryDir, {\n maxDepth: config.recallHandleSnapshotDepth,\n });\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.handleHistory.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 // Auto-register every cron job in one pass. Each registration is gated\n // by its config flag inside the scheduler and individually non-fatal\n // (issue #1526 PR1 — moved to MaintenanceScheduler).\n await this.maintenanceScheduler.autoRegisterCrons(signal);\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 * 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 /**\n * Fan out pattern reinforcement across all maintained namespaces (issue #1500).\n * Delegates per-namespace execution to {@link runPatternReinforcement} while\n * the planner handles discovery, budgeting, locking, and status recording.\n * When namespaces are disabled, runs once against default storage.\n */\n async runPatternReinforcementFanout(options: {\n force?: boolean;\n } = {}): Promise<NamespaceMaintenanceSummary> {\n return this.runNamespaceMaintenanceFanoutForJob(\n \"pattern-reinforcement\",\n async (ctx) => {\n const result = await this.runPatternReinforcement({\n namespace: ctx.candidate.namespace,\n force: options.force,\n });\n // runPatternReinforcement has its own per-namespace cadence gate\n // (lastPatternReinforcementAtByNs). When it throttles (ran:false),\n // signal skip so the planner records state:\"skipped\" and does NOT\n // touch lastMaintenanceAt — otherwise a throttled namespace would\n // look maintained while pattern reinforcement never ran (#1500\n // review: cadence-skip accuracy).\n if (!result.ran) {\n return {\n skipped: true,\n skipReason: result.skippedReason ?? \"throttled\",\n };\n }\n return result.result\n ? { itemCount: result.result.clustersFound }\n : { itemCount: 0 };\n },\n { enabled: this.config.patternReinforcementEnabled },\n );\n }\n\n /**\n * Fan out lifecycle/governance policy across all maintained namespaces\n * (issue #1500). Each namespace gets its own lifecycle pass against its\n * namespace-scoped storage. When namespaces are disabled, runs once against\n * default storage.\n */\n async runLifecyclePolicyFanout(): Promise<NamespaceMaintenanceSummary> {\n return this.runNamespaceMaintenanceFanoutForJob(\n \"lifecycle\",\n async (ctx) => {\n const storage = await this.getStorage(ctx.candidate.namespace);\n const corpus = await storage.readAllMemories();\n const assessed = await this.runLifecyclePolicyPass(corpus, storage);\n return { itemCount: assessed };\n },\n { enabled: this.config.lifecyclePolicyEnabled },\n );\n }\n\n /**\n * Fan out semantic consolidation across all maintained namespaces (issue #1500).\n * Each namespace gets its own consolidation pass against its namespace-scoped\n * storage. When namespaces are disabled, runs once against default storage.\n */\n async runSemanticConsolidationFanout(options: {\n dryRun?: boolean;\n } = {}): Promise<NamespaceMaintenanceSummary> {\n return this.runNamespaceMaintenanceFanoutForJob(\n \"semantic-consolidation\",\n async (ctx) => {\n const storage = await this.getStorage(ctx.candidate.namespace);\n const result = await this.runSemanticConsolidation({\n dryRun: options.dryRun,\n thresholdOverride: undefined,\n force: true,\n storage,\n });\n return { itemCount: result.clustersFound };\n },\n { enabled: this.config.semanticConsolidationEnabled },\n );\n }\n\n /**\n * Fan out deep-sleep governance across all maintained namespaces (issue #1500).\n * Each namespace gets its own governance scan against its namespace-scoped\n * storage. When namespaces are disabled, runs once against default storage.\n */\n async runDeepSleepGovernanceFanout(options: {\n dryRun?: boolean;\n } = {}): Promise<NamespaceMaintenanceSummary> {\n return this.runNamespaceMaintenanceFanoutForJob(\n \"governance\",\n async (ctx) => {\n const storage = await this.getStorage(ctx.candidate.namespace);\n const result = await this.runDeepSleepGovernanceNow({\n dryRun: options.dryRun,\n storage,\n });\n return { itemCount: result.scannedMemories };\n },\n { enabled: this.config.dreamsPhases.deepSleep.enabled },\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.storageDirNamespace(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 // #1522: catalog touch handled at the storage chokepoint.\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.maintenanceScheduler.isConsolidationInFlight()) {\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 MAX_CHARS = 100_000;\n\n // --- Read memory files from each category dir × date directory ---\n // Iterate every recall category dir (RECALL_FALLBACK_DIRS — single source\n // of truth) so the day summary includes decisions/, moments/, ... not just\n // facts/ (#1546). corrections/ is flat, so corrections/<date>/ never exists\n // and is skipped by the ENOENT guard — preserving the prior exclusion. The\n // per-file created→local-day filter below is unchanged.\n //\n // Symlink/containment hardening (mirrors scanDir / the CLI walker): the\n // gathered contents feed the day-summary LLM input, so a symlinked category\n // dir (decisions/ → outside memoryDir) must not be followed and leak files.\n // Resolve the store root once; skip symlinked / out-of-root dirs and\n // entries; skip the scan gracefully if the root can't be resolved.\n const facts: MemoryFile[] = [];\n let memoryRootReal: string | null = null;\n try {\n memoryRootReal = await realpath(storage.dir);\n } catch {\n memoryRootReal = null;\n }\n for (const categoryDir of RECALL_FALLBACK_DIRS) {\n if (memoryRootReal === null) break;\n for (const date of datesToScan) {\n const dateDir = path.join(storage.dir, categoryDir, date);\n try {\n const dirStat = await lstat(dateDir);\n if (dirStat.isSymbolicLink() || !dirStat.isDirectory()) continue;\n assertPathInsideRoot(memoryRootReal, await realpath(dateDir), dateDir);\n const entries = await readdir(dateDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isSymbolicLink()) continue;\n if (!entry.name.endsWith(\".md\")) continue;\n const fullPath = path.join(dateDir, entry.name);\n try {\n assertPathInsideRoot(memoryRootReal, await realpath(fullPath), fullPath);\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 // Absent dir (ENOENT), symlinked/out-of-root dir, or containment\n // violation — skip this category/date without aborting the summary.\n }\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 // Resolve the recall-operation capability gates ONCE, at the operation\n // entry, and thread the frozen set down (issue #1523). Never re-read the\n // migrated flags off `this.config` mid-operation.\n const caps = resolveCapabilities(this.config);\n const graphCaps = resolveGraphConstructionCapabilities(this.config); // #1566 Cluster A\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 const namespacesEnabled = this.config.namespacesEnabled;\n if (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 }, caps, graphCaps);\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 (caps.recallDirectAnswer && sessionKey) {\n try {\n this.enqueueDirectAnswerObservation(\n prompt,\n sessionKey,\n options.namespace?.trim() || undefined,\n options.principalOverride,\n caps,\n namespacesEnabled,\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 caps: CapabilitySet,\n namespacesEnabled: boolean,\n ): void {\n const expectedSnapshot = this.lastRecall.get(sessionKey);\n if (expectedSnapshot === null) return;\n if (expectedSnapshot.plannerMode === \"no_recall\") return;\n\n // Resolve the observation namespace set through the SAME ScopePlan resolver\n // the main recall path uses (#1521). The observe path does NOT throw on an\n // unreadable override (it falls through to the coding/legacy branches), so\n // we skip the readability gate the recall path enforces.\n const observationScopePlan = resolveScopePlan({\n config: this.config,\n sessionKey,\n namespace: namespaceOverride,\n principalOverride,\n codingContext: sessionKey\n ? this.getCodingContextForSession(sessionKey)\n : null,\n namespacesEnabled,\n });\n const observationNamespaces = observationScopePlan.readNamespaces;\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 caps,\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 caps: CapabilitySet,\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 enabled: caps.recallDirectAnswer,\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 /** Backend degradation observer, threaded into every QMD call (#1536). */\n onDegradation?: (degradation: SearchDegradation) => 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 onDegradation: options.onDegradation,\n },\n )\n : await this.qmd.search(\n prompt,\n options.collection,\n fetchLimit,\n primarySearchOptions,\n { onDegradation: options.onDegradation },\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: {\n signal: options.abortSignal,\n onDegradation: options.onDegradation,\n },\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 onDegradation: options.onDegradation,\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: {\n signal: options.abortSignal,\n onDegradation: options.onDegradation,\n },\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 /**\n * Clock source for the shared post-retrieval assembly/enrichment budget. The\n * deadline is set from this value and every expiry check reads it back, so a\n * test can drive the budget deterministically instead of racing the few-ms\n * wall-clock window that made the \"skips … after budget expires\" tests flaky.\n * Production behavior is unchanged — it returns the wall clock.\n */\n protected recallAssemblyClockMs(): number {\n return Date.now();\n }\n\n private async recallInternal(\n prompt: string,\n sessionKey?: string,\n options: RecallInvocationOptions = {},\n caps: CapabilitySet = resolveCapabilities(this.config),\n graphCaps: GraphConstructionCapabilitySet = resolveGraphConstructionCapabilities(this.config),\n ): Promise<string> {\n const recallStart = Date.now();\n // Backend degradations observed by this recall's QMD searches (#1536):\n // collected via the execution-options observer and attached to the\n // LastRecallSnapshot after it is recorded, so surfaces can distinguish\n // \"no matches\" from \"backend could not answer\" (CLAUDE.md rule 34).\n const backendDegradations: SearchDegradation[] = [];\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: caps.recallPlanner,\n graphRecallEnabled: caps.graphRecall,\n multiGraphMemoryEnabled: graphCaps.multiGraphMemory,\n graphExpandedIntentEnabled: caps.graphExpandedIntent,\n prompt,\n };\n // Issue #1547 — let the heuristic decide no_recall BEFORE the planner/non-planner fork so it fires with planner on OR off.\n const requestedMode: RecallPlanMode | undefined = options.mode ?? (planRecallMode(prompt) === \"no_recall\" ? \"no_recall\" : undefined);\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 caps,\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 const namespacesEnabled = this.config.namespacesEnabled;\n if (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 if (\n namespaceOverride &&\n !canReadNamespace(principal, namespaceOverride, this.config)\n ) {\n throw new Error(\n `namespace override is not readable: ${namespaceOverride}`,\n );\n }\n // Resolve every namespace-bearing field through ONE ScopePlan (#1521): the\n // read set, the LCM read keys, the coding overlay, and the scope-profile plan\n // all come from a single pure resolver that delegates to the same helpers\n // the inline code used. Parity snapshots in scope-plan.test.ts pin the\n // outputs so this migration cannot change behavior.\n //\n // Catalog read touch (issue #1499) is recorded LATER — after the Phase 1\n // abort gate — so it fires only when retrieval actually runs, not for\n // aborted / short-circuited recalls.\n const scopePlan = resolveScopePlan({\n config: this.config,\n sessionKey,\n namespace: options.namespace,\n principalOverride:\n typeof options.principalOverride === \"string\"\n && options.principalOverride.length > 0\n ? options.principalOverride\n : undefined,\n codingContext: sessionKey\n ? this.getCodingContextForSession(sessionKey)\n : null,\n namespacesEnabled,\n });\n const {\n readNamespaces: recallNamespaces,\n baseNamespace: selfNamespace,\n scopeProfilePlan,\n lcmReadSessionIds,\n } = scopePlan;\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: caps.recallPlanner,\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: caps.graphRecall,\n multiGraphMemoryEnabled: graphCaps.multiGraphMemory,\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.storageRouter.recordRead(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 /**\n * Degradations observed while producing this phase result (#1536).\n * Cached WITH the result so cache hits replay them — a served-from-\n * cache partial result must still explain why it is partial (codex\n * round-4 review on #1544).\n */\n degradations?: SearchDegradation[];\n } | null;\n\n const qmdEnrichmentAbort = createEnrichmentAbortHandle(options.abortSignal);\n const qmdPromise = observeEnrichmentPromise(\n (async (): Promise<QmdPhaseResult> => {\n const t0 = Date.now();\n // Degradation accounting for this phase (#1536): everything pushed\n // after this mark belongs to this phase and is cached with its\n // result; cache hits and stale fallbacks replay stored degradations\n // so served-from-cache results still explain their gaps, and every\n // path that skips QMD entirely reports backend_unavailable.\n const phaseDegradationsStart = backendDegradations.length;\n const replayCachedDegradations = (value: {\n degradations?: SearchDegradation[];\n }) => {\n for (const degradation of value.degradations ?? []) {\n backendDegradations.push(degradation);\n }\n };\n const reportRecallQmdUnavailable = (detail: string) => {\n backendDegradations.push({\n backend: \"qmd\",\n code: \"backend_unavailable\",\n detail,\n });\n };\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 replayCachedDegradations(cachedQmd.value);\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 reportRecallQmdUnavailable(\"served stale recall cache (reprobe cooldown)\");\n replayCachedDegradations(staleQmdFallback.value);\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 reportRecallQmdUnavailable(\"recall skipped QMD (reprobe cooldown)\");\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 reportRecallQmdUnavailable(\"served stale recall cache (reprobe failed)\");\n replayCachedDegradations(staleQmdFallback.value);\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 reportRecallQmdUnavailable(\"recall skipped QMD (reprobe failed)\");\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 onDegradation: (degradation) => {\n backendDegradations.push(degradation);\n },\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 phaseDegradations = backendDegradations.slice(\n phaseDegradationsStart,\n );\n const result = {\n memoryResultsLists: [augmentedResults],\n globalResults: [],\n preAugmentTopScore,\n maxSpecializedScore,\n ...(phaseDegradations.length > 0\n ? { degradations: phaseDegradations }\n : {}),\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 reportRecallQmdUnavailable(\"served stale recall cache (qmd phase error)\");\n replayCachedDegradations(staleQmdFallback.value);\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 () => {\n // The enrichment budget abandoned the hot QMD phase mid-flight\n // (#1536, codex round-7 on #1544): QmdClient treats this abort as\n // caller cancellation and never reports, so report the abandonment\n // deterministically here — the exact mirror of the cold-tier\n // deadline gate. Guarded: a CALLER abort also routes through this\n // cancel callback, and an aborted recall is not a backend\n // degradation (no snapshot is recorded for it anyway).\n if (!options.abortSignal?.aborted) {\n backendDegradations.push({\n backend: \"qmd\",\n code: \"deadline_exceeded\",\n detail: \"hot qmd enrichment abandoned (enrichment deadline)\",\n });\n }\n qmdEnrichmentAbort.cancel();\n },\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 ? this.recallAssemblyClockMs() + 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 - this.recallAssemblyClockMs());\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 - this.recallAssemblyClockMs());\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 graphCaps.multiGraphMemory &&\n caps.graphAssistInFullMode &&\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: caps.rerankCache,\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 (caps.recallMemoryWorthFilter && 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 (caps.recallConfidenceGate && 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 caps,\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 caps,\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 caps,\n graphCaps,\n queryAwarePrefilter,\n abortSignal: options.abortSignal,\n onDegradation: (degradation) => {\n backendDegradations.push(degradation);\n },\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, sessionKey),\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 caps,\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 caps,\n graphCaps,\n queryAwarePrefilter,\n abortSignal: options.abortSignal,\n onDegradation: (degradation) => {\n backendDegradations.push(degradation);\n },\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 caps,\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 caps,\n graphCaps,\n queryAwarePrefilter,\n abortSignal: options.abortSignal,\n onDegradation: (degradation) => {\n backendDegradations.push(degradation);\n },\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 caps,\n graphCaps,\n queryAwarePrefilter,\n abortSignal: options.abortSignal,\n onDegradation: (degradation) => {\n backendDegradations.push(degradation);\n },\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 let sourceSpan: RecallXrayResult[\"sourceSpan\"] | 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 // Claim-level provenance span (#1575 PR 3): surface the first\n // source excerpt so the X-ray shows the literal utterance this\n // fact derives from. Thin read from already-loaded frontmatter.\n const fm = memory.frontmatter;\n if (fm.sources && fm.sources.length > 0) {\n sourceSpan = {\n quote: fm.sources[0]!.quote,\n observedAt: fm.sources[0]!.observedAt,\n provenance: fm.provenance ?? \"none\",\n };\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 ...(sourceSpan ? { sourceSpan } : {}),\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 // Included at record time so the published snapshot is born\n // annotated — a post-record annotation leaves a window where\n // readers see the snapshot without degradations, and a concurrent\n // same-session recall could drop them entirely (codex + cursor\n // reviews on #1544).\n backendDegradations:\n backendDegradations.length > 0 ? backendDegradations : undefined,\n })\n .catch((err) => log.debug(`last recall record failed: ${err}`));\n // Issue #1582 — record the admitted memory-id set for handle resolution.\n // Only when handles are enabled: if injection is off, no handle is ever\n // rendered, so there is nothing to resolve and we skip the write.\n if (this.config.recallMemoryHandles && recalledMemoryIds.length > 0) {\n // Only handle-eligible ids aid resolution; filter out non-memory .md\n // basenames (entity reconstructions) so the resolver never records a\n // citation target that cannot be loaded.\n const handleEligibleIds = recalledMemoryIds.filter((id) =>\n MEMORY_ID_PATTERN.test(id),\n );\n if (handleEligibleIds.length > 0) {\n this.handleHistory\n .record(sessionKey, handleEligibleIds)\n .catch((err) => log.debug(`handle history record failed: ${err}`));\n }\n }\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 captureTimestamp = new Date().toISOString();\n // Issue #1582 hygiene §2 — strip any echoed `[m:xxxx]` handle before the\n // turn enters the extraction buffer so handles never become memory content\n // or get QMD-indexed (rule 23). Gated on the feature flag: when handles are\n // off none are ever injected, so there is nothing to strip and the buffer\n // stays byte-identical to the pre-#1582 path.\n const bufferedContent = this.config.recallMemoryHandles\n ? stripHandles(content)\n : content;\n const turn: BufferTurn = {\n role,\n content: bufferedContent,\n timestamp: captureTimestamp,\n // #1578: anchor live-capture turns to wall-clock when bi-temporal is on;\n // replay/import turns carry sourceValidAt explicitly (codex P1).\n ...(this.config.temporalBiTemporal\n ? { sourceValidAt: captureTimestamp }\n : {}),\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 /**\n * Passive correction capture (issue #1581) — detects corrections expressed\n * passively in conversation turns and routes them to the Correction Contract\n * (#1580). Called from `runExtraction` after persistence completes.\n *\n * Thin wiring: delegates ALL correction logic to the detector + capture\n * modules + the CorrectionService. This method only checks gates, calls the\n * detector, and routes results. Fail-open: capture errors never block the\n * extraction return path.\n */\n private async maybeCapturePassiveCorrections(\n turns: readonly BufferTurn[],\n opts: {\n sessionKey: string;\n principal?: string;\n namespace: string;\n bufferKey: string;\n isLiveSession: boolean;\n },\n ): Promise<void> {\n const mode = this.config.correctionCaptureMode;\n if (mode === \"off\") return;\n if (!this.config.correctionEnabled) return;\n\n try {\n const corrections = detectPassiveCorrections(\n turns.map((t) => ({ role: t.role, content: t.content })),\n );\n if (corrections.length === 0) return;\n\n // Replay/import: force queue-only mode even if config says auto.\n const effectiveMode = opts.isLiveSession ? mode : \"queue\";\n const captureConfig: PassiveCaptureConfig = {\n mode: effectiveMode,\n confidenceFloor: this.config.correctionCaptureConfidenceFloor,\n autoApplyMaxAffected: this.config.correctionCaptureAutoApplyMaxAffected,\n };\n\n const service = this.passiveCorrectionService();\n const result = await capturePassiveCorrections(\n corrections,\n {\n correctionEnabled: this.config.correctionEnabled,\n isLiveSession: opts.isLiveSession,\n bufferKey: opts.bufferKey,\n sessionKey: opts.sessionKey,\n principal: opts.principal,\n namespace: opts.namespace,\n },\n captureConfig,\n {\n planCorrection: (req) => service.plan(req),\n applyCorrection: (planId, applyOpts) => service.apply(planId, applyOpts),\n storageDir: async (ns) => (await this.getStorage(ns)).dir,\n // Resolve `[m:xxxx]` handles to concrete memory ids via the single\n // shared helper (#1582). Returns null on miss/ambiguity so the\n // capture loop drops the handle and the planner falls back to text\n // search (review: \"memory handles not resolved\").\n resolveHandle: (ref, sessionKey) => {\n try {\n return this.resolveMemoryIdOrHandle(ref, sessionKey);\n } catch {\n return null;\n }\n },\n },\n this.passiveCorrectionDedup,\n );\n\n // Accumulate telemetry\n this.passiveCorrectionTelemetry.detected += result.telemetry.detected;\n this.passiveCorrectionTelemetry.queued += result.telemetry.queued;\n this.passiveCorrectionTelemetry.autoApplied += result.telemetry.autoApplied;\n for (const [reason, count] of Object.entries(result.telemetry.suppressedReasons)) {\n this.passiveCorrectionTelemetry.suppressedReasonCounts[reason] =\n (this.passiveCorrectionTelemetry.suppressedReasonCounts[reason] ?? 0) + count;\n }\n } catch (err) {\n // Fail-open: passive capture never blocks extraction.\n log.debug(\n `passive-correction: capture failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n /** Lazily construct the CorrectionService for passive capture. Stateless\n * across requests (per #1580 design); cached for the orchestrator's life. */\n private passiveCorrectionService(): CorrectionService {\n if (this._passiveCorrectionService) return this._passiveCorrectionService;\n this._passiveCorrectionService = createCorrectionService({\n orchestrator: this,\n // Session-scoped write ACL (review: \"passive capture bypasses write\n // ACL\"). A correction detected in session S plans only against S readable\n // namespaces and applies only to writable ones (rule 42) — passive\n // capture never becomes a cross-tenant mutation vector. Mirrors the\n // access-service createCorrectionService wiring rather than bypassing it.\n resolveAuthorizedNamespace: async (req) => {\n const principal = req.principal || resolvePrincipal(req.sessionKey, this.config);\n const ns = req.namespace ?? defaultNamespaceForPrincipal(principal, this.config);\n if (!canWriteNamespace(principal, ns, this.config)) {\n throw new Error(\n `passive correction: namespace \"${ns}\" is not writable for principal ${principal ?? \"(none)\"}`,\n );\n }\n return ns;\n },\n resolveReadableNamespaces: (req) => {\n const principal = req.principal || resolvePrincipal(req.sessionKey, this.config);\n return recallNamespacesForPrincipal(principal, this.config);\n },\n canWriteNamespace: async (req) => {\n const principal = req.principal || resolvePrincipal(req.sessionKey, this.config);\n return canWriteNamespace(principal, req.namespace, this.config);\n },\n llmComplete: async ({ system, user }) => {\n const llmResult = await this.localLlm.chatCompletion(\n [\n { role: \"system\", content: system },\n { role: \"user\", content: user },\n ],\n { operation: \"correction-classify\", priority: \"background\" },\n );\n if (!llmResult) {\n throw new Error(\n \"passive correction classify+draft: local LLM unavailable (disabled or in cooldown)\",\n );\n }\n return llmResult.content;\n },\n });\n return this._passiveCorrectionService;\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 // Context-only turns may still contain corrections (review: \"context-only\n // turns skip capture\"). Scan normalizedTurns before clearing the buffer.\n if (normalizedTurns.length > 0) {\n await this.maybeCapturePassiveCorrections(normalizedTurns as BufferTurn[], { sessionKey, principal: resolvePrincipal(sessionKey, this.config), namespace: this.resolveSelfNamespace(sessionKey), bufferKey, isLiveSession: clearBufferAfterExtraction });\n }\n await clearBuffer();\n return { status: \"skipped\", reason: \"empty_normalized_turns\", persistedCount: 0, durableOutputCount: 0 };\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 // Passive correction capture runs even when extraction is skipped for\n // being below the char/user-turn threshold (review: \"skipped extraction\n // skips capture\"). A short correction like \"stop using Vim\" is under\n // extractionMinChars but is exactly the high-value case this feature\n // exists for. The write namespace resolves through the SAME scope-profile\n // plan as the full extraction path so corrections target the active\n // profile's write layer, not just resolveSelfNamespace (review:\n // \"below-threshold wrong namespace\"). The ACL in passiveCorrectionService\n // authorizes the actual plan/apply.\n {\n const capturePrincipal =\n typeof options.principalOverride === \"string\" && options.principalOverride.length > 0\n ? options.principalOverride\n : resolvePrincipal(sessionKey, this.config);\n const captureWO = typeof options.writeNamespaceOverride === \"string\" && options.writeNamespaceOverride.length > 0\n ? options.writeNamespaceOverride : undefined;\n const captureCodingCtx = sessionKey ? this.getCodingContextForSession(sessionKey) : null;\n const captureCodingOv = resolveCodingNamespaceOverlay(captureCodingCtx, this.config.codingMode, this.config.defaultNamespace);\n const captureScopePlan = resolveScopeProfilePlan({ config: this.config, principal: capturePrincipal, codingContext: captureCodingCtx, codingOverlay: captureCodingOv });\n const captureNamespace = captureWO ?? captureScopePlan?.writeNamespace ?? this.resolveSelfNamespace(sessionKey);\n await this.maybeCapturePassiveCorrections(normalizedTurns as BufferTurn[], {\n sessionKey, principal: capturePrincipal, namespace: captureNamespace, bufferKey, isLiveSession: clearBufferAfterExtraction,\n });\n }\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 // Correction-only turns that meet char/user-turn thresholds but yield\n // zero facts still need passive capture (review: \"empty extraction skips\n // capture\"). selfNamespace/principal already resolved above.\n await this.maybeCapturePassiveCorrections(normalizedTurns as BufferTurn[], { sessionKey, principal, namespace: selfNamespace, bufferKey, isLiveSession: clearBufferAfterExtraction });\n await clearBuffer();\n return { status: \"skipped\", reason: \"empty_extraction_result\", persistedCount: 0, durableOutputCount: 0 };\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 // Verbatim source turns for the faithfulness gate (#1576) so it can\n // locate a quote per fact when #1575 spans are absent.\n normalizedTurns.map((t) => t.content).join(\"\\n\\n\"),\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 // Passive correction capture (issue #1581) — detect corrections expressed\n // passively in the extracted turns and route to the Correction Contract.\n // Runs AFTER persistence + buffer clear so a capture failure never blocks\n // the extraction return. `clearBufferAfterExtraction` gates live-session\n // auto-apply (replay/import → queue-only).\n await this.maybeCapturePassiveCorrections(normalizedTurns as BufferTurn[], {\n sessionKey,\n principal,\n namespace: selfNamespace,\n bufferKey,\n isLiveSession: clearBufferAfterExtraction,\n });\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. The helper excludes pending_review ids (#1635).\n if (\n this.config.threadingEnabled &&\n threadIdForExtraction &&\n persistedIds.length > 0\n ) {\n await this.appendPersistedThreadEpisodes(\n threadIdForExtraction,\n persistedIds,\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 // The increment of nonZeroExtractionsSinceConsolidation moved into\n // the scheduler with the rest of the cadence state (issue #1526 PR1).\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 this.maintenanceScheduler.maybeScheduleConsolidation(\n nonZeroExtraction,\n () => this.runConsolidation(),\n );\n }\n\n requestQmdMaintenance(): void {\n this.maintenanceScheduler.requestQmdMaintenanceForTool(\"__internal__\");\n }\n\n /**\n * Public entrypoint for tool-driven QMD maintenance requests.\n * Delegates to the maintenance scheduler (issue #1526 PR1).\n */\n requestQmdMaintenanceForTool(reason: string): void {\n this.maintenanceScheduler.requestQmdMaintenanceForTool(reason);\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 /** Verbatim source turn text the facts were extracted from (faithfulness gate #1576). */\n sourceText?: string,\n graphCaps: GraphConstructionCapabilitySet = resolveGraphConstructionCapabilities(this.config),\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 persistedIds: string[] = [];\n const supersessionOrderingAt = (validAt?: string): string =>\n validAt && validAt.length > 0 ? validAt : new Date().toISOString();\n // #1635: pending_review persisted ids, excluded from the thread episode set below.\n const pendingReviewPersistedIds: 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: {\n includeReturnedIds?: boolean;\n /** #1635: keep this id out of the persisted thread episode set. */\n pendingReview?: boolean;\n } = {},\n ): void => {\n if (options.includeReturnedIds !== false) {\n persistedIds.push(id);\n }\n if (options.pendingReview) {\n pendingReviewPersistedIds.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.storageDirNamespace(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 // #1578 — bi-temporal bounds + ingestion provenance forwarded to profile-\n // target copies (same defect class as shared promotion; cursor bugbot).\n invalidAt?: string;\n observedAt?: string;\n eventTimeSource?: \"extracted\" | \"assumed\";\n source: string;\n sources?: ProvenanceSource[];\n provenance?: \"verified\" | \"unverified\" | \"none\";\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 // #1578 — forward bi-temporal bounds + ingestion provenance.\n ...(options.invalidAt ? { invalidAt: options.invalidAt } : {}),\n ...(options.observedAt ? { observedAt: options.observedAt } : {}),\n ...(options.eventTimeSource ? { eventTimeSource: options.eventTimeSource } : {}),\n contentHashSource: options.category === \"fact\" ? dedupContent : rawContent,\n ...(options.sources && options.sources.length > 0 ? { sources: options.sources } : {}),\n ...(options.provenance ? { provenance: options.provenance } : {}),\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: !(options.eventTimeSource === \"extracted\" && !options.validAt),\n });\n } catch (profileSupersessionErr) {\n log.warn(\n `persistExtraction: ${target.target} promotion temporal supersession failed open for promoted ${promotedId}: ${profileSupersessionErr}`,\n );\n }\n }\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 // #1578 — bi-temporal bounds + ingestion provenance forwarded to the\n // shared-namespace copy so shared recall honours the same invalid_at\n // window as the source fact (cursor bugbot).\n invalidAt?: string;\n observedAt?: string;\n eventTimeSource?: \"extracted\" | \"assumed\";\n source: string;\n /** Claim-level provenance spans (issue #1575 PR 2). */\n sources?: ProvenanceSource[];\n provenance?: \"verified\" | \"unverified\" | \"none\";\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: !(options.eventTimeSource === \"extracted\" && !options.validAt),\n useCallerTimestamp: true,\n });\n // Catalog touch (issue #1499 — codex P2 NElSf): this dedup branch\n // returns WITHOUT the post-write catalog touch (now at the storage chokepoint #1522),\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 (the storage chokepoint swallows\n // errors); only touch when work happened to avoid spurious writes.\n if (hashDedupSupersession.supersededIds.length > 0) {\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 // #1578 — forward bi-temporal bounds + ingestion provenance.\n ...(options.invalidAt ? { invalidAt: options.invalidAt } : {}),\n ...(options.observedAt ? { observedAt: options.observedAt } : {}),\n ...(options.eventTimeSource ? { eventTimeSource: options.eventTimeSource } : {}),\n contentHashSource: options.category === \"fact\" ? dedupContent : rawContent,\n // Claim-level provenance spans (issue #1575 PR 2).\n ...(options.sources && options.sources.length > 0 ? { sources: options.sources } : {}),\n ...(options.provenance ? { provenance: options.provenance } : {}),\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: !(options.eventTimeSource === \"extracted\" && !options.validAt),\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 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 (graphCaps.multiGraphMemory) {\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 (graphCaps.multiGraphMemory && 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 // Faithfulness gate (issue #1576). Entailment-verification of extracted\n // facts against their verified source spans from #1575. Placement: after\n // parse + provenance validation, BEFORE persist/index (rule 44). The\n // substantive batch logic lives in the pure module; this is thin\n // delegation (ground rule 4). off → null map (byte-identical pre-feature\n // pipeline, rule 39); shadow → record only; enforce → pending_review.\n const faithfulnessMode = this.config.extractionFaithfulnessGate;\n const faithfulnessResultsByFactIndex =\n faithfulnessMode === \"shadow\" || faithfulnessMode === \"enforce\"\n ? await runFaithfulnessGateBatch(\n facts,\n faithfulnessMode,\n this.config,\n this.localLlm,\n new FallbackLlmClient(\n this.config.gatewayConfig,\n fallbackLlmRuntimeContextFromConfig(this.config),\n ),\n this.faithfulnessCounters,\n sourceText,\n )\n : null;\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 const biTemporal = this.config.temporalBiTemporal && sourceContext?.validAt ? resolveFactEventTime(fact.eventTime, sourceContext.validAt) : undefined;\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.storageDirNamespace(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.storageDirNamespace(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 // Faithfulness gate verdict application (issue #1576). Look up the\n // pre-computed verdict for this fact and translate it to frontmatter +\n // an optional enforce-mode pending_review status. Logic lives in the\n // pure module; this is thin read-through (ground rule 4).\n const { faithfulness: faithfulnessFm, enforceStatus: faithfulnessGateStatus } =\n applyFaithfulnessVerdict(\n faithfulnessResultsByFactIndex,\n factLoopIndex,\n faithfulnessMode,\n fact.content,\n this.faithfulnessCounters,\n );\n\n // requireSpans enforcement (issue #1575 PR 2): when an operator opts\n // into provenance.requireSpans, a fact whose quote could not be located\n // in any source turn (carried as the transient requireSpansPending\n // signal from the extraction validator) routes to pending_review — the\n // same review queue an unsupported faithfulness verdict uses. This is\n // the persist-path wiring ProvenanceConfig.requireSpans documents.\n // Faithfulness takes precedence when it already routed the fact; both\n // gates agree on pending_review so the merge is a simple coalesce\n // (chatgpt-codex-connector thread 4xB).\n const requireSpansPendingStatus =\n this.config.provenance?.requireSpans === true &&\n fact.requireSpansPending === true\n ? (\"pending_review\" as const)\n : undefined;\n const faithfulnessEnforceStatus = faithfulnessGateStatus ?? requireSpansPendingStatus;\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 // Faithfulness gate (#1576, chatgpt P2): skip contradiction detection\n // for a pending_review fact — an unfaithful extraction in the review queue\n // must not trigger auto-resolve and retire an existing active memory.\n if (\n this.config.contradictionDetectionEnabled &&\n this.qmd.isAvailable() &&\n faithfulnessEnforceStatus !== \"pending_review\"\n ) {\n const targetNamespace = this.storageDirNamespace(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 // Faithfulness gate (#1576, cursor High): a pending_review fact must\n // bypass the semantic-dedup skip so it reaches the review queue — the\n // gate's contract is \"persists with status: pending_review, never\n // silently dropped\" (issue #1576).\n if (\n pendingSemanticSkip &&\n !contradictionDetected &&\n !isCorrection &&\n faithfulnessEnforceStatus !== \"pending_review\"\n ) {\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 // 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: biTemporal ? biTemporal.validFrom : sourceContext?.validAt,\n ...(biTemporal ? { observedAt: biTemporal.observedAt, eventTimeSource: biTemporal.eventTimeSource, ...(biTemporal.validUntil ? { invalidAt: biTemporal.validUntil } : {}) } : {}),\n contentHashSource: rawChunkedContent,\n // Faithfulness gate (issue #1576).\n ...(faithfulnessFm ? { faithfulness: faithfulnessFm } : {}),\n ...(faithfulnessEnforceStatus ? { status: faithfulnessEnforceStatus } : {}),\n // Claim-level provenance spans (issue #1575 PR 2).\n ...(fact.sources && fact.sources.length > 0 ? { sources: fact.sources } : {}),\n ...(fact.provenance ? { provenance: fact.provenance } : {}),\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: biTemporal ? biTemporal.validFrom : sourceContext?.validAt,\n // #1578: propagate end bound + provenance to chunks (cursor bugbot).\n ...(biTemporal\n ? {\n observedAt: biTemporal.observedAt,\n eventTimeSource: biTemporal.eventTimeSource,\n ...(biTemporal.validUntil\n ? { invalidAt: biTemporal.validUntil }\n : {}),\n }\n : {}),\n // Faithfulness gate (issue #1576): propagate the parent\n // fact's verdict + enforce status so a pending_review fact\n // is not indexed as active through its chunks (chatgpt P2).\n ...(faithfulnessFm ? { faithfulness: faithfulnessFm } : {}),\n ...(faithfulnessEnforceStatus ? { status: faithfulnessEnforceStatus } : {}),\n // Claim-level provenance (issue #1575 PR 2): mirror the\n // parent's spans onto each chunk so a chunk surfaced\n // independently (memory_get/x-ray on a chunk ID) preserves\n // the verified span (chatgpt-codex-connector thread Ocvmo).\n ...(fact.sources && fact.sources.length > 0 ? { sources: fact.sources } : {}),\n ...(fact.provenance ? { provenance: fact.provenance } : {}),\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 }\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 pendingReview: faithfulnessEnforceStatus === \"pending_review\",\n });\n // #1576 (cursor Medium): keep pending_review ids out of threadEpisodeIdsForGraph — else later active facts build thread-predecessor edges to an unfaithful memory.\n if (\n faithfulnessEnforceStatus !== \"pending_review\" &&\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 // Faithfulness gate (#1576, cursor High): skip supersession for a\n // pending_review fact — an unfaithful extraction in the review queue\n // must NOT retire older active memories.\n if (faithfulnessEnforceStatus !== \"pending_review\") {\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(biTemporal?.validFrom ?? sourceContext?.validAt),\n // #1578 r3: an extracted end-only bound (validFrom absent) is\n // historical, not a new authoritative state — never let it\n // supersede a later active fact (codex P1 on :15534).\n enabled: this.config.temporalSupersessionEnabled &&\n !(biTemporal && !biTemporal.validFrom),\n });\n } catch (err) {\n log.warn(`temporal-supersession (chunked): unexpected error: ${err}`);\n }\n }\n // Faithfulness gate (#1576, chatgpt P2): do not promote a\n // pending_review fact to shared/profile — it must enter the review\n // queue without active copies that bypass the gate.\n if (faithfulnessEnforceStatus !== \"pending_review\") 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: biTemporal ? biTemporal.validFrom : sourceContext?.validAt,\n ...(biTemporal\n ? {\n observedAt: biTemporal.observedAt,\n eventTimeSource: biTemporal.eventTimeSource,\n ...(biTemporal.validUntil ? { invalidAt: biTemporal.validUntil } : {}),\n }\n : {}),\n source: extractionWriteSource,\n ...(fact.sources && fact.sources.length > 0 ? { sources: fact.sources } : {}),\n ...(fact.provenance ? { provenance: fact.provenance } : {}),\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 faithfulnessEnforceStatus !== \"pending_review\"\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. #1576: skip pending_review.\n if (graphCaps.multiGraphMemory && faithfulnessEnforceStatus !== \"pending_review\") {\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 graphCaps,\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 }\n trackBehaviorSignals(\n targetStorage,\n buildBehaviorSignalsForMemory({\n memoryId: parentId,\n category: writeCategory,\n content: fact.content,\n namespace: this.storageDirNamespace(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.storageDirNamespace(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 // 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 // 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: biTemporal ? biTemporal.validFrom : sourceContext?.validAt,\n ...(biTemporal ? { observedAt: biTemporal.observedAt, eventTimeSource: biTemporal.eventTimeSource, ...(biTemporal.validUntil ? { invalidAt: biTemporal.validUntil } : {}) } : {}),\n contentHashSource: writeCategory === \"fact\" ? fact.content : undefined,\n // Faithfulness gate (issue #1576).\n ...(faithfulnessFm ? { faithfulness: faithfulnessFm } : {}),\n ...(faithfulnessEnforceStatus ? { status: faithfulnessEnforceStatus } : {}),\n // Claim-level provenance spans (issue #1575 PR 2). Carry verified\n // sources + the coarse strength tag from the extraction validator\n // through to frontmatter so they survive end-to-end.\n ...(fact.sources && fact.sources.length > 0 ? { sources: fact.sources } : {}),\n ...(fact.provenance ? { provenance: fact.provenance } : {}),\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. Faithfulness gate (#1576, cursor\n // High): skip for a pending_review fact — an unfaithful extraction in\n // the review queue must NOT retire older active memories.\n if (faithfulnessEnforceStatus !== \"pending_review\") {\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(biTemporal?.validFrom ?? sourceContext?.validAt),\n enabled: this.config.temporalSupersessionEnabled &&\n !(biTemporal && !biTemporal.validFrom),\n });\n } catch (err) {\n log.warn(`temporal-supersession: unexpected error: ${err}`);\n }\n }\n try {\n trackBehaviorSignals(\n targetStorage,\n buildBehaviorSignalsForMemory({\n memoryId,\n category: writeCategory,\n content: fact.content,\n namespace: this.storageDirNamespace(targetStorage.dir),\n confidence: fact.confidence,\n source: \"extraction\",\n }),\n );\n trackPersistedId(targetStorage, memoryId, {\n pendingReview: faithfulnessEnforceStatus === \"pending_review\",\n });\n if (\n faithfulnessEnforceStatus !== \"pending_review\" &&\n threadEpisodeIdsForGraph &&\n !threadEpisodeIdsForGraph.includes(memoryId)\n ) {\n threadEpisodeIdsForGraph.push(memoryId);\n }\n await this.indexPersistedMemory(targetStorage, memoryId);\n // Faithfulness gate (#1576, chatgpt P2): skip promotion for a\n // pending_review fact so no active shared/profile copy bypasses the gate.\n if (faithfulnessEnforceStatus !== \"pending_review\") 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: biTemporal ? biTemporal.validFrom : sourceContext?.validAt,\n ...(biTemporal\n ? {\n observedAt: biTemporal.observedAt,\n eventTimeSource: biTemporal.eventTimeSource,\n ...(biTemporal.validUntil ? { invalidAt: biTemporal.validUntil } : {}),\n }\n : {}),\n source: extractionWriteSource,\n ...(fact.sources && fact.sources.length > 0 ? { sources: fact.sources } : {}),\n ...(fact.provenance ? { provenance: fact.provenance } : {}),\n });\n // v8.2: graph edge building (fail-open). #1576: skip pending_review facts.\n if (graphCaps.multiGraphMemory && faithfulnessEnforceStatus !== \"pending_review\") {\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 graphCaps,\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 faithfulnessEnforceStatus !== \"pending_review\"\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 }\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 catalog touch (storage chokepoint #1522) 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.storageDirNamespace(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 catalog touch (storage chokepoint #1522) 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 (storage chokepoint #1522 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 // #1635: surface pending_review ids so the thread episode set excludes them.\n this.lastPersistExtractionPendingReviewIds = pendingReviewPersistedIds;\n // Return the persisted fact IDs for threading\n return persistedIds;\n }\n /**\n * Append persisted ids to the thread episode set, excluding pending_review\n * fact ids (#1635) so they don't re-seed predecessor edges. Fail-open like\n * the raw appendEpisodeIds call it replaces.\n */\n private async appendPersistedThreadEpisodes(\n threadId: string,\n persistedIds: string[],\n ): Promise<void> {\n const pendingReviewIds = this.lastPersistExtractionPendingReviewIds ?? [];\n const episodeIds =\n pendingReviewIds.length > 0\n ? persistedIds.filter((id) => !pendingReviewIds.includes(id))\n : persistedIds;\n if (episodeIds.length === 0) return;\n try {\n await this.threading.appendEpisodeIds(threadId, episodeIds);\n } catch (err) {\n log.warn(\n \"[threading] appendEpisodeIds failed after persistence (non-fatal)\",\n err,\n );\n }\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 graphCaps: GraphConstructionCapabilitySet = resolveGraphConstructionCapabilities(this.config),\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 graphCaps.graphWriteSessionAdjacency &&\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 graphCapsOverride: {\n entityGraph: graphCaps.entityGraph,\n timeGraph: graphCaps.timeGraph,\n causalGraph: graphCaps.causalGraph,\n multiGraphMemory: graphCaps.multiGraphMemory,\n },\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\" && m.frontmatter.status !== \"archived\" &&\n m.frontmatter.status !== \"forgotten\" && m.frontmatter.status !== \"pending_review\", // #1576: unfaithful queue items must not feed TMT clusters\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 — belt-and-suspenders for cleanup-only\n // passes that mutate the store via delete-only paths (entity merges, TTL\n // cleanup) without triggering the storage chokepoint's post-write hook.\n // Gated on memoryItemMutated (set by every durable mutation including cleanup-only passes)\n // Best-effort and failure-tolerant.\n if (memoryItemMutated) {\n this.storageRouter.recordWrite(this.config.defaultNamespace, this.storage.dir);\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 }\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 // #1522: catalog touch handled at the storage chokepoint.\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 (the storage chokepoint (#1522) 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 log.info(\n `IDENTITY(${namespace}) consolidated: ${identityContent.length} → ${newContent.length} chars, ${result.learnedPatterns.length} patterns`,\n );\n }\n }\n\n private formatQmdResults(\n title: string,\n results: QmdSearchResult[],\n sessionKey?: string,\n ): string {\n // Issue #1582 — handles are only rendered when a session key is available:\n // resolution requires the handle history to have been recorded for this\n // session, which only happens when sessionKey is present. Rendering handles\n // without recording would show tokens a user can never resolve (cursor\n // review). The rendering logic itself lives in the pure handles module.\n const handleByIndex = buildHandleIndexForResults(\n results,\n this.config.recallMemoryHandles === true && sessionKey != null,\n );\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 const head = `[${i + 1}] ${source} (score: ${r.score.toFixed(3)})\\n${snippet}`;\n const handle = handleByIndex.get(i);\n return handle ? `${head.replace(/\\s+$/, \"\")} ${handle}` : head;\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, options.sessionKey),\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.storageDirNamespace(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.storageDirNamespace(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 // `caps` is additive AND last (issue #1523) so the positional call shape\n // stays backward-compatible: the recall pipeline threads a resolved set,\n // but callers that omit it (e.g. direct unit-test invocations) get an\n // equivalent set derived from the same config — behavior-preserving.\n caps: CapabilitySet = resolveCapabilities(this.config),\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 caps.recallReasoningTraceBoost && typeof retrievalQuery === \"string\"\n ? applyReasoningTraceBoost(results, {\n enabled: true,\n query: retrievalQuery,\n })\n : results;\n const diversified = this.applyMmrToQmdResults(sectionId, boosted, caps);\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 // Additive `caps` (issue #1523); defaults to a config-derived set so direct\n // callers that omit it behave identically to the threaded recall path.\n caps: CapabilitySet = resolveCapabilities(this.config),\n ): QmdSearchResult[] {\n if (!caps.recallMmr) 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 /**\n * Recall-operation capability gates resolved once at recall entry (#1523).\n * OPTIONAL and additive: the recall pipeline threads a resolved set, but\n * callers that omit it (e.g. direct unit-test invocations) get an\n * equivalent config-derived set — behavior-preserving.\n */\n caps?: CapabilitySet;\n /** Graph-construction gates resolved at recall entry (#1566 Cluster A). */\n graphCaps?: GraphConstructionCapabilitySet;\n queryAwarePrefilter?: QueryAwarePrefilter;\n abortSignal?: AbortSignal;\n /** Backend degradation observer — cold-tier QMD must report like hot (#1536). */\n onDegradation?: (degradation: SearchDegradation) => void;\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 // Prefer the threaded set; fall back to a config-derived set so direct\n // callers (unit tests) behave identically to the recall pipeline (#1523).\n const caps = options.caps ?? resolveCapabilities(this.config);\n const graphCaps = options.graphCaps ?? resolveGraphConstructionCapabilities(this.config);\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 // Invoked when the deadline abandons this step (before it started or\n // while it runs), so callers can report the abandonment and gate off\n // late observer callbacks (#1536, cursor round-6 on #1544).\n onDeadline?: () => void,\n ): Promise<T> => {\n throwIfRecallAborted(options.abortSignal);\n const remainingMs = deadlineRemainingMs();\n if (remainingMs === 0) {\n try {\n onDeadline?.();\n } catch {\n // Observers must never break recall.\n }\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 try {\n onDeadline?.();\n } catch {\n // Observers must never break recall.\n }\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 // Deadline-gated observer (#1536, cursor round-6 on #1544): when the\n // shared assembly deadline abandons this lookup, the still-running\n // fetch's LATE reports must not land after the recall snapshot has\n // been recorded — gate them off and report the abandonment itself\n // deterministically at resolution time instead.\n let coldQmdObserverActive = true;\n const reportColdQmdDeadline = () => {\n coldQmdObserverActive = false;\n try {\n options.onDegradation?.({\n backend: \"qmd\",\n code: \"deadline_exceeded\",\n detail: \"cold-tier qmd lookup abandoned (assembly deadline)\",\n });\n } catch {\n // Observers must never break recall.\n }\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 onDegradation: (degradation) => {\n if (coldQmdObserverActive) {\n options.onDegradation?.(degradation);\n }\n },\n },\n ),\n reportColdQmdDeadline,\n );\n // Normal completion also closes the gate: a deadline that fires\n // after this await has nothing left to suppress, and a fetch that\n // limps home later cannot mutate a recorded recall's collector.\n coldQmdObserverActive = false;\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 graphCaps.multiGraphMemory &&\n caps.graphAssistInFullMode &&\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: caps.rerankCache,\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 (caps.recallMemoryWorthFilter && 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 caps,\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 biTemporalExpiredFilteredCount = 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 // Review-lifecycle statuses never enter active recall injection\n // (forgotten, pending_review, rejected, quarantined). Superseded and\n // archived have dedicated filters below. #1576: the faithfulness gate\n // routes unsupported/contradicted facts to pending_review — they must\n // not leak back via the QMD/embedding path. chatgpt P2.\n const recallStatus = memory.frontmatter.status;\n if (\n recallStatus === \"forgotten\" ||\n recallStatus === \"pending_review\" ||\n recallStatus === \"rejected\" ||\n recallStatus === \"quarantined\"\n ) {\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 // Bi-temporal INJECTION filter (issue #1578): when the master gate\n // is on and the caller did NOT pin `as_of`, drop facts whose event-\n // time interval has ended before now. This lives ONLY in the recall\n // injection path (filterSearchResultsByRecallSafety) — explicit\n // search (access-service.memorySearch → searchAcrossNamespaces /\n // qmd.search) never routes through here, so expired-validity facts\n // remain findable by memory_search and `as_of` queries (escape\n // hatch: the as_of branch above also admits historically-valid\n // records). Gated off entirely when `temporalExpiredInInjection` is\n // set. Status-orthogonal: an `active` fact can be validity-expired;\n // a `superseded` one may still be within its window.\n if (\n !asOfActive &&\n this.config.temporalBiTemporal &&\n !this.config.temporalExpiredInInjection &&\n isValidityExpiredNow(memory.frontmatter, Date.now())\n ) {\n biTemporalExpiredFilteredCount += 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 (biTemporalExpiredFilteredCount > 0) {\n log.debug(\n `bi-temporal validity filter removed ${biTemporalExpiredFilteredCount} expired-validity candidates from injection (temporal.biTemporal on)`,\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 * Issue #1582 — resolve a memory handle (`[m:4f2a]` / bare hex) to its memory\n * id against THIS session's recent recall history. Returns the id on a unique\n * hit, `null` on a miss, and throws on ambiguity (callers must disambiguate —\n * rule 34/51). Resolution is per-session and snapshot-scoped; there is no\n * global handle→id map (rule 42).\n */\n resolveMemoryHandle(handle: string, sessionKey: string): string | null {\n if (!sessionKey) return null;\n const depth = this.config.recallHandleSnapshotDepth;\n const snapshots: RecallSnapshotIds[] = this.handleHistory\n .recent(sessionKey, depth)\n .map((ids) => ({ memoryIds: ids }));\n const result = resolveHandle(handle, snapshots, depth);\n if (result.ok) return result.memoryId;\n if (result.reason === \"ambiguous\") {\n throw new Error(\n `Memory handle ${handle} is ambiguous in session ${sessionKey}: ` +\n `${result.candidates.join(\", \")}. Cite a unique memory id instead.`,\n );\n }\n return null;\n }\n\n /**\n * Issue #1582 — resolve a caller reference that may be EITHER a memory id or\n * a handle to a concrete memory id. Handles resolve against the session's\n * recall history; raw ids pass through unchanged. The single shared helper\n * every surface (memory_get / feedback / outcome / correction targetIds)\n * calls so handle resolution has one path (rule 22).\n */\n resolveMemoryIdOrHandle(ref: string, sessionKey?: string): string {\n const parsed = parseIdOrHandle(ref);\n if (!parsed.isHandle) return parsed.value;\n if (!sessionKey) {\n throw new Error(\n `Memory handle ${ref} cannot be resolved without a session key.`,\n );\n }\n const resolved = this.resolveMemoryHandle(parsed.value, sessionKey);\n if (resolved === null) {\n throw new Error(\n `Memory handle ${ref} was not found in the recent recall history for session ${sessionKey}.`,\n );\n }\n return resolved;\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 storageDirNamespace(storageDir: string): string {\n // #1521: delegates to the scope-module resolver. The inline dir→namespace\n // derivation (token round-trip guard, catalog hints) is retired so the\n // adHocNamespaceResolutions ratchet no longer counts this site. Hints are\n // loaded lazily via the callback (only after early returns, matching the\n // original behavior — codex P2).\n return resolveNamespaceFromStorageDir(storageDir, {\n config: this.config,\n configuredNamespaces: this.configuredNamespaceList(),\n hints: this.namespaceStorageDirHints,\n loadHints: () => this.loadNamespaceStorageDirHintsFromCatalog(),\n });\n }\n\n // #1522: catalog touch methods removed — touches now happen at the storage chokepoint.\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 owns the catalog touch. 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\n\n // markCatalogRead removed — use storageRouter.recordRead() instead (#1522).\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 { buildRetiredFactTombstoneInputs, type TombstoneReason, type TombstoneCreatedBy } from \"../lifecycle/tombstones.js\";\nimport { supersessionKeysForFact } from \"../temporal-supersession.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 * Best-effort tombstone append for retired duplicates (issue #1579 thread\n * Oblq9). Optional so unit-test stubs need not implement it; the production\n * StorageManager satisfies it via its appendTombstone chokepoint.\n */\n appendTombstone?(input: {\n reason: TombstoneReason;\n createdBy: TombstoneCreatedBy;\n sourceMemoryId: string;\n contentHash?: string;\n rawContent: string;\n entityRef?: string;\n supersessionKey?: string;\n createdAt: string;\n }): Promise<string | null>;\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 // Issue #1579 thread Oblq9 / Ocn0C / OcoPs: emit a tombstone so the\n // retired duplicate cannot resurrect through re-extraction / import.\n // Pattern reinforcement retires via writeMemoryFrontmatter which\n // bypasses the writeMemory chokepoint; without this emit, the same\n // content re-extracted before a manual rebuild would be stored active.\n // Threads Ocn0C/OcoPs: emit one tombstone PER derived supersession key\n // via buildRetiredFactTombstoneInputs (same helper as supersedeMemory +\n // forgetMemory), not a single entityRef-only record — a paraphrased\n // re-extraction with the same entity/attribute can only be caught by\n // the keyed tier. Best-effort (the interface method is optional; a\n // failure must not fail the reinforcement job).\n if (storage.appendTombstone) {\n for (const input of buildRetiredFactTombstoneInputs(\n {\n id: dup.frontmatter.id,\n content: dup.content,\n contentHash: dup.frontmatter.contentHash,\n entityRef: dup.frontmatter.entityRef,\n structuredAttributes: dup.frontmatter.structuredAttributes,\n },\n { reason: \"supersession\", createdBy: \"supersession\", createdAt: nowIso, supersessionKeysForFact },\n )) {\n try {\n await storage.appendTombstone(input);\n } catch {\n // Best-effort: a tombstone append failure must not fail the\n // reinforcement job (gotcha #13 / rule 34 spirit).\n }\n }\n }\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"],"mappings":"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","names":["path","mkdir","readFile","writeFile","results","path","buildCompressionGuidelinesMarkdown","result","readFile","writeFile","mkdir","FallbackLlmClient","gatewayTaskChainOptions","llm","capped","profile","outcome","throwIfAborted","options","memoryKind"]}
|