@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
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  rebuildMemoryProjection
3
- } from "./chunk-AOMVOC2E.js";
3
+ } from "./chunk-KBHDV7P3.js";
4
4
 
5
5
  // src/convergence-refresh.ts
6
6
  async function refreshConvergedNamespaces(namespaces, namespaceSearchRouter, getStorage, searchEnabled) {
@@ -32,4 +32,4 @@ async function refreshConvergedNamespaces(namespaces, namespaceSearchRouter, get
32
32
  export {
33
33
  refreshConvergedNamespaces
34
34
  };
35
- //# sourceMappingURL=chunk-EST3J4LX.js.map
35
+ //# sourceMappingURL=chunk-2SZBCM2S.js.map
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  computeCorpusWatermarks,
6
6
  resolveCorpusNamespaceRoots
7
- } from "./chunk-3MX4GWJO.js";
7
+ } from "./chunk-JGPG5UHM.js";
8
8
 
9
9
  // src/operator-doctor-corpus.ts
10
10
  var DIGEST_PREFIX_LENGTH = 12;
@@ -78,4 +78,4 @@ export {
78
78
  corpusWatermarksFromCheck,
79
79
  summarizeCorpusAndReplica
80
80
  };
81
- //# sourceMappingURL=chunk-UB4UVALS.js.map
81
+ //# sourceMappingURL=chunk-33SX6K3N.js.map
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-B7RWBZXW.js";
4
4
  import {
5
5
  StorageManager
6
- } from "./chunk-AJLQH4RO.js";
6
+ } from "./chunk-RIP2AOZW.js";
7
7
  import {
8
8
  getCachedEpisodeMap,
9
9
  setCachedEpisodeMap
@@ -109,4 +109,4 @@ export {
109
109
  compareVerifiedEpisodeResults,
110
110
  searchVerifiedEpisodes
111
111
  };
112
- //# sourceMappingURL=chunk-P36WML7L.js.map
112
+ //# sourceMappingURL=chunk-3QZRSEAM.js.map
@@ -0,0 +1,197 @@
1
+ import {
2
+ coerceBooleanLike,
3
+ coerceNumber
4
+ } from "./chunk-PQVCH2AE.js";
5
+ import {
6
+ log
7
+ } from "./chunk-3WCASNQZ.js";
8
+
9
+ // src/recall-recognition-tier.ts
10
+ import { promises as fsp } from "fs";
11
+ import path from "path";
12
+ var DEFAULT_RECALL_RECOGNITION_TIER = false;
13
+ var DEFAULT_RECOGNITION_INDEX_MAX_ENTRIES = 500;
14
+ var RECOGNITION_INDEX_VERSION = 1;
15
+ var RECOGNITION_INDEX_FILE = "index_recognition.json";
16
+ var RECOGNITION_PROMPT_HEADER = "Memory index \u2014 one line per memory. Name the ids that bear on the question.";
17
+ var RECOGNITION_PROMPT_FOOTER = "Answer with the relevant ids only, comma-separated. If none bear on the question, answer with nothing.";
18
+ function parseRecallRecognitionTier(raw) {
19
+ return coerceBooleanLike(raw, "recallRecognitionTier") === true;
20
+ }
21
+ function parseRecognitionIndexMaxEntries(raw) {
22
+ if (raw === void 0 || raw === null) return DEFAULT_RECOGNITION_INDEX_MAX_ENTRIES;
23
+ const n = coerceNumber(raw, "recognitionIndexMaxEntries");
24
+ if (n === void 0 || !Number.isFinite(n) || n < 1) {
25
+ throw new Error(
26
+ `Invalid recognitionIndexMaxEntries: expected an integer >= 1, got ${JSON.stringify(raw)}`
27
+ );
28
+ }
29
+ return Math.floor(n);
30
+ }
31
+ function recognitionIndexPath(memoryDir) {
32
+ return path.join(memoryDir, "state", RECOGNITION_INDEX_FILE);
33
+ }
34
+ function buildRecognitionIndex(records) {
35
+ const seen = /* @__PURE__ */ new Set();
36
+ const out = [];
37
+ for (const record of records) {
38
+ const id = typeof record.id === "string" ? record.id.trim() : "";
39
+ if (id.length === 0 || seen.has(id)) continue;
40
+ seen.add(id);
41
+ out.push({
42
+ id,
43
+ description: typeof record.description === "string" ? record.description.trim() : ""
44
+ });
45
+ }
46
+ return { version: RECOGNITION_INDEX_VERSION, entries: out };
47
+ }
48
+ async function saveRecognitionIndex(memoryDir, index) {
49
+ const file = recognitionIndexPath(memoryDir);
50
+ await fsp.mkdir(path.dirname(file), { recursive: true });
51
+ await fsp.writeFile(file, `${JSON.stringify(index, null, 2)}
52
+ `, "utf8");
53
+ }
54
+ function isRecognitionIndex(raw) {
55
+ if (typeof raw !== "object" || raw === null) return false;
56
+ const candidate = raw;
57
+ if (candidate.version !== RECOGNITION_INDEX_VERSION) return false;
58
+ if (!Array.isArray(candidate.entries)) return false;
59
+ return candidate.entries.every(
60
+ (entry) => typeof entry === "object" && entry !== null && typeof entry.id === "string" && typeof entry.description === "string"
61
+ );
62
+ }
63
+ async function loadRecognitionIndex(memoryDir) {
64
+ try {
65
+ const raw = await fsp.readFile(recognitionIndexPath(memoryDir), "utf8");
66
+ const parsed = JSON.parse(raw);
67
+ if (isRecognitionIndex(parsed)) return parsed;
68
+ log.warn(
69
+ `recognition index ignored at ${RECOGNITION_INDEX_FILE}: unexpected shape; falling back to vector search`
70
+ );
71
+ return null;
72
+ } catch {
73
+ return null;
74
+ }
75
+ }
76
+ function decideRecognitionTier(index, opts) {
77
+ const maxEntries = Math.max(1, Math.floor(opts.maxEntries));
78
+ if (index === null) {
79
+ return { tier: "vector", reason: "index_absent", entriesConsidered: 0, maxEntries };
80
+ }
81
+ if (index.entries.length > maxEntries) {
82
+ return {
83
+ tier: "vector",
84
+ reason: "index_above_threshold",
85
+ entriesConsidered: index.entries.length,
86
+ maxEntries
87
+ };
88
+ }
89
+ return {
90
+ tier: "recognition",
91
+ reason: "index_within_threshold",
92
+ entriesConsidered: index.entries.length,
93
+ maxEntries
94
+ };
95
+ }
96
+ function renderRecognitionIndex(entries) {
97
+ return entries.map((entry) => `${entry.id}: ${entry.description}`).join("\n");
98
+ }
99
+ function buildRecognitionPrompt(query, entries) {
100
+ return [
101
+ RECOGNITION_PROMPT_HEADER,
102
+ renderRecognitionIndex(entries),
103
+ `Question: ${query}`,
104
+ RECOGNITION_PROMPT_FOOTER
105
+ ].join("\n\n");
106
+ }
107
+ function dedupeOrdered(tokens) {
108
+ const seen = /* @__PURE__ */ new Set();
109
+ const out = [];
110
+ for (const token of tokens) {
111
+ if (token.length > 0 && !seen.has(token)) {
112
+ seen.add(token);
113
+ out.push(token);
114
+ }
115
+ }
116
+ return out;
117
+ }
118
+ var TRAILING_PUNCTUATION = { ".": true, ",": true, ";": true, ":": true };
119
+ function stripTrailingPunctuation(value) {
120
+ let end = value.length;
121
+ while (end > 0 && TRAILING_PUNCTUATION[value.charAt(end - 1)]) end -= 1;
122
+ return value.slice(0, end);
123
+ }
124
+ function parseRecognizerIds(output) {
125
+ if (typeof output !== "string") return [];
126
+ const text = output.trim();
127
+ if (text.length === 0) return [];
128
+ if (text.startsWith("[")) {
129
+ try {
130
+ const parsed = JSON.parse(text);
131
+ if (Array.isArray(parsed)) {
132
+ return dedupeOrdered(
133
+ parsed.filter((item) => typeof item === "string").map((item) => stripTrailingPunctuation(item.trim()).trim())
134
+ );
135
+ }
136
+ } catch {
137
+ }
138
+ }
139
+ return dedupeOrdered(
140
+ text.split(/[\s,]+/).map((token) => stripTrailingPunctuation(token.replace(/^[•\-*\d.)\]]+/, "")).trim())
141
+ );
142
+ }
143
+ async function runRecognitionTier(query, entries, recognize) {
144
+ if (entries.length === 0) {
145
+ return { ids: [], dropped: [], skipped: true };
146
+ }
147
+ const raw = parseRecognizerIds(await recognize(buildRecognitionPrompt(query, entries)));
148
+ const byId = new Map(entries.map((entry) => [entry.id, entry]));
149
+ const picked = new Set(raw.filter((token) => byId.has(token)));
150
+ return {
151
+ ids: entries.filter((entry) => picked.has(entry.id)).map((entry) => entry.id),
152
+ dropped: dedupeOrdered(raw.filter((token) => !byId.has(token))),
153
+ skipped: false
154
+ };
155
+ }
156
+ async function recallViaRecognitionTier(args) {
157
+ const index = await loadRecognitionIndex(args.memoryDir);
158
+ const decision = decideRecognitionTier(index, { maxEntries: args.maxEntries });
159
+ if (index === null || decision.tier === "vector") {
160
+ return { decision, ids: [], vectorResults: await args.vectorSearch() };
161
+ }
162
+ try {
163
+ const run = await runRecognitionTier(args.query, index.entries, args.recognize);
164
+ return { decision, ids: run.ids, vectorResults: [] };
165
+ } catch (err) {
166
+ log.warn(
167
+ `recognition tier degraded to vector search: recognizer failed${err instanceof Error ? ` (${err.message})` : ""}`
168
+ );
169
+ return {
170
+ decision,
171
+ ids: [],
172
+ vectorResults: await args.vectorSearch(),
173
+ degraded: "recognizer_unavailable"
174
+ };
175
+ }
176
+ }
177
+
178
+ export {
179
+ DEFAULT_RECALL_RECOGNITION_TIER,
180
+ DEFAULT_RECOGNITION_INDEX_MAX_ENTRIES,
181
+ RECOGNITION_INDEX_VERSION,
182
+ RECOGNITION_PROMPT_HEADER,
183
+ RECOGNITION_PROMPT_FOOTER,
184
+ parseRecallRecognitionTier,
185
+ parseRecognitionIndexMaxEntries,
186
+ recognitionIndexPath,
187
+ buildRecognitionIndex,
188
+ saveRecognitionIndex,
189
+ loadRecognitionIndex,
190
+ decideRecognitionTier,
191
+ renderRecognitionIndex,
192
+ buildRecognitionPrompt,
193
+ parseRecognizerIds,
194
+ runRecognitionTier,
195
+ recallViaRecognitionTier
196
+ };
197
+ //# sourceMappingURL=chunk-4KQIWY4A.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/recall-recognition-tier.ts"],"sourcesContent":["/**\n * Full-index recognition tier (issue #2975, foundation slice).\n *\n * distill-kura's recall does not search — it recognizes: the entire\n * namespace index (one line per memory: id + description) goes into a\n * single prompt and a small model names which entries bear on the\n * question. Keyword/vector search misses same-subject-different-words\n * cases; a recognizer that reads the whole index cannot miss what it\n * can see (~500 entries ≈ 6k tokens, sub-second locally).\n *\n * This slice ships the deterministic tier machinery only — nothing on\n * the live recall path reads it yet, so recall behavior is unchanged:\n * - a compact per-namespace index persisted at\n * `<namespace memoryDir>/state/index_recognition.json` with\n * build/save/load; loading is total: missing, corrupt, wrong-shape,\n * or future-version indexes all yield `null`, never an error;\n * - the tier decision, pure on (index, maxEntries): index present and\n * at or under the entry threshold → recognition; absent or above →\n * the vector tier, no error thrown;\n * - the runner: renders the FULL index into one prompt, asks the\n * recognizer for ids, keeps only ids the index actually carries, and\n * returns them in index order — never recognizer order;\n * - loud degradation: a recognizer that fails falls back to vector\n * search labeled `recognizer_unavailable` (quiet degradation is\n * worse than degradation).\n *\n * Determinism rules:\n * - the decision is a pure function of (index, maxEntries) — no clock,\n * no I/O, no locale;\n * - an empty index short-circuits: no model call, zero candidates;\n * - the prompt and the returned ids are byte-identical across runs\n * with unchanged inputs.\n *\n * Host contract for the wiring slices:\n * - maintenance slice: build/save the index at memory write time from\n * each memory's id + description line (a recognition trigger — proper\n * nouns, numbers, landmines, the conclusion reached — not a summary),\n * serializing writes the way temporal-index does (op chain + lock);\n * saveRecognitionIndex here is single-writer and does not lock;\n * - recall slice: for each recalled namespace call\n * recallViaRecognitionTier with the recognizer (one small-model call)\n * and the existing vector search as the fallback; expand picks\n * through the graph neighborhood, merge through the normal pipeline\n * (filters → rerank → budget), and record tier = recognition plus any\n * degraded fallback in xray;\n * - config keys recallRecognitionTier (default false) and\n * recognitionIndexMaxEntries (default 500) gate the wiring.\n */\nimport { promises as fsp } from \"node:fs\";\nimport path from \"node:path\";\nimport { coerceBooleanLike, coerceNumber } from \"./connectors/coerce.js\";\nimport { log } from \"./logger.js\";\n\nexport const DEFAULT_RECALL_RECOGNITION_TIER = false;\nexport const DEFAULT_RECOGNITION_INDEX_MAX_ENTRIES = 500;\nexport const RECOGNITION_INDEX_VERSION = 1;\nconst RECOGNITION_INDEX_FILE = \"index_recognition.json\";\n\nexport const RECOGNITION_PROMPT_HEADER =\n \"Memory index — one line per memory. Name the ids that bear on the question.\";\nexport const RECOGNITION_PROMPT_FOOTER =\n \"Answer with the relevant ids only, comma-separated. If none bear on the question, answer with nothing.\";\n\nexport interface RecognitionIndexEntry {\n /** Stable memory id. Candidates always come back in index order. */\n id: string;\n /** One-line recognition trigger; not a summary (issue #2975 swap test). */\n description: string;\n}\n\nexport interface RecognitionIndex {\n version: number;\n entries: RecognitionIndexEntry[];\n}\n\n/**\n * Config fields this tier owns, mixed into `PluginConfig` (issue #2975) so\n * the keys live beside their parsers instead of growing `types.ts`.\n */\nexport interface RecognitionTierSettings {\n /** Small namespaces recall by recognizing against the whole compact index instead of vector search; parsed now, wiring lands in a later slice. Default false. */\n recallRecognitionTier: boolean;\n /** Max entries a namespace's recognition index may carry for the tier to engage (inclusive). Default 500. */\n recognitionIndexMaxEntries: number;\n}\n\nexport function parseRecallRecognitionTier(raw: unknown): boolean {\n return coerceBooleanLike(raw, \"recallRecognitionTier\") === true;\n}\n\nexport function parseRecognitionIndexMaxEntries(raw: unknown): number {\n if (raw === undefined || raw === null) return DEFAULT_RECOGNITION_INDEX_MAX_ENTRIES;\n const n = coerceNumber(raw, \"recognitionIndexMaxEntries\");\n if (n === undefined || !Number.isFinite(n) || n < 1) {\n throw new Error(\n `Invalid recognitionIndexMaxEntries: expected an integer >= 1, got ${JSON.stringify(raw)}`,\n );\n }\n return Math.floor(n);\n}\n\n/** On-disk location of a namespace's recognition index. */\nexport function recognitionIndexPath(memoryDir: string): string {\n return path.join(memoryDir, \"state\", RECOGNITION_INDEX_FILE);\n}\n\n/**\n * Normalize raw records into a recognition index: blank/whitespace ids\n * are dropped, descriptions are trimmed, and the first record for an id\n * wins. Input order is preserved — it is the recognition order.\n */\nexport function buildRecognitionIndex(\n records: ReadonlyArray<{ id?: string | null; description?: string | null }>,\n): RecognitionIndex {\n const seen = new Set<string>();\n const out: RecognitionIndexEntry[] = [];\n for (const record of records) {\n const id = typeof record.id === \"string\" ? record.id.trim() : \"\";\n if (id.length === 0 || seen.has(id)) continue;\n seen.add(id);\n out.push({\n id,\n description: typeof record.description === \"string\" ? record.description.trim() : \"\",\n });\n }\n return { version: RECOGNITION_INDEX_VERSION, entries: out };\n}\n\n/**\n * Persist a recognition index. Single-writer: the maintenance slice that\n * owns index writes must serialize calls the way temporal-index does.\n */\nexport async function saveRecognitionIndex(\n memoryDir: string,\n index: RecognitionIndex,\n): Promise<void> {\n const file = recognitionIndexPath(memoryDir);\n await fsp.mkdir(path.dirname(file), { recursive: true });\n await fsp.writeFile(file, `${JSON.stringify(index, null, 2)}\\n`, \"utf8\");\n}\n\nfunction isRecognitionIndex(raw: unknown): raw is RecognitionIndex {\n if (typeof raw !== \"object\" || raw === null) return false;\n const candidate = raw as { version?: unknown; entries?: unknown };\n if (candidate.version !== RECOGNITION_INDEX_VERSION) return false;\n if (!Array.isArray(candidate.entries)) return false;\n return candidate.entries.every(\n (entry) =>\n typeof entry === \"object\" &&\n entry !== null &&\n typeof (entry as RecognitionIndexEntry).id === \"string\" &&\n typeof (entry as RecognitionIndexEntry).description === \"string\",\n );\n}\n\n/**\n * Load a namespace's recognition index. Total: a missing, corrupt,\n * wrong-shape, or future-version file all return `null` so the caller\n * falls back to vector search without an error.\n */\nexport async function loadRecognitionIndex(memoryDir: string): Promise<RecognitionIndex | null> {\n try {\n const raw = await fsp.readFile(recognitionIndexPath(memoryDir), \"utf8\");\n const parsed: unknown = JSON.parse(raw);\n if (isRecognitionIndex(parsed)) return parsed;\n log.warn(\n `recognition index ignored at ${RECOGNITION_INDEX_FILE}: unexpected shape; falling back to vector search`,\n );\n return null;\n } catch {\n return null;\n }\n}\n\nexport type RecognitionRecallTier = \"recognition\" | \"vector\";\nexport type RecognitionTierReason =\n | \"index_absent\"\n | \"index_above_threshold\"\n | \"index_within_threshold\";\n\nexport interface RecognitionTierDecision {\n tier: RecognitionRecallTier;\n reason: RecognitionTierReason;\n /** Entries the decision considered; 0 when the index is absent. */\n entriesConsidered: number;\n /** Threshold in force. */\n maxEntries: number;\n}\n\n/**\n * Deterministic tier choice, pure on (index, maxEntries). The threshold\n * is inclusive: an index of exactly maxEntries entries still recognizes\n * (a threshold-sized index is the designed working set, not an overrun).\n */\nexport function decideRecognitionTier(\n index: RecognitionIndex | null,\n opts: { maxEntries: number },\n): RecognitionTierDecision {\n const maxEntries = Math.max(1, Math.floor(opts.maxEntries));\n if (index === null) {\n return { tier: \"vector\", reason: \"index_absent\", entriesConsidered: 0, maxEntries };\n }\n if (index.entries.length > maxEntries) {\n return {\n tier: \"vector\",\n reason: \"index_above_threshold\",\n entriesConsidered: index.entries.length,\n maxEntries,\n };\n }\n return {\n tier: \"recognition\",\n reason: \"index_within_threshold\",\n entriesConsidered: index.entries.length,\n maxEntries,\n };\n}\n\n/** Render the full index, one line per entry, in index order. */\nexport function renderRecognitionIndex(entries: ReadonlyArray<RecognitionIndexEntry>): string {\n return entries.map((entry) => `${entry.id}: ${entry.description}`).join(\"\\n\");\n}\n\n/** The single recognition prompt: header, the FULL index, the question, the answer shape. */\nexport function buildRecognitionPrompt(\n query: string,\n entries: ReadonlyArray<RecognitionIndexEntry>,\n): string {\n return [\n RECOGNITION_PROMPT_HEADER,\n renderRecognitionIndex(entries),\n `Question: ${query}`,\n RECOGNITION_PROMPT_FOOTER,\n ].join(\"\\n\\n\");\n}\n\nfunction dedupeOrdered(tokens: string[]): string[] {\n const seen = new Set<string>();\n const out: string[] = [];\n for (const token of tokens) {\n if (token.length > 0 && !seen.has(token)) {\n seen.add(token);\n out.push(token);\n }\n }\n return out;\n}\n\nconst TRAILING_PUNCTUATION: Record<string, true> = { \".\": true, \",\": true, \";\": true, \":\": true };\n\n/**\n * Strip trailing sentence punctuation in linear time. A quantified anchored\n * regex (`/[.,;:]+$/`) backtracks polynomially on recognizer output made of\n * many separators, and that output is uncontrolled model text.\n */\nfunction stripTrailingPunctuation(value: string): string {\n let end = value.length;\n while (end > 0 && TRAILING_PUNCTUATION[value.charAt(end - 1)]) end -= 1;\n return value.slice(0, end);\n}\n\n/**\n * Parse recognizer output into ordered unique id tokens. Accepts a JSON\n * string array or comma/whitespace-separated ids, and strips sentence\n * punctuation so prose wrappers do not corrupt ids. Tokens that are not\n * real ids are dropped later by validation against the index.\n */\nexport function parseRecognizerIds(output: string | null | undefined): string[] {\n if (typeof output !== \"string\") return [];\n const text = output.trim();\n if (text.length === 0) return [];\n if (text.startsWith(\"[\")) {\n try {\n const parsed: unknown = JSON.parse(text);\n if (Array.isArray(parsed)) {\n return dedupeOrdered(\n parsed\n .filter((item): item is string => typeof item === \"string\")\n .map((item) => stripTrailingPunctuation(item.trim()).trim()),\n );\n }\n } catch {\n // Fall through to separator parsing.\n }\n }\n return dedupeOrdered(\n text\n .split(/[\\s,]+/)\n .map((token) => stripTrailingPunctuation(token.replace(/^[•\\-*\\d.)\\]]+/, \"\")).trim()),\n );\n}\n\n/** One model call over the full index; supplied by the wiring slice. */\nexport type Recognizer = (prompt: string) => Promise<string | null | undefined>;\n\nexport interface RecognitionRunResult {\n /** Recognized ids, validated against the index, in index order. */\n ids: string[];\n /** Recognizer tokens the index does not carry (hallucinated ids). */\n dropped: string[];\n /** True when no model call was made (empty index). */\n skipped: boolean;\n}\n\n/**\n * Run the recognition pass: the FULL index goes into one prompt, the\n * recognizer names ids, unknown ids are dropped, and the kept ids come\n * back in index order so downstream merging stays deterministic.\n */\nexport async function runRecognitionTier(\n query: string,\n entries: ReadonlyArray<RecognitionIndexEntry>,\n recognize: Recognizer,\n): Promise<RecognitionRunResult> {\n if (entries.length === 0) {\n return { ids: [], dropped: [], skipped: true };\n }\n const raw = parseRecognizerIds(await recognize(buildRecognitionPrompt(query, entries)));\n const byId = new Map(entries.map((entry) => [entry.id, entry]));\n const picked = new Set(raw.filter((token) => byId.has(token)));\n return {\n ids: entries.filter((entry) => picked.has(entry.id)).map((entry) => entry.id),\n dropped: dedupeOrdered(raw.filter((token) => !byId.has(token))),\n skipped: false,\n };\n}\n\nexport interface RecognitionTierOutcome<TVector> {\n decision: RecognitionTierDecision;\n /** Recognition picks, index order; empty on the vector tier. */\n ids: string[];\n /** Vector-tier results from the fallback; empty on the recognition tier. */\n vectorResults: TVector[];\n /**\n * Set when recognition was routed but the recognizer failed and the\n * vector tier served the recall instead — loud degradation.\n */\n degraded?: \"recognizer_unavailable\";\n}\n\n/**\n * The wiring-seam composition for one namespace: load the index, decide\n * the tier, then either recognize against the full index or run the\n * caller's vector search. Never throws for index problems; a failing\n * recognizer degrades to vector search labeled `recognizer_unavailable`.\n */\nexport async function recallViaRecognitionTier<TVector>(args: {\n memoryDir: string;\n query: string;\n maxEntries: number;\n recognize: Recognizer;\n vectorSearch: () => Promise<TVector[]>;\n}): Promise<RecognitionTierOutcome<TVector>> {\n const index = await loadRecognitionIndex(args.memoryDir);\n const decision = decideRecognitionTier(index, { maxEntries: args.maxEntries });\n if (index === null || decision.tier === \"vector\") {\n return { decision, ids: [], vectorResults: await args.vectorSearch() };\n }\n try {\n const run = await runRecognitionTier(args.query, index.entries, args.recognize);\n return { decision, ids: run.ids, vectorResults: [] };\n } catch (err) {\n log.warn(\n `recognition tier degraded to vector search: recognizer failed${\n err instanceof Error ? ` (${err.message})` : \"\"\n }`,\n );\n return {\n decision,\n ids: [],\n vectorResults: await args.vectorSearch(),\n degraded: \"recognizer_unavailable\",\n };\n }\n}\n"],"mappings":";;;;;;;;;AAgDA,SAAS,YAAY,WAAW;AAChC,OAAO,UAAU;AAIV,IAAM,kCAAkC;AACxC,IAAM,wCAAwC;AAC9C,IAAM,4BAA4B;AACzC,IAAM,yBAAyB;AAExB,IAAM,4BACX;AACK,IAAM,4BACX;AAyBK,SAAS,2BAA2B,KAAuB;AAChE,SAAO,kBAAkB,KAAK,uBAAuB,MAAM;AAC7D;AAEO,SAAS,gCAAgC,KAAsB;AACpE,MAAI,QAAQ,UAAa,QAAQ,KAAM,QAAO;AAC9C,QAAM,IAAI,aAAa,KAAK,4BAA4B;AACxD,MAAI,MAAM,UAAa,CAAC,OAAO,SAAS,CAAC,KAAK,IAAI,GAAG;AACnD,UAAM,IAAI;AAAA,MACR,qEAAqE,KAAK,UAAU,GAAG,CAAC;AAAA,IAC1F;AAAA,EACF;AACA,SAAO,KAAK,MAAM,CAAC;AACrB;AAGO,SAAS,qBAAqB,WAA2B;AAC9D,SAAO,KAAK,KAAK,WAAW,SAAS,sBAAsB;AAC7D;AAOO,SAAS,sBACd,SACkB;AAClB,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,MAA+B,CAAC;AACtC,aAAW,UAAU,SAAS;AAC5B,UAAM,KAAK,OAAO,OAAO,OAAO,WAAW,OAAO,GAAG,KAAK,IAAI;AAC9D,QAAI,GAAG,WAAW,KAAK,KAAK,IAAI,EAAE,EAAG;AACrC,SAAK,IAAI,EAAE;AACX,QAAI,KAAK;AAAA,MACP;AAAA,MACA,aAAa,OAAO,OAAO,gBAAgB,WAAW,OAAO,YAAY,KAAK,IAAI;AAAA,IACpF,CAAC;AAAA,EACH;AACA,SAAO,EAAE,SAAS,2BAA2B,SAAS,IAAI;AAC5D;AAMA,eAAsB,qBACpB,WACA,OACe;AACf,QAAM,OAAO,qBAAqB,SAAS;AAC3C,QAAM,IAAI,MAAM,KAAK,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AACvD,QAAM,IAAI,UAAU,MAAM,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAAA,GAAM,MAAM;AACzE;AAEA,SAAS,mBAAmB,KAAuC;AACjE,MAAI,OAAO,QAAQ,YAAY,QAAQ,KAAM,QAAO;AACpD,QAAM,YAAY;AAClB,MAAI,UAAU,YAAY,0BAA2B,QAAO;AAC5D,MAAI,CAAC,MAAM,QAAQ,UAAU,OAAO,EAAG,QAAO;AAC9C,SAAO,UAAU,QAAQ;AAAA,IACvB,CAAC,UACC,OAAO,UAAU,YACjB,UAAU,QACV,OAAQ,MAAgC,OAAO,YAC/C,OAAQ,MAAgC,gBAAgB;AAAA,EAC5D;AACF;AAOA,eAAsB,qBAAqB,WAAqD;AAC9F,MAAI;AACF,UAAM,MAAM,MAAM,IAAI,SAAS,qBAAqB,SAAS,GAAG,MAAM;AACtE,UAAM,SAAkB,KAAK,MAAM,GAAG;AACtC,QAAI,mBAAmB,MAAM,EAAG,QAAO;AACvC,QAAI;AAAA,MACF,gCAAgC,sBAAsB;AAAA,IACxD;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAsBO,SAAS,sBACd,OACA,MACyB;AACzB,QAAM,aAAa,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,UAAU,CAAC;AAC1D,MAAI,UAAU,MAAM;AAClB,WAAO,EAAE,MAAM,UAAU,QAAQ,gBAAgB,mBAAmB,GAAG,WAAW;AAAA,EACpF;AACA,MAAI,MAAM,QAAQ,SAAS,YAAY;AACrC,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,mBAAmB,MAAM,QAAQ;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,mBAAmB,MAAM,QAAQ;AAAA,IACjC;AAAA,EACF;AACF;AAGO,SAAS,uBAAuB,SAAuD;AAC5F,SAAO,QAAQ,IAAI,CAAC,UAAU,GAAG,MAAM,EAAE,KAAK,MAAM,WAAW,EAAE,EAAE,KAAK,IAAI;AAC9E;AAGO,SAAS,uBACd,OACA,SACQ;AACR,SAAO;AAAA,IACL;AAAA,IACA,uBAAuB,OAAO;AAAA,IAC9B,aAAa,KAAK;AAAA,IAClB;AAAA,EACF,EAAE,KAAK,MAAM;AACf;AAEA,SAAS,cAAc,QAA4B;AACjD,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,MAAgB,CAAC;AACvB,aAAW,SAAS,QAAQ;AAC1B,QAAI,MAAM,SAAS,KAAK,CAAC,KAAK,IAAI,KAAK,GAAG;AACxC,WAAK,IAAI,KAAK;AACd,UAAI,KAAK,KAAK;AAAA,IAChB;AAAA,EACF;AACA,SAAO;AACT;AAEA,IAAM,uBAA6C,EAAE,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,KAAK;AAOhG,SAAS,yBAAyB,OAAuB;AACvD,MAAI,MAAM,MAAM;AAChB,SAAO,MAAM,KAAK,qBAAqB,MAAM,OAAO,MAAM,CAAC,CAAC,EAAG,QAAO;AACtE,SAAO,MAAM,MAAM,GAAG,GAAG;AAC3B;AAQO,SAAS,mBAAmB,QAA6C;AAC9E,MAAI,OAAO,WAAW,SAAU,QAAO,CAAC;AACxC,QAAM,OAAO,OAAO,KAAK;AACzB,MAAI,KAAK,WAAW,EAAG,QAAO,CAAC;AAC/B,MAAI,KAAK,WAAW,GAAG,GAAG;AACxB,QAAI;AACF,YAAM,SAAkB,KAAK,MAAM,IAAI;AACvC,UAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,eAAO;AAAA,UACL,OACG,OAAO,CAAC,SAAyB,OAAO,SAAS,QAAQ,EACzD,IAAI,CAAC,SAAS,yBAAyB,KAAK,KAAK,CAAC,EAAE,KAAK,CAAC;AAAA,QAC/D;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO;AAAA,IACL,KACG,MAAM,QAAQ,EACd,IAAI,CAAC,UAAU,yBAAyB,MAAM,QAAQ,kBAAkB,EAAE,CAAC,EAAE,KAAK,CAAC;AAAA,EACxF;AACF;AAmBA,eAAsB,mBACpB,OACA,SACA,WAC+B;AAC/B,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO,EAAE,KAAK,CAAC,GAAG,SAAS,CAAC,GAAG,SAAS,KAAK;AAAA,EAC/C;AACA,QAAM,MAAM,mBAAmB,MAAM,UAAU,uBAAuB,OAAO,OAAO,CAAC,CAAC;AACtF,QAAM,OAAO,IAAI,IAAI,QAAQ,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;AAC9D,QAAM,SAAS,IAAI,IAAI,IAAI,OAAO,CAAC,UAAU,KAAK,IAAI,KAAK,CAAC,CAAC;AAC7D,SAAO;AAAA,IACL,KAAK,QAAQ,OAAO,CAAC,UAAU,OAAO,IAAI,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,UAAU,MAAM,EAAE;AAAA,IAC5E,SAAS,cAAc,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC;AAAA,IAC9D,SAAS;AAAA,EACX;AACF;AAqBA,eAAsB,yBAAkC,MAMX;AAC3C,QAAM,QAAQ,MAAM,qBAAqB,KAAK,SAAS;AACvD,QAAM,WAAW,sBAAsB,OAAO,EAAE,YAAY,KAAK,WAAW,CAAC;AAC7E,MAAI,UAAU,QAAQ,SAAS,SAAS,UAAU;AAChD,WAAO,EAAE,UAAU,KAAK,CAAC,GAAG,eAAe,MAAM,KAAK,aAAa,EAAE;AAAA,EACvE;AACA,MAAI;AACF,UAAM,MAAM,MAAM,mBAAmB,KAAK,OAAO,MAAM,SAAS,KAAK,SAAS;AAC9E,WAAO,EAAE,UAAU,KAAK,IAAI,KAAK,eAAe,CAAC,EAAE;AAAA,EACrD,SAAS,KAAK;AACZ,QAAI;AAAA,MACF,gEACE,eAAe,QAAQ,KAAK,IAAI,OAAO,MAAM,EAC/C;AAAA,IACF;AACA,WAAO;AAAA,MACL;AAAA,MACA,KAAK,CAAC;AAAA,MACN,eAAe,MAAM,KAAK,aAAa;AAAA,MACvC,UAAU;AAAA,IACZ;AAAA,EACF;AACF;","names":[]}
@@ -48,4 +48,4 @@ export {
48
48
  appendRecallAuditEntry,
49
49
  pruneRecallAuditEntries
50
50
  };
51
- //# sourceMappingURL=chunk-LBLXEFWK.js.map
51
+ //# sourceMappingURL=chunk-4MN27537.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/recall-audit.ts"],"sourcesContent":["import type { Dirent } from \"node:fs\";\nimport { appendFile, mkdir, readdir, rm } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { RecallContextDegradation } from \"./recall-context-composition.js\";\n\nexport interface RecallAuditEntry {\n ts: string;\n sessionKey: string;\n agentId: string;\n trigger: string;\n queryText: string;\n candidateMemoryIds: string[];\n summary: string | null;\n injectedChars: number;\n toggleState: \"enabled\" | \"disabled-primary\" | \"disabled-secondary\";\n latencyMs?: number;\n plannerMode?: string;\n requestedMode?: string;\n fallbackUsed?: boolean;\n /** Injected-context degradation (#2972). Absent on a healthy recall. */\n degradation?: RecallContextDegradation;\n}\n\nfunction formatIsoDate(ts: string): string {\n const normalized = new Date(ts);\n if (Number.isNaN(normalized.getTime())) {\n return new Date().toISOString().slice(0, 10);\n }\n return normalized.toISOString().slice(0, 10);\n}\n\nexport function buildRecallAuditPath(rootDir: string, ts: string, sessionKey: string): string {\n const safeSessionKey = encodeURIComponent(sessionKey);\n return path.join(rootDir, \"transcripts\", formatIsoDate(ts), `${safeSessionKey}.jsonl`);\n}\n\nexport async function appendRecallAuditEntry(\n rootDir: string,\n entry: RecallAuditEntry,\n): Promise<string> {\n const filePath = buildRecallAuditPath(rootDir, entry.ts, entry.sessionKey);\n await mkdir(path.dirname(filePath), { recursive: true });\n await appendFile(filePath, `${JSON.stringify(entry)}\\n`, \"utf8\");\n return filePath;\n}\n\nexport async function pruneRecallAuditEntries(\n rootDir: string,\n retentionDays: number,\n now: Date = new Date(),\n): Promise<string[]> {\n const transcriptsDir = path.join(rootDir, \"transcripts\");\n const removed: string[] = [];\n const cutoff = new Date(now);\n cutoff.setUTCHours(0, 0, 0, 0);\n cutoff.setUTCDate(cutoff.getUTCDate() - Math.max(1, Math.floor(retentionDays)));\n let entries: Dirent[];\n try {\n entries = await readdir(transcriptsDir, { withFileTypes: true });\n } catch {\n return removed;\n }\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(entry.name)) continue;\n const day = new Date(`${entry.name}T00:00:00.000Z`);\n if (Number.isNaN(day.getTime()) || day >= cutoff) continue;\n const dirPath = path.join(transcriptsDir, entry.name);\n await rm(dirPath, { recursive: true, force: true });\n removed.push(dirPath);\n }\n\n return removed;\n}\n"],"mappings":";AACA,SAAS,YAAY,OAAO,SAAS,UAAU;AAC/C,OAAO,UAAU;AAsBjB,SAAS,cAAc,IAAoB;AACzC,QAAM,aAAa,IAAI,KAAK,EAAE;AAC9B,MAAI,OAAO,MAAM,WAAW,QAAQ,CAAC,GAAG;AACtC,YAAO,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AAAA,EAC7C;AACA,SAAO,WAAW,YAAY,EAAE,MAAM,GAAG,EAAE;AAC7C;AAEO,SAAS,qBAAqB,SAAiB,IAAY,YAA4B;AAC5F,QAAM,iBAAiB,mBAAmB,UAAU;AACpD,SAAO,KAAK,KAAK,SAAS,eAAe,cAAc,EAAE,GAAG,GAAG,cAAc,QAAQ;AACvF;AAEA,eAAsB,uBACpB,SACA,OACiB;AACjB,QAAM,WAAW,qBAAqB,SAAS,MAAM,IAAI,MAAM,UAAU;AACzE,QAAM,MAAM,KAAK,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AACvD,QAAM,WAAW,UAAU,GAAG,KAAK,UAAU,KAAK,CAAC;AAAA,GAAM,MAAM;AAC/D,SAAO;AACT;AAEA,eAAsB,wBACpB,SACA,eACA,MAAY,oBAAI,KAAK,GACF;AACnB,QAAM,iBAAiB,KAAK,KAAK,SAAS,aAAa;AACvD,QAAM,UAAoB,CAAC;AAC3B,QAAM,SAAS,IAAI,KAAK,GAAG;AAC3B,SAAO,YAAY,GAAG,GAAG,GAAG,CAAC;AAC7B,SAAO,WAAW,OAAO,WAAW,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,aAAa,CAAC,CAAC;AAC9E,MAAI;AACJ,MAAI;AACF,cAAU,MAAM,QAAQ,gBAAgB,EAAE,eAAe,KAAK,CAAC;AAAA,EACjE,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,aAAW,SAAS,SAAS;AAC3B,QAAI,CAAC,MAAM,YAAY,EAAG;AAC1B,QAAI,CAAC,sBAAsB,KAAK,MAAM,IAAI,EAAG;AAC7C,UAAM,MAAM,oBAAI,KAAK,GAAG,MAAM,IAAI,gBAAgB;AAClD,QAAI,OAAO,MAAM,IAAI,QAAQ,CAAC,KAAK,OAAO,OAAQ;AAClD,UAAM,UAAU,KAAK,KAAK,gBAAgB,MAAM,IAAI;AACpD,UAAM,GAAG,SAAS,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAClD,YAAQ,KAAK,OAAO;AAAA,EACtB;AAEA,SAAO;AACT;","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  startLocationAutoSync
3
- } from "./chunk-Z2OKRO3E.js";
3
+ } from "./chunk-PYTSGD5M.js";
4
4
  import {
5
5
  ensureContradictionScanCron,
6
6
  ensureDaySummaryCron,
@@ -12,14 +12,14 @@ import {
12
12
  } from "./chunk-666A3MOW.js";
13
13
  import {
14
14
  rebuildMemoryLifecycleLedger
15
- } from "./chunk-WGCASEEQ.js";
15
+ } from "./chunk-SZ75IB2T.js";
16
16
  import {
17
17
  planNamespaceMaintenance,
18
18
  runNamespaceMaintenanceBatchPlan
19
- } from "./chunk-UE7L4EDU.js";
19
+ } from "./chunk-HEKWNWNL.js";
20
20
  import {
21
21
  rebuildMemoryProjection
22
- } from "./chunk-AOMVOC2E.js";
22
+ } from "./chunk-KBHDV7P3.js";
23
23
  import {
24
24
  DEFAULT_TIMELINE_CATEGORIES,
25
25
  TIMELINE_RESERVED_IDLE,
@@ -2450,4 +2450,4 @@ export {
2450
2450
  ActivitySyncScheduler,
2451
2451
  MaintenanceScheduler
2452
2452
  };
2453
- //# sourceMappingURL=chunk-JI5Q6EOY.js.map
2453
+ //# sourceMappingURL=chunk-6HCJWCA4.js.map
@@ -0,0 +1,69 @@
1
+ import {
2
+ RECALL_CONTEXT_SEPARATOR,
3
+ boundRecallContextComposition,
4
+ composeMissingMemoryContext,
5
+ composeRecallContext
6
+ } from "./chunk-IHOXK2I6.js";
7
+ import {
8
+ isAbortError
9
+ } from "./chunk-BTTPKDIL.js";
10
+
11
+ // src/recall-composition-decision.ts
12
+ function firstLine(content) {
13
+ const trimmed = content.trim();
14
+ if (trimmed.length === 0) return "";
15
+ const newline = trimmed.indexOf("\n");
16
+ return newline === -1 ? trimmed : trimmed.slice(0, newline).trimEnd();
17
+ }
18
+ function chunkContent(chunk) {
19
+ return typeof chunk === "string" ? chunk : chunk.content;
20
+ }
21
+ function compactRecallContextFromBuckets(buckets) {
22
+ const sections = [];
23
+ for (const [, chunks] of buckets) {
24
+ const lines = [];
25
+ for (const chunk of chunks) {
26
+ const line = firstLine(chunkContent(chunk));
27
+ if (line.length > 0) lines.push(line);
28
+ }
29
+ if (lines.length > 0) sections.push(lines.join("\n"));
30
+ }
31
+ return sections.join(RECALL_CONTEXT_SEPARATOR);
32
+ }
33
+ function decideRecallContextComposition(input) {
34
+ const composition = boundRecallContextComposition({
35
+ context: input.context,
36
+ footer: input.footer,
37
+ maxChars: input.maxChars,
38
+ compactContext: input.compactContext
39
+ });
40
+ return {
41
+ composition,
42
+ context: composeRecallContext(composition),
43
+ truncated: composition.degradation?.reason === "budget-clipped" || composition.degradation?.reason === "budget-compacted"
44
+ };
45
+ }
46
+ function notifyContextComposition(onContextComposition, composition, onError) {
47
+ if (!onContextComposition) return;
48
+ try {
49
+ const result = onContextComposition(composition);
50
+ if (result && typeof result.then === "function") {
51
+ void Promise.resolve(result).catch(onError);
52
+ }
53
+ } catch (err) {
54
+ onError(err);
55
+ }
56
+ }
57
+ function recallFailureComposition(err) {
58
+ if (isAbortError(err)) return null;
59
+ const detail = err instanceof Error && err.message === "recall timeout" ? "timeout" : "recall_failed";
60
+ return composeMissingMemoryContext({ detail });
61
+ }
62
+
63
+ export {
64
+ compactRecallContextFromBuckets,
65
+ decideRecallContextComposition,
66
+ notifyContextComposition,
67
+ recallFailureComposition
68
+ };
69
+ //# sourceMappingURL=chunk-6VITOSPL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/recall-composition-decision.ts"],"sourcesContent":["/**\n * Recall composition decision (#2972 layer 2).\n *\n * Extracted from recall-internal so that file stays under its ratchet\n * ceiling. Classifies injected memory context as complete / degraded /\n * missing, builds the compact (first-line) form from section buckets,\n * and turns outer-recall failures into the missing-note instead of \"\".\n */\n\nimport { isAbortError } from \"./abort-error.js\";\nimport {\n boundRecallContextComposition,\n composeMissingMemoryContext,\n composeRecallContext,\n RECALL_CONTEXT_SEPARATOR,\n type RecallContextComposition,\n} from \"./recall-context-composition.js\";\n\nexport type RecallCompositionChunk = string | { readonly content: string };\n\nexport interface DecideRecallContextCompositionInput {\n context: string;\n compactContext?: string;\n footer?: string;\n maxChars: number;\n}\n\nexport interface DecidedRecallContextComposition {\n composition: RecallContextComposition;\n context: string;\n truncated: boolean;\n}\n\nfunction firstLine(content: string): string {\n const trimmed = content.trim();\n if (trimmed.length === 0) return \"\";\n const newline = trimmed.indexOf(\"\\n\");\n return newline === -1 ? trimmed : trimmed.slice(0, newline).trimEnd();\n}\n\nfunction chunkContent(chunk: RecallCompositionChunk): string {\n return typeof chunk === \"string\" ? chunk : chunk.content;\n}\n\n/**\n * Shallow form of every section chunk: the first line of each entry,\n * so a budget miss prefers breadth-complete-but-shallow over a clipped\n * tail. Empty chunks contribute nothing.\n */\nexport function compactRecallContextFromBuckets(\n buckets: Iterable<readonly [unknown, readonly RecallCompositionChunk[]]>,\n): string {\n const sections: string[] = [];\n for (const [, chunks] of buckets) {\n const lines: string[] = [];\n for (const chunk of chunks) {\n const line = firstLine(chunkContent(chunk));\n if (line.length > 0) lines.push(line);\n }\n if (lines.length > 0) sections.push(lines.join(\"\\n\"));\n }\n return sections.join(RECALL_CONTEXT_SEPARATOR);\n}\n\nexport function decideRecallContextComposition(\n input: DecideRecallContextCompositionInput,\n): DecidedRecallContextComposition {\n const composition = boundRecallContextComposition({\n context: input.context,\n footer: input.footer,\n maxChars: input.maxChars,\n compactContext: input.compactContext,\n });\n return {\n composition,\n context: composeRecallContext(composition),\n truncated:\n composition.degradation?.reason === \"budget-clipped\" ||\n composition.degradation?.reason === \"budget-compacted\",\n };\n}\n\nexport function notifyContextComposition(\n onContextComposition:\n | ((composition: RecallContextComposition) => void | PromiseLike<void>)\n | undefined,\n composition: RecallContextComposition,\n onError: (err: unknown) => void,\n): void {\n if (!onContextComposition) return;\n try {\n const result = onContextComposition(composition);\n if (result && typeof result.then === \"function\") {\n void Promise.resolve(result).catch(onError);\n }\n } catch (err) {\n onError(err);\n }\n}\n\n/**\n * Outer-recall failure: abort stays silent (empty string). Timeout and\n * other errors become the missing-note so a failed query is never\n * indistinguishable from \"no matches\".\n */\nexport function recallFailureComposition(err: unknown): RecallContextComposition | null {\n if (isAbortError(err)) return null;\n const detail =\n err instanceof Error && err.message === \"recall timeout\"\n ? \"timeout\"\n : \"recall_failed\";\n return composeMissingMemoryContext({ detail });\n}\n"],"mappings":";;;;;;;;;;;AAiCA,SAAS,UAAU,SAAyB;AAC1C,QAAM,UAAU,QAAQ,KAAK;AAC7B,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,QAAM,UAAU,QAAQ,QAAQ,IAAI;AACpC,SAAO,YAAY,KAAK,UAAU,QAAQ,MAAM,GAAG,OAAO,EAAE,QAAQ;AACtE;AAEA,SAAS,aAAa,OAAuC;AAC3D,SAAO,OAAO,UAAU,WAAW,QAAQ,MAAM;AACnD;AAOO,SAAS,gCACd,SACQ;AACR,QAAM,WAAqB,CAAC;AAC5B,aAAW,CAAC,EAAE,MAAM,KAAK,SAAS;AAChC,UAAM,QAAkB,CAAC;AACzB,eAAW,SAAS,QAAQ;AAC1B,YAAM,OAAO,UAAU,aAAa,KAAK,CAAC;AAC1C,UAAI,KAAK,SAAS,EAAG,OAAM,KAAK,IAAI;AAAA,IACtC;AACA,QAAI,MAAM,SAAS,EAAG,UAAS,KAAK,MAAM,KAAK,IAAI,CAAC;AAAA,EACtD;AACA,SAAO,SAAS,KAAK,wBAAwB;AAC/C;AAEO,SAAS,+BACd,OACiC;AACjC,QAAM,cAAc,8BAA8B;AAAA,IAChD,SAAS,MAAM;AAAA,IACf,QAAQ,MAAM;AAAA,IACd,UAAU,MAAM;AAAA,IAChB,gBAAgB,MAAM;AAAA,EACxB,CAAC;AACD,SAAO;AAAA,IACL;AAAA,IACA,SAAS,qBAAqB,WAAW;AAAA,IACzC,WACE,YAAY,aAAa,WAAW,oBACpC,YAAY,aAAa,WAAW;AAAA,EACxC;AACF;AAEO,SAAS,yBACd,sBAGA,aACA,SACM;AACN,MAAI,CAAC,qBAAsB;AAC3B,MAAI;AACF,UAAM,SAAS,qBAAqB,WAAW;AAC/C,QAAI,UAAU,OAAO,OAAO,SAAS,YAAY;AAC/C,WAAK,QAAQ,QAAQ,MAAM,EAAE,MAAM,OAAO;AAAA,IAC5C;AAAA,EACF,SAAS,KAAK;AACZ,YAAQ,GAAG;AAAA,EACb;AACF;AAOO,SAAS,yBAAyB,KAA+C;AACtF,MAAI,aAAa,GAAG,EAAG,QAAO;AAC9B,QAAM,SACJ,eAAe,SAAS,IAAI,YAAY,mBACpC,YACA;AACN,SAAO,4BAA4B,EAAE,OAAO,CAAC;AAC/C;","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  isNamespaceKind
3
- } from "./chunk-DHTOYRDE.js";
3
+ } from "./chunk-6ZMIASYT.js";
4
4
  import {
5
5
  EngramAccessInputError
6
6
  } from "./chunk-2Z24E5W2.js";
@@ -40,4 +40,4 @@ export {
40
40
  positiveIntQueryParam,
41
41
  optionalNamespaceKindQueryParam
42
42
  };
43
- //# sourceMappingURL=chunk-OTGIAJQ2.js.map
43
+ //# sourceMappingURL=chunk-6Z4OLQUO.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  resolveDefaultNamespaceRoot,
3
3
  resolveNamespaceStorageRoot
4
- } from "./chunk-FLZJMXFV.js";
4
+ } from "./chunk-T73ZC7C5.js";
5
5
  import {
6
6
  MutationSerializer,
7
7
  withHeldFileLock
@@ -1473,4 +1473,4 @@ export {
1473
1473
  isNamespaceKind,
1474
1474
  NamespaceCatalog
1475
1475
  };
1476
- //# sourceMappingURL=chunk-DHTOYRDE.js.map
1476
+ //# sourceMappingURL=chunk-6ZMIASYT.js.map
@@ -4,6 +4,9 @@ import {
4
4
  import {
5
5
  normalizeProjectionPreview
6
6
  } from "./chunk-SCU65EZI.js";
7
+ import {
8
+ coerceBooleanLike
9
+ } from "./chunk-PQVCH2AE.js";
7
10
  import {
8
11
  writeFileAtomically
9
12
  } from "./chunk-AW4QUFQF.js";
@@ -20,6 +23,10 @@ var DIRECTORY_SIDECAR_MARKER = "<!-- remnic-directory-sidecar -->";
20
23
  var ABSTRACT_MAX_CHARS = 256;
21
24
  var OVERVIEW_MAX_CHARS = 4e3;
22
25
  var DEFAULT_QUERY_LIMIT = 5;
26
+ var CATEGORY_ROOTS = new Set(RECALL_FALLBACK_DIRS);
27
+ function parseDirectorySidecarsEnabled(raw) {
28
+ return coerceBooleanLike(raw, "directorySidecarsEnabled") === true;
29
+ }
23
30
  var RESERVED_CHILD_BASENAMES = Object.freeze({
24
31
  ...OKF_RESERVED_BASENAMES,
25
32
  [DIRECTORY_SIDECAR_BASENAME]: true
@@ -149,40 +156,81 @@ function collectSidecarDirs(scopeRoot) {
149
156
  }
150
157
  return dirs;
151
158
  }
159
+ async function syncSidecarDir(dir, enabled, childAbstracts, written, removed) {
160
+ const target = sidecarPath(dir);
161
+ const raw = readFileOrNull(target);
162
+ const existing = raw !== null && raw.startsWith(DIRECTORY_SIDECAR_MARKER) ? raw : null;
163
+ if (!enabled) {
164
+ if (existing !== null) {
165
+ unlinkSync(target);
166
+ removed.push(target);
167
+ }
168
+ return;
169
+ }
170
+ const next = renderSidecar(dir, directoryFingerprint(dir), childAbstracts);
171
+ if (next === null) {
172
+ if (existing !== null) {
173
+ unlinkSync(target);
174
+ removed.push(target);
175
+ }
176
+ return;
177
+ }
178
+ const parsedNext = parseSidecar(next);
179
+ if (parsedNext) childAbstracts.set(dir, parsedNext.abstract);
180
+ if (raw === next) return;
181
+ if (existing === null && raw !== null) return;
182
+ await writeFileAtomically(target, next);
183
+ written.push(target);
184
+ }
185
+ function childAbstractsFromDisk(dir) {
186
+ const abstracts = /* @__PURE__ */ new Map();
187
+ for (const name of directoryChildren(dir)) {
188
+ const childDir = path.join(dir, name);
189
+ const parsed = parseSidecar(readFileOrNull(sidecarPath(childDir)) ?? "");
190
+ if (parsed) abstracts.set(childDir, parsed.abstract);
191
+ }
192
+ return abstracts;
193
+ }
194
+ function directorySidecarAncestry(memoryDir, changedPath) {
195
+ const root = path.resolve(memoryDir);
196
+ const abs = path.isAbsolute(changedPath) ? path.resolve(changedPath) : path.resolve(root, changedPath);
197
+ const rel = path.relative(root, abs);
198
+ if (rel.startsWith("..") || path.isAbsolute(rel)) return [];
199
+ const parts = rel.split(path.sep).filter(Boolean);
200
+ const dirParts = isRealDirectory(abs) ? parts : parts.slice(0, -1);
201
+ let categoryAt = -1;
202
+ if (dirParts[0] === "namespaces" && dirParts.length >= 3 && CATEGORY_ROOTS.has(dirParts[2] ?? "")) {
203
+ categoryAt = 2;
204
+ } else if (CATEGORY_ROOTS.has(dirParts[0] ?? "")) {
205
+ categoryAt = 0;
206
+ }
207
+ if (categoryAt === -1) return [];
208
+ const dirs = [];
209
+ for (let i = dirParts.length; i > categoryAt; i--) {
210
+ dirs.push(path.join(root, ...dirParts.slice(0, i)));
211
+ }
212
+ return dirs;
213
+ }
152
214
  async function runDirectorySidecarMaintenance(memoryDir, enabled) {
153
215
  const written = [];
154
216
  const removed = [];
155
217
  for (const scope of scopeRoots(memoryDir)) {
156
218
  const childAbstracts = /* @__PURE__ */ new Map();
157
219
  for (const dir of collectSidecarDirs(scope)) {
158
- const target = sidecarPath(dir);
159
- const raw = readFileOrNull(target);
160
- const existing = raw !== null && raw.startsWith(DIRECTORY_SIDECAR_MARKER) ? raw : null;
161
- if (!enabled) {
162
- if (existing !== null) {
163
- unlinkSync(target);
164
- removed.push(target);
165
- }
166
- continue;
167
- }
168
- const next = renderSidecar(dir, directoryFingerprint(dir), childAbstracts);
169
- if (next === null) {
170
- if (existing !== null) {
171
- unlinkSync(target);
172
- removed.push(target);
173
- }
174
- continue;
175
- }
176
- const parsedNext = parseSidecar(next);
177
- if (parsedNext) childAbstracts.set(dir, parsedNext.abstract);
178
- if (raw === next) continue;
179
- if (existing === null && raw !== null) continue;
180
- await writeFileAtomically(target, next);
181
- written.push(target);
220
+ await syncSidecarDir(dir, enabled, childAbstracts, written, removed);
182
221
  }
183
222
  }
184
223
  return { written, removed };
185
224
  }
225
+ async function refreshDirectorySidecarsAfterWrite(memoryDir, changedPath, enabled) {
226
+ if (!enabled) return { written: [], removed: [] };
227
+ const written = [];
228
+ const removed = [];
229
+ for (const dir of directorySidecarAncestry(memoryDir, changedPath)) {
230
+ await syncSidecarDir(dir, true, childAbstractsFromDisk(dir), written, removed);
231
+ }
232
+ return { written, removed };
233
+ }
186
234
  async function loadDirectorySidecar(dir, options = {}) {
187
235
  const refresh = options.refresh !== false;
188
236
  const target = sidecarPath(dir);
@@ -252,9 +300,12 @@ async function findDirectorySidecarsForQuery(memoryDir, query, options = {}) {
252
300
  export {
253
301
  DIRECTORY_SIDECAR_BASENAME,
254
302
  DIRECTORY_SIDECAR_MARKER,
303
+ parseDirectorySidecarsEnabled,
255
304
  directoryFingerprint,
305
+ directorySidecarAncestry,
256
306
  runDirectorySidecarMaintenance,
307
+ refreshDirectorySidecarsAfterWrite,
257
308
  loadDirectorySidecar,
258
309
  findDirectorySidecarsForQuery
259
310
  };
260
- //# sourceMappingURL=chunk-UD6W67JM.js.map
311
+ //# sourceMappingURL=chunk-72AV2H3R.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/directory-sidecars.ts"],"sourcesContent":["/**\n * @remnic/core — per-directory abstract/overview sidecars (issue #2977).\n *\n * One derived `overview.md` per memory directory (category roots and every\n * directory beneath them, including `namespaces/<ns>/` subtrees), rendered\n * bottom-up from existing memory content:\n *\n * - the ABSTRACT is a single line (<=256 chars) composed from child titles;\n * - the OVERVIEW body lists one preview line per child memory and embeds\n * each child DIRECTORY's abstract, so a parent summarizes its subtree\n * without embedding full child overviews.\n *\n * Determinism: no LLM, no embeddings. Content is assembled with the same\n * preview machinery the OKF index files use (`normalizeProjectionPreview`).\n *\n * Invalidation: each sidecar stores a content-free fingerprint of its subtree\n * (child name|size|mtime for files, recursive fingerprints for child dirs).\n * Any add/edit/delete anywhere below a directory changes its fingerprint, so\n * `loadDirectorySidecar` can detect staleness with `readdir`+`stat` alone and\n * refresh without reading child memory files first. Eager regeneration runs\n * through {@link runDirectorySidecarMaintenance}; lazy refresh on read covers\n * direct-write paths that bypass scheduled maintenance (Gotcha #43).\n *\n * Isolation: sidecars are derived artifacts, excluded from generic recall via\n * `isGenericRecallExcludedPath` (basename match, the same tradeoff OKF makes\n * for `index.md`/`log.md`) while staying full-text searchable. Files at the\n * sidecar path WITHOUT the marker are user content: never overwritten, never\n * removed.\n *\n * Layer 2 (this slice): {@link refreshDirectorySidecarsAfterWrite} refreshes\n * only the changed directory and its category ancestors, so a memory write\n * populates sidecars without walking the rest of the store. `enabled: false`\n * is a proven no-op (no reads, no writes). Config parsing lives here;\n * `parseConfig` wiring, retrieval drill-down, xray, and LLM summarization\n * remain later layers on #2977 (`config.ts` is at its file-size ratchet).\n */\n\nimport { createHash } from \"node:crypto\";\nimport { lstatSync, readFileSync, readdirSync, statSync, unlinkSync } from \"node:fs\";\nimport path from \"node:path\";\n\nimport { coerceBooleanLike } from \"./connectors/coerce.js\";\nimport { writeFileAtomically } from \"./maintenance/atomic-file.js\";\nimport { normalizeProjectionPreview } from \"./memory-projection-format.js\";\nimport { OKF_RESERVED_BASENAMES } from \"./okf/type-mapping.js\";\nimport { RECALL_FALLBACK_DIRS } from \"./utils/category-dir.js\";\n\nexport const DIRECTORY_SIDECAR_BASENAME = \"overview.md\";\nexport const DIRECTORY_SIDECAR_MARKER = \"<!-- remnic-directory-sidecar -->\";\n\nconst ABSTRACT_MAX_CHARS = 256;\nconst OVERVIEW_MAX_CHARS = 4000;\nconst DEFAULT_QUERY_LIMIT = 5;\nconst CATEGORY_ROOTS: ReadonlySet<string> = new Set(RECALL_FALLBACK_DIRS);\n\n/** Config fields this slice owns. Mix into `PluginConfig` in a later layer. */\nexport interface DirectorySidecarSettings {\n /** Populate sidecars on memory writes. Default false. */\n directorySidecarsEnabled: boolean;\n}\n\n/** Strict off-default: only an explicit true/\"true\"/1 opts in. */\nexport function parseDirectorySidecarsEnabled(raw: unknown): boolean {\n return coerceBooleanLike(raw, \"directorySidecarsEnabled\") === true;\n}\n\n/** Basenames never treated as child memories (ours plus OKF's reserved ones). */\nconst RESERVED_CHILD_BASENAMES: Readonly<Record<string, true>> = Object.freeze({\n ...OKF_RESERVED_BASENAMES,\n [DIRECTORY_SIDECAR_BASENAME]: true,\n});\n\nexport interface DirectorySidecar {\n /** Absolute directory the sidecar describes. */\n readonly dir: string;\n /** Single-line L0 abstract (<=256 chars). */\n readonly abstract: string;\n /** Abstract plus the per-child preview body (<=4000 chars). */\n readonly overview: string;\n /** Number of memory `.md` children in this directory. */\n readonly childCount: number;\n /** False when the stored fingerprint no longer matches the subtree. */\n readonly fresh: boolean;\n}\n\nexport interface DirectorySidecarMatch extends DirectorySidecar {\n readonly score: number;\n}\n\nexport interface DirectorySidecarReport {\n written: string[];\n removed: string[];\n}\n\ninterface ParsedSidecar {\n abstract: string;\n overview: string;\n childCount: number;\n fingerprint: string;\n}\n\nfunction listEntries(dir: string) {\n try {\n return readdirSync(dir, { withFileTypes: true });\n } catch {\n return [];\n }\n}\n\n/** Root check that refuses symlinks (fs-boundary rule, PRs #1938/#1999). */\nfunction isRealDirectory(entryPath: string): boolean {\n try {\n const stats = lstatSync(entryPath);\n return !stats.isSymbolicLink() && stats.isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction memoryChildren(dir: string): string[] {\n // Dirent.isFile() is false for symlinks, so a linked memory never enters the corpus.\n return listEntries(dir)\n .filter((entry) => entry.isFile() && !RESERVED_CHILD_BASENAMES[entry.name] && entry.name.endsWith(\".md\"))\n .map((entry) => entry.name)\n .sort((a, b) => a.localeCompare(b));\n}\n\nfunction directoryChildren(dir: string): string[] {\n // Dirent.isDirectory() is false for symlinks (fs-boundary rule, PRs #1938/#1999).\n return listEntries(dir)\n .filter((entry) => entry.isDirectory())\n .map((entry) => entry.name)\n .sort((a, b) => a.localeCompare(b));\n}\n\n/**\n * Content-free subtree fingerprint: sha256 over sorted child descriptors.\n * Files contribute `name|size|mtimeMs`; directories contribute their own\n * recursive fingerprint, so any change below a directory invalidates every\n * ancestor. Reads no file contents.\n */\nexport function directoryFingerprint(dir: string): string {\n const hash = createHash(\"sha256\");\n for (const name of memoryChildren(dir)) {\n try {\n const stats = statSync(path.join(dir, name));\n hash.update(`f|${name}|${stats.size}|${Math.trunc(stats.mtimeMs)}\\n`);\n } catch {\n hash.update(`f|${name}|missing\\n`);\n }\n }\n for (const name of directoryChildren(dir)) {\n hash.update(`d|${name}|${directoryFingerprint(path.join(dir, name))}\\n`);\n }\n return hash.digest(\"hex\");\n}\n\nfunction readFileOrNull(target: string): string | null {\n try {\n return readFileSync(target, \"utf8\");\n } catch {\n return null;\n }\n}\n\nfunction parseSidecar(content: string): ParsedSidecar | null {\n if (!content.startsWith(DIRECTORY_SIDECAR_MARKER)) return null;\n const fingerprint = /^fingerprint: ([0-9a-f]{64})$/m.exec(content)?.[1];\n if (!fingerprint) return null;\n const abstract = /^## Abstract\\n([^\\n]+)$/m.exec(content)?.[1] ?? \"\";\n const overviewStart = content.indexOf(\"## Abstract\");\n const overview =\n overviewStart === -1 ? \"\" : content.slice(overviewStart, overviewStart + OVERVIEW_MAX_CHARS).trim();\n // The `* name — preview` child bullets are the rendered child count.\n const childCount = (content.match(/^\\* .+$/gm) ?? []).length;\n return { abstract, overview, childCount, fingerprint };\n}\n\nfunction sidecarPath(dir: string): string {\n return path.join(dir, DIRECTORY_SIDECAR_BASENAME);\n}\n\nfunction renderSidecar(dir: string, fingerprint: string, childAbstracts: Map<string, string>): string | null {\n const children = memoryChildren(dir);\n const childDirs = directoryChildren(dir).filter((name) => childAbstracts.has(path.join(dir, name)));\n if (children.length === 0 && childDirs.length === 0) return null;\n\n const previews = children.map((name) => {\n try {\n return normalizeProjectionPreview(readFileSync(path.join(dir, name), \"utf8\"), 120);\n } catch {\n return \"\";\n }\n });\n const titles = children.map(\n (name, index) => previews[index].split(\" \").slice(0, 8).join(\" \") || name.replace(/\\.md$/, \"\"),\n );\n const abstract = normalizeProjectionPreview(\n `${path.basename(dir)}/ — ${children.length} memories: ${titles.slice(0, 5).join(\" · \")}`,\n ABSTRACT_MAX_CHARS,\n );\n\n const lines = [\n DIRECTORY_SIDECAR_MARKER,\n `fingerprint: ${fingerprint}`,\n `# ${path.basename(dir)}/ overview`,\n \"\",\n \"## Abstract\",\n abstract,\n \"\",\n \"## Children\",\n ];\n for (const [index, name] of children.entries()) {\n lines.push(`* ${name} — ${previews[index]}`);\n }\n for (const name of childDirs) {\n lines.push(`### ${name}/`);\n lines.push(childAbstracts.get(path.join(dir, name)) ?? \"\");\n }\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\n/** Scope roots whose category subtrees carry sidecars: the memory root plus every namespace root. */\nfunction scopeRoots(memoryDir: string): string[] {\n const roots = [memoryDir];\n const namespacesRoot = path.join(memoryDir, \"namespaces\");\n for (const entry of listEntries(namespacesRoot)) {\n if (entry.isDirectory() && isRealDirectory(path.join(namespacesRoot, entry.name))) {\n roots.push(path.join(namespacesRoot, entry.name));\n }\n }\n return roots;\n}\n\n/**\n * Every directory that should carry a sidecar, deepest first (post-order) so\n * parents render after their children and can embed child abstracts.\n */\nfunction collectSidecarDirs(scopeRoot: string): string[] {\n const dirs: string[] = [];\n const walk = (dir: string, isCategoryRoot: boolean): boolean => {\n let carries = memoryChildren(dir).length > 0;\n for (const name of directoryChildren(dir)) {\n carries = walk(path.join(dir, name), false) || carries;\n }\n // A directory that stopped carrying memories must still be visited so its\n // orphaned sidecar can be pruned or rewritten (cache-invalidation completeness).\n const hasSidecar = readFileOrNull(sidecarPath(dir))?.startsWith(DIRECTORY_SIDECAR_MARKER) === true;\n if (isCategoryRoot || carries || hasSidecar) dirs.push(dir);\n return carries;\n };\n for (const category of RECALL_FALLBACK_DIRS) {\n const categoryDir = path.join(scopeRoot, category);\n if (!isRealDirectory(categoryDir)) continue;\n walk(categoryDir, true);\n }\n return dirs;\n}\n\nasync function syncSidecarDir(\n dir: string,\n enabled: boolean,\n childAbstracts: Map<string, string>,\n written: string[],\n removed: string[],\n): Promise<void> {\n const target = sidecarPath(dir);\n const raw = readFileOrNull(target);\n const existing = raw !== null && raw.startsWith(DIRECTORY_SIDECAR_MARKER) ? raw : null;\n if (!enabled) {\n if (existing !== null) {\n unlinkSync(target);\n removed.push(target);\n }\n return;\n }\n const next = renderSidecar(dir, directoryFingerprint(dir), childAbstracts);\n if (next === null) {\n if (existing !== null) {\n unlinkSync(target);\n removed.push(target);\n }\n return;\n }\n const parsedNext = parseSidecar(next);\n if (parsedNext) childAbstracts.set(dir, parsedNext.abstract);\n if (raw === next) return;\n if (existing === null && raw !== null) return; // user-authored file: hands off\n await writeFileAtomically(target, next);\n written.push(target);\n}\n\nfunction childAbstractsFromDisk(dir: string): Map<string, string> {\n const abstracts = new Map<string, string>();\n for (const name of directoryChildren(dir)) {\n const childDir = path.join(dir, name);\n const parsed = parseSidecar(readFileOrNull(sidecarPath(childDir)) ?? \"\");\n if (parsed) abstracts.set(childDir, parsed.abstract);\n }\n return abstracts;\n}\n\n/**\n * Category-root ancestry of a changed memory path, deepest first.\n * Paths outside a recall category return `[]` so writes to `state/` or\n * `namespaces/<ns>/` itself never mint a sidecar.\n */\nexport function directorySidecarAncestry(memoryDir: string, changedPath: string): string[] {\n const root = path.resolve(memoryDir);\n const abs = path.isAbsolute(changedPath) ? path.resolve(changedPath) : path.resolve(root, changedPath);\n const rel = path.relative(root, abs);\n if (rel.startsWith(\"..\") || path.isAbsolute(rel)) return [];\n const parts = rel.split(path.sep).filter(Boolean);\n const dirParts = isRealDirectory(abs) ? parts : parts.slice(0, -1);\n let categoryAt = -1;\n if (dirParts[0] === \"namespaces\" && dirParts.length >= 3 && CATEGORY_ROOTS.has(dirParts[2] ?? \"\")) {\n categoryAt = 2;\n } else if (CATEGORY_ROOTS.has(dirParts[0] ?? \"\")) {\n categoryAt = 0;\n }\n if (categoryAt === -1) return [];\n const dirs: string[] = [];\n for (let i = dirParts.length; i > categoryAt; i--) {\n dirs.push(path.join(root, ...dirParts.slice(0, i)));\n }\n return dirs;\n}\n\n/**\n * Regenerates directory sidecars incrementally. Unchanged sidecars are left\n * untouched; emptied directories lose theirs; user files at the sidecar path\n * (no marker) are never written or removed. With `enabled: false` every\n * generated sidecar is removed — the OKF index-maintenance contract.\n */\nexport async function runDirectorySidecarMaintenance(\n memoryDir: string,\n enabled: boolean,\n): Promise<DirectorySidecarReport> {\n const written: string[] = [];\n const removed: string[] = [];\n for (const scope of scopeRoots(memoryDir)) {\n const childAbstracts = new Map<string, string>();\n for (const dir of collectSidecarDirs(scope)) {\n await syncSidecarDir(dir, enabled, childAbstracts, written, removed);\n }\n }\n return { written, removed };\n}\n\n/**\n * Incremental write-path refresh: only the changed directory and its\n * category ancestors, using the same fingerprint/render path as maintenance.\n * `enabled: false` returns immediately — no readdir, no writes.\n */\nexport async function refreshDirectorySidecarsAfterWrite(\n memoryDir: string,\n changedPath: string,\n enabled: boolean,\n): Promise<DirectorySidecarReport> {\n if (!enabled) return { written: [], removed: [] };\n const written: string[] = [];\n const removed: string[] = [];\n for (const dir of directorySidecarAncestry(memoryDir, changedPath)) {\n await syncSidecarDir(dir, true, childAbstractsFromDisk(dir), written, removed);\n }\n return { written, removed };\n}\n\n/**\n * Read a directory's sidecar for retrieval. By default a stale sidecar is\n * refreshed in place (child directories first), which is what makes direct\n * writes that bypass maintenance still converge. With `{ refresh: false }`\n * the stored sidecar is returned as-is with `fresh: false` so callers can\n * observe staleness without writes.\n */\nexport async function loadDirectorySidecar(\n dir: string,\n options: { refresh?: boolean } = {},\n): Promise<DirectorySidecar | null> {\n const refresh = options.refresh !== false;\n const target = sidecarPath(dir);\n const stored = readFileOrNull(target);\n const generated = stored !== null && stored.startsWith(DIRECTORY_SIDECAR_MARKER);\n const parsed = generated ? parseSidecar(stored) : null;\n const fingerprint = directoryFingerprint(dir);\n if (parsed !== null && (parsed.fingerprint === fingerprint || !refresh)) {\n return {\n dir,\n abstract: parsed.abstract,\n overview: parsed.overview,\n childCount: parsed.childCount,\n fresh: parsed.fingerprint === fingerprint,\n };\n }\n if (!refresh) return null;\n\n // Refresh bottom-up so this directory's body embeds current child abstracts.\n const childAbstracts = new Map<string, string>();\n for (const name of directoryChildren(dir)) {\n const child = await loadDirectorySidecar(path.join(dir, name));\n if (child) childAbstracts.set(path.join(dir, name), child.abstract);\n }\n const next = renderSidecar(dir, directoryFingerprint(dir), childAbstracts);\n if (next === null) {\n if (generated) unlinkSync(target);\n return null;\n }\n if (readFileOrNull(target) !== next) {\n if (stored !== null && !generated) {\n // User-authored file at the sidecar path: serve nothing rather than clobber it.\n return null;\n }\n await writeFileAtomically(target, next);\n }\n const refreshed = parseSidecar(next);\n return refreshed\n ? {\n dir,\n abstract: refreshed.abstract,\n overview: refreshed.overview,\n childCount: refreshed.childCount,\n fresh: true,\n }\n : null;\n}\n\n/**\n * Overview-query primitive for hierarchical retrieval (layer 1 of #2977):\n * score every sidecar's abstract (+3 per query term) and overview (+1 per\n * term) lexically, then return the most specific matches — when both a\n * directory and its descendant match, only the descendant is kept, matching\n * the drill-down semantics the full retrieval mode will build on.\n */\nexport async function findDirectorySidecarsForQuery(\n memoryDir: string,\n query: string,\n options: { namespace?: string; limit?: number } = {},\n): Promise<DirectorySidecarMatch[]> {\n const scope = options.namespace ? path.join(memoryDir, \"namespaces\", options.namespace) : memoryDir;\n if (!isRealDirectory(scope)) return [];\n const terms = query\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter((term) => term.length >= 2);\n\n const matches: DirectorySidecarMatch[] = [];\n for (const root of scopeRoots(scope)) {\n for (const dir of collectSidecarDirs(root)) {\n const sidecar = await loadDirectorySidecar(dir);\n if (!sidecar) continue;\n const abstractLower = sidecar.abstract.toLowerCase();\n const overviewLower = sidecar.overview.toLowerCase();\n let score = 0;\n for (const term of terms) {\n if (abstractLower.includes(term)) score += 3;\n else if (overviewLower.includes(term)) score += 1;\n }\n if (score > 0) matches.push({ ...sidecar, score });\n }\n }\n matches.sort((a, b) => b.score - a.score || a.dir.localeCompare(b.dir));\n\n const limit = options.limit ?? DEFAULT_QUERY_LIMIT;\n return matches\n .filter((candidate) => !matches.some((other) => other.dir.startsWith(`${candidate.dir}${path.sep}`)))\n .slice(0, limit);\n}\n"],"mappings":"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","names":[]}