@remnic/core 9.69.49 → 9.69.51

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 (555) hide show
  1. package/dist/access-admin-ops-surface.d.ts +15 -14
  2. package/dist/access-admin-ops-surface.js +33 -33
  3. package/dist/access-audit.d.ts +1 -0
  4. package/dist/access-audit.js +2 -2
  5. package/dist/access-authorization-probe.d.ts +15 -14
  6. package/dist/access-authorization-probe.js +34 -34
  7. package/dist/access-boundary.d.ts +15 -14
  8. package/dist/access-boundary.js +33 -33
  9. package/dist/access-cli.js +97 -95
  10. package/dist/access-cli.js.map +1 -1
  11. package/dist/access-coding-context-resolution.d.ts +2 -1
  12. package/dist/access-extraction-force-flush.d.ts +15 -14
  13. package/dist/access-extraction-force-flush.js +33 -33
  14. package/dist/access-health-types.d.ts +2 -1
  15. package/dist/access-http-briefing.d.ts +15 -14
  16. package/dist/access-http-briefing.js +34 -34
  17. package/dist/access-http-lcm-compaction.d.ts +15 -14
  18. package/dist/access-http-lifecycle-flush.d.ts +15 -14
  19. package/dist/access-http-offline-stream.d.ts +15 -14
  20. package/dist/access-http-query.d.ts +3 -2
  21. package/dist/access-http-query.js +35 -35
  22. package/dist/access-http.d.ts +16 -15
  23. package/dist/access-http.js +53 -53
  24. package/dist/access-identity-continuity-surface.d.ts +12 -11
  25. package/dist/access-identity-continuity-surface.js +33 -33
  26. package/dist/access-lcm-surface.d.ts +15 -14
  27. package/dist/access-lcm-surface.js +33 -33
  28. package/dist/access-mcp-output-schemas.js +1 -1
  29. package/dist/access-mcp-shared-context-tools.d.ts +15 -14
  30. package/dist/access-mcp.d.ts +15 -14
  31. package/dist/access-mcp.js +44 -44
  32. package/dist/access-memory-search-fanout.d.ts +3 -2
  33. package/dist/{access-namespace-preflight-DqRw_g-8.d.ts → access-namespace-preflight-C1q3XuAc.d.ts} +1 -1
  34. package/dist/access-namespace-preflight.d.ts +4 -3
  35. package/dist/access-namespace-preflight.js +33 -33
  36. package/dist/access-observe-transcript.d.ts +12 -11
  37. package/dist/access-observe-write-category.d.ts +4 -3
  38. package/dist/access-observe-write-category.js +4 -4
  39. package/dist/access-observe-write-surface.d.ts +15 -14
  40. package/dist/access-observe-write-surface.js +33 -33
  41. package/dist/access-offline-manifest.d.ts +12 -11
  42. package/dist/access-operations-batch.js +35 -35
  43. package/dist/access-operations.d.ts +15 -14
  44. package/dist/access-operations.js +42 -42
  45. package/dist/access-recall-concurrency.d.ts +15 -14
  46. package/dist/access-recall-concurrency.js +33 -33
  47. package/dist/access-recall-response.d.ts +15 -14
  48. package/dist/access-recall-response.js +33 -33
  49. package/dist/access-recall-surface.d.ts +16 -15
  50. package/dist/access-recall-surface.js +33 -33
  51. package/dist/access-schema.d.ts +2 -1
  52. package/dist/access-schema.js +3 -3
  53. package/dist/{access-service-70VHaltr.d.ts → access-service-BZaC-RZw.d.ts} +9 -9
  54. package/dist/access-service-helpers.d.ts +15 -14
  55. package/dist/access-service.d.ts +15 -14
  56. package/dist/access-service.js +33 -33
  57. package/dist/access-surface-catalog.d.ts +15 -14
  58. package/dist/access-surface-catalog.js +35 -35
  59. package/dist/access-wearables-meetings-surface.d.ts +5 -4
  60. package/dist/action-confidence.d.ts +2 -1
  61. package/dist/active-memory-bridge.d.ts +2 -1
  62. package/dist/active-recall.d.ts +2 -1
  63. package/dist/active-recall.js +3 -2
  64. package/dist/active-recall.js.map +1 -1
  65. package/dist/activity/digest.d.ts +2 -1
  66. package/dist/ambient-provenance.d.ts +2 -1
  67. package/dist/artifact-search.d.ts +2 -1
  68. package/dist/background-generation.d.ts +2 -1
  69. package/dist/behavior-learner.d.ts +2 -1
  70. package/dist/behavior-signals.d.ts +2 -1
  71. package/dist/bootstrap.d.ts +12 -11
  72. package/dist/briefing-window.d.ts +3 -2
  73. package/dist/briefing.d.ts +3 -2
  74. package/dist/briefing.js +8 -8
  75. package/dist/buffer-surprise-report.d.ts +2 -1
  76. package/dist/buffer-turn-helpers.d.ts +2 -1
  77. package/dist/buffer.d.ts +3 -2
  78. package/dist/bulk-import/index.d.ts +4 -3
  79. package/dist/calibration.d.ts +2 -1
  80. package/dist/capabilities.d.ts +2 -1
  81. package/dist/{capsule-crypto-7FJQINUR.js → capsule-crypto-YO5QJ6L3.js} +2 -2
  82. package/dist/{catalog-Byi9prz9.d.ts → catalog-DK2eHhax.d.ts} +1 -1
  83. package/dist/causal-behavior.d.ts +2 -1
  84. package/dist/causal-consolidation.d.ts +2 -1
  85. package/dist/causal-consolidation.js +9 -9
  86. package/dist/causal-trajectory-graph.d.ts +2 -1
  87. package/dist/{chunk-6DYCSSHN.js → chunk-25HSEIEM.js} +2 -2
  88. package/dist/{chunk-PAQ7YGJY.js → chunk-2EICZYIG.js} +2 -2
  89. package/dist/{chunk-2IVHOQRY.js → chunk-2ERLN25A.js} +2 -2
  90. package/dist/{chunk-TUSY4KRE.js → chunk-2G2CVN2T.js} +29 -28
  91. package/dist/{chunk-TUSY4KRE.js.map → chunk-2G2CVN2T.js.map} +1 -1
  92. package/dist/{chunk-EST3J4LX.js → chunk-2SZBCM2S.js} +2 -2
  93. package/dist/{chunk-UB4UVALS.js → chunk-33SX6K3N.js} +2 -2
  94. package/dist/{chunk-P36WML7L.js → chunk-3QZRSEAM.js} +2 -2
  95. package/dist/chunk-4KQIWY4A.js +197 -0
  96. package/dist/chunk-4KQIWY4A.js.map +1 -0
  97. package/dist/{chunk-LBLXEFWK.js → chunk-4MN27537.js} +1 -1
  98. package/dist/chunk-4MN27537.js.map +1 -0
  99. package/dist/{chunk-JI5Q6EOY.js → chunk-6HCJWCA4.js} +5 -5
  100. package/dist/chunk-6VITOSPL.js +69 -0
  101. package/dist/chunk-6VITOSPL.js.map +1 -0
  102. package/dist/{chunk-OTGIAJQ2.js → chunk-6Z4OLQUO.js} +2 -2
  103. package/dist/{chunk-DHTOYRDE.js → chunk-6ZMIASYT.js} +2 -2
  104. package/dist/{chunk-UD6W67JM.js → chunk-72AV2H3R.js} +76 -25
  105. package/dist/chunk-72AV2H3R.js.map +1 -0
  106. package/dist/{chunk-KHLNIDWB.js → chunk-7TTOX6NW.js} +2 -2
  107. package/dist/{chunk-7VTQETLT.js → chunk-A33DLYNY.js} +2 -2
  108. package/dist/{chunk-QQA6VTOY.js → chunk-AH3OIMS7.js} +2 -2
  109. package/dist/{chunk-T3F2HWIG.js → chunk-AIVRD66I.js} +2 -2
  110. package/dist/{chunk-RBHQA2UU.js → chunk-BMAYH7F4.js} +487 -343
  111. package/dist/chunk-BMAYH7F4.js.map +1 -0
  112. package/dist/{chunk-WHSNLCRO.js → chunk-BULK6DGB.js} +2 -2
  113. package/dist/{chunk-2NLLXCJG.js → chunk-BXLOS5AJ.js} +2 -2
  114. package/dist/{chunk-K26LFJE4.js → chunk-CKBA2MWS.js} +2 -2
  115. package/dist/{chunk-TVVEYCNW.js → chunk-DAOMWGO2.js} +2 -2
  116. package/dist/{chunk-E64HBW7M.js → chunk-DLXBMXIB.js} +2 -2
  117. package/dist/{chunk-X7Y7WX73.js → chunk-DQEMWVMT.js} +1 -1
  118. package/dist/{chunk-T3OLYUU6.js → chunk-DQSVGTKB.js} +2 -2
  119. package/dist/{chunk-4WSR7MYV.js → chunk-DX63RFDJ.js} +2 -2
  120. package/dist/{chunk-SNOAFXKX.js → chunk-EBJL6HGR.js} +12 -4
  121. package/dist/chunk-EBJL6HGR.js.map +1 -0
  122. package/dist/{chunk-LX32KV2C.js → chunk-ETNC6TT6.js} +2 -2
  123. package/dist/{chunk-UE7L4EDU.js → chunk-HEKWNWNL.js} +3 -3
  124. package/dist/{chunk-ZDGSHXJU.js → chunk-IGDEKECC.js} +1 -1
  125. package/dist/{chunk-YKWWG3CM.js → chunk-ISA5U5AP.js} +2 -2
  126. package/dist/{chunk-3MX4GWJO.js → chunk-JGPG5UHM.js} +2 -2
  127. package/dist/{chunk-U3ZRHNNG.js → chunk-JHUODJRW.js} +2 -2
  128. package/dist/{chunk-5WIGM42T.js → chunk-JXSOB3SA.js} +2 -2
  129. package/dist/{chunk-YOC3EEZH.js → chunk-KAPYPTPS.js} +16 -16
  130. package/dist/{chunk-AOMVOC2E.js → chunk-KBHDV7P3.js} +3 -3
  131. package/dist/{chunk-2WMXZYMS.js → chunk-LIAKZGOY.js} +2 -2
  132. package/dist/{chunk-A7GQBJP5.js → chunk-LVFI5LG7.js} +7 -7
  133. package/dist/{chunk-EHUUXLLA.js → chunk-LX7KIJQF.js} +2 -2
  134. package/dist/{chunk-BHXY5FXL.js → chunk-LZI6FWZW.js} +8 -2
  135. package/dist/chunk-LZI6FWZW.js.map +1 -0
  136. package/dist/{chunk-EBLKS57G.js → chunk-MNF6PTNL.js} +2 -2
  137. package/dist/{chunk-LE2UESGS.js → chunk-MYDA2GA2.js} +2 -2
  138. package/dist/{chunk-XQFHKPNB.js → chunk-NROI5XMG.js} +2 -2
  139. package/dist/{chunk-N57PUWUE.js → chunk-NVW5ISEJ.js} +40 -40
  140. package/dist/{chunk-PSQRBCGR.js → chunk-NXSNFPYI.js} +2 -2
  141. package/dist/{chunk-LLFMZYFS.js → chunk-O4JFBEUL.js} +2 -2
  142. package/dist/{chunk-JVM3CEGL.js → chunk-OIK3YL2P.js} +3 -3
  143. package/dist/{chunk-C3YEB7CR.js → chunk-PLJ2MQFT.js} +7 -7
  144. package/dist/{chunk-DNAD57VY.js → chunk-PQWICTRO.js} +1 -1
  145. package/dist/chunk-PQWICTRO.js.map +1 -0
  146. package/dist/{chunk-Z2OKRO3E.js → chunk-PYTSGD5M.js} +2 -2
  147. package/dist/{chunk-VBRS7Z3O.js → chunk-Q6OC4UUT.js} +2 -2
  148. package/dist/{chunk-ZYZW46HZ.js → chunk-QRSC37NC.js} +5 -5
  149. package/dist/{chunk-AJLQH4RO.js → chunk-RIP2AOZW.js} +9 -9
  150. package/dist/{chunk-SYJZUVTN.js → chunk-SCM4VYJW.js} +3 -3
  151. package/dist/{chunk-76RTJ533.js → chunk-SMI2G3MA.js} +3 -3
  152. package/dist/{chunk-6VLOKESS.js → chunk-ST7FDKZT.js} +12 -2
  153. package/dist/chunk-ST7FDKZT.js.map +1 -0
  154. package/dist/{chunk-WGCASEEQ.js → chunk-SZ75IB2T.js} +2 -2
  155. package/dist/{chunk-FLZJMXFV.js → chunk-T73ZC7C5.js} +2 -2
  156. package/dist/{chunk-FVRZDZ7J.js → chunk-TNFDWJRS.js} +2 -2
  157. package/dist/{chunk-WNMVUWI7.js → chunk-TTFJQ5B5.js} +2 -2
  158. package/dist/{chunk-HIBNECBQ.js → chunk-UP3226JC.js} +6 -6
  159. package/dist/{chunk-NDWBT2VV.js → chunk-UVEBBXB5.js} +2 -2
  160. package/dist/{chunk-KQAFEZQX.js → chunk-VDX2J7OX.js} +2 -2
  161. package/dist/{chunk-AIKUSXIS.js → chunk-VLR4S5GF.js} +7 -7
  162. package/dist/{chunk-ZHXSOMYH.js → chunk-VVX5PZFS.js} +2 -2
  163. package/dist/{chunk-HS75MCQF.js → chunk-WUUGE7QC.js} +4 -4
  164. package/dist/{chunk-RS53SDCA.js → chunk-X25NTN3W.js} +2 -2
  165. package/dist/{chunk-PZHN7R35.js → chunk-XFXVIXDI.js} +2 -2
  166. package/dist/{chunk-YA5M7OC4.js → chunk-XHDQQ2TT.js} +2 -2
  167. package/dist/{chunk-IIDXU2CY.js → chunk-XRUOO7OT.js} +2 -2
  168. package/dist/{chunk-WVI43D54.js → chunk-YEIKOBOW.js} +15 -2
  169. package/dist/chunk-YEIKOBOW.js.map +1 -0
  170. package/dist/{chunk-JUOJGZPV.js → chunk-YIIW2OH2.js} +2 -2
  171. package/dist/{chunk-SKYYPVBW.js → chunk-YJJMJH6J.js} +8 -8
  172. package/dist/{cli-CdJiBilM.d.ts → cli-BHDMJqJS.d.ts} +5 -5
  173. package/dist/cli.d.ts +17 -16
  174. package/dist/cli.js +76 -75
  175. package/dist/coding/export-okf-codegraph.d.ts +2 -1
  176. package/dist/coding/export-okf-codegraph.js +7 -7
  177. package/dist/coding/pre-action-gate.d.ts +2 -1
  178. package/dist/compounding/engine.d.ts +3 -2
  179. package/dist/compounding/engine.js +8 -8
  180. package/dist/compounding/preference-consolidator.d.ts +2 -1
  181. package/dist/compression-optimizer.d.ts +2 -1
  182. package/dist/config.d.ts +2 -1
  183. package/dist/config.js +3 -2
  184. package/dist/connectors/codex-materialize-runner.d.ts +2 -1
  185. package/dist/connectors/codex-materialize-runner.js +8 -8
  186. package/dist/connectors/codex-materialize.d.ts +2 -1
  187. package/dist/connectors/index.d.ts +2 -1
  188. package/dist/connectors/index.js +8 -8
  189. package/dist/consolidation-provenance-check.d.ts +3 -2
  190. package/dist/consolidation-undo.d.ts +3 -2
  191. package/dist/contradiction/index.d.ts +5 -4
  192. package/dist/converge-config.d.ts +2 -1
  193. package/dist/convergence-refresh.d.ts +3 -2
  194. package/dist/convergence-refresh.js +10 -10
  195. package/dist/conversation-index/backend.d.ts +2 -1
  196. package/dist/conversation-index/chunker.d.ts +2 -1
  197. package/dist/conversation-index/faiss-adapter.d.ts +2 -1
  198. package/dist/conversation-index/indexer.d.ts +2 -1
  199. package/dist/conversation-index/search.d.ts +2 -1
  200. package/dist/corpus-watermark.d.ts +2 -1
  201. package/dist/corpus-watermark.js +10 -10
  202. package/dist/cross-lingual-recall.d.ts +2 -1
  203. package/dist/day-summary.d.ts +2 -1
  204. package/dist/deep-recall-http-glue.d.ts +15 -14
  205. package/dist/deep-recall-http-glue.js +4 -4
  206. package/dist/deep-recall-mcp-tools.d.ts +15 -14
  207. package/dist/deep-recall-policy-llm.d.ts +3 -2
  208. package/dist/deep-recall-seeds.d.ts +2 -1
  209. package/dist/deep-recall.js +2 -2
  210. package/dist/delinearize.d.ts +2 -1
  211. package/dist/dependency-propagation-config.d.ts +2 -1
  212. package/dist/{dependency-propagation-delivery-BgHy44WX.d.ts → dependency-propagation-delivery-BMkR4gmY.d.ts} +1 -1
  213. package/dist/direct-answer-wiring.d.ts +2 -1
  214. package/dist/direct-answer.d.ts +2 -1
  215. package/dist/directory-sidecars.d.ts +28 -2
  216. package/dist/directory-sidecars.js +9 -1
  217. package/dist/embedding-fallback.d.ts +2 -1
  218. package/dist/enrichment/index.d.ts +2 -1
  219. package/dist/entity-origin-fields.d.ts +2 -1
  220. package/dist/entity-retrieval.d.ts +3 -2
  221. package/dist/entity-retrieval.js +8 -8
  222. package/dist/entity-schema.d.ts +2 -1
  223. package/dist/episodic-context.d.ts +2 -1
  224. package/dist/eval-trajectory-contracts.d.ts +2 -1
  225. package/dist/eval-trajectory-store.d.ts +2 -1
  226. package/dist/eval-trajectory.d.ts +2 -1
  227. package/dist/explicit-capture.d.ts +12 -11
  228. package/dist/external-wiki-access.d.ts +15 -14
  229. package/dist/external-wiki-access.js +34 -34
  230. package/dist/external-wiki-collection-registration.d.ts +2 -1
  231. package/dist/external-wiki-collection.d.ts +2 -1
  232. package/dist/external-wiki-mcp-tools.d.ts +15 -14
  233. package/dist/extraction-error-classification.d.ts +2 -1
  234. package/dist/extraction-evidence-class.d.ts +2 -1
  235. package/dist/extraction-faithfulness.d.ts +3 -2
  236. package/dist/extraction-judge-telemetry.d.ts +3 -2
  237. package/dist/extraction-judge-training.d.ts +3 -2
  238. package/dist/extraction-judge.d.ts +3 -2
  239. package/dist/extraction-liveness.d.ts +2 -1
  240. package/dist/extraction-normalization.d.ts +2 -1
  241. package/dist/extraction-prompt.d.ts +2 -1
  242. package/dist/extraction-source-grounding-rules.d.ts +2 -1
  243. package/dist/extraction-source-grounding.d.ts +2 -1
  244. package/dist/extraction-span-config.d.ts +2 -1
  245. package/dist/extraction-span-materialize.d.ts +2 -1
  246. package/dist/extraction-span-wire.d.ts +2 -1
  247. package/dist/extraction.d.ts +3 -2
  248. package/dist/extraction.js +8 -8
  249. package/dist/fallback-llm-codex-subscription.d.ts +2 -1
  250. package/dist/fallback-llm.d.ts +2 -1
  251. package/dist/{generic-recall-paths-BoueWXYr.d.ts → generic-recall-paths-BCRtXU32.d.ts} +1 -1
  252. package/dist/graph-append-error.d.ts +2 -1
  253. package/dist/graph-dashboard-diff.d.ts +2 -1
  254. package/dist/graph-dashboard-key.d.ts +2 -1
  255. package/dist/graph-dashboard-parser.d.ts +2 -1
  256. package/dist/graph-edge-reinforcement.d.ts +2 -1
  257. package/dist/graph-jsonl.d.ts +2 -1
  258. package/dist/graph-path-reconstruction.d.ts +2 -1
  259. package/dist/graph-path-scoring.d.ts +2 -1
  260. package/dist/graph-snapshot.d.ts +2 -1
  261. package/dist/graph.d.ts +2 -1
  262. package/dist/harmonic-retrieval.js +1 -1
  263. package/dist/importance.d.ts +2 -1
  264. package/dist/importers/index.d.ts +2 -1
  265. package/dist/importers/test-utils.d.ts +2 -1
  266. package/dist/in-flight-reads.d.ts +2 -1
  267. package/dist/{index-cwbrXoxe.d.ts → index-DMNTW4W6.d.ts} +3 -3
  268. package/dist/index.d.ts +29 -26
  269. package/dist/index.js +149 -103
  270. package/dist/intent.d.ts +2 -1
  271. package/dist/lcm/engine.d.ts +2 -1
  272. package/dist/lcm/engine.js +3 -3
  273. package/dist/lcm/index.d.ts +2 -1
  274. package/dist/lcm/index.js +11 -11
  275. package/dist/lcm/tools.d.ts +2 -1
  276. package/dist/lifecycle.d.ts +2 -1
  277. package/dist/live-connectors-runner.d.ts +2 -1
  278. package/dist/{local-llm-B0vd_rp9.d.ts → local-llm-BXYC-mbU.d.ts} +1 -1
  279. package/dist/local-llm-helpers.d.ts +3 -2
  280. package/dist/local-llm.d.ts +3 -2
  281. package/dist/local-model-endpoint.d.ts +2 -1
  282. package/dist/location/index.d.ts +6 -5
  283. package/dist/location/index.js +10 -10
  284. package/dist/maintenance/memory-governance.d.ts +2 -1
  285. package/dist/maintenance/memory-governance.js +8 -8
  286. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +3 -2
  287. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +8 -8
  288. package/dist/maintenance/rebuild-memory-projection.d.ts +3 -2
  289. package/dist/maintenance/rebuild-memory-projection.js +9 -9
  290. package/dist/{maintenance-DJgQkoLh.d.ts → maintenance-zJiLsKBY.d.ts} +3 -3
  291. package/dist/mcp-memory-inspector-app.d.ts +15 -14
  292. package/dist/memory-action-policy.d.ts +2 -1
  293. package/dist/memory-browse-http-glue.d.ts +15 -14
  294. package/dist/memory-browse-mcp-tools.d.ts +15 -14
  295. package/dist/memory-browse-operations.js +34 -34
  296. package/dist/memory-browse.d.ts +2 -1
  297. package/dist/memory-browse.js +3 -3
  298. package/dist/memory-cache.d.ts +2 -1
  299. package/dist/memory-controller.d.ts +2 -1
  300. package/dist/memory-lifecycle-ledger-utils.d.ts +2 -1
  301. package/dist/memory-projection-store.d.ts +2 -1
  302. package/dist/memory-provenance.d.ts +2 -1
  303. package/dist/memory-snapshot.d.ts +2 -1
  304. package/dist/memory-subject-cli.d.ts +15 -14
  305. package/dist/memory-subject.d.ts +15 -14
  306. package/dist/memory-worth-outcomes.d.ts +3 -2
  307. package/dist/models-json.d.ts +2 -1
  308. package/dist/namespaces/migrate.d.ts +4 -3
  309. package/dist/namespaces/migrate.js +9 -9
  310. package/dist/namespaces/principal.d.ts +2 -1
  311. package/dist/namespaces/search.d.ts +2 -1
  312. package/dist/namespaces/search.js +4 -4
  313. package/dist/namespaces/storage.d.ts +4 -3
  314. package/dist/namespaces/storage.js +8 -8
  315. package/dist/native-knowledge.d.ts +2 -1
  316. package/dist/offline-sync-impression-drain.d.ts +2 -1
  317. package/dist/operator-doctor-corpus.d.ts +2 -1
  318. package/dist/operator-doctor-corpus.js +11 -11
  319. package/dist/operator-doctor-replica.d.ts +2 -1
  320. package/dist/operator-toolkit.d.ts +4 -3
  321. package/dist/operator-toolkit.js +19 -18
  322. package/dist/orchestration/compression-guideline-coordinator.d.ts +3 -2
  323. package/dist/orchestration/maintenance.d.ts +5 -4
  324. package/dist/orchestration/maintenance.js +16 -16
  325. package/dist/{orchestrator-Kx5zwNUm.d.ts → orchestrator-BTqT3F6X.d.ts} +10 -10
  326. package/dist/orchestrator.d.ts +12 -11
  327. package/dist/orchestrator.js +97 -95
  328. package/dist/patterns-cli.d.ts +2 -1
  329. package/dist/{pipeline-9SYxxign.d.ts → pipeline-CgO2Sd4O.d.ts} +1 -1
  330. package/dist/policy-runtime.d.ts +2 -1
  331. package/dist/proactive-contention.d.ts +3 -2
  332. package/dist/provenance.d.ts +2 -1
  333. package/dist/{public-http-Bvol6Jr4.d.ts → public-http-Dk1EA9ix.d.ts} +1 -1
  334. package/dist/{qmd-DjwuG9Xa.d.ts → qmd-CwxtVz64.d.ts} +1 -1
  335. package/dist/qmd-preflight.d.ts +3 -2
  336. package/dist/qmd-recall-cache.d.ts +2 -1
  337. package/dist/qmd.d.ts +3 -2
  338. package/dist/recall-audit-anomaly.d.ts +1 -0
  339. package/dist/recall-audit.d.ts +4 -0
  340. package/dist/recall-audit.js +1 -1
  341. package/dist/recall-composition-decision.d.ts +41 -0
  342. package/dist/recall-composition-decision.js +17 -0
  343. package/dist/recall-composition-decision.js.map +1 -0
  344. package/dist/recall-concurrency-config.d.ts +2 -1
  345. package/dist/recall-disclosure-escalation.d.ts +2 -1
  346. package/dist/recall-explain-renderer.d.ts +3 -1
  347. package/dist/recall-explain-renderer.js +3 -3
  348. package/dist/recall-memory-map.d.ts +2 -1
  349. package/dist/recall-navigate-access.d.ts +2 -1
  350. package/dist/recall-navigate-access.js +2 -2
  351. package/dist/recall-navigate-disclosure.d.ts +2 -1
  352. package/dist/recall-navigate-disclosure.js +2 -2
  353. package/dist/recall-navigate.d.ts +2 -1
  354. package/dist/recall-navigate.js +2 -2
  355. package/dist/recall-navigation-http-glue.d.ts +15 -14
  356. package/dist/recall-navigation-mcp-tools.d.ts +15 -14
  357. package/dist/recall-navigation-operations.js +34 -34
  358. package/dist/recall-navigation-renderer.d.ts +3 -1
  359. package/dist/recall-navigation.d.ts +3 -1
  360. package/dist/recall-navigation.js +33 -33
  361. package/dist/recall-planner-llm.d.ts +2 -1
  362. package/dist/recall-recognition-tier.d.ts +121 -0
  363. package/dist/recall-recognition-tier.js +42 -0
  364. package/dist/recall-recognition-tier.js.map +1 -0
  365. package/dist/recall-state-view-admission.d.ts +3 -2
  366. package/dist/recall-state-view-admission.js +3 -3
  367. package/dist/recall-state-view-anchors.d.ts +2 -1
  368. package/dist/recall-state.d.ts +2 -1
  369. package/dist/recall-tag-filter.d.ts +3 -1
  370. package/dist/recall-timings.d.ts +2 -1
  371. package/dist/recall-xray-cli.d.ts +3 -1
  372. package/dist/recall-xray-cli.js +4 -4
  373. package/dist/recall-xray-renderer.d.ts +3 -1
  374. package/dist/recall-xray-renderer.js +3 -3
  375. package/dist/recall-xray.d.ts +11 -1
  376. package/dist/recall-xray.js +2 -2
  377. package/dist/reconcile/cursor.d.ts +2 -1
  378. package/dist/reconcile/manifest.d.ts +2 -1
  379. package/dist/reconcile/plan.d.ts +2 -1
  380. package/dist/replay/normalizers/chatgpt.d.ts +2 -1
  381. package/dist/replay/normalizers/claude.d.ts +2 -1
  382. package/dist/replay/normalizers/openclaw.d.ts +2 -1
  383. package/dist/replay/normalizers/shared.d.ts +2 -1
  384. package/dist/replay/runner.d.ts +2 -1
  385. package/dist/replay/types.d.ts +2 -1
  386. package/dist/replica-divergence.d.ts +2 -1
  387. package/dist/replica-peers-config.d.ts +2 -1
  388. package/dist/resolve-auth-token.d.ts +2 -1
  389. package/dist/resume-bundles.js +4 -3
  390. package/dist/retrieval-agents.d.ts +3 -2
  391. package/dist/retrieval-tiers.d.ts +2 -1
  392. package/dist/routing/engine.d.ts +2 -1
  393. package/dist/routing/store.d.ts +2 -1
  394. package/dist/salvage-envelope.d.ts +2 -1
  395. package/dist/{scope-profiles-DPegZtRf.d.ts → scope-profiles-Bg1rB-Dp.d.ts} +1 -1
  396. package/dist/search/embed-helper.d.ts +2 -1
  397. package/dist/search/factory.d.ts +2 -1
  398. package/dist/search/factory.js +3 -3
  399. package/dist/search/index.d.ts +2 -1
  400. package/dist/search/index.js +7 -7
  401. package/dist/search/lancedb-backend.d.ts +2 -1
  402. package/dist/search/meilisearch-backend.d.ts +2 -1
  403. package/dist/search/noop-backend.d.ts +2 -1
  404. package/dist/search/orama-backend.d.ts +2 -1
  405. package/dist/search/port.d.ts +2 -1
  406. package/dist/search/remote-backend.d.ts +2 -1
  407. package/dist/{semantic-consolidation-DMzhKRYl.d.ts → semantic-consolidation-DEzRyeyn.d.ts} +1 -1
  408. package/dist/semantic-consolidation.d.ts +3 -2
  409. package/dist/semantic-consolidation.js +9 -9
  410. package/dist/semantic-rule-promotion.js +8 -8
  411. package/dist/semantic-rule-verifier.d.ts +2 -1
  412. package/dist/semantic-rule-verifier.js +8 -8
  413. package/dist/{service-E99KuPvi.d.ts → service-DGEIDOeD.d.ts} +2 -2
  414. package/dist/session-observer-bands.d.ts +2 -1
  415. package/dist/session-observer-state.d.ts +2 -1
  416. package/dist/shared-context/manager.d.ts +2 -1
  417. package/dist/signal.d.ts +2 -1
  418. package/dist/source-agent-qualifier.d.ts +2 -1
  419. package/dist/source-agent-qualifier.js +8 -8
  420. package/dist/standup/build.js +8 -8
  421. package/dist/{storage-BS7ux8F7.d.ts → storage-DNQWtOSM.d.ts} +1 -1
  422. package/dist/storage.d.ts +3 -2
  423. package/dist/storage.js +7 -7
  424. package/dist/subject-config.d.ts +2 -1
  425. package/dist/summarizer.d.ts +2 -1
  426. package/dist/summary-snapshot.d.ts +2 -1
  427. package/dist/support-passport/index.d.ts +18 -17
  428. package/dist/support-passport/index.js +36 -36
  429. package/dist/{tagging-BhOEcSXP.d.ts → tagging-CPVwgadt.d.ts} +2 -2
  430. package/dist/temporal-supersession.d.ts +3 -2
  431. package/dist/temporal-timeline-recall.d.ts +2 -1
  432. package/dist/temporal-validity.d.ts +2 -1
  433. package/dist/threading.d.ts +2 -1
  434. package/dist/tier-migration.d.ts +3 -2
  435. package/dist/tier-routing.d.ts +2 -1
  436. package/dist/topics.d.ts +2 -1
  437. package/dist/transcript.d.ts +2 -1
  438. package/dist/transfer/backup.js +2 -2
  439. package/dist/transfer/capsule-export.js +2 -2
  440. package/dist/transfer/capsule-import.js +2 -2
  441. package/dist/transfer/export-okf.d.ts +2 -1
  442. package/dist/transfer/export-okf.js +8 -8
  443. package/dist/trust-score-stage.d.ts +2 -1
  444. package/dist/trust-score.d.ts +2 -1
  445. package/dist/{types-DQ2H8gAC.d.ts → types-DCB90q3g.d.ts} +2 -1
  446. package/dist/types.d.ts +2 -1
  447. package/dist/types.js +1 -1
  448. package/dist/utility-runtime.d.ts +2 -1
  449. package/dist/verified-recall.js +8 -8
  450. package/dist/who-knows-cli.d.ts +15 -14
  451. package/dist/who-knows-cli.js +9 -9
  452. package/dist/who-knows.d.ts +15 -14
  453. package/dist/who-knows.js +8 -8
  454. package/dist/write-envelope.d.ts +2 -1
  455. package/package.json +2 -2
  456. package/src/access-mcp-output-schemas.ts +14 -1
  457. package/src/access-recall-response.ts +3 -0
  458. package/src/config.ts +5 -0
  459. package/src/directory-sidecars.test.ts +119 -0
  460. package/src/directory-sidecars.ts +110 -25
  461. package/src/experience/session-experience-recall.test.ts +228 -0
  462. package/src/experience/session-experience-recall.ts +60 -0
  463. package/src/index.ts +2 -0
  464. package/src/lifecycle/seed-graduation.test.ts +424 -0
  465. package/src/lifecycle/seed-graduation.ts +376 -0
  466. package/src/orchestration/recall-entry.ts +16 -2
  467. package/src/orchestration/recall-internal.ts +21 -18
  468. package/src/orchestration/recall-recognition-search.test.ts +290 -0
  469. package/src/orchestration/recall-recognition-search.ts +160 -0
  470. package/src/procedural/procedure-recall.ts +14 -3
  471. package/src/recall-audit.test.ts +34 -0
  472. package/src/recall-audit.ts +4 -0
  473. package/src/recall-composition-decision.test.ts +134 -0
  474. package/src/recall-composition-decision.ts +113 -0
  475. package/src/recall-recognition-tier.test.ts +306 -0
  476. package/src/recall-recognition-tier.ts +375 -0
  477. package/src/recall-xray-renderer.test.ts +17 -0
  478. package/src/recall-xray-renderer.ts +10 -0
  479. package/src/recall-xray.test.ts +28 -0
  480. package/src/recall-xray.ts +15 -0
  481. package/src/testing/subjects/recall-recognition-tier.test.ts +106 -0
  482. package/src/testing/subjects/seed-graduation.test.ts +128 -0
  483. package/src/types.ts +2 -0
  484. package/dist/chunk-6VLOKESS.js.map +0 -1
  485. package/dist/chunk-BHXY5FXL.js.map +0 -1
  486. package/dist/chunk-DNAD57VY.js.map +0 -1
  487. package/dist/chunk-LBLXEFWK.js.map +0 -1
  488. package/dist/chunk-RBHQA2UU.js.map +0 -1
  489. package/dist/chunk-SNOAFXKX.js.map +0 -1
  490. package/dist/chunk-UD6W67JM.js.map +0 -1
  491. package/dist/chunk-WVI43D54.js.map +0 -1
  492. /package/dist/{capsule-crypto-7FJQINUR.js.map → capsule-crypto-YO5QJ6L3.js.map} +0 -0
  493. /package/dist/{chunk-6DYCSSHN.js.map → chunk-25HSEIEM.js.map} +0 -0
  494. /package/dist/{chunk-PAQ7YGJY.js.map → chunk-2EICZYIG.js.map} +0 -0
  495. /package/dist/{chunk-2IVHOQRY.js.map → chunk-2ERLN25A.js.map} +0 -0
  496. /package/dist/{chunk-EST3J4LX.js.map → chunk-2SZBCM2S.js.map} +0 -0
  497. /package/dist/{chunk-UB4UVALS.js.map → chunk-33SX6K3N.js.map} +0 -0
  498. /package/dist/{chunk-P36WML7L.js.map → chunk-3QZRSEAM.js.map} +0 -0
  499. /package/dist/{chunk-JI5Q6EOY.js.map → chunk-6HCJWCA4.js.map} +0 -0
  500. /package/dist/{chunk-OTGIAJQ2.js.map → chunk-6Z4OLQUO.js.map} +0 -0
  501. /package/dist/{chunk-DHTOYRDE.js.map → chunk-6ZMIASYT.js.map} +0 -0
  502. /package/dist/{chunk-KHLNIDWB.js.map → chunk-7TTOX6NW.js.map} +0 -0
  503. /package/dist/{chunk-7VTQETLT.js.map → chunk-A33DLYNY.js.map} +0 -0
  504. /package/dist/{chunk-QQA6VTOY.js.map → chunk-AH3OIMS7.js.map} +0 -0
  505. /package/dist/{chunk-T3F2HWIG.js.map → chunk-AIVRD66I.js.map} +0 -0
  506. /package/dist/{chunk-WHSNLCRO.js.map → chunk-BULK6DGB.js.map} +0 -0
  507. /package/dist/{chunk-2NLLXCJG.js.map → chunk-BXLOS5AJ.js.map} +0 -0
  508. /package/dist/{chunk-K26LFJE4.js.map → chunk-CKBA2MWS.js.map} +0 -0
  509. /package/dist/{chunk-TVVEYCNW.js.map → chunk-DAOMWGO2.js.map} +0 -0
  510. /package/dist/{chunk-E64HBW7M.js.map → chunk-DLXBMXIB.js.map} +0 -0
  511. /package/dist/{chunk-X7Y7WX73.js.map → chunk-DQEMWVMT.js.map} +0 -0
  512. /package/dist/{chunk-T3OLYUU6.js.map → chunk-DQSVGTKB.js.map} +0 -0
  513. /package/dist/{chunk-4WSR7MYV.js.map → chunk-DX63RFDJ.js.map} +0 -0
  514. /package/dist/{chunk-LX32KV2C.js.map → chunk-ETNC6TT6.js.map} +0 -0
  515. /package/dist/{chunk-UE7L4EDU.js.map → chunk-HEKWNWNL.js.map} +0 -0
  516. /package/dist/{chunk-ZDGSHXJU.js.map → chunk-IGDEKECC.js.map} +0 -0
  517. /package/dist/{chunk-YKWWG3CM.js.map → chunk-ISA5U5AP.js.map} +0 -0
  518. /package/dist/{chunk-3MX4GWJO.js.map → chunk-JGPG5UHM.js.map} +0 -0
  519. /package/dist/{chunk-U3ZRHNNG.js.map → chunk-JHUODJRW.js.map} +0 -0
  520. /package/dist/{chunk-5WIGM42T.js.map → chunk-JXSOB3SA.js.map} +0 -0
  521. /package/dist/{chunk-YOC3EEZH.js.map → chunk-KAPYPTPS.js.map} +0 -0
  522. /package/dist/{chunk-AOMVOC2E.js.map → chunk-KBHDV7P3.js.map} +0 -0
  523. /package/dist/{chunk-2WMXZYMS.js.map → chunk-LIAKZGOY.js.map} +0 -0
  524. /package/dist/{chunk-A7GQBJP5.js.map → chunk-LVFI5LG7.js.map} +0 -0
  525. /package/dist/{chunk-EHUUXLLA.js.map → chunk-LX7KIJQF.js.map} +0 -0
  526. /package/dist/{chunk-EBLKS57G.js.map → chunk-MNF6PTNL.js.map} +0 -0
  527. /package/dist/{chunk-LE2UESGS.js.map → chunk-MYDA2GA2.js.map} +0 -0
  528. /package/dist/{chunk-XQFHKPNB.js.map → chunk-NROI5XMG.js.map} +0 -0
  529. /package/dist/{chunk-N57PUWUE.js.map → chunk-NVW5ISEJ.js.map} +0 -0
  530. /package/dist/{chunk-PSQRBCGR.js.map → chunk-NXSNFPYI.js.map} +0 -0
  531. /package/dist/{chunk-LLFMZYFS.js.map → chunk-O4JFBEUL.js.map} +0 -0
  532. /package/dist/{chunk-JVM3CEGL.js.map → chunk-OIK3YL2P.js.map} +0 -0
  533. /package/dist/{chunk-C3YEB7CR.js.map → chunk-PLJ2MQFT.js.map} +0 -0
  534. /package/dist/{chunk-Z2OKRO3E.js.map → chunk-PYTSGD5M.js.map} +0 -0
  535. /package/dist/{chunk-VBRS7Z3O.js.map → chunk-Q6OC4UUT.js.map} +0 -0
  536. /package/dist/{chunk-ZYZW46HZ.js.map → chunk-QRSC37NC.js.map} +0 -0
  537. /package/dist/{chunk-AJLQH4RO.js.map → chunk-RIP2AOZW.js.map} +0 -0
  538. /package/dist/{chunk-SYJZUVTN.js.map → chunk-SCM4VYJW.js.map} +0 -0
  539. /package/dist/{chunk-76RTJ533.js.map → chunk-SMI2G3MA.js.map} +0 -0
  540. /package/dist/{chunk-WGCASEEQ.js.map → chunk-SZ75IB2T.js.map} +0 -0
  541. /package/dist/{chunk-FLZJMXFV.js.map → chunk-T73ZC7C5.js.map} +0 -0
  542. /package/dist/{chunk-FVRZDZ7J.js.map → chunk-TNFDWJRS.js.map} +0 -0
  543. /package/dist/{chunk-WNMVUWI7.js.map → chunk-TTFJQ5B5.js.map} +0 -0
  544. /package/dist/{chunk-HIBNECBQ.js.map → chunk-UP3226JC.js.map} +0 -0
  545. /package/dist/{chunk-NDWBT2VV.js.map → chunk-UVEBBXB5.js.map} +0 -0
  546. /package/dist/{chunk-KQAFEZQX.js.map → chunk-VDX2J7OX.js.map} +0 -0
  547. /package/dist/{chunk-AIKUSXIS.js.map → chunk-VLR4S5GF.js.map} +0 -0
  548. /package/dist/{chunk-ZHXSOMYH.js.map → chunk-VVX5PZFS.js.map} +0 -0
  549. /package/dist/{chunk-HS75MCQF.js.map → chunk-WUUGE7QC.js.map} +0 -0
  550. /package/dist/{chunk-RS53SDCA.js.map → chunk-X25NTN3W.js.map} +0 -0
  551. /package/dist/{chunk-PZHN7R35.js.map → chunk-XFXVIXDI.js.map} +0 -0
  552. /package/dist/{chunk-YA5M7OC4.js.map → chunk-XHDQQ2TT.js.map} +0 -0
  553. /package/dist/{chunk-IIDXU2CY.js.map → chunk-XRUOO7OT.js.map} +0 -0
  554. /package/dist/{chunk-JUOJGZPV.js.map → chunk-YIIW2OH2.js.map} +0 -0
  555. /package/dist/{chunk-SKYYPVBW.js.map → chunk-YJJMJH6J.js.map} +0 -0
@@ -0,0 +1,134 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+
4
+ import { abortError } from "./abort-error.js";
5
+ import {
6
+ compactRecallContextFromBuckets,
7
+ decideRecallContextComposition,
8
+ notifyContextComposition,
9
+ recallFailureComposition,
10
+ } from "./recall-composition-decision.js";
11
+
12
+ test("#2972 healthy recall composition carries no degradation marker", () => {
13
+ const { composition, truncated } = decideRecallContextComposition({
14
+ context: "A remembered deployment decision.",
15
+ maxChars: 512,
16
+ });
17
+
18
+ assert.equal("degradation" in composition, false);
19
+ assert.equal(truncated, false);
20
+ assert.ok(!JSON.stringify(composition).includes("degradation"));
21
+ });
22
+
23
+ test("#2972 empty recall stays marker-free", () => {
24
+ const { composition, context } = decideRecallContextComposition({
25
+ context: "",
26
+ maxChars: 512,
27
+ });
28
+
29
+ assert.equal(context, "");
30
+ assert.equal("degradation" in composition, false);
31
+ });
32
+
33
+ test("#2972 compact form from section buckets is preferred over clipping", () => {
34
+ const longOne = "full-form entry one with a long body ".repeat(6).trim();
35
+ const longTwo = "full-form entry two with a long body ".repeat(6).trim();
36
+ const buckets = new Map<string, Array<string | { content: string }>>([
37
+ [
38
+ "memories",
39
+ [
40
+ "## Relevant Memories",
41
+ { content: `[1] notes/one.md (score: 0.900)\n${longOne}` },
42
+ { content: `[2] notes/two.md (score: 0.800)\n${longTwo}` },
43
+ ],
44
+ ],
45
+ ]);
46
+ const compactContext = compactRecallContextFromBuckets(buckets);
47
+ assert.equal(
48
+ compactContext,
49
+ "## Relevant Memories\n[1] notes/one.md (score: 0.900)\n[2] notes/two.md (score: 0.800)",
50
+ );
51
+
52
+ const fullContext = `[1] notes/one.md (score: 0.900)\n${longOne}\n\n[2] notes/two.md (score: 0.800)\n${longTwo}`;
53
+ assert.ok(fullContext.length > compactContext.length);
54
+ assert.ok(compactContext.length <= 90);
55
+
56
+ const { composition, truncated } = decideRecallContextComposition({
57
+ context: fullContext,
58
+ compactContext,
59
+ maxChars: 90,
60
+ });
61
+
62
+ assert.equal(composition.context, compactContext);
63
+ assert.equal(composition.degradation?.state, "degraded");
64
+ assert.equal(composition.degradation?.reason, "budget-compacted");
65
+ assert.equal(truncated, true);
66
+ });
67
+
68
+ test("#2972 whitespace-only context stays marker-free", () => {
69
+ const { composition, context, truncated } = decideRecallContextComposition({
70
+ context: " ",
71
+ maxChars: 512,
72
+ });
73
+
74
+ assert.equal(context, "");
75
+ assert.equal("degradation" in composition, false);
76
+ assert.equal(truncated, false);
77
+ });
78
+
79
+ test("#2972 recall failure composition is missing, abort stays silent", () => {
80
+ const timeout = recallFailureComposition(new Error("recall timeout"));
81
+ assert.equal(timeout?.degradation?.state, "missing");
82
+ assert.equal(timeout?.degradation?.reason, "backend-unavailable");
83
+ assert.equal(timeout?.degradation?.detail, "timeout");
84
+ assert.match(timeout?.context ?? "", /memory context unavailable/i);
85
+
86
+ const failed = recallFailureComposition(new Error("qmd exploded"));
87
+ assert.equal(failed?.degradation?.detail, "recall_failed");
88
+
89
+ assert.equal(recallFailureComposition(abortError("recall aborted")), null);
90
+ });
91
+
92
+ test("#2972 composition observer is fail-open", async () => {
93
+ const seen: unknown[] = [];
94
+ notifyContextComposition(
95
+ (composition) => {
96
+ seen.push(composition.context);
97
+ },
98
+ { context: "ok" },
99
+ () => {
100
+ throw new Error("onError must not run on success");
101
+ },
102
+ );
103
+ assert.deepEqual(seen, ["ok"]);
104
+
105
+ const errors: unknown[] = [];
106
+ notifyContextComposition(
107
+ () => {
108
+ throw new Error("observer boom");
109
+ },
110
+ { context: "ok" },
111
+ (err) => {
112
+ errors.push(err);
113
+ },
114
+ );
115
+ assert.equal(errors.length, 1);
116
+
117
+ await new Promise<void>((resolve, reject) => {
118
+ notifyContextComposition(
119
+ async () => {
120
+ throw new Error("async boom");
121
+ },
122
+ { context: "ok" },
123
+ (err) => {
124
+ try {
125
+ assert.equal((err as Error).message, "async boom");
126
+ resolve();
127
+ } catch (caught) {
128
+ reject(caught);
129
+ }
130
+ },
131
+ );
132
+ });
133
+ });
134
+
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Recall composition decision (#2972 layer 2).
3
+ *
4
+ * Extracted from recall-internal so that file stays under its ratchet
5
+ * ceiling. Classifies injected memory context as complete / degraded /
6
+ * missing, builds the compact (first-line) form from section buckets,
7
+ * and turns outer-recall failures into the missing-note instead of "".
8
+ */
9
+
10
+ import { isAbortError } from "./abort-error.js";
11
+ import {
12
+ boundRecallContextComposition,
13
+ composeMissingMemoryContext,
14
+ composeRecallContext,
15
+ RECALL_CONTEXT_SEPARATOR,
16
+ type RecallContextComposition,
17
+ } from "./recall-context-composition.js";
18
+
19
+ export type RecallCompositionChunk = string | { readonly content: string };
20
+
21
+ export interface DecideRecallContextCompositionInput {
22
+ context: string;
23
+ compactContext?: string;
24
+ footer?: string;
25
+ maxChars: number;
26
+ }
27
+
28
+ export interface DecidedRecallContextComposition {
29
+ composition: RecallContextComposition;
30
+ context: string;
31
+ truncated: boolean;
32
+ }
33
+
34
+ function firstLine(content: string): string {
35
+ const trimmed = content.trim();
36
+ if (trimmed.length === 0) return "";
37
+ const newline = trimmed.indexOf("\n");
38
+ return newline === -1 ? trimmed : trimmed.slice(0, newline).trimEnd();
39
+ }
40
+
41
+ function chunkContent(chunk: RecallCompositionChunk): string {
42
+ return typeof chunk === "string" ? chunk : chunk.content;
43
+ }
44
+
45
+ /**
46
+ * Shallow form of every section chunk: the first line of each entry,
47
+ * so a budget miss prefers breadth-complete-but-shallow over a clipped
48
+ * tail. Empty chunks contribute nothing.
49
+ */
50
+ export function compactRecallContextFromBuckets(
51
+ buckets: Iterable<readonly [unknown, readonly RecallCompositionChunk[]]>,
52
+ ): string {
53
+ const sections: string[] = [];
54
+ for (const [, chunks] of buckets) {
55
+ const lines: string[] = [];
56
+ for (const chunk of chunks) {
57
+ const line = firstLine(chunkContent(chunk));
58
+ if (line.length > 0) lines.push(line);
59
+ }
60
+ if (lines.length > 0) sections.push(lines.join("\n"));
61
+ }
62
+ return sections.join(RECALL_CONTEXT_SEPARATOR);
63
+ }
64
+
65
+ export function decideRecallContextComposition(
66
+ input: DecideRecallContextCompositionInput,
67
+ ): DecidedRecallContextComposition {
68
+ const composition = boundRecallContextComposition({
69
+ context: input.context,
70
+ footer: input.footer,
71
+ maxChars: input.maxChars,
72
+ compactContext: input.compactContext,
73
+ });
74
+ return {
75
+ composition,
76
+ context: composeRecallContext(composition),
77
+ truncated:
78
+ composition.degradation?.reason === "budget-clipped" ||
79
+ composition.degradation?.reason === "budget-compacted",
80
+ };
81
+ }
82
+
83
+ export function notifyContextComposition(
84
+ onContextComposition:
85
+ | ((composition: RecallContextComposition) => void | PromiseLike<void>)
86
+ | undefined,
87
+ composition: RecallContextComposition,
88
+ onError: (err: unknown) => void,
89
+ ): void {
90
+ if (!onContextComposition) return;
91
+ try {
92
+ const result = onContextComposition(composition);
93
+ if (result && typeof result.then === "function") {
94
+ void Promise.resolve(result).catch(onError);
95
+ }
96
+ } catch (err) {
97
+ onError(err);
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Outer-recall failure: abort stays silent (empty string). Timeout and
103
+ * other errors become the missing-note so a failed query is never
104
+ * indistinguishable from "no matches".
105
+ */
106
+ export function recallFailureComposition(err: unknown): RecallContextComposition | null {
107
+ if (isAbortError(err)) return null;
108
+ const detail =
109
+ err instanceof Error && err.message === "recall timeout"
110
+ ? "timeout"
111
+ : "recall_failed";
112
+ return composeMissingMemoryContext({ detail });
113
+ }
@@ -0,0 +1,306 @@
1
+ /**
2
+ * recall-recognition-tier.test.ts — issue #2975 foundation slice.
3
+ *
4
+ * Pins the full-index recognition tier contract:
5
+ * - under-threshold namespaces recall by recognizing against the FULL
6
+ * compact index (every id+description line reaches the recognizer) and
7
+ * never touch vector search;
8
+ * - above-threshold namespaces route to vector search and never call the
9
+ * recognizer;
10
+ * - a missing (or unreadable) index falls back to vector search cleanly,
11
+ * without throwing;
12
+ * - the tier decision is deterministic and pure on (index, maxEntries);
13
+ * - recognizer picks are validated against the index and returned in
14
+ * index order, never recognizer order;
15
+ * - a failing recognizer degrades LOUDLY to vector search, labeled.
16
+ */
17
+ import assert from "node:assert/strict";
18
+ import os from "node:os";
19
+ import path from "node:path";
20
+ import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
21
+ import test from "node:test";
22
+
23
+ import { parseConfig } from "./config.js";
24
+ import {
25
+ buildRecognitionIndex,
26
+ buildRecognitionPrompt,
27
+ decideRecognitionTier,
28
+ loadRecognitionIndex,
29
+ parseRecognizerIds,
30
+ parseRecallRecognitionTier,
31
+ parseRecognitionIndexMaxEntries,
32
+ recallViaRecognitionTier,
33
+ recognitionIndexPath,
34
+ renderRecognitionIndex,
35
+ runRecognitionTier,
36
+ saveRecognitionIndex,
37
+ type RecognitionIndex,
38
+ type RecognitionIndexEntry,
39
+ } from "./recall-recognition-tier.js";
40
+
41
+ function entries(n: number): RecognitionIndexEntry[] {
42
+ const out: RecognitionIndexEntry[] = [];
43
+ for (let i = 1; i <= n; i++) {
44
+ out.push({
45
+ id: `m-${String(i).padStart(3, "0")}`,
46
+ description: `Recognition trigger line ${i} for namespace fixture ${i}.`,
47
+ });
48
+ }
49
+ return out;
50
+ }
51
+
52
+ async function tmpNamespace(): Promise<string> {
53
+ return mkdtemp(path.join(os.tmpdir(), "remnic-recognition-"));
54
+ }
55
+
56
+ test("decideRecognitionTier: deterministic decision table", () => {
57
+ const absent = decideRecognitionTier(null, { maxEntries: 10 });
58
+ assert.equal(absent.tier, "vector");
59
+ assert.equal(absent.reason, "index_absent");
60
+ assert.equal(absent.entriesConsidered, 0);
61
+
62
+ const within = decideRecognitionTier(
63
+ { version: 1, entries: entries(3) },
64
+ { maxEntries: 10 },
65
+ );
66
+ assert.equal(within.tier, "recognition");
67
+ assert.equal(within.reason, "index_within_threshold");
68
+ assert.equal(within.entriesConsidered, 3);
69
+
70
+ const atThreshold = decideRecognitionTier(
71
+ { version: 1, entries: entries(4) },
72
+ { maxEntries: 4 },
73
+ );
74
+ assert.equal(atThreshold.tier, "recognition");
75
+
76
+ const above = decideRecognitionTier(
77
+ { version: 1, entries: entries(5) },
78
+ { maxEntries: 4 },
79
+ );
80
+ assert.equal(above.tier, "vector");
81
+ assert.equal(above.reason, "index_above_threshold");
82
+ assert.equal(above.entriesConsidered, 5);
83
+
84
+ const empty = decideRecognitionTier({ version: 1, entries: [] }, { maxEntries: 10 });
85
+ assert.equal(empty.tier, "recognition");
86
+ assert.equal(empty.reason, "index_within_threshold");
87
+ });
88
+
89
+ test("loadRecognitionIndex: missing, corrupt, wrong-shape, and future-version indexes return null without throwing", async () => {
90
+ const dir = await tmpNamespace();
91
+ try {
92
+ // Missing file.
93
+ assert.equal(await loadRecognitionIndex(dir), null);
94
+
95
+ // Corrupt JSON.
96
+ const file = recognitionIndexPath(dir);
97
+ await mkdir(path.dirname(file), { recursive: true });
98
+ await writeFile(file, "{ not json", "utf8");
99
+ assert.equal(await loadRecognitionIndex(dir), null);
100
+
101
+ // Valid JSON, wrong shape.
102
+ await writeFile(file, JSON.stringify({ version: 1, entries: "nope" }), "utf8");
103
+ assert.equal(await loadRecognitionIndex(dir), null);
104
+
105
+ // Future schema version.
106
+ await writeFile(
107
+ file,
108
+ JSON.stringify({ version: 99, entries: entries(2) }),
109
+ "utf8",
110
+ );
111
+ assert.equal(await loadRecognitionIndex(dir), null);
112
+
113
+ // Roundtrip: save then load returns the same index.
114
+ const index: RecognitionIndex = { version: 1, entries: entries(2) };
115
+ await saveRecognitionIndex(dir, index);
116
+ assert.deepEqual(await loadRecognitionIndex(dir), index);
117
+ } finally {
118
+ await rm(dir, { recursive: true, force: true });
119
+ }
120
+ });
121
+
122
+ test("buildRecognitionIndex: drops blank ids, trims descriptions, first id wins", () => {
123
+ const built = buildRecognitionIndex([
124
+ { id: "m-001", description: " first line " },
125
+ { id: "", description: "blank id is dropped" },
126
+ { id: " ", description: "whitespace id is dropped" },
127
+ { id: "m-001", description: "duplicate id keeps the first description" },
128
+ { id: "m-002", description: "second line" },
129
+ ]);
130
+ assert.deepEqual(built.entries, [
131
+ { id: "m-001", description: "first line" },
132
+ { id: "m-002", description: "second line" },
133
+ ]);
134
+ assert.equal(built.version, 1);
135
+ });
136
+
137
+ test("acceptance: under-threshold namespace uses the full-index path, not vector search", async () => {
138
+ const dir = await tmpNamespace();
139
+ try {
140
+ const index: RecognitionIndex = { version: 1, entries: entries(3) };
141
+ await saveRecognitionIndex(dir, index);
142
+
143
+ const prompts: string[] = [];
144
+ const outcome = await recallViaRecognitionTier({
145
+ memoryDir: dir,
146
+ query: "which memories bear on the question?",
147
+ maxEntries: 10,
148
+ recognize: async (prompt) => {
149
+ prompts.push(prompt);
150
+ return "m-002, m-003";
151
+ },
152
+ vectorSearch: async () => {
153
+ throw new Error("vector search must not run on the recognition tier");
154
+ },
155
+ });
156
+
157
+ assert.equal(outcome.decision.tier, "recognition");
158
+ assert.equal(outcome.decision.reason, "index_within_threshold");
159
+ assert.deepEqual(outcome.ids, ["m-002", "m-003"]);
160
+ assert.deepEqual(outcome.vectorResults, []);
161
+ assert.equal(outcome.degraded, undefined);
162
+
163
+ // Full-index proof: the recognizer saw EVERY index line.
164
+ assert.equal(prompts.length, 1);
165
+ for (const entry of index.entries) {
166
+ assert.ok(prompts[0].includes(`${entry.id}: ${entry.description}`), `prompt must carry ${entry.id}`);
167
+ }
168
+ } finally {
169
+ await rm(dir, { recursive: true, force: true });
170
+ }
171
+ });
172
+
173
+ test("acceptance: above-threshold namespace uses vector search, not the recognizer", async () => {
174
+ const dir = await tmpNamespace();
175
+ try {
176
+ await saveRecognitionIndex(dir, { version: 1, entries: entries(5) });
177
+
178
+ const outcome = await recallViaRecognitionTier({
179
+ memoryDir: dir,
180
+ query: "anything",
181
+ maxEntries: 4,
182
+ recognize: async () => {
183
+ throw new Error("recognizer must not run on the vector tier");
184
+ },
185
+ vectorSearch: async () => ["vec-hit-1", "vec-hit-2"],
186
+ });
187
+
188
+ assert.equal(outcome.decision.tier, "vector");
189
+ assert.equal(outcome.decision.reason, "index_above_threshold");
190
+ assert.deepEqual(outcome.ids, []);
191
+ assert.deepEqual(outcome.vectorResults, ["vec-hit-1", "vec-hit-2"]);
192
+ assert.equal(outcome.degraded, undefined);
193
+ } finally {
194
+ await rm(dir, { recursive: true, force: true });
195
+ }
196
+ });
197
+
198
+ test("acceptance: missing index falls back to vector search cleanly, without error", async () => {
199
+ const dir = await tmpNamespace();
200
+ try {
201
+ const outcome = await recallViaRecognitionTier({
202
+ memoryDir: dir,
203
+ query: "anything",
204
+ maxEntries: 10,
205
+ recognize: async () => {
206
+ throw new Error("recognizer must not run without an index");
207
+ },
208
+ vectorSearch: async () => ["vec-fallback"],
209
+ });
210
+
211
+ assert.equal(outcome.decision.tier, "vector");
212
+ assert.equal(outcome.decision.reason, "index_absent");
213
+ assert.deepEqual(outcome.ids, []);
214
+ assert.deepEqual(outcome.vectorResults, ["vec-fallback"]);
215
+ assert.equal(outcome.degraded, undefined);
216
+ } finally {
217
+ await rm(dir, { recursive: true, force: true });
218
+ }
219
+ });
220
+
221
+ test("loud degradation: a failing recognizer falls back to vector search, labeled", async () => {
222
+ const dir = await tmpNamespace();
223
+ try {
224
+ await saveRecognitionIndex(dir, { version: 1, entries: entries(2) });
225
+
226
+ const outcome = await recallViaRecognitionTier({
227
+ memoryDir: dir,
228
+ query: "anything",
229
+ maxEntries: 10,
230
+ recognize: async () => {
231
+ throw new Error("model down");
232
+ },
233
+ vectorSearch: async () => ["vec-degraded"],
234
+ });
235
+
236
+ assert.equal(outcome.decision.tier, "recognition");
237
+ assert.equal(outcome.degraded, "recognizer_unavailable");
238
+ assert.deepEqual(outcome.ids, []);
239
+ assert.deepEqual(outcome.vectorResults, ["vec-degraded"]);
240
+ } finally {
241
+ await rm(dir, { recursive: true, force: true });
242
+ }
243
+ });
244
+
245
+ test("runRecognitionTier: empty index short-circuits with no model call", async () => {
246
+ let calls = 0;
247
+ const run = await runRecognitionTier("q", [], async () => {
248
+ calls++;
249
+ return "m-001";
250
+ });
251
+ assert.equal(calls, 0);
252
+ assert.equal(run.skipped, true);
253
+ assert.deepEqual(run.ids, []);
254
+ });
255
+
256
+ test("runRecognitionTier: unknown ids are dropped; output is index order, not recognizer order", async () => {
257
+ const idx = entries(4);
258
+ const run = await runRecognitionTier("q", idx, async () =>
259
+ "m-004, hallucinated-id, m-001, m-004",
260
+ );
261
+ assert.deepEqual(run.ids, ["m-001", "m-004"]);
262
+ assert.deepEqual(run.dropped, ["hallucinated-id"]);
263
+ });
264
+
265
+ test("runRecognitionTier and prompt are byte-identical across runs with unchanged inputs", async () => {
266
+ const idx = entries(5);
267
+ const recognizer = async () => "m-003, m-001";
268
+ const first = await runRecognitionTier("same query", idx, recognizer);
269
+ const second = await runRecognitionTier("same query", idx, recognizer);
270
+ assert.deepEqual(first, second);
271
+ assert.equal(
272
+ buildRecognitionPrompt("same query", idx),
273
+ buildRecognitionPrompt("same query", idx),
274
+ );
275
+ assert.equal(renderRecognitionIndex(idx).split("\n").length, 5);
276
+ });
277
+
278
+ test("parseRecognizerIds: tolerant parsing of JSON arrays, lists, and noise", () => {
279
+ assert.deepEqual(parseRecognizerIds('["m-001","m-002"]'), ["m-001", "m-002"]);
280
+ assert.deepEqual(parseRecognizerIds("m-001, m-002"), ["m-001", "m-002"]);
281
+ assert.deepEqual(parseRecognizerIds("m-001\nm-002."), ["m-001", "m-002"]);
282
+ assert.deepEqual(parseRecognizerIds("m-001, m-001, m-002"), ["m-001", "m-002"]);
283
+ assert.deepEqual(parseRecognizerIds(null), []);
284
+ assert.deepEqual(parseRecognizerIds(" "), []);
285
+ });
286
+
287
+ test("config parse helpers: defaults, coercion, and rejection", () => {
288
+ assert.equal(parseRecallRecognitionTier(undefined), false);
289
+ assert.equal(parseRecallRecognitionTier(true), true);
290
+ assert.equal(parseRecallRecognitionTier("false"), false);
291
+
292
+ assert.equal(parseRecognitionIndexMaxEntries(undefined), 500);
293
+ assert.equal(parseRecognitionIndexMaxEntries(128.9), 128);
294
+ assert.throws(() => parseRecognitionIndexMaxEntries(0), /recognitionIndexMaxEntries/);
295
+ assert.throws(() => parseRecognitionIndexMaxEntries("abc"), /recognitionIndexMaxEntries/);
296
+ });
297
+
298
+ test("parseConfig: recognition tier keys parse with byte-identical defaults", () => {
299
+ const config = parseConfig({});
300
+ assert.equal(config.recallRecognitionTier, false);
301
+ assert.equal(config.recognitionIndexMaxEntries, 500);
302
+
303
+ const optedIn = parseConfig({ recallRecognitionTier: true, recognitionIndexMaxEntries: 42 });
304
+ assert.equal(optedIn.recallRecognitionTier, true);
305
+ assert.equal(optedIn.recognitionIndexMaxEntries, 42);
306
+ });