@remnic/core 9.3.751 → 9.3.752

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.
Files changed (319) hide show
  1. package/dist/access-boundary.d.ts +5 -5
  2. package/dist/access-boundary.js +29 -29
  3. package/dist/access-cli.js +88 -88
  4. package/dist/access-http.d.ts +5 -5
  5. package/dist/access-http.js +35 -35
  6. package/dist/access-mcp.d.ts +5 -5
  7. package/dist/access-mcp.js +34 -34
  8. package/dist/access-operations-batch.js +31 -31
  9. package/dist/access-operations.d.ts +5 -5
  10. package/dist/access-operations.js +33 -33
  11. package/dist/access-recall-surface.d.ts +363 -0
  12. package/dist/access-recall-surface.js +128 -0
  13. package/dist/access-schema.js +7 -7
  14. package/dist/{access-service-DmAEOJdJ.d.ts → access-service-C2cOHQvg.d.ts} +7 -26
  15. package/dist/access-service.d.ts +5 -5
  16. package/dist/access-service.js +28 -28
  17. package/dist/access-surface-catalog.d.ts +5 -5
  18. package/dist/action-confidence.d.ts +1 -1
  19. package/dist/active-memory-bridge.d.ts +1 -1
  20. package/dist/active-recall.d.ts +1 -1
  21. package/dist/active-recall.js +1 -1
  22. package/dist/behavior-learner.d.ts +1 -1
  23. package/dist/behavior-signals.d.ts +1 -1
  24. package/dist/bootstrap.d.ts +4 -4
  25. package/dist/briefing.d.ts +1 -1
  26. package/dist/briefing.js +4 -4
  27. package/dist/buffer-surprise-report.d.ts +1 -1
  28. package/dist/buffer.d.ts +1 -1
  29. package/dist/buffer.js +2 -2
  30. package/dist/calibration.d.ts +1 -1
  31. package/dist/capabilities.d.ts +1 -1
  32. package/dist/{capsule-crypto-7FJQINUR.js → capsule-crypto-CZJSLEFG.js} +3 -3
  33. package/dist/{catalog-BpOcwHdE.d.ts → catalog-D_FvzTM0.d.ts} +1 -1
  34. package/dist/causal-behavior.d.ts +1 -1
  35. package/dist/causal-behavior.js +2 -2
  36. package/dist/causal-chain.js +2 -2
  37. package/dist/causal-consolidation.d.ts +1 -1
  38. package/dist/causal-consolidation.js +9 -9
  39. package/dist/causal-retrieval.js +2 -2
  40. package/dist/causal-trajectory-graph.d.ts +1 -1
  41. package/dist/causal-trajectory.js +1 -1
  42. package/dist/{chunk-2NLLXCJG.js → chunk-2BFLDH5F.js} +2 -2
  43. package/dist/{chunk-UU32EAIY.js → chunk-2DPCAW2T.js} +5 -5
  44. package/dist/{chunk-5PZCDUJ6.js → chunk-2U4E34Y3.js} +4 -4
  45. package/dist/{chunk-JRZV3767.js → chunk-33NX5BLR.js} +4 -4
  46. package/dist/{chunk-X7Y7WX73.js → chunk-437S3G37.js} +2 -2
  47. package/dist/{chunk-HAZVVOYT.js → chunk-5DXUE7GB.js} +2 -2
  48. package/dist/{chunk-4DLFJJOQ.js → chunk-5JAT4ZJD.js} +4 -4
  49. package/dist/{chunk-RS25QOKZ.js → chunk-64SE4X5G.js} +2 -2
  50. package/dist/{chunk-QRRBXD24.js → chunk-67JRXV6Z.js} +7 -7
  51. package/dist/{chunk-WA7FECSG.js → chunk-6ROCH5JV.js} +7 -7
  52. package/dist/{chunk-5QANTTY2.js → chunk-BIAMJUUJ.js} +4 -4
  53. package/dist/{chunk-IKHKHADN.js → chunk-C4LNKQ3M.js} +5 -5
  54. package/dist/{chunk-B35L45HZ.js → chunk-DC5OBZS3.js} +2 -2
  55. package/dist/{chunk-ORAK3LNZ.js → chunk-ER3CCWK2.js} +2 -2
  56. package/dist/{chunk-SD34EK4Z.js → chunk-FEELYTRT.js} +5 -5
  57. package/dist/{chunk-KQAFEZQX.js → chunk-FLVL4L3L.js} +2 -2
  58. package/dist/{chunk-WIWPSQYU.js → chunk-FXRFFYWD.js} +4 -4
  59. package/dist/{chunk-W3M34XT4.js → chunk-GECEETQ3.js} +4 -4
  60. package/dist/{chunk-WWSXVOGY.js → chunk-GFGYHLON.js} +2 -2
  61. package/dist/{chunk-BJMBJZ2Y.js → chunk-GWTFLF2P.js} +59 -59
  62. package/dist/chunk-GWTFLF2P.js.map +1 -0
  63. package/dist/{chunk-WOX2UW4K.js → chunk-IBPEVGP5.js} +2 -2
  64. package/dist/{chunk-JZ7P26GF.js → chunk-IQWFWSCP.js} +4 -4
  65. package/dist/{chunk-6SXNQFHB.js → chunk-J2JB6BHT.js} +8 -8
  66. package/dist/{chunk-K2JM4DZZ.js → chunk-JHZ3LEM7.js} +2 -2
  67. package/dist/{chunk-YGGXUNS4.js → chunk-JNKSFIAY.js} +45 -45
  68. package/dist/{chunk-CGZWGVQF.js → chunk-K5CWCJKJ.js} +6 -6
  69. package/dist/{chunk-TPLE6SNY.js → chunk-KFNG72W7.js} +7 -7
  70. package/dist/{chunk-4NWIGAIC.js → chunk-KT2VQLP7.js} +8 -8
  71. package/dist/{chunk-6FNZ3NMS.js → chunk-L3VSTJ2V.js} +2 -2
  72. package/dist/{chunk-ARV3AUOM.js → chunk-M5QKGHCR.js} +2 -2
  73. package/dist/{chunk-E4PFDD3N.js → chunk-MEPWWSTD.js} +4 -4
  74. package/dist/{chunk-V5RVMULT.js → chunk-MLDAD27I.js} +7 -7
  75. package/dist/{chunk-K2R3DEEH.js → chunk-MTN2G4DT.js} +2 -2
  76. package/dist/{chunk-DBSMLRTO.js → chunk-MW7UUXTA.js} +5 -5
  77. package/dist/{chunk-OSMBC3JU.js → chunk-OKOF7ITI.js} +6 -6
  78. package/dist/{chunk-DBRVU5PR.js → chunk-OVMLS7TN.js} +3 -3
  79. package/dist/{chunk-NNL4LJAD.js → chunk-QMMCMV2L.js} +5 -5
  80. package/dist/{chunk-RNWWAS5V.js → chunk-QRM3K3XT.js} +5 -5
  81. package/dist/{chunk-HM6UJPPO.js → chunk-R7TGDLV3.js} +4 -4
  82. package/dist/{chunk-EEKDRAWX.js → chunk-RBYV3WSB.js} +4 -4
  83. package/dist/{chunk-LOPZ2DWR.js → chunk-RRRZ3CLN.js} +4 -4
  84. package/dist/{chunk-7TWA7DKP.js → chunk-S5UYWK3O.js} +6 -6
  85. package/dist/{chunk-QOGXUNWL.js → chunk-SC5AEZLU.js} +9 -9
  86. package/dist/{chunk-SNEXVX3U.js → chunk-UFNQKZV7.js} +15 -15
  87. package/dist/{chunk-W3BFT5OJ.js → chunk-V4ZPLQLC.js} +2 -2
  88. package/dist/{chunk-SQNED75R.js → chunk-V5UV7BOA.js} +1 -1
  89. package/dist/{chunk-RWZB6MAY.js → chunk-VQL22SHO.js} +891 -1002
  90. package/dist/chunk-VQL22SHO.js.map +1 -0
  91. package/dist/{chunk-UETBEHBA.js → chunk-VX2RYM2K.js} +2232 -1942
  92. package/dist/chunk-VX2RYM2K.js.map +1 -0
  93. package/dist/{chunk-K5LLP4CY.js → chunk-XKAOT4ZB.js} +4 -4
  94. package/dist/{chunk-ZBVQ4ZM4.js → chunk-YGNQG4Q6.js} +8 -8
  95. package/dist/{chunk-EZ25VE3G.js → chunk-YNDLCWXS.js} +4 -4
  96. package/dist/{chunk-HYI2GP3F.js → chunk-ZGGI3COG.js} +9 -9
  97. package/dist/{cli-lmf5RGyQ.d.ts → cli-DFUU9WYu.d.ts} +3 -3
  98. package/dist/cli.d.ts +6 -6
  99. package/dist/cli.js +60 -60
  100. package/dist/compounding/engine.d.ts +1 -1
  101. package/dist/compounding/engine.js +6 -6
  102. package/dist/compounding/preference-consolidator.d.ts +1 -1
  103. package/dist/compression-optimizer.d.ts +1 -1
  104. package/dist/config.d.ts +1 -1
  105. package/dist/config.js +1 -1
  106. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  107. package/dist/connectors/codex-materialize-runner.js +5 -5
  108. package/dist/connectors/codex-materialize.d.ts +1 -1
  109. package/dist/connectors/index.d.ts +1 -1
  110. package/dist/connectors/index.js +7 -7
  111. package/dist/consolidation-provenance-check.d.ts +1 -1
  112. package/dist/consolidation-undo.d.ts +1 -1
  113. package/dist/contradiction/index.d.ts +1 -1
  114. package/dist/contradiction/index.js +2 -2
  115. package/dist/{contradiction-scan-3FJYWS3G.js → contradiction-scan-KO4WWCS4.js} +3 -3
  116. package/dist/contradiction-scan-KO4WWCS4.js.map +1 -0
  117. package/dist/conversation-index/backend.d.ts +1 -1
  118. package/dist/conversation-index/chunker.d.ts +1 -1
  119. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  120. package/dist/conversation-index/indexer.d.ts +1 -1
  121. package/dist/conversation-index/search.d.ts +1 -1
  122. package/dist/dashboard-runtime.js +2 -2
  123. package/dist/day-summary.d.ts +1 -1
  124. package/dist/day-summary.js +2 -2
  125. package/dist/delinearize.d.ts +1 -1
  126. package/dist/direct-answer-wiring.d.ts +1 -1
  127. package/dist/direct-answer.d.ts +1 -1
  128. package/dist/embedding-fallback.d.ts +1 -1
  129. package/dist/embedding-fallback.js +2 -2
  130. package/dist/enrichment/index.d.ts +1 -1
  131. package/dist/entity-retrieval.d.ts +1 -1
  132. package/dist/entity-retrieval.js +5 -5
  133. package/dist/entity-schema.d.ts +1 -1
  134. package/dist/explicit-capture.d.ts +4 -4
  135. package/dist/explicit-capture.js +2 -2
  136. package/dist/extraction-faithfulness.d.ts +1 -1
  137. package/dist/extraction-judge-telemetry.d.ts +1 -1
  138. package/dist/extraction-judge-training.d.ts +1 -1
  139. package/dist/extraction-judge.d.ts +1 -1
  140. package/dist/extraction.d.ts +1 -1
  141. package/dist/extraction.js +4 -4
  142. package/dist/fallback-llm.d.ts +1 -1
  143. package/dist/graph-dashboard-diff.d.ts +1 -1
  144. package/dist/graph-dashboard-key.d.ts +1 -1
  145. package/dist/graph-dashboard-parser.d.ts +1 -1
  146. package/dist/graph-edge-reinforcement.d.ts +1 -1
  147. package/dist/graph-snapshot.d.ts +1 -1
  148. package/dist/graph.d.ts +1 -1
  149. package/dist/identity-continuity.d.ts +1 -1
  150. package/dist/importance.d.ts +1 -1
  151. package/dist/index.d.ts +9 -9
  152. package/dist/index.js +142 -142
  153. package/dist/intent.d.ts +1 -1
  154. package/dist/lcm/engine.d.ts +1 -1
  155. package/dist/lcm/engine.js +3 -3
  156. package/dist/lcm/index.d.ts +1 -1
  157. package/dist/lcm/index.js +8 -8
  158. package/dist/lcm/tools.d.ts +1 -1
  159. package/dist/lifecycle.d.ts +1 -1
  160. package/dist/live-connectors-runner.d.ts +1 -1
  161. package/dist/local-llm.d.ts +1 -1
  162. package/dist/local-llm.js +2 -2
  163. package/dist/local-model-endpoint.d.ts +1 -1
  164. package/dist/maintenance/memory-governance.d.ts +1 -1
  165. package/dist/maintenance/memory-governance.js +4 -4
  166. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +4 -4
  167. package/dist/maintenance/rebuild-memory-projection.js +5 -5
  168. package/dist/mcp-memory-inspector-app.d.ts +5 -5
  169. package/dist/memory-action-policy.d.ts +1 -1
  170. package/dist/memory-cache.d.ts +1 -1
  171. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  172. package/dist/memory-projection-store.d.ts +1 -1
  173. package/dist/memory-provenance.d.ts +1 -1
  174. package/dist/memory-worth-outcomes.d.ts +1 -1
  175. package/dist/models-json.d.ts +1 -1
  176. package/dist/namespaces/migrate.d.ts +2 -2
  177. package/dist/namespaces/migrate.js +10 -10
  178. package/dist/namespaces/principal.d.ts +1 -1
  179. package/dist/namespaces/search.d.ts +1 -1
  180. package/dist/namespaces/search.js +4 -4
  181. package/dist/namespaces/storage.d.ts +2 -2
  182. package/dist/namespaces/storage.js +6 -6
  183. package/dist/native-knowledge.d.ts +1 -1
  184. package/dist/operator-toolkit.d.ts +1 -1
  185. package/dist/operator-toolkit.js +17 -17
  186. package/dist/orchestration/compression-guideline-coordinator.d.ts +1 -1
  187. package/dist/orchestration/compression-guideline-coordinator.js +2 -2
  188. package/dist/orchestration/maintenance.d.ts +2 -2
  189. package/dist/orchestration/maintenance.js +10 -10
  190. package/dist/{orchestrator-D7bb8ZGp.d.ts → orchestrator-BhxMxtQJ.d.ts} +27 -106
  191. package/dist/orchestrator.d.ts +4 -4
  192. package/dist/orchestrator.js +86 -86
  193. package/dist/patterns-cli.d.ts +1 -1
  194. package/dist/policy-runtime.d.ts +1 -1
  195. package/dist/provenance.d.ts +1 -1
  196. package/dist/qmd-recall-cache.d.ts +1 -1
  197. package/dist/qmd.d.ts +1 -1
  198. package/dist/recall-disclosure-escalation.d.ts +1 -1
  199. package/dist/recall-explain-renderer.d.ts +1 -1
  200. package/dist/recall-planner-llm.d.ts +1 -1
  201. package/dist/recall-state.d.ts +1 -1
  202. package/dist/recall-tag-filter.d.ts +1 -1
  203. package/dist/recall-xray-cli.d.ts +1 -1
  204. package/dist/recall-xray-renderer.d.ts +1 -1
  205. package/dist/recall-xray.d.ts +1 -1
  206. package/dist/resolve-auth-token.d.ts +1 -1
  207. package/dist/resume-bundles.js +1 -1
  208. package/dist/retrieval-agents.d.ts +1 -1
  209. package/dist/retrieval-tiers.d.ts +1 -1
  210. package/dist/routing/engine.d.ts +1 -1
  211. package/dist/routing/store.d.ts +1 -1
  212. package/dist/routing/store.js +2 -2
  213. package/dist/schemas.d.ts +22 -22
  214. package/dist/search/embed-helper.d.ts +1 -1
  215. package/dist/search/embed-helper.js +2 -2
  216. package/dist/search/factory.d.ts +1 -1
  217. package/dist/search/factory.js +3 -3
  218. package/dist/search/index.d.ts +1 -1
  219. package/dist/search/index.js +3 -3
  220. package/dist/search/lancedb-backend.d.ts +1 -1
  221. package/dist/search/meilisearch-backend.d.ts +1 -1
  222. package/dist/search/noop-backend.d.ts +1 -1
  223. package/dist/search/orama-backend.d.ts +1 -1
  224. package/dist/search/port.d.ts +1 -1
  225. package/dist/search/remote-backend.d.ts +1 -1
  226. package/dist/secure-store/index.js +2 -2
  227. package/dist/{semantic-consolidation-CTfbVwCA.d.ts → semantic-consolidation-BrsoFeMP.d.ts} +1 -1
  228. package/dist/semantic-consolidation.d.ts +2 -2
  229. package/dist/semantic-consolidation.js +7 -7
  230. package/dist/semantic-rule-promotion.js +4 -4
  231. package/dist/semantic-rule-verifier.d.ts +1 -1
  232. package/dist/semantic-rule-verifier.js +4 -4
  233. package/dist/session-observer-bands.d.ts +1 -1
  234. package/dist/session-observer-state.d.ts +1 -1
  235. package/dist/shared-context/manager.d.ts +1 -1
  236. package/dist/shared-context/manager.js +2 -2
  237. package/dist/signal.d.ts +1 -1
  238. package/dist/storage.d.ts +1 -1
  239. package/dist/storage.js +3 -3
  240. package/dist/summarizer.d.ts +1 -1
  241. package/dist/summarizer.js +3 -3
  242. package/dist/summary-snapshot.d.ts +1 -1
  243. package/dist/temporal-supersession.d.ts +1 -1
  244. package/dist/temporal-validity.d.ts +1 -1
  245. package/dist/threading.d.ts +1 -1
  246. package/dist/tier-migration.d.ts +1 -1
  247. package/dist/tier-routing.d.ts +1 -1
  248. package/dist/topics.d.ts +1 -1
  249. package/dist/transcript.d.ts +1 -1
  250. package/dist/transfer/backup.js +3 -3
  251. package/dist/transfer/capsule-export.js +3 -3
  252. package/dist/transfer/capsule-import.js +3 -3
  253. package/dist/transfer/types.d.ts +12 -12
  254. package/dist/trust-score-stage.d.ts +1 -1
  255. package/dist/trust-score.d.ts +1 -1
  256. package/dist/{types-D4NYDtXI.d.ts → types-BfI4uJeb.d.ts} +1 -1
  257. package/dist/types.d.ts +1 -1
  258. package/dist/utility-runtime.d.ts +1 -1
  259. package/dist/verified-recall.js +4 -4
  260. package/package.json +2 -2
  261. package/src/access-recall-surface.ts +1552 -0
  262. package/src/access-service.ts +29 -1219
  263. package/src/orchestration/recall-entry.ts +290 -0
  264. package/src/orchestration/session-context.ts +407 -0
  265. package/src/orchestrator.ts +125 -462
  266. package/dist/chunk-BJMBJZ2Y.js.map +0 -1
  267. package/dist/chunk-RWZB6MAY.js.map +0 -1
  268. package/dist/chunk-UETBEHBA.js.map +0 -1
  269. /package/dist/{capsule-crypto-7FJQINUR.js.map → access-recall-surface.js.map} +0 -0
  270. /package/dist/{contradiction-scan-3FJYWS3G.js.map → capsule-crypto-CZJSLEFG.js.map} +0 -0
  271. /package/dist/{chunk-2NLLXCJG.js.map → chunk-2BFLDH5F.js.map} +0 -0
  272. /package/dist/{chunk-UU32EAIY.js.map → chunk-2DPCAW2T.js.map} +0 -0
  273. /package/dist/{chunk-5PZCDUJ6.js.map → chunk-2U4E34Y3.js.map} +0 -0
  274. /package/dist/{chunk-JRZV3767.js.map → chunk-33NX5BLR.js.map} +0 -0
  275. /package/dist/{chunk-X7Y7WX73.js.map → chunk-437S3G37.js.map} +0 -0
  276. /package/dist/{chunk-HAZVVOYT.js.map → chunk-5DXUE7GB.js.map} +0 -0
  277. /package/dist/{chunk-4DLFJJOQ.js.map → chunk-5JAT4ZJD.js.map} +0 -0
  278. /package/dist/{chunk-RS25QOKZ.js.map → chunk-64SE4X5G.js.map} +0 -0
  279. /package/dist/{chunk-QRRBXD24.js.map → chunk-67JRXV6Z.js.map} +0 -0
  280. /package/dist/{chunk-WA7FECSG.js.map → chunk-6ROCH5JV.js.map} +0 -0
  281. /package/dist/{chunk-5QANTTY2.js.map → chunk-BIAMJUUJ.js.map} +0 -0
  282. /package/dist/{chunk-IKHKHADN.js.map → chunk-C4LNKQ3M.js.map} +0 -0
  283. /package/dist/{chunk-B35L45HZ.js.map → chunk-DC5OBZS3.js.map} +0 -0
  284. /package/dist/{chunk-ORAK3LNZ.js.map → chunk-ER3CCWK2.js.map} +0 -0
  285. /package/dist/{chunk-SD34EK4Z.js.map → chunk-FEELYTRT.js.map} +0 -0
  286. /package/dist/{chunk-KQAFEZQX.js.map → chunk-FLVL4L3L.js.map} +0 -0
  287. /package/dist/{chunk-WIWPSQYU.js.map → chunk-FXRFFYWD.js.map} +0 -0
  288. /package/dist/{chunk-W3M34XT4.js.map → chunk-GECEETQ3.js.map} +0 -0
  289. /package/dist/{chunk-WWSXVOGY.js.map → chunk-GFGYHLON.js.map} +0 -0
  290. /package/dist/{chunk-WOX2UW4K.js.map → chunk-IBPEVGP5.js.map} +0 -0
  291. /package/dist/{chunk-JZ7P26GF.js.map → chunk-IQWFWSCP.js.map} +0 -0
  292. /package/dist/{chunk-6SXNQFHB.js.map → chunk-J2JB6BHT.js.map} +0 -0
  293. /package/dist/{chunk-K2JM4DZZ.js.map → chunk-JHZ3LEM7.js.map} +0 -0
  294. /package/dist/{chunk-YGGXUNS4.js.map → chunk-JNKSFIAY.js.map} +0 -0
  295. /package/dist/{chunk-CGZWGVQF.js.map → chunk-K5CWCJKJ.js.map} +0 -0
  296. /package/dist/{chunk-TPLE6SNY.js.map → chunk-KFNG72W7.js.map} +0 -0
  297. /package/dist/{chunk-4NWIGAIC.js.map → chunk-KT2VQLP7.js.map} +0 -0
  298. /package/dist/{chunk-6FNZ3NMS.js.map → chunk-L3VSTJ2V.js.map} +0 -0
  299. /package/dist/{chunk-ARV3AUOM.js.map → chunk-M5QKGHCR.js.map} +0 -0
  300. /package/dist/{chunk-E4PFDD3N.js.map → chunk-MEPWWSTD.js.map} +0 -0
  301. /package/dist/{chunk-V5RVMULT.js.map → chunk-MLDAD27I.js.map} +0 -0
  302. /package/dist/{chunk-K2R3DEEH.js.map → chunk-MTN2G4DT.js.map} +0 -0
  303. /package/dist/{chunk-DBSMLRTO.js.map → chunk-MW7UUXTA.js.map} +0 -0
  304. /package/dist/{chunk-OSMBC3JU.js.map → chunk-OKOF7ITI.js.map} +0 -0
  305. /package/dist/{chunk-DBRVU5PR.js.map → chunk-OVMLS7TN.js.map} +0 -0
  306. /package/dist/{chunk-NNL4LJAD.js.map → chunk-QMMCMV2L.js.map} +0 -0
  307. /package/dist/{chunk-RNWWAS5V.js.map → chunk-QRM3K3XT.js.map} +0 -0
  308. /package/dist/{chunk-HM6UJPPO.js.map → chunk-R7TGDLV3.js.map} +0 -0
  309. /package/dist/{chunk-EEKDRAWX.js.map → chunk-RBYV3WSB.js.map} +0 -0
  310. /package/dist/{chunk-LOPZ2DWR.js.map → chunk-RRRZ3CLN.js.map} +0 -0
  311. /package/dist/{chunk-7TWA7DKP.js.map → chunk-S5UYWK3O.js.map} +0 -0
  312. /package/dist/{chunk-QOGXUNWL.js.map → chunk-SC5AEZLU.js.map} +0 -0
  313. /package/dist/{chunk-SNEXVX3U.js.map → chunk-UFNQKZV7.js.map} +0 -0
  314. /package/dist/{chunk-W3BFT5OJ.js.map → chunk-V4ZPLQLC.js.map} +0 -0
  315. /package/dist/{chunk-SQNED75R.js.map → chunk-V5UV7BOA.js.map} +0 -0
  316. /package/dist/{chunk-K5LLP4CY.js.map → chunk-XKAOT4ZB.js.map} +0 -0
  317. /package/dist/{chunk-ZBVQ4ZM4.js.map → chunk-YGNQG4Q6.js.map} +0 -0
  318. /package/dist/{chunk-EZ25VE3G.js.map → chunk-YNDLCWXS.js.map} +0 -0
  319. /package/dist/{chunk-HYI2GP3F.js.map → chunk-ZGGI3COG.js.map} +0 -0
@@ -0,0 +1,290 @@
1
+ /**
2
+ * Recall-entry coordinator — extracted from the orchestrator
3
+ * (issue #1526, seam 28).
4
+ *
5
+ * Owns the public recall() entry surface: the init gate + timeout
6
+ * fallback around recallInternal, recall failure logging/suppression,
7
+ * recall result publication, and eval shadow-recall queueing.
8
+ *
9
+ * Behavior-preserving move (late-binding selfDeps wiring, seams 18–27).
10
+ */
11
+
12
+ import { type CapabilitySet, type GraphConstructionCapabilitySet, type MemoryLifecycleCapabilitySet, resolveCapabilities, resolveEvalCapabilities, resolveGraphConstructionCapabilities, resolveNamespaceCapabilities, resolveRecallAuxiliaryCapabilities } from "../capabilities.js";
13
+ import { type EvalShadowRecallRecord, recordEvalShadowRecall } from "../evals.js";
14
+ import { StorageManager } from "../index.js";
15
+ import { log } from "../logger.js";
16
+ import { resolvePrincipal } from "../namespaces/principal.js";
17
+ import { type RecallInvocationOptions, abortRecallError } from "./orchestrator-helpers.js";
18
+ import { ProfilingCollector } from "../profiling.js";
19
+ import type { TrustStageResultItem } from "../trust-score-stage.js";
20
+ import type { IdentityInjectionMode, PluginConfig, QmdSearchResult } from "../types.js";
21
+
22
+ export interface RecallEntryDeps {
23
+ appendRecallSection(
24
+ sectionBuckets: Map<string, string[]>,
25
+ sectionId: string,
26
+ content: string,
27
+ ): boolean;
28
+ readonly config: PluginConfig;
29
+ enqueueDirectAnswerObservation(
30
+ prompt: string,
31
+ sessionKey: string,
32
+ namespaceOverride: string | undefined,
33
+ principalOverride: string | undefined,
34
+ caps: CapabilitySet,
35
+ namespacesEnabled: boolean,
36
+ ): void;
37
+ evalShadowWriteChain: Promise<void>;
38
+ extractMemoryIdsFromResults(results: QmdSearchResult[]): string[];
39
+ formatQmdResults(
40
+ title: string,
41
+ results: QmdSearchResult[],
42
+ sessionKey?: string,
43
+ trustByPath?: Map<string, TrustStageResultItem> | null,
44
+ ): string;
45
+ readonly initPromise: Promise<void> | null;
46
+ lastRecallFailureAtMs: number;
47
+ lastRecallFailureLogAtMs: number;
48
+ logRecallFailure(err: unknown): void;
49
+ readonly profiler: ProfilingCollector;
50
+ recallInternal(
51
+ prompt: string,
52
+ sessionKey?: string,
53
+ options?: RecallInvocationOptions,
54
+ caps?: CapabilitySet,
55
+ graphCaps?: GraphConstructionCapabilitySet,
56
+ lifecycleCaps?: MemoryLifecycleCapabilitySet,
57
+ ): Promise<string>;
58
+ readonly storage: StorageManager;
59
+ suppressedRecallFailures: number;
60
+ trackMemoryAccess(memoryIds: string[]): void;
61
+ }
62
+
63
+ export class RecallEntryCoordinator {
64
+ constructor(
65
+ private readonly deps: RecallEntryDeps,
66
+ ) {}
67
+
68
+ async recall(
69
+ prompt: string,
70
+ sessionKey?: string,
71
+ options: RecallInvocationOptions = {},
72
+ ): Promise<string> {
73
+ // Resolve the recall-operation capability gates ONCE, at the operation
74
+ // entry, and thread the frozen set down (issue #1523). Never re-read the
75
+ // migrated flags off `this.deps.config` mid-operation.
76
+ const caps = resolveCapabilities(this.deps.config);
77
+ const graphCaps = resolveGraphConstructionCapabilities(this.deps.config); // #1566 Cluster A
78
+ const abortController = new AbortController();
79
+ const onAbort = () => {
80
+ abortController.abort();
81
+ };
82
+ if (options.abortSignal?.aborted) {
83
+ abortController.abort();
84
+ } else {
85
+ options.abortSignal?.addEventListener("abort", onAbort, { once: true });
86
+ }
87
+
88
+ const principal =
89
+ typeof options.principalOverride === "string" &&
90
+ options.principalOverride.length > 0
91
+ ? options.principalOverride
92
+ : resolvePrincipal(sessionKey, this.deps.config);
93
+ const namespacesEnabled = resolveNamespaceCapabilities(this.deps.config).namespaces;
94
+ if (namespacesEnabled && !principal) {
95
+ throw new Error("authentication required: namespaces are enabled and no principal was supplied");
96
+ }
97
+
98
+ // Wait for initialization to complete before attempting recall. The timeout
99
+ // is configurable so OpenClaw's per-hook budget and Remnic's internal init
100
+ // gate can stay aligned during cold starts.
101
+ let initGateTimeoutHandle: NodeJS.Timeout | null = null;
102
+ let onInitGateAbort: (() => void) | null = null;
103
+ if (this.deps.initPromise) {
104
+ const gateResult = await Promise.race([
105
+ this.deps.initPromise.then(() => "ok" as const),
106
+ new Promise<"timeout">((resolve) => {
107
+ initGateTimeoutHandle = setTimeout(
108
+ () => resolve("timeout"),
109
+ this.deps.config.initGateTimeoutMs,
110
+ );
111
+ }),
112
+ abortController.signal.aborted
113
+ ? Promise.resolve("aborted" as const)
114
+ : new Promise<"aborted">((resolve) => {
115
+ onInitGateAbort = () => resolve("aborted");
116
+ abortController.signal.addEventListener(
117
+ "abort",
118
+ onInitGateAbort,
119
+ { once: true },
120
+ );
121
+ }),
122
+ ]);
123
+ if (initGateTimeoutHandle) clearTimeout(initGateTimeoutHandle);
124
+ if (onInitGateAbort)
125
+ abortController.signal.removeEventListener("abort", onInitGateAbort);
126
+ if (gateResult === "aborted") {
127
+ this.deps.logRecallFailure(abortRecallError("recall aborted before init"));
128
+ return "";
129
+ }
130
+ if (gateResult === "timeout") {
131
+ log.warn("recall: init gate timed out — proceeding without full init");
132
+ }
133
+ }
134
+
135
+ // Secure-store lock gate (issue #690 PR 3/4).
136
+ // If secure-store is enabled but the keyring holds no key for this
137
+ // memory directory, reject recall with a clear human-readable error
138
+ // rather than surfacing a cryptic SecureStoreLockedError from deep
139
+ // inside the storage layer.
140
+ if (resolveRecallAuxiliaryCapabilities(this.deps.config).secureStore && !this.deps.storage.isSecureStoreUnlocked()) {
141
+ const lockedMsg =
142
+ "[secure-store locked] Memory store is encrypted and locked. " +
143
+ "Unlock the secure-store inside this daemon process, or restart the daemon through a secure-store aware launcher that installs the key.";
144
+ log.warn("recall blocked: secure-store is locked");
145
+ return lockedMsg;
146
+ }
147
+
148
+ // Keep outer recall timeout above worst-case serialized hybrid search:
149
+ // QMD subprocess BM25 (30s) + vector (30s) can consume ~60s under contention.
150
+ try {
151
+ const recallPromise = this.deps.recallInternal(prompt, sessionKey, {
152
+ ...options,
153
+ abortSignal: abortController.signal,
154
+ }, caps, graphCaps);
155
+ const RECALL_TIMEOUT_MS = this.deps.config.recallOuterTimeoutMs ?? 75_000;
156
+ if (RECALL_TIMEOUT_MS <= 0) {
157
+ return await recallPromise;
158
+ }
159
+
160
+ let timeoutHandle: NodeJS.Timeout | null = null;
161
+ const timeoutPromise = new Promise<string>((_, reject) => {
162
+ timeoutHandle = setTimeout(() => {
163
+ abortController.abort();
164
+ reject(new Error("recall timeout"));
165
+ }, RECALL_TIMEOUT_MS);
166
+ });
167
+
168
+ let recallResult: string;
169
+ try {
170
+ recallResult = await Promise.race([recallPromise, timeoutPromise]);
171
+ } finally {
172
+ if (timeoutHandle) clearTimeout(timeoutHandle);
173
+ }
174
+
175
+ // Observation-mode direct-answer tier (issue #518 slice 3c).
176
+ // Runs after the user's recall already succeeded, fire-and-forget,
177
+ // so annotation latency can never delay the caller's response.
178
+ if (caps.recallDirectAnswer && sessionKey) {
179
+ try {
180
+ this.deps.enqueueDirectAnswerObservation(
181
+ prompt,
182
+ sessionKey,
183
+ options.namespace?.trim() || undefined,
184
+ options.principalOverride,
185
+ caps,
186
+ namespacesEnabled,
187
+ );
188
+ } catch (err) {
189
+ log.debug(`direct-answer observation setup failed: ${err}`);
190
+ }
191
+ }
192
+
193
+ return recallResult;
194
+ } catch (err) {
195
+ this.deps.logRecallFailure(err);
196
+ // endTrace() is safe here: if no trace is active (disabled or already
197
+ // closed by recallInternal's try/finally), it returns null immediately.
198
+ this.deps.profiler.endTrace();
199
+ return ""; // Return empty context on timeout/error
200
+ } finally {
201
+ options.abortSignal?.removeEventListener("abort", onAbort);
202
+ }
203
+ }
204
+
205
+ logRecallFailure(err: unknown): void {
206
+ const now = Date.now();
207
+ const errorMsg = err instanceof Error ? err.message : String(err);
208
+ const LOG_WINDOW_MS = 60_000;
209
+ const idleSinceLastFailureMs = now - this.deps.lastRecallFailureAtMs;
210
+ this.deps.lastRecallFailureAtMs = now;
211
+ if (idleSinceLastFailureMs >= LOG_WINDOW_MS) {
212
+ this.deps.suppressedRecallFailures = 0;
213
+ }
214
+
215
+ if (now - this.deps.lastRecallFailureLogAtMs >= LOG_WINDOW_MS) {
216
+ const suffix =
217
+ this.deps.suppressedRecallFailures > 0
218
+ ? ` (suppressed ${this.deps.suppressedRecallFailures} similar failures in last minute)`
219
+ : "";
220
+ log.warn(`recall timed out or failed: ${errorMsg}${suffix}`);
221
+ this.deps.lastRecallFailureLogAtMs = now;
222
+ this.deps.suppressedRecallFailures = 0;
223
+ return;
224
+ }
225
+
226
+ this.deps.suppressedRecallFailures += 1;
227
+ log.debug(`recall timed out or failed (suppressed): ${errorMsg}`);
228
+ }
229
+
230
+ queueEvalShadowRecall(
231
+ record: Omit<EvalShadowRecallRecord, "schemaVersion">,
232
+ ): void {
233
+ if (!resolveEvalCapabilities(this.deps.config).evalHarness || !resolveEvalCapabilities(this.deps.config).evalShadowMode)
234
+ return;
235
+ this.deps.evalShadowWriteChain = this.deps.evalShadowWriteChain
236
+ .catch(() => undefined)
237
+ .then(async () => {
238
+ try {
239
+ await recordEvalShadowRecall({
240
+ memoryDir: this.deps.config.memoryDir,
241
+ evalStoreDir: this.deps.config.evalStoreDir,
242
+ record: {
243
+ schemaVersion: 1,
244
+ ...record,
245
+ },
246
+ });
247
+ } catch (err) {
248
+ log.debug(`eval shadow recall write failed: ${err}`);
249
+ }
250
+ });
251
+ }
252
+
253
+ publishRecallResults(options: {
254
+ title: string;
255
+ results: QmdSearchResult[];
256
+ sectionBuckets: Map<string, string[]>;
257
+ retrievalQuery: string;
258
+ sessionKey: string | undefined;
259
+ identityInjection?: {
260
+ mode: IdentityInjectionMode | "none";
261
+ injectedChars: number;
262
+ truncated: boolean;
263
+ };
264
+ /**
265
+ * Issue #1577 — per-recall trust map. When present, quarantined items
266
+ * are filtered from injection on EVERY recall path (hot QMD, embedding
267
+ * fallback, cold archive, recent) so a faithfulness-contradicted memory
268
+ * cannot sneak in via a branch that bypasses trust scoring (review:
269
+ * fallback paths bypass trust). The map is also threaded to
270
+ * formatQmdResults for the epistemic hedge.
271
+ */
272
+ trustByPath?: Map<string, TrustStageResultItem> | null;
273
+ }): void {
274
+ const sectionId = "memories";
275
+ // Filter quarantined items from ALL recall paths so no branch can inject
276
+ // a hard-negative memory that trust scoring excluded on another path.
277
+ const trustByPath = options.trustByPath ?? null;
278
+ const injectable = trustByPath
279
+ ? options.results.filter((r) => !trustByPath.get(r.path)?.quarantined)
280
+ : options.results;
281
+ const memoryIds = this.deps.extractMemoryIdsFromResults(injectable);
282
+ this.deps.trackMemoryAccess(memoryIds);
283
+
284
+ this.deps.appendRecallSection(
285
+ options.sectionBuckets,
286
+ sectionId,
287
+ this.deps.formatQmdResults(options.title, injectable, options.sessionKey, trustByPath),
288
+ );
289
+ }
290
+ }
@@ -0,0 +1,407 @@
1
+ /**
2
+ * Session-context coordinator — extracted from the orchestrator
3
+ * (issue #1526, seam 28).
4
+ *
5
+ * Owns per-session binding surfaces and session-facing service glue:
6
+ * - peer-id and coding-context bindings (incl. namespace overlay)
7
+ * - LCM read-namespace resolution for a session
8
+ * - session flush, passive-correction service construction
9
+ * - day-summary generation and deep-sleep governance triggers
10
+ *
11
+ * Behavior-preserving move (late-binding selfDeps wiring, seams 18–27).
12
+ */
13
+
14
+ import { SmartBuffer } from "../buffer.js";
15
+ import { resolveNamespaceCapabilities } from "../capabilities.js";
16
+ import { combineNamespaces, resolveCodingNamespaceOverlay } from "../coding/coding-namespace.js";
17
+ import { createCorrectionService } from "../correction/correction-access-wiring.js";
18
+ import type { CorrectionService } from "../correction/correction-service.js";
19
+ import { ExtractionEngine } from "../extraction.js";
20
+ import { StorageManager } from "../index.js";
21
+ import { LocalLlmClient } from "../local-llm.js";
22
+ import { log } from "../logger.js";
23
+ import { canWriteNamespace, defaultNamespaceForPrincipal, recallNamespacesForPrincipal, resolvePrincipal } from "../namespaces/principal.js";
24
+ import type { ExtractionRunResult } from "./extraction-run.js";
25
+ import type { BufferTurn, CodingContext, DaySummaryResult, MemoryFile, PluginConfig } from "../types.js";
26
+ import {
27
+ Orchestrator,
28
+ } from "../orchestrator.js";
29
+
30
+ export interface SessionContextDeps {
31
+ readonly _codingContextBySession: Map<string, CodingContext>;
32
+ /** Defensive init for Object.create(prototype) fakes — creates the session-binding maps on the orchestrator. */
33
+ ensureSessionBindingMaps(): void;
34
+ _passiveCorrectionService: CorrectionService | null;
35
+ readonly _peerIdBySession: Map<string, string>;
36
+ applyCodingNamespaceOverlay(sessionKey: string | undefined, baseNamespace: string): string;
37
+ readonly buffer: SmartBuffer;
38
+ readonly config: PluginConfig;
39
+ readonly extraction: ExtractionEngine;
40
+ getCodingContextForSession(sessionKey: string | undefined): CodingContext | null;
41
+ readonly initPromise: Promise<void> | null;
42
+ readonly localLlm: LocalLlmClient;
43
+ processEntitySynthesisQueue(
44
+ namespace?: string,
45
+ maxEntities?: number,
46
+ ): Promise<number>;
47
+ queueBufferedExtraction(
48
+ turnsToExtract: BufferTurn[],
49
+ reason: "trigger_mode" | "heartbeat_observer",
50
+ options?: {
51
+ skipDedupeCheck?: boolean;
52
+ clearBufferAfterExtraction?: boolean;
53
+ skipCharThreshold?: boolean;
54
+ skipUserTurnThreshold?: boolean;
55
+ extractionDeadlineMs?: number;
56
+ failOnExtractionFailure?: boolean;
57
+ onTaskSettled?: (
58
+ error?: unknown,
59
+ result?: ExtractionRunResult,
60
+ ) => void;
61
+ bufferKey?: string;
62
+ abortSignal?: AbortSignal;
63
+ /**
64
+ * Explicit namespace override for the write path (#460). When set,
65
+ * `runExtraction` writes to this namespace instead of deriving one
66
+ * from `defaultNamespaceForPrincipal(resolvePrincipal(sessionKey))`.
67
+ * Used by bulk-import to pin writes to a deterministic namespace
68
+ * regardless of user-configured principal routing rules.
69
+ */
70
+ writeNamespaceOverride?: string;
71
+ /**
72
+ * Pin the provenance principal (#1495 thread 1). Forwarded to
73
+ * `runExtraction` so access `observe` can record provenance under the
74
+ * authenticated principal instead of `resolvePrincipal(sessionKey)`.
75
+ */
76
+ principalOverride?: string;
77
+ },
78
+ ): Promise<void>;
79
+ resolvePrincipal(sessionKey?: string): string | undefined;
80
+ readonly storage: StorageManager;
81
+ storageDirNamespace(storageDir: string): string;
82
+ /** The orchestrator itself — passiveCorrectionService constructs the CorrectionService against it. */
83
+ readonly orchestratorSelf: Orchestrator;
84
+ }
85
+
86
+ export class SessionContextCoordinator {
87
+ constructor(
88
+ private readonly deps: SessionContextDeps,
89
+ ) {}
90
+
91
+ /**
92
+ * Effective namespace a same-session LCM/structured-history READER must use
93
+ * to find what the access `observe` surface WROTE (#1495 thread 2).
94
+ *
95
+ * This MUST mirror the `observe` scope plan's write-namespace resolution, NOT
96
+ * `resolveSelfNamespace`: when no coding overlay applies, `observe` archives
97
+ * under `config.defaultNamespace` (an unqualified observed turn is NOT moved
98
+ * to the principal self namespace — identical to
99
+ * `resolveCodingScopedWriteNamespace`/`memory_store`, rule 39). Only when a
100
+ * coding overlay actually changes the namespace does the writer (and so the
101
+ * reader) use the overlaid `project-*` namespace. Returning the self base for
102
+ * the no-overlay case would prefix the read key with a namespace the writer
103
+ * never used, so the reader would miss its own evidence.
104
+ *
105
+ * Honours the access-surface `principalOverride` (#1505 thread 2, codex): when
106
+ * a recall supplies an authenticated principal NOT encoded in the raw
107
+ * `sessionKey`, `observe` archived LCM under THAT principal's base namespace.
108
+ * Deriving the base from `resolvePrincipal(sessionKey)` alone could fall back
109
+ * to `default`, so principal `alice` observing `sess-1` would write under
110
+ * `alice` but READ under `default`. Threading the override here keeps the read
111
+ * base identical to the write base.
112
+ *
113
+ * READ-AUTHORIZATION gate (#1505 round 3, codex P2 "Gate LCM recall keys by
114
+ * readable namespaces"): the overlay LCM read key is a `<principal>-project-*`
115
+ * sub-namespace of the principal SELF base. The normal recall namespace set
116
+ * below only substitutes the coding overlay when the principal SELF base is
117
+ * actually in the readable recall set (`recallNamespacesForPrincipal` — gated
118
+ * by `defaultRecallNamespaces.includes("self")` AND `canReadNamespace`). If a
119
+ * principal can WRITE but not READ its self namespace (or `defaultRecall-
120
+ * Namespaces` omits `self`), QMD/file recall never touches those overlay rows,
121
+ * so neither may the LCM read key. When the self base is NOT readable, fall
122
+ * back to the default store — exactly what an unqualified, unauthorized recall
123
+ * resolves to — rather than injecting overlay rows the rest of recall excludes
124
+ * (rule 42 read/write parity; rule 48 least-privilege).
125
+ */
126
+ lcmReadNamespaceForSession(
127
+ sessionKey?: string,
128
+ principalOverride?: string,
129
+ ): string {
130
+ const principal =
131
+ typeof principalOverride === "string" && principalOverride.length > 0
132
+ ? principalOverride
133
+ : this.deps.resolvePrincipal(sessionKey);
134
+ const base = defaultNamespaceForPrincipal(principal, this.deps.config);
135
+ const overlaid = this.deps.applyCodingNamespaceOverlay(sessionKey, base);
136
+ // No overlay → collapse to the default store so the LCM key is the raw
137
+ // sessionKey, exactly what an unqualified observe archived under.
138
+ if (overlaid === base) return this.deps.config.defaultNamespace;
139
+ // Overlay applied. Only honour it when the principal SELF base is in the
140
+ // readable recall set (same gate the recall namespace set uses to
141
+ // substitute the overlay). Otherwise the overlay rows are unauthorized for
142
+ // this reader — fall back to the default store so the LCM read matches
143
+ // what QMD/file recall would surface.
144
+ const selfReadableInRecall = recallNamespacesForPrincipal(
145
+ principal,
146
+ this.deps.config,
147
+ ).includes(base);
148
+ return selfReadableInRecall ? overlaid : this.deps.config.defaultNamespace;
149
+ }
150
+
151
+ /**
152
+ * Attach a coding-agent context to a session (issue #569). Called by the
153
+ * Claude Code / Codex / Cursor connectors at session start after
154
+ * `resolveGitContext(cwd)`. The context is consulted by the recall path
155
+ * and the write path so that memories route to a project- (and optionally
156
+ * branch-) scoped namespace.
157
+ *
158
+ * Pass `null` to clear.
159
+ */
160
+ setCodingContextForSession(sessionKey: string, codingContext: CodingContext | null): void {
161
+ if (typeof sessionKey !== "string" || sessionKey.length === 0) return;
162
+ // Defensive init — `Object.create(Orchestrator.prototype)` stubs in
163
+ // legacy tests skip class-field initializers. The init runs on the
164
+ // ORCHESTRATOR via deps (PR #1802 review: writing here would create
165
+ // the map on the coordinator while reads keep going through deps).
166
+ this.deps.ensureSessionBindingMaps();
167
+ if (codingContext === null) {
168
+ this.deps._codingContextBySession.delete(sessionKey);
169
+ return;
170
+ }
171
+ this.deps._codingContextBySession.set(sessionKey, codingContext);
172
+ }
173
+
174
+ /**
175
+ * Read-only accessor for the coding context attached to a session. Returns
176
+ * `null` when none is set. Used by `remnic doctor` and by tests.
177
+ *
178
+ * Defensive `_codingContextBySession` lookup — legacy orchestrator-flush
179
+ * tests use `Object.create(Orchestrator.prototype)` which does not run
180
+ * class-field initializers, so the Map may be undefined on stubs.
181
+ */
182
+ getCodingContextForSession(sessionKey: string | undefined): CodingContext | null {
183
+ if (typeof sessionKey !== "string" || sessionKey.length === 0) return null;
184
+ return this.deps._codingContextBySession?.get(sessionKey) ?? null;
185
+ }
186
+
187
+ /**
188
+ * Shared helper used by both the recall path and the write path (rule 42).
189
+ *
190
+ * Given a base namespace computed from the principal, returns the overlaid
191
+ * coding namespace when the session has a coding context AND
192
+ * `codingMode.projectScope` is true AND `namespacesEnabled` is true.
193
+ * Otherwise returns `baseNamespace` unchanged — CLAUDE.md #30 escape hatch.
194
+ *
195
+ * Principal isolation (CLAUDE.md rule 42): the overlay is COMBINED with
196
+ * the principal-derived `baseNamespace` rather than replacing it, so two
197
+ * principals working in the same repository do not share memories through
198
+ * a common `project-*` namespace.
199
+ *
200
+ * Namespaces-disabled gate: when `namespacesEnabled` is false, the
201
+ * storage router maps every namespace to the same `memoryDir`. Returning
202
+ * `project-*` in that mode would create apparent route separation with
203
+ * no actual storage isolation — a false-isolation trap. In that mode we
204
+ * return `baseNamespace` unchanged so coding mode degrades to the existing
205
+ * unscoped behavior.
206
+ *
207
+ * @internal
208
+ */
209
+ applyCodingNamespaceOverlay(sessionKey: string | undefined, baseNamespace: string): string {
210
+ if (!resolveNamespaceCapabilities(this.deps.config).namespaces) return baseNamespace;
211
+ const codingContext = this.deps.getCodingContextForSession(sessionKey);
212
+ const overlay = resolveCodingNamespaceOverlay(codingContext, this.deps.config.codingMode, this.deps.config.defaultNamespace);
213
+ if (!overlay) return baseNamespace;
214
+ return combineNamespaces(baseNamespace, overlay.namespace);
215
+ }
216
+
217
+ /**
218
+ * Register a peer ID for a session so recall can inject the peer's
219
+ * profile into context (issue #679 PR 3/5). Pass `null` to clear.
220
+ *
221
+ * Connectors and the `before_agent_start` hook call this when the
222
+ * session's counter-party is known. The ID is validated against
223
+ * `PEER_ID_PATTERN` before storing.
224
+ *
225
+ * Fail-closed (Codex P1 review): an invalid peerId clears any
226
+ * previously registered mapping for the session rather than silently
227
+ * keeping stale data. This prevents a malformed metadata update from
228
+ * mixing one peer's profile context into another session.
229
+ *
230
+ * Defensive init (Cursor review + rule 16): `Object.create(
231
+ * Orchestrator.prototype)` stubs in legacy tests skip class-field
232
+ * initializers, so `_peerIdBySession` may be undefined. Mirror the
233
+ * same guard used by `setCodingContextForSession`.
234
+ */
235
+ setPeerIdForSession(sessionKey: string, peerId: string | null): void {
236
+ if (typeof sessionKey !== "string" || sessionKey.length === 0) return;
237
+ // Defensive init — mirrors setCodingContextForSession (rule 16);
238
+ // runs on the orchestrator via deps (PR #1802 review).
239
+ this.deps.ensureSessionBindingMaps();
240
+ if (peerId === null) {
241
+ this.deps._peerIdBySession.delete(sessionKey);
242
+ return;
243
+ }
244
+ // Basic pattern guard — full validation lives in peers/storage.ts.
245
+ // Invalid input is fail-closed: clear the existing mapping so stale
246
+ // peer context can't bleed in after a bad metadata update (Codex P1).
247
+ if (
248
+ typeof peerId !== "string" ||
249
+ peerId.length === 0 ||
250
+ peerId.length > 64 ||
251
+ !/^[A-Za-z0-9]+(?:[._-][A-Za-z0-9]+)*$/.test(peerId)
252
+ ) {
253
+ log.warn(`setPeerIdForSession: invalid peerId — clearing session mapping`);
254
+ this.deps._peerIdBySession.delete(sessionKey);
255
+ return;
256
+ }
257
+ this.deps._peerIdBySession.set(sessionKey, peerId);
258
+ }
259
+
260
+ /**
261
+ * Return the peer ID registered for a session, or `null` when none
262
+ * is set. Used by `recallInternal` to inject the peer profile section.
263
+ * Defensive `_peerIdBySession` lookup — legacy orchestrator-flush tests
264
+ * use `Object.create(Orchestrator.prototype)` which skips class-field
265
+ * initializers, so the Map may be undefined on stubs.
266
+ */
267
+ getPeerIdForSession(sessionKey: string | undefined): string | null {
268
+ if (typeof sessionKey !== "string" || sessionKey.length === 0) return null;
269
+ return this.deps._peerIdBySession?.get(sessionKey) ?? null;
270
+ }
271
+
272
+ async runDeepSleepGovernanceNow(options?: {
273
+ dryRun?: boolean;
274
+ storage?: StorageManager;
275
+ }): Promise<{ scannedMemories: number; appliedActionCount: number; notes?: string }> {
276
+ const targetStorage = options?.storage ?? this.deps.storage;
277
+ const { runMemoryGovernance } = await import("../maintenance/memory-governance.js");
278
+ const { summarizeGovernanceResultForDreams } = await import("../maintenance/dreams-ledger.js");
279
+ const govResult = await runMemoryGovernance({
280
+ memoryDir: targetStorage.dir,
281
+ mode: options?.dryRun === true ? "shadow" : "apply",
282
+ });
283
+ if (options?.dryRun !== true) {
284
+ try {
285
+ await this.deps.processEntitySynthesisQueue(
286
+ this.deps.storageDirNamespace(targetStorage.dir),
287
+ 5,
288
+ );
289
+ } catch (error) {
290
+ log.debug(`deep-sleep governance: entity synthesis refresh failed after apply: ${error}`);
291
+ }
292
+ }
293
+ return summarizeGovernanceResultForDreams(govResult, options?.dryRun === true);
294
+ }
295
+
296
+ async generateDaySummary(
297
+ memories: string | MemoryFile[],
298
+ ): Promise<DaySummaryResult | null> {
299
+ if (this.deps.initPromise) {
300
+ let initGateTimeoutHandle: ReturnType<typeof setTimeout> | undefined;
301
+ try {
302
+ await Promise.race([
303
+ this.deps.initPromise.catch(() => undefined),
304
+ new Promise((resolve) => {
305
+ initGateTimeoutHandle = setTimeout(
306
+ resolve,
307
+ this.deps.config.initGateTimeoutMs,
308
+ );
309
+ }),
310
+ ]);
311
+ } finally {
312
+ if (initGateTimeoutHandle) clearTimeout(initGateTimeoutHandle);
313
+ }
314
+ }
315
+ return this.deps.extraction.generateDaySummary(memories);
316
+ }
317
+
318
+ async flushSession(
319
+ sessionKey: string,
320
+ options: {
321
+ reason: string;
322
+ abortSignal?: AbortSignal;
323
+ bufferKey?: string;
324
+ },
325
+ ): Promise<void> {
326
+ const explicitBufferKey =
327
+ typeof options.bufferKey === "string" && options.bufferKey.length > 0
328
+ ? options.bufferKey
329
+ : null;
330
+ const discoveredBufferKeys =
331
+ explicitBufferKey ||
332
+ typeof sessionKey !== "string" ||
333
+ sessionKey.length === 0 ||
334
+ typeof this.deps.buffer.findBufferKeysForSession !== "function"
335
+ ? []
336
+ : await this.deps.buffer.findBufferKeysForSession(sessionKey);
337
+ const bufferKeys = explicitBufferKey
338
+ ? [explicitBufferKey]
339
+ : discoveredBufferKeys.length > 0
340
+ ? discoveredBufferKeys
341
+ : typeof sessionKey === "string" && sessionKey.length > 0
342
+ ? [sessionKey]
343
+ : ["default"];
344
+ for (const bufferKey of bufferKeys) {
345
+ const turns = this.deps.buffer.getTurns(bufferKey);
346
+ if (turns.length === 0) continue;
347
+ await new Promise<void>((resolve, reject) => {
348
+ void this.deps.queueBufferedExtraction(turns, "trigger_mode", {
349
+ bufferKey,
350
+ clearBufferAfterExtraction: true,
351
+ skipDedupeCheck: true,
352
+ abortSignal: options.abortSignal,
353
+ onTaskSettled: (error) => (error ? reject(error) : resolve()),
354
+ })
355
+ .catch(reject);
356
+ });
357
+ }
358
+ }
359
+
360
+ /** Lazily construct the CorrectionService for passive capture. Stateless
361
+ * across requests (per #1580 design); cached for the orchestrator's life. */
362
+ passiveCorrectionService(): CorrectionService {
363
+ if (this.deps._passiveCorrectionService) return this.deps._passiveCorrectionService;
364
+ this.deps._passiveCorrectionService = createCorrectionService({
365
+ orchestrator: this.deps.orchestratorSelf,
366
+ // Session-scoped write ACL (review: "passive capture bypasses write
367
+ // ACL"). A correction detected in session S plans only against S readable
368
+ // namespaces and applies only to writable ones (rule 42) — passive
369
+ // capture never becomes a cross-tenant mutation vector. Mirrors the
370
+ // access-service createCorrectionService wiring rather than bypassing it.
371
+ resolveAuthorizedNamespace: async (req) => {
372
+ const principal = req.principal || resolvePrincipal(req.sessionKey, this.deps.config);
373
+ const ns = req.namespace ?? defaultNamespaceForPrincipal(principal, this.deps.config);
374
+ if (!canWriteNamespace(principal, ns, this.deps.config)) {
375
+ throw new Error(
376
+ `passive correction: namespace "${ns}" is not writable for principal ${principal ?? "(none)"}`,
377
+ );
378
+ }
379
+ return ns;
380
+ },
381
+ resolveReadableNamespaces: (req) => {
382
+ const principal = req.principal || resolvePrincipal(req.sessionKey, this.deps.config);
383
+ return recallNamespacesForPrincipal(principal, this.deps.config);
384
+ },
385
+ canWriteNamespace: async (req) => {
386
+ const principal = req.principal || resolvePrincipal(req.sessionKey, this.deps.config);
387
+ return canWriteNamespace(principal, req.namespace, this.deps.config);
388
+ },
389
+ llmComplete: async ({ system, user }) => {
390
+ const llmResult = await this.deps.localLlm.chatCompletion(
391
+ [
392
+ { role: "system", content: system },
393
+ { role: "user", content: user },
394
+ ],
395
+ { operation: "correction-classify", priority: "background" },
396
+ );
397
+ if (!llmResult) {
398
+ throw new Error(
399
+ "passive correction classify+draft: local LLM unavailable (disabled or in cooldown)",
400
+ );
401
+ }
402
+ return llmResult.content;
403
+ },
404
+ });
405
+ return this.deps._passiveCorrectionService;
406
+ }
407
+ }