@remnic/core 9.66.0 → 9.66.2

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 (575) hide show
  1. package/dist/access-admin-ops-surface.d.ts +11 -11
  2. package/dist/access-admin-ops-surface.js +31 -31
  3. package/dist/access-audit.js +2 -2
  4. package/dist/access-authorization-probe.d.ts +11 -11
  5. package/dist/access-authorization-probe.js +32 -32
  6. package/dist/access-boundary.d.ts +11 -11
  7. package/dist/access-boundary.js +31 -31
  8. package/dist/access-cli.js +105 -101
  9. package/dist/access-cli.js.map +1 -1
  10. package/dist/access-coding-context-resolution.d.ts +1 -1
  11. package/dist/access-extraction-force-flush.d.ts +11 -11
  12. package/dist/access-extraction-force-flush.js +31 -31
  13. package/dist/access-health-types.d.ts +1 -1
  14. package/dist/access-http-lcm-compaction.d.ts +11 -11
  15. package/dist/access-http-lifecycle-flush.d.ts +11 -11
  16. package/dist/access-http-offline-stream.d.ts +11 -11
  17. package/dist/access-http-query.d.ts +2 -2
  18. package/dist/access-http-query.js +33 -33
  19. package/dist/access-http.d.ts +12 -12
  20. package/dist/access-http.js +48 -48
  21. package/dist/access-identity-continuity-surface.d.ts +9 -9
  22. package/dist/access-identity-continuity-surface.js +31 -31
  23. package/dist/access-lcm-surface.d.ts +11 -11
  24. package/dist/access-lcm-surface.js +31 -31
  25. package/dist/access-mcp.d.ts +11 -11
  26. package/dist/access-mcp.js +39 -39
  27. package/dist/access-memory-search-fanout.d.ts +2 -2
  28. package/dist/{access-namespace-preflight-CLWUoMyW.d.ts → access-namespace-preflight-50VIkPhB.d.ts} +1 -1
  29. package/dist/access-namespace-preflight.d.ts +3 -3
  30. package/dist/access-namespace-preflight.js +31 -31
  31. package/dist/access-observe-write-surface.d.ts +11 -11
  32. package/dist/access-observe-write-surface.js +31 -31
  33. package/dist/access-offline-manifest.d.ts +9 -9
  34. package/dist/access-operations-batch.js +34 -34
  35. package/dist/access-operations.d.ts +11 -11
  36. package/dist/access-operations.js +38 -38
  37. package/dist/access-recall-concurrency.d.ts +11 -11
  38. package/dist/access-recall-concurrency.js +31 -31
  39. package/dist/access-recall-response.d.ts +11 -11
  40. package/dist/access-recall-response.js +31 -31
  41. package/dist/access-recall-surface.d.ts +11 -11
  42. package/dist/access-recall-surface.js +31 -31
  43. package/dist/access-schema.js +3 -3
  44. package/dist/{access-service-CEUE1Isj.d.ts → access-service-Dz6I9AZ-.d.ts} +13 -13
  45. package/dist/access-service-helpers.d.ts +11 -11
  46. package/dist/access-service.d.ts +11 -11
  47. package/dist/access-service.js +31 -31
  48. package/dist/access-surface-catalog.d.ts +11 -11
  49. package/dist/access-surface-catalog.js +33 -33
  50. package/dist/access-wearables-meetings-surface.d.ts +3 -3
  51. package/dist/action-confidence.d.ts +1 -1
  52. package/dist/active-memory-bridge.d.ts +1 -1
  53. package/dist/active-recall.d.ts +1 -1
  54. package/dist/active-recall.js +4 -4
  55. package/dist/adapters/index.js +4 -4
  56. package/dist/adapters/registry.js +2 -2
  57. package/dist/ambient-provenance.d.ts +1 -1
  58. package/dist/artifact-search.d.ts +1 -1
  59. package/dist/behavior-learner.d.ts +1 -1
  60. package/dist/behavior-signals.d.ts +1 -1
  61. package/dist/bootstrap.d.ts +9 -9
  62. package/dist/briefing-window.d.ts +2 -2
  63. package/dist/briefing.d.ts +2 -2
  64. package/dist/briefing.js +10 -10
  65. package/dist/buffer-surprise-report.d.ts +1 -1
  66. package/dist/buffer-turn-helpers.d.ts +1 -1
  67. package/dist/buffer.d.ts +2 -2
  68. package/dist/buffer.js +4 -4
  69. package/dist/bulk-import/index.d.ts +3 -3
  70. package/dist/calibration.d.ts +1 -1
  71. package/dist/capabilities.d.ts +1 -1
  72. package/dist/{catalog-D1HgugTA.d.ts → catalog-C2jA-gLm.d.ts} +1 -1
  73. package/dist/causal-behavior.d.ts +1 -1
  74. package/dist/causal-behavior.js +2 -2
  75. package/dist/causal-chain.js +2 -2
  76. package/dist/causal-consolidation.d.ts +1 -1
  77. package/dist/causal-consolidation.js +13 -13
  78. package/dist/causal-retrieval.js +2 -2
  79. package/dist/causal-trajectory-graph.d.ts +1 -1
  80. package/dist/causal-trajectory-graph.js +2 -2
  81. package/dist/causal-trajectory.js +1 -1
  82. package/dist/{chunk-EZSCW4EM.js → chunk-25OLNWYG.js} +2 -2
  83. package/dist/{chunk-2LBAFHOQ.js → chunk-2QSGJTDG.js} +10 -10
  84. package/dist/{chunk-7UTDHQZ5.js → chunk-2VZHB5US.js} +2 -2
  85. package/dist/{chunk-VQNRICAQ.js → chunk-36HJ36FK.js} +3 -3
  86. package/dist/{chunk-XKNHFDTT.js → chunk-3A2Z4OOS.js} +2 -2
  87. package/dist/{chunk-KODXCHXJ.js → chunk-46XR5FNZ.js} +39 -3
  88. package/dist/chunk-46XR5FNZ.js.map +1 -0
  89. package/dist/{chunk-56IV4J5W.js → chunk-47WWTCJY.js} +1384 -99
  90. package/dist/chunk-47WWTCJY.js.map +1 -0
  91. package/dist/{chunk-RDGKVH6T.js → chunk-4NKIGSJM.js} +2 -2
  92. package/dist/{chunk-EFQCDJZ2.js → chunk-4PG2CKI6.js} +2 -2
  93. package/dist/{chunk-HJXA6ZM7.js → chunk-6545JDIM.js} +2 -2
  94. package/dist/{chunk-J3OND5QT.js → chunk-65HXVEVG.js} +2 -2
  95. package/dist/{chunk-HNPE66LB.js → chunk-6BYJQ3L2.js} +8 -8
  96. package/dist/{chunk-ZW4VXELZ.js → chunk-6PUF7LUO.js} +2 -2
  97. package/dist/{chunk-TVVEYCNW.js → chunk-7K5Q6COX.js} +4 -4
  98. package/dist/{chunk-MN5NOOI7.js → chunk-AI5M4FVQ.js} +2 -2
  99. package/dist/{chunk-IHGMRDEE.js → chunk-B4B3QDV3.js} +235 -151
  100. package/dist/chunk-B4B3QDV3.js.map +1 -0
  101. package/dist/{chunk-YMOPYG3K.js → chunk-BIJAWZYW.js} +6 -6
  102. package/dist/{chunk-I5VB44ZK.js → chunk-BLHKR4GJ.js} +2 -2
  103. package/dist/chunk-BLUYQFRH.js +36 -0
  104. package/dist/chunk-BLUYQFRH.js.map +1 -0
  105. package/dist/{chunk-CEH2AFXG.js → chunk-C24UZSFW.js} +6 -6
  106. package/dist/{chunk-MJRGVXPQ.js → chunk-C3ZYZKDJ.js} +2 -2
  107. package/dist/{chunk-QCRJMU5V.js → chunk-CDLPF3PX.js} +2 -2
  108. package/dist/{chunk-23CVL7HS.js → chunk-CQ6IWZDI.js} +2 -2
  109. package/dist/{chunk-KWIGDKM2.js → chunk-D2YNNDML.js} +2 -2
  110. package/dist/{chunk-FTTJRVB7.js → chunk-D3DUA64S.js} +2 -2
  111. package/dist/{chunk-7XOG75AU.js → chunk-D6Q5EPOV.js} +2 -2
  112. package/dist/{chunk-GEJKYA7D.js → chunk-DSEHPUID.js} +6 -6
  113. package/dist/chunk-E4X2YX2F.js +22 -0
  114. package/dist/chunk-E4X2YX2F.js.map +1 -0
  115. package/dist/{chunk-PEBH5DCK.js → chunk-EH7BNIUN.js} +101 -19
  116. package/dist/chunk-EH7BNIUN.js.map +1 -0
  117. package/dist/{chunk-OAJMQKQR.js → chunk-EQRD4NMH.js} +2 -2
  118. package/dist/{chunk-H7VDIF2V.js → chunk-ER2UPUMG.js} +2 -2
  119. package/dist/{chunk-4FHRZD5T.js → chunk-F2JXJABQ.js} +2 -2
  120. package/dist/{chunk-FKKGCGYL.js → chunk-F4W5HTED.js} +2 -2
  121. package/dist/{chunk-DMEHOEC7.js → chunk-FFWONAAW.js} +3 -3
  122. package/dist/chunk-FYDW33ZB.js +13 -0
  123. package/dist/chunk-FYDW33ZB.js.map +1 -0
  124. package/dist/{chunk-TNGH4ZYI.js → chunk-GNWLTCKC.js} +2 -2
  125. package/dist/{chunk-CFVTRUR3.js → chunk-H6RSANGQ.js} +2 -2
  126. package/dist/chunk-HVAEXYPL.js +98 -0
  127. package/dist/chunk-HVAEXYPL.js.map +1 -0
  128. package/dist/{chunk-CTCGHNWN.js → chunk-J2R275FN.js} +4 -4
  129. package/dist/{chunk-IVIAHQBR.js → chunk-JJ6ZEFXC.js} +2 -2
  130. package/dist/{chunk-KXIXO76C.js → chunk-JMXHVJ2V.js} +14 -14
  131. package/dist/{chunk-7LCGFUMB.js → chunk-KQAFEZQX.js} +4 -4
  132. package/dist/{chunk-NACLNNFQ.js → chunk-KSZKQTZS.js} +2 -2
  133. package/dist/{chunk-NPIBN2VL.js → chunk-LK4TOYPU.js} +2 -2
  134. package/dist/{chunk-K66OY4EI.js → chunk-LSR5LQXN.js} +2 -2
  135. package/dist/chunk-MAG6M3B6.js +51 -0
  136. package/dist/chunk-MAG6M3B6.js.map +1 -0
  137. package/dist/{chunk-6CEGSTBD.js → chunk-NTFXBILO.js} +5 -5
  138. package/dist/{chunk-2PSX5BJU.js → chunk-NZPFCP5A.js} +2 -2
  139. package/dist/{chunk-FYWLSFFS.js → chunk-OERZXNSK.js} +2 -2
  140. package/dist/{chunk-ZJPM7GZ3.js → chunk-OIDICRH7.js} +2 -2
  141. package/dist/{chunk-LTBKKSCX.js → chunk-OLBZ2WGG.js} +2 -2
  142. package/dist/{chunk-PD66CVSD.js → chunk-OUKBMQ2O.js} +2 -2
  143. package/dist/{chunk-GPFZFCRN.js → chunk-PP7R754B.js} +1 -1
  144. package/dist/{chunk-GX6FTSYH.js → chunk-PRRUK2ZH.js} +2 -2
  145. package/dist/{chunk-MAH64N55.js → chunk-PW3GKWH3.js} +4 -4
  146. package/dist/chunk-Q3SHEAXR.js +80 -0
  147. package/dist/chunk-Q3SHEAXR.js.map +1 -0
  148. package/dist/{chunk-33MFRY25.js → chunk-R2Q6FTOX.js} +2 -2
  149. package/dist/{chunk-VCKWULAK.js → chunk-RCPKBW7K.js} +5 -5
  150. package/dist/{chunk-CN4VKV3S.js → chunk-RH3XLQG4.js} +2 -2
  151. package/dist/{chunk-2QSZNTDO.js → chunk-RKNJBZ55.js} +4 -4
  152. package/dist/{chunk-YXFCALVT.js → chunk-U4HZEW2B.js} +8 -8
  153. package/dist/{chunk-RZ3IZIJG.js → chunk-UHQE37NI.js} +2 -2
  154. package/dist/{chunk-Z3YEGSR4.js → chunk-UMZUKOJU.js} +4 -4
  155. package/dist/{chunk-72OIT7KS.js → chunk-UVYL5G7A.js} +3 -3
  156. package/dist/{chunk-4STAANV7.js → chunk-VKDBDJIX.js} +3 -3
  157. package/dist/{chunk-WKJFIMVN.js → chunk-VSMSYDIH.js} +2 -2
  158. package/dist/{chunk-GSKINLAK.js → chunk-W5IYHQA5.js} +3 -3
  159. package/dist/{chunk-FESUGFIL.js → chunk-WKWY7YF3.js} +2 -2
  160. package/dist/{chunk-UNUMFURP.js → chunk-X5PIDJ3L.js} +3 -3
  161. package/dist/{chunk-MINHJ55X.js → chunk-XXW32OL7.js} +1 -1
  162. package/dist/{chunk-MINHJ55X.js.map → chunk-XXW32OL7.js.map} +1 -1
  163. package/dist/{chunk-6RUHELWR.js → chunk-Y2YM4C75.js} +2 -2
  164. package/dist/{chunk-L4X4PJYK.js → chunk-YZ5VC2JJ.js} +2 -2
  165. package/dist/{chunk-VQ4AMTGZ.js → chunk-ZBIEX4XN.js} +1 -1
  166. package/dist/{chunk-O57GM3FR.js → chunk-ZMVW2HJJ.js} +2 -2
  167. package/dist/{chunk-6QDXA26G.js → chunk-ZXROBS53.js} +68 -68
  168. package/dist/{cli-BEkm2MEf.d.ts → cli-BOuEb4Ia.d.ts} +5 -5
  169. package/dist/cli.d.ts +13 -13
  170. package/dist/cli.js +76 -76
  171. package/dist/coding/export-okf-codegraph.d.ts +1 -1
  172. package/dist/coding/export-okf-codegraph.js +10 -10
  173. package/dist/coding/pre-action-gate.d.ts +1 -1
  174. package/dist/coding/pre-action-gate.js +2 -2
  175. package/dist/compounding/engine.d.ts +2 -2
  176. package/dist/compounding/engine.js +10 -10
  177. package/dist/compounding/preference-consolidator.d.ts +1 -1
  178. package/dist/compression-optimizer.d.ts +1 -1
  179. package/dist/config.d.ts +1 -1
  180. package/dist/config.js +4 -4
  181. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  182. package/dist/connectors/codex-materialize-runner.js +10 -10
  183. package/dist/connectors/codex-materialize.d.ts +1 -1
  184. package/dist/connectors/index.d.ts +1 -1
  185. package/dist/connectors/index.js +10 -10
  186. package/dist/consolidation-provenance-check.d.ts +2 -2
  187. package/dist/consolidation-undo.d.ts +2 -2
  188. package/dist/contradiction/index.d.ts +3 -3
  189. package/dist/converge-config.d.ts +1 -1
  190. package/dist/convergence-refresh.d.ts +2 -2
  191. package/dist/convergence-refresh.js +12 -12
  192. package/dist/conversation-index/backend.d.ts +1 -1
  193. package/dist/conversation-index/chunker.d.ts +1 -1
  194. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  195. package/dist/conversation-index/indexer.d.ts +1 -1
  196. package/dist/conversation-index/search.d.ts +1 -1
  197. package/dist/corpus-watermark.d.ts +1 -1
  198. package/dist/corpus-watermark.js +12 -12
  199. package/dist/cross-lingual-recall.d.ts +1 -1
  200. package/dist/day-summary.d.ts +1 -1
  201. package/dist/delinearize.d.ts +1 -1
  202. package/dist/dependency-propagation-config.d.ts +1 -1
  203. package/dist/{dependency-propagation-delivery-BCpeo14F.d.ts → dependency-propagation-delivery-D4WMbOwA.d.ts} +1 -1
  204. package/dist/direct-answer-wiring.d.ts +1 -1
  205. package/dist/direct-answer.d.ts +1 -1
  206. package/dist/embedding-fallback.d.ts +1 -1
  207. package/dist/enrichment/index.d.ts +1 -1
  208. package/dist/entity-origin-fields.d.ts +1 -1
  209. package/dist/entity-retrieval.d.ts +2 -2
  210. package/dist/entity-retrieval.js +10 -10
  211. package/dist/entity-schema.d.ts +1 -1
  212. package/dist/episodic-context.d.ts +1 -1
  213. package/dist/eval-trajectory-contracts.d.ts +1 -1
  214. package/dist/eval-trajectory-store.d.ts +1 -1
  215. package/dist/eval-trajectory.d.ts +1 -1
  216. package/dist/explicit-capture.d.ts +9 -9
  217. package/dist/external-wiki-access.d.ts +11 -11
  218. package/dist/external-wiki-access.js +32 -32
  219. package/dist/external-wiki-collection-registration.d.ts +1 -1
  220. package/dist/external-wiki-collection.d.ts +1 -1
  221. package/dist/external-wiki-mcp-tools.d.ts +11 -11
  222. package/dist/extraction-error-classification.d.ts +1 -1
  223. package/dist/extraction-faithfulness.d.ts +1 -1
  224. package/dist/extraction-judge-telemetry.d.ts +1 -1
  225. package/dist/extraction-judge-training.d.ts +1 -1
  226. package/dist/extraction-judge.d.ts +1 -1
  227. package/dist/extraction-liveness.d.ts +1 -1
  228. package/dist/extraction-normalization.d.ts +1 -1
  229. package/dist/extraction-prompt.d.ts +1 -1
  230. package/dist/extraction-source-grounding-rules.d.ts +1 -1
  231. package/dist/extraction-source-grounding.d.ts +1 -1
  232. package/dist/extraction-span-wire.d.ts +17 -0
  233. package/dist/extraction-span-wire.js +13 -0
  234. package/dist/extraction-span-wire.js.map +1 -0
  235. package/dist/extraction-span.d.ts +17 -0
  236. package/dist/extraction-span.js +8 -0
  237. package/dist/extraction.d.ts +1 -1
  238. package/dist/extraction.js +13 -13
  239. package/dist/fallback-llm.d.ts +1 -1
  240. package/dist/graph-dashboard-diff.d.ts +1 -1
  241. package/dist/graph-dashboard-key.d.ts +1 -1
  242. package/dist/graph-dashboard-parser.d.ts +1 -1
  243. package/dist/{graph-edge-decay-A4SDFMMS.js → graph-edge-decay-FXGELBFA.js} +4 -4
  244. package/dist/graph-edge-decay-FXGELBFA.js.map +1 -0
  245. package/dist/graph-edge-reinforcement.d.ts +1 -1
  246. package/dist/graph-path-reconstruction.d.ts +1 -1
  247. package/dist/graph-path-scoring.d.ts +1 -1
  248. package/dist/graph-snapshot.d.ts +1 -1
  249. package/dist/graph-snapshot.js +3 -3
  250. package/dist/graph.d.ts +1 -1
  251. package/dist/graph.js +3 -3
  252. package/dist/harmonic-retrieval.js +1 -1
  253. package/dist/importance.d.ts +1 -1
  254. package/dist/importers/index.d.ts +1 -1
  255. package/dist/in-flight-reads.d.ts +1 -1
  256. package/dist/{index-D_pyMUaP.d.ts → index-DuJnzwHv.d.ts} +2 -2
  257. package/dist/index.d.ts +341 -26
  258. package/dist/index.js +195 -114
  259. package/dist/intent.d.ts +1 -1
  260. package/dist/lcm/engine.d.ts +1 -1
  261. package/dist/lcm/engine.js +2 -2
  262. package/dist/lcm/index.d.ts +1 -1
  263. package/dist/lcm/index.js +7 -7
  264. package/dist/lcm/tools.d.ts +1 -1
  265. package/dist/lifecycle.d.ts +1 -1
  266. package/dist/live-connectors-runner.d.ts +1 -1
  267. package/dist/local-llm.d.ts +1 -1
  268. package/dist/local-model-endpoint.d.ts +1 -1
  269. package/dist/location/index.d.ts +3 -3
  270. package/dist/location/index.js +12 -12
  271. package/dist/maintenance/memory-governance.d.ts +1 -1
  272. package/dist/maintenance/memory-governance.js +10 -10
  273. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
  274. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +10 -10
  275. package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
  276. package/dist/maintenance/rebuild-memory-projection.js +11 -11
  277. package/dist/{maintenance-DDUX9d6D.d.ts → maintenance-BBeaeYRR.d.ts} +3 -3
  278. package/dist/mcp-memory-inspector-app.d.ts +11 -11
  279. package/dist/memory-action-policy.d.ts +1 -1
  280. package/dist/memory-cache.d.ts +1 -1
  281. package/dist/memory-controller.d.ts +1 -1
  282. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  283. package/dist/memory-projection-store.d.ts +1 -1
  284. package/dist/memory-provenance.d.ts +1 -1
  285. package/dist/memory-snapshot.d.ts +1 -1
  286. package/dist/memory-subject-cli.d.ts +11 -11
  287. package/dist/memory-subject.d.ts +11 -11
  288. package/dist/memory-worth-outcomes.d.ts +2 -2
  289. package/dist/models-json.d.ts +1 -1
  290. package/dist/namespaces/migrate.d.ts +3 -3
  291. package/dist/namespaces/migrate.js +11 -11
  292. package/dist/namespaces/principal.d.ts +1 -1
  293. package/dist/namespaces/search.d.ts +1 -1
  294. package/dist/namespaces/search.js +6 -6
  295. package/dist/namespaces/storage.d.ts +3 -3
  296. package/dist/namespaces/storage.js +10 -10
  297. package/dist/native-knowledge.d.ts +1 -1
  298. package/dist/offline-sync-impression-drain.d.ts +1 -1
  299. package/dist/operator-doctor-corpus.d.ts +1 -1
  300. package/dist/operator-doctor-corpus.js +13 -13
  301. package/dist/operator-doctor-replica.d.ts +1 -1
  302. package/dist/operator-toolkit.d.ts +3 -3
  303. package/dist/operator-toolkit.js +24 -24
  304. package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
  305. package/dist/orchestration/maintenance.d.ts +4 -4
  306. package/dist/orchestration/maintenance.js +19 -19
  307. package/dist/{orchestrator-3F4jihCo.d.ts → orchestrator-CaqnwNwM.d.ts} +8 -8
  308. package/dist/orchestrator.d.ts +9 -9
  309. package/dist/orchestrator.js +105 -101
  310. package/dist/patterns-cli.d.ts +1 -1
  311. package/dist/{pipeline-CB1dj6Uh.d.ts → pipeline-CrxVjlJr.d.ts} +1 -1
  312. package/dist/policy-runtime.d.ts +1 -1
  313. package/dist/proactive-contention.d.ts +1 -1
  314. package/dist/provenance.d.ts +1 -1
  315. package/dist/{public-http-34-JIAGQ.d.ts → public-http-CmQRjQCD.d.ts} +1 -1
  316. package/dist/{qmd-edLLZXc5.d.ts → qmd-BZgbJm0g.d.ts} +1 -1
  317. package/dist/qmd-preflight.d.ts +2 -2
  318. package/dist/qmd-recall-cache.d.ts +1 -1
  319. package/dist/qmd.d.ts +2 -2
  320. package/dist/qmd.js +4 -4
  321. package/dist/recall-concurrency-config.d.ts +1 -1
  322. package/dist/recall-deep-access.d.ts +30 -0
  323. package/dist/recall-deep-access.js +50 -0
  324. package/dist/recall-deep-access.js.map +1 -0
  325. package/dist/recall-deep-render.d.ts +11 -0
  326. package/dist/recall-deep-render.js +28 -0
  327. package/dist/recall-deep-render.js.map +1 -0
  328. package/dist/recall-deep.d.ts +37 -0
  329. package/dist/recall-deep.js +14 -0
  330. package/dist/recall-deep.js.map +1 -0
  331. package/dist/recall-disclosure-escalation.d.ts +1 -1
  332. package/dist/recall-explain-renderer.d.ts +1 -1
  333. package/dist/recall-explain-renderer.js +3 -3
  334. package/dist/recall-memory-map.d.ts +1 -1
  335. package/dist/recall-navigate.d.ts +70 -0
  336. package/dist/recall-navigate.js +15 -0
  337. package/dist/recall-navigate.js.map +1 -0
  338. package/dist/recall-planner-llm.d.ts +1 -1
  339. package/dist/recall-state-view-render.d.ts +18 -0
  340. package/dist/recall-state-view-render.js +22 -0
  341. package/dist/recall-state-view-render.js.map +1 -0
  342. package/dist/recall-state-view-widen.d.ts +13 -0
  343. package/dist/recall-state-view-widen.js +11 -0
  344. package/dist/recall-state-view-widen.js.map +1 -0
  345. package/dist/recall-state-view-wire.d.ts +13 -0
  346. package/dist/recall-state-view-wire.js +12 -0
  347. package/dist/recall-state-view-wire.js.map +1 -0
  348. package/dist/recall-state-view.d.ts +25 -0
  349. package/dist/recall-state-view.js +22 -0
  350. package/dist/recall-state-view.js.map +1 -0
  351. package/dist/recall-state.d.ts +1 -1
  352. package/dist/recall-tag-filter.d.ts +1 -1
  353. package/dist/recall-timings.d.ts +1 -1
  354. package/dist/recall-xray-cli.d.ts +1 -1
  355. package/dist/recall-xray-cli.js +4 -4
  356. package/dist/recall-xray-renderer.d.ts +1 -1
  357. package/dist/recall-xray-renderer.js +3 -3
  358. package/dist/recall-xray.d.ts +1 -1
  359. package/dist/recall-xray.js +2 -2
  360. package/dist/reconcile/cursor.d.ts +1 -1
  361. package/dist/reconcile/manifest.d.ts +1 -1
  362. package/dist/reconcile/plan.d.ts +1 -1
  363. package/dist/replay/normalizers/chatgpt.d.ts +1 -1
  364. package/dist/replay/normalizers/claude.d.ts +1 -1
  365. package/dist/replay/normalizers/openclaw.d.ts +1 -1
  366. package/dist/replay/normalizers/shared.d.ts +1 -1
  367. package/dist/replay/runner.d.ts +1 -1
  368. package/dist/replay/types.d.ts +1 -1
  369. package/dist/replica-divergence.d.ts +1 -1
  370. package/dist/replica-peers-config.d.ts +1 -1
  371. package/dist/resolve-auth-token.d.ts +1 -1
  372. package/dist/resume-bundles.js +5 -5
  373. package/dist/retrieval-agents.d.ts +2 -2
  374. package/dist/retrieval-tiers.d.ts +1 -1
  375. package/dist/routing/engine.d.ts +1 -1
  376. package/dist/routing/store.d.ts +1 -1
  377. package/dist/salvage-envelope.d.ts +1 -1
  378. package/dist/schemas.d.ts +42 -42
  379. package/dist/{scope-profiles-BF2lu81V.d.ts → scope-profiles-DFaojvoP.d.ts} +1 -1
  380. package/dist/search/embed-helper.d.ts +1 -1
  381. package/dist/search/factory.d.ts +1 -1
  382. package/dist/search/factory.js +5 -5
  383. package/dist/search/index.d.ts +1 -1
  384. package/dist/search/index.js +9 -9
  385. package/dist/search/lancedb-backend.d.ts +1 -1
  386. package/dist/search/meilisearch-backend.d.ts +1 -1
  387. package/dist/search/noop-backend.d.ts +1 -1
  388. package/dist/search/orama-backend.d.ts +1 -1
  389. package/dist/search/port.d.ts +1 -1
  390. package/dist/search/remote-backend.d.ts +1 -1
  391. package/dist/{semantic-consolidation-5OuWXBRt.d.ts → semantic-consolidation-BiX68wZA.d.ts} +1 -1
  392. package/dist/semantic-consolidation.d.ts +2 -2
  393. package/dist/semantic-consolidation.js +11 -11
  394. package/dist/semantic-rule-promotion.js +10 -10
  395. package/dist/semantic-rule-verifier.d.ts +1 -1
  396. package/dist/semantic-rule-verifier.js +10 -10
  397. package/dist/{service-CrqEhLXD.d.ts → service-D5h2zZ0M.d.ts} +2 -2
  398. package/dist/session-observer-bands.d.ts +1 -1
  399. package/dist/session-observer-state.d.ts +1 -1
  400. package/dist/shared-context/manager.d.ts +1 -1
  401. package/dist/signal.d.ts +1 -1
  402. package/dist/source-agent-qualifier.d.ts +1 -1
  403. package/dist/source-agent-qualifier.js +12 -12
  404. package/dist/{storage-BQn-xnxm.d.ts → storage-CtsaojWD.d.ts} +1 -1
  405. package/dist/storage.d.ts +2 -2
  406. package/dist/storage.js +9 -9
  407. package/dist/subject-config.d.ts +1 -1
  408. package/dist/summarizer.d.ts +1 -1
  409. package/dist/summary-snapshot.d.ts +1 -1
  410. package/dist/support-passport/index.d.ts +14 -14
  411. package/dist/support-passport/index.js +34 -34
  412. package/dist/temporal-supersession.d.ts +2 -2
  413. package/dist/temporal-timeline-recall.d.ts +1 -1
  414. package/dist/temporal-validity.d.ts +1 -1
  415. package/dist/threading.d.ts +1 -1
  416. package/dist/tier-migration.d.ts +2 -2
  417. package/dist/tier-routing.d.ts +1 -1
  418. package/dist/topics.d.ts +1 -1
  419. package/dist/transcript.d.ts +1 -1
  420. package/dist/transfer/capsule-export.js +2 -2
  421. package/dist/transfer/capsule-import.js +2 -2
  422. package/dist/transfer/export-okf.d.ts +1 -1
  423. package/dist/transfer/export-okf.js +11 -11
  424. package/dist/transfer/types.d.ts +12 -12
  425. package/dist/trust-score-stage.d.ts +1 -1
  426. package/dist/trust-score.d.ts +1 -1
  427. package/dist/{types-BRpcNjHZ.d.ts → types-CIpfYz1I.d.ts} +16 -11
  428. package/dist/types.d.ts +1 -1
  429. package/dist/types.js +1 -1
  430. package/dist/utility-runtime.d.ts +1 -1
  431. package/dist/verified-recall.js +10 -10
  432. package/dist/who-knows-cli.d.ts +11 -11
  433. package/dist/who-knows-cli.js +11 -11
  434. package/dist/who-knows.d.ts +11 -11
  435. package/dist/who-knows.js +10 -10
  436. package/dist/write-envelope.d.ts +1 -1
  437. package/package.json +2 -2
  438. package/src/activity/config.test.ts +1 -1
  439. package/src/activity/config.ts +48 -3
  440. package/src/activity/index.ts +5 -0
  441. package/src/activity/journal-vault-read.test.ts +153 -0
  442. package/src/activity/journal-vault-read.ts +214 -0
  443. package/src/activity/journal.test.ts +97 -0
  444. package/src/activity/journal.ts +113 -0
  445. package/src/activity/privacy.test.ts +53 -0
  446. package/src/activity/privacy.ts +80 -0
  447. package/src/activity/timeline/analysis-batch.test.ts +56 -0
  448. package/src/activity/timeline/analysis-batch.ts +45 -0
  449. package/src/activity/timeline/analysis.test.ts +413 -0
  450. package/src/activity/timeline/analysis.ts +362 -0
  451. package/src/activity/timeline/index.ts +7 -0
  452. package/src/activity/timeline/journal-recap-persist.test.ts +148 -0
  453. package/src/activity/timeline/journal-recap-persist.ts +37 -0
  454. package/src/activity/timeline/journal-recap.test.ts +113 -0
  455. package/src/activity/timeline/journal-recap.ts +130 -0
  456. package/src/activity/timeline/query.test.ts +198 -0
  457. package/src/activity/timeline/query.ts +313 -0
  458. package/src/activity/timeline/weekly-persist.test.ts +121 -0
  459. package/src/activity/timeline/weekly-persist.ts +103 -0
  460. package/src/activity/timeline/weekly.test.ts +215 -0
  461. package/src/activity/timeline/weekly.ts +234 -0
  462. package/src/activity/types.ts +14 -0
  463. package/src/activity/vault-path.test.ts +38 -0
  464. package/src/activity/vault-path.ts +59 -0
  465. package/src/activity/vault-publish.test.ts +268 -0
  466. package/src/activity/vault-publish.ts +180 -0
  467. package/src/config.test.ts +1 -1
  468. package/src/config.ts +2 -22
  469. package/src/dedup/merge-on-write-wire.test.ts +101 -0
  470. package/src/dedup/merge-on-write-wire.ts +34 -0
  471. package/src/dedup/merge-on-write.test.ts +91 -0
  472. package/src/dedup/merge-on-write.ts +75 -0
  473. package/src/dedup/novelty-gate.test.ts +143 -0
  474. package/src/dedup/novelty-gate.ts +163 -0
  475. package/src/extraction-span-wire.test.ts +20 -0
  476. package/src/extraction-span-wire.ts +17 -0
  477. package/src/extraction-span.test.ts +59 -0
  478. package/src/extraction-span.ts +39 -0
  479. package/src/index.ts +1 -0
  480. package/src/location/recall-exclusion.test.ts +1 -0
  481. package/src/orchestration/extraction-persist.ts +22 -23
  482. package/src/orchestration/generic-recall-paths.ts +11 -0
  483. package/src/orchestration/recall-entry.ts +8 -3
  484. package/src/recall-deep-access.test.ts +58 -0
  485. package/src/recall-deep-access.ts +71 -0
  486. package/src/recall-deep-render.test.ts +68 -0
  487. package/src/recall-deep-render.ts +32 -0
  488. package/src/recall-deep.test.ts +72 -0
  489. package/src/recall-deep.ts +113 -0
  490. package/src/recall-navigate.test.ts +84 -0
  491. package/src/recall-navigate.ts +100 -0
  492. package/src/recall-state-view-render.test.ts +94 -0
  493. package/src/recall-state-view-render.ts +24 -0
  494. package/src/recall-state-view-widen.test.ts +66 -0
  495. package/src/recall-state-view-widen.ts +49 -0
  496. package/src/recall-state-view-wire.test.ts +35 -0
  497. package/src/recall-state-view-wire.ts +18 -0
  498. package/src/recall-state-view.test.ts +131 -0
  499. package/src/recall-state-view.ts +138 -0
  500. package/src/shared-context/governance.test.ts +53 -0
  501. package/src/shared-context/governance.ts +86 -0
  502. package/src/shared-context/staleness.test.ts +36 -0
  503. package/src/shared-context/staleness.ts +38 -0
  504. package/src/shared-context/trajectories.test.ts +77 -0
  505. package/src/shared-context/trajectories.ts +49 -0
  506. package/src/types.ts +3 -10
  507. package/dist/chunk-56IV4J5W.js.map +0 -1
  508. package/dist/chunk-IHGMRDEE.js.map +0 -1
  509. package/dist/chunk-KODXCHXJ.js.map +0 -1
  510. package/dist/chunk-PEBH5DCK.js.map +0 -1
  511. /package/dist/{chunk-EZSCW4EM.js.map → chunk-25OLNWYG.js.map} +0 -0
  512. /package/dist/{chunk-2LBAFHOQ.js.map → chunk-2QSGJTDG.js.map} +0 -0
  513. /package/dist/{chunk-7UTDHQZ5.js.map → chunk-2VZHB5US.js.map} +0 -0
  514. /package/dist/{chunk-VQNRICAQ.js.map → chunk-36HJ36FK.js.map} +0 -0
  515. /package/dist/{chunk-XKNHFDTT.js.map → chunk-3A2Z4OOS.js.map} +0 -0
  516. /package/dist/{chunk-RDGKVH6T.js.map → chunk-4NKIGSJM.js.map} +0 -0
  517. /package/dist/{chunk-EFQCDJZ2.js.map → chunk-4PG2CKI6.js.map} +0 -0
  518. /package/dist/{chunk-HJXA6ZM7.js.map → chunk-6545JDIM.js.map} +0 -0
  519. /package/dist/{chunk-J3OND5QT.js.map → chunk-65HXVEVG.js.map} +0 -0
  520. /package/dist/{chunk-HNPE66LB.js.map → chunk-6BYJQ3L2.js.map} +0 -0
  521. /package/dist/{chunk-ZW4VXELZ.js.map → chunk-6PUF7LUO.js.map} +0 -0
  522. /package/dist/{chunk-TVVEYCNW.js.map → chunk-7K5Q6COX.js.map} +0 -0
  523. /package/dist/{chunk-MN5NOOI7.js.map → chunk-AI5M4FVQ.js.map} +0 -0
  524. /package/dist/{chunk-YMOPYG3K.js.map → chunk-BIJAWZYW.js.map} +0 -0
  525. /package/dist/{chunk-I5VB44ZK.js.map → chunk-BLHKR4GJ.js.map} +0 -0
  526. /package/dist/{chunk-CEH2AFXG.js.map → chunk-C24UZSFW.js.map} +0 -0
  527. /package/dist/{chunk-MJRGVXPQ.js.map → chunk-C3ZYZKDJ.js.map} +0 -0
  528. /package/dist/{chunk-QCRJMU5V.js.map → chunk-CDLPF3PX.js.map} +0 -0
  529. /package/dist/{chunk-23CVL7HS.js.map → chunk-CQ6IWZDI.js.map} +0 -0
  530. /package/dist/{chunk-KWIGDKM2.js.map → chunk-D2YNNDML.js.map} +0 -0
  531. /package/dist/{chunk-FTTJRVB7.js.map → chunk-D3DUA64S.js.map} +0 -0
  532. /package/dist/{chunk-7XOG75AU.js.map → chunk-D6Q5EPOV.js.map} +0 -0
  533. /package/dist/{chunk-GEJKYA7D.js.map → chunk-DSEHPUID.js.map} +0 -0
  534. /package/dist/{chunk-OAJMQKQR.js.map → chunk-EQRD4NMH.js.map} +0 -0
  535. /package/dist/{chunk-H7VDIF2V.js.map → chunk-ER2UPUMG.js.map} +0 -0
  536. /package/dist/{chunk-4FHRZD5T.js.map → chunk-F2JXJABQ.js.map} +0 -0
  537. /package/dist/{chunk-FKKGCGYL.js.map → chunk-F4W5HTED.js.map} +0 -0
  538. /package/dist/{chunk-DMEHOEC7.js.map → chunk-FFWONAAW.js.map} +0 -0
  539. /package/dist/{chunk-TNGH4ZYI.js.map → chunk-GNWLTCKC.js.map} +0 -0
  540. /package/dist/{chunk-CFVTRUR3.js.map → chunk-H6RSANGQ.js.map} +0 -0
  541. /package/dist/{chunk-CTCGHNWN.js.map → chunk-J2R275FN.js.map} +0 -0
  542. /package/dist/{chunk-IVIAHQBR.js.map → chunk-JJ6ZEFXC.js.map} +0 -0
  543. /package/dist/{chunk-KXIXO76C.js.map → chunk-JMXHVJ2V.js.map} +0 -0
  544. /package/dist/{chunk-7LCGFUMB.js.map → chunk-KQAFEZQX.js.map} +0 -0
  545. /package/dist/{chunk-NACLNNFQ.js.map → chunk-KSZKQTZS.js.map} +0 -0
  546. /package/dist/{chunk-NPIBN2VL.js.map → chunk-LK4TOYPU.js.map} +0 -0
  547. /package/dist/{chunk-K66OY4EI.js.map → chunk-LSR5LQXN.js.map} +0 -0
  548. /package/dist/{chunk-6CEGSTBD.js.map → chunk-NTFXBILO.js.map} +0 -0
  549. /package/dist/{chunk-2PSX5BJU.js.map → chunk-NZPFCP5A.js.map} +0 -0
  550. /package/dist/{chunk-FYWLSFFS.js.map → chunk-OERZXNSK.js.map} +0 -0
  551. /package/dist/{chunk-ZJPM7GZ3.js.map → chunk-OIDICRH7.js.map} +0 -0
  552. /package/dist/{chunk-LTBKKSCX.js.map → chunk-OLBZ2WGG.js.map} +0 -0
  553. /package/dist/{chunk-PD66CVSD.js.map → chunk-OUKBMQ2O.js.map} +0 -0
  554. /package/dist/{chunk-GPFZFCRN.js.map → chunk-PP7R754B.js.map} +0 -0
  555. /package/dist/{chunk-GX6FTSYH.js.map → chunk-PRRUK2ZH.js.map} +0 -0
  556. /package/dist/{chunk-MAH64N55.js.map → chunk-PW3GKWH3.js.map} +0 -0
  557. /package/dist/{chunk-33MFRY25.js.map → chunk-R2Q6FTOX.js.map} +0 -0
  558. /package/dist/{chunk-VCKWULAK.js.map → chunk-RCPKBW7K.js.map} +0 -0
  559. /package/dist/{chunk-CN4VKV3S.js.map → chunk-RH3XLQG4.js.map} +0 -0
  560. /package/dist/{chunk-2QSZNTDO.js.map → chunk-RKNJBZ55.js.map} +0 -0
  561. /package/dist/{chunk-YXFCALVT.js.map → chunk-U4HZEW2B.js.map} +0 -0
  562. /package/dist/{chunk-RZ3IZIJG.js.map → chunk-UHQE37NI.js.map} +0 -0
  563. /package/dist/{chunk-Z3YEGSR4.js.map → chunk-UMZUKOJU.js.map} +0 -0
  564. /package/dist/{chunk-72OIT7KS.js.map → chunk-UVYL5G7A.js.map} +0 -0
  565. /package/dist/{chunk-4STAANV7.js.map → chunk-VKDBDJIX.js.map} +0 -0
  566. /package/dist/{chunk-WKJFIMVN.js.map → chunk-VSMSYDIH.js.map} +0 -0
  567. /package/dist/{chunk-GSKINLAK.js.map → chunk-W5IYHQA5.js.map} +0 -0
  568. /package/dist/{chunk-FESUGFIL.js.map → chunk-WKWY7YF3.js.map} +0 -0
  569. /package/dist/{chunk-UNUMFURP.js.map → chunk-X5PIDJ3L.js.map} +0 -0
  570. /package/dist/{chunk-6RUHELWR.js.map → chunk-Y2YM4C75.js.map} +0 -0
  571. /package/dist/{chunk-L4X4PJYK.js.map → chunk-YZ5VC2JJ.js.map} +0 -0
  572. /package/dist/{chunk-VQ4AMTGZ.js.map → chunk-ZBIEX4XN.js.map} +0 -0
  573. /package/dist/{chunk-O57GM3FR.js.map → chunk-ZMVW2HJJ.js.map} +0 -0
  574. /package/dist/{chunk-6QDXA26G.js.map → chunk-ZXROBS53.js.map} +0 -0
  575. /package/dist/{graph-edge-decay-A4SDFMMS.js.map → extraction-span.js.map} +0 -0
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Persist seam for merge-on-write (issue #2330 leftover slice).
3
+ *
4
+ * Default off. Failures and disabled gates create. Persist callers inject
5
+ * writeMerged / writeNew. This module does not touch extraction-persist.
6
+ */
7
+
8
+ import {
9
+ applyMergeOnWrite,
10
+ type MergeJudge,
11
+ type MergeOnWritePair,
12
+ } from "./merge-on-write.js";
13
+
14
+ export async function applyMergeOnWriteAtPersist<T>(opts: {
15
+ enabled?: boolean;
16
+ pair: MergeOnWritePair;
17
+ judge: MergeJudge;
18
+ mergeMin?: number;
19
+ skipThreshold?: number;
20
+ writeMerged: (id: string) => T | Promise<T>;
21
+ writeNew: () => T | Promise<T>;
22
+ }): Promise<T> {
23
+ const decision = await applyMergeOnWrite({
24
+ enabled: opts.enabled,
25
+ pair: opts.pair,
26
+ judge: opts.judge,
27
+ mergeMin: opts.mergeMin,
28
+ skipThreshold: opts.skipThreshold,
29
+ });
30
+ if (decision === "merge" && opts.pair.existingId) {
31
+ return opts.writeMerged(opts.pair.existingId);
32
+ }
33
+ return opts.writeNew();
34
+ }
@@ -0,0 +1,91 @@
1
+ import assert from "node:assert/strict";
2
+ import { test } from "node:test";
3
+ import {
4
+ type MergeJudgeVerdict,
5
+ type MergeOnWritePair,
6
+ applyMergeOnWrite,
7
+ judgeMergeDecision,
8
+ shouldConsiderMerge,
9
+ } from "./merge-on-write.js";
10
+
11
+ function pair(overrides: Partial<MergeOnWritePair> = {}): MergeOnWritePair {
12
+ return {
13
+ category: "fact",
14
+ score: 0.85,
15
+ incomingContent: "User prefers dark mode on laptops.",
16
+ existingContent: "User likes dark mode.",
17
+ existingId: "mem-1",
18
+ ...overrides,
19
+ };
20
+ }
21
+
22
+ const mergeJudge = async () => "merge" as const;
23
+
24
+ test("merge-on-write: skip band is not considered", () => {
25
+ assert.equal(shouldConsiderMerge({ score: 0.92 }), false);
26
+ assert.equal(shouldConsiderMerge({ score: 0.99 }), false);
27
+ });
28
+
29
+ test("merge-on-write: merge band is considered", () => {
30
+ assert.equal(shouldConsiderMerge({ score: 0.8 }), true);
31
+ assert.equal(shouldConsiderMerge({ score: 0.85 }), true);
32
+ assert.equal(shouldConsiderMerge({ score: 0.919 }), true);
33
+ });
34
+
35
+ test("merge-on-write: score below mergeMin is not considered", () => {
36
+ assert.equal(shouldConsiderMerge({ score: 0.79 }), false);
37
+ });
38
+
39
+ test("merge-on-write: refused categories always create", async () => {
40
+ for (const category of ["procedure", "reasoning_trace", "moment", "correction"]) {
41
+ const decision = await applyMergeOnWrite({
42
+ enabled: true,
43
+ pair: pair({ category }),
44
+ judge: mergeJudge,
45
+ });
46
+ assert.equal(decision, "create", category);
47
+ }
48
+ });
49
+
50
+ test("merge-on-write: judge throw creates", async () => {
51
+ const viaJudge = await judgeMergeDecision(pair(), async () => {
52
+ throw new Error("timeout");
53
+ });
54
+ assert.equal(viaJudge, "create");
55
+
56
+ const viaApply = await applyMergeOnWrite({
57
+ enabled: true,
58
+ pair: pair(),
59
+ judge: async () => {
60
+ throw new Error("timeout");
61
+ },
62
+ });
63
+ assert.equal(viaApply, "create");
64
+ });
65
+
66
+ test("merge-on-write: uncertain judge creates", async () => {
67
+ const decision = await judgeMergeDecision(pair(), async (): Promise<MergeJudgeVerdict> => "uncertain");
68
+ assert.equal(decision, "create");
69
+ });
70
+
71
+ test("merge-on-write: disabled or mergeMin 0 creates", async () => {
72
+ let called = 0;
73
+ const judge = async () => {
74
+ called += 1;
75
+ return "merge" as const;
76
+ };
77
+
78
+ assert.equal(await applyMergeOnWrite({ pair: pair(), judge }), "create");
79
+ assert.equal(await applyMergeOnWrite({ enabled: false, pair: pair(), judge }), "create");
80
+ assert.equal(await applyMergeOnWrite({ enabled: true, mergeMin: 0, pair: pair(), judge }), "create");
81
+ assert.equal(called, 0);
82
+ });
83
+
84
+ test("merge-on-write: enabled in-band merge applies", async () => {
85
+ const decision = await applyMergeOnWrite({
86
+ enabled: true,
87
+ pair: pair(),
88
+ judge: mergeJudge,
89
+ });
90
+ assert.equal(decision, "merge");
91
+ });
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Isolated merge-on-write judge (issue #2330 first slice).
3
+ *
4
+ * Default off. Persist wiring comes later. Failures create.
5
+ */
6
+
7
+ export const DEFAULT_MERGE_MIN = 0.8;
8
+ export const DEFAULT_SKIP_THRESHOLD = 0.92;
9
+
10
+ export const REFUSED_MERGE_CATEGORIES = [
11
+ "procedure",
12
+ "reasoning_trace",
13
+ "moment",
14
+ "correction",
15
+ ] as const;
16
+
17
+ export type MergeOnWriteDecision = "merge" | "create";
18
+ export type MergeJudgeVerdict = MergeOnWriteDecision | "uncertain";
19
+
20
+ export interface MergeOnWritePair {
21
+ category: string;
22
+ score: number;
23
+ incomingContent?: string;
24
+ existingContent?: string;
25
+ existingId?: string;
26
+ }
27
+
28
+ export type MergeJudge = (
29
+ pair: MergeOnWritePair,
30
+ ) => Promise<MergeJudgeVerdict> | MergeJudgeVerdict;
31
+
32
+ export function shouldConsiderMerge(opts: {
33
+ score: number;
34
+ skipThreshold?: number;
35
+ mergeMin?: number;
36
+ }): boolean {
37
+ const mergeMin = opts.mergeMin ?? DEFAULT_MERGE_MIN;
38
+ const skipThreshold = opts.skipThreshold ?? DEFAULT_SKIP_THRESHOLD;
39
+ if (!(mergeMin > 0)) return false;
40
+ if (!Number.isFinite(opts.score) || !Number.isFinite(skipThreshold)) return false;
41
+ return mergeMin <= opts.score && opts.score < skipThreshold;
42
+ }
43
+
44
+ export async function judgeMergeDecision(
45
+ pair: MergeOnWritePair,
46
+ judge: MergeJudge,
47
+ ): Promise<MergeOnWriteDecision> {
48
+ try {
49
+ const verdict = await judge(pair);
50
+ return verdict === "merge" ? "merge" : "create";
51
+ } catch {
52
+ return "create";
53
+ }
54
+ }
55
+
56
+ export async function applyMergeOnWrite(opts: {
57
+ pair: MergeOnWritePair;
58
+ judge: MergeJudge;
59
+ enabled?: boolean;
60
+ mergeMin?: number;
61
+ skipThreshold?: number;
62
+ }): Promise<MergeOnWriteDecision> {
63
+ if (opts.enabled !== true) return "create";
64
+ if ((REFUSED_MERGE_CATEGORIES as readonly string[]).includes(opts.pair.category)) return "create";
65
+ if (
66
+ !shouldConsiderMerge({
67
+ score: opts.pair.score,
68
+ mergeMin: opts.mergeMin,
69
+ skipThreshold: opts.skipThreshold,
70
+ })
71
+ ) {
72
+ return "create";
73
+ }
74
+ return judgeMergeDecision(opts.pair, opts.judge);
75
+ }
@@ -0,0 +1,143 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+
4
+ import { parseConfig } from "../config.js";
5
+ import {
6
+ applyNoveltyGate,
7
+ DEFAULT_NOVELTY_ADD_THRESHOLD,
8
+ DEFAULT_NOVELTY_NOOP_THRESHOLD,
9
+ embeddingsFromCosineHits,
10
+ scoreNovelty,
11
+ type NoveltyNeighbor,
12
+ } from "./novelty-gate.js";
13
+
14
+ function neighborAtCosine(id: string, cosine: number): NoveltyNeighbor {
15
+ const s = Math.min(1, Math.max(-1, cosine));
16
+ return { id, embedding: [s, Math.sqrt(Math.max(0, 1 - s * s))] };
17
+ }
18
+
19
+ const CANDIDATE = [1, 0];
20
+
21
+ test("novelty gate: parseConfig defaults keep the gate off with a wide uncertain band", () => {
22
+ const config = parseConfig({});
23
+ assert.equal(config.noveltyGateEnabled, false);
24
+ assert.equal(config.noveltyAddThreshold, DEFAULT_NOVELTY_ADD_THRESHOLD);
25
+ assert.equal(config.noveltyNoopThreshold, DEFAULT_NOVELTY_NOOP_THRESHOLD);
26
+ assert.ok(config.noveltyAddThreshold - config.noveltyNoopThreshold > 0.3);
27
+ });
28
+
29
+ test("novelty gate: conservative preset stays off", () => {
30
+ const config = parseConfig({ memoryOsPreset: "conservative" });
31
+ assert.equal(config.noveltyGateEnabled, false);
32
+ });
33
+
34
+ test("novelty gate: gate off does not call lookup", async () => {
35
+ let called = 0;
36
+ const decision = await applyNoveltyGate({
37
+ enabled: false,
38
+ addThreshold: DEFAULT_NOVELTY_ADD_THRESHOLD,
39
+ noopThreshold: DEFAULT_NOVELTY_NOOP_THRESHOLD,
40
+ lookup: async () => {
41
+ called += 1;
42
+ throw new Error("lookup must not run when the gate is off");
43
+ },
44
+ });
45
+ assert.equal(called, 0);
46
+ assert.equal(decision.decision, "uncertain");
47
+ });
48
+
49
+ test("novelty gate: paraphrase routes noop", () => {
50
+ const decision = scoreNovelty(CANDIDATE, [neighborAtCosine("paraphrase", 0.98)]);
51
+ assert.equal(decision.decision, "noop");
52
+ assert.equal(decision.neighborId, "paraphrase");
53
+ assert.ok(decision.score <= DEFAULT_NOVELTY_NOOP_THRESHOLD);
54
+ });
55
+
56
+ test("novelty gate: unrelated routes add", () => {
57
+ const decision = scoreNovelty(CANDIDATE, [neighborAtCosine("other", 0.05)]);
58
+ assert.equal(decision.decision, "add");
59
+ assert.equal(decision.neighborId, "other");
60
+ assert.ok(decision.score >= DEFAULT_NOVELTY_ADD_THRESHOLD);
61
+ });
62
+
63
+ test("novelty gate: exactly at addThreshold is add", () => {
64
+ const neighbor = neighborAtCosine("edge-add", 1 - DEFAULT_NOVELTY_ADD_THRESHOLD);
65
+ const measured = scoreNovelty(CANDIDATE, [neighbor], { addThreshold: 1, noopThreshold: -1 });
66
+ const decision = scoreNovelty(CANDIDATE, [neighbor], {
67
+ addThreshold: measured.score,
68
+ noopThreshold: DEFAULT_NOVELTY_NOOP_THRESHOLD,
69
+ });
70
+ assert.equal(decision.decision, "add");
71
+ });
72
+
73
+ test("novelty gate: exactly at noopThreshold is noop", () => {
74
+ const neighbor = neighborAtCosine("edge-noop", 1 - DEFAULT_NOVELTY_NOOP_THRESHOLD);
75
+ const measured = scoreNovelty(CANDIDATE, [neighbor], { addThreshold: 1, noopThreshold: -1 });
76
+ const decision = scoreNovelty(CANDIDATE, [neighbor], {
77
+ addThreshold: DEFAULT_NOVELTY_ADD_THRESHOLD,
78
+ noopThreshold: measured.score,
79
+ });
80
+ assert.equal(decision.decision, "noop");
81
+ });
82
+
83
+ test("novelty gate: mid-band routes uncertain", () => {
84
+ const mid = (DEFAULT_NOVELTY_ADD_THRESHOLD + DEFAULT_NOVELTY_NOOP_THRESHOLD) / 2;
85
+ const decision = scoreNovelty(CANDIDATE, [neighborAtCosine("mid", 1 - mid)]);
86
+ assert.equal(decision.decision, "uncertain");
87
+ });
88
+
89
+ test("novelty gate: empty neighborhood is add", () => {
90
+ const decision = scoreNovelty(CANDIDATE, []);
91
+ assert.equal(decision.decision, "add");
92
+ assert.equal(decision.score, 1);
93
+ assert.equal(decision.neighborId, undefined);
94
+ });
95
+
96
+ test("novelty gate: thrown lookup is uncertain", async () => {
97
+ const decision = await applyNoveltyGate({
98
+ enabled: true,
99
+ addThreshold: DEFAULT_NOVELTY_ADD_THRESHOLD,
100
+ noopThreshold: DEFAULT_NOVELTY_NOOP_THRESHOLD,
101
+ lookup: async () => {
102
+ throw new Error("backend down");
103
+ },
104
+ });
105
+ assert.equal(decision.decision, "uncertain");
106
+ });
107
+
108
+ test("novelty gate: cross-connector neighbor cannot noop (PR #2564 review)", () => {
109
+ // Identical content already stored by connector A (cosine ~1) must not
110
+ // suppress connector B's candidate: neighborhood scoped to same-connector
111
+ // neighbors only (mirrors the PR #1852 semantic skip gate).
112
+ const identicalFromA = { id: "a-dup", score: 1, sourceConnector: "connector-a" };
113
+ const { neighborhood } = embeddingsFromCosineHits([identicalFromA], {
114
+ candidateConnector: "connector-b",
115
+ });
116
+ assert.deepEqual(neighborhood, []);
117
+ const decision = scoreNovelty(CANDIDATE, neighborhood);
118
+ assert.equal(decision.decision, "add");
119
+ });
120
+
121
+ test("novelty gate: unattributed neighbor is scoped out when candidate has a connector", () => {
122
+ const unattributed = { id: "anon-dup", score: 1 };
123
+ const { neighborhood } = embeddingsFromCosineHits([unattributed], {
124
+ candidateConnector: "connector-b",
125
+ });
126
+ assert.deepEqual(neighborhood, []);
127
+ });
128
+
129
+ test("novelty gate: same-connector paraphrase still noops", () => {
130
+ const sameConnector = { id: "b-dup", score: 0.98, sourceConnector: "connector-b" };
131
+ const { neighborhood } = embeddingsFromCosineHits([sameConnector], {
132
+ candidateConnector: "connector-b",
133
+ });
134
+ assert.equal(neighborhood.length, 1);
135
+ assert.equal(scoreNovelty(CANDIDATE, neighborhood).decision, "noop");
136
+ });
137
+
138
+ test("novelty gate: candidate without connector keeps unscoped neighborhood", () => {
139
+ const foreign = { id: "a-dup", score: 0.98, sourceConnector: "connector-a" };
140
+ const { neighborhood } = embeddingsFromCosineHits([foreign]);
141
+ assert.equal(neighborhood.length, 1);
142
+ assert.equal(scoreNovelty(CANDIDATE, neighborhood).decision, "noop");
143
+ });
@@ -0,0 +1,163 @@
1
+ import { coerceBooleanLike, coerceNumber } from "../connectors/coerce.js";
2
+
3
+ /**
4
+ * Embedding-density novelty gate (issue #1953, SAGE).
5
+ *
6
+ * score = 1 - mean(cosine of k nearest). Higher score = more novel.
7
+ * score >= noveltyAddThreshold → add (skip semantic/LLM dedup)
8
+ * score <= noveltyNoopThreshold → noop (drop; do not touch contentHashIndex)
9
+ * else → uncertain (fall through to semantic dedup)
10
+ *
11
+ * Defaults keep a wide UNCERTAIN band. noveltyGateEnabled defaults false.
12
+ * Backend failure is not handled here — callers treat a thrown lookup as uncertain.
13
+ */
14
+ export const DEFAULT_NOVELTY_ADD_THRESHOLD = 0.55;
15
+ export const DEFAULT_NOVELTY_NOOP_THRESHOLD = 0.15;
16
+ export const DEFAULT_NOVELTY_K = 5;
17
+
18
+ export interface NoveltyNeighbor {
19
+ id: string;
20
+ embedding: number[];
21
+ }
22
+
23
+ export interface NoveltyDecision {
24
+ score: number;
25
+ decision: "add" | "noop" | "uncertain";
26
+ neighborId?: string;
27
+ }
28
+
29
+ export interface NoveltyThresholds {
30
+ addThreshold?: number;
31
+ noopThreshold?: number;
32
+ k?: number;
33
+ }
34
+
35
+ export interface WritePathDedupConfig {
36
+ semanticDedupEnabled: boolean;
37
+ semanticDedupThreshold: number;
38
+ semanticDedupCandidates: number;
39
+ noveltyGateEnabled: boolean;
40
+ noveltyAddThreshold: number;
41
+ noveltyNoopThreshold: number;
42
+ }
43
+
44
+ function clamp01(value: number | undefined, fallback: number): number {
45
+ return value !== undefined && Number.isFinite(value) ? Math.min(1, Math.max(0, value)) : fallback;
46
+ }
47
+
48
+ function cosine(a: number[], b: number[]): number {
49
+ if (a.length === 0 || a.length !== b.length) return 0;
50
+ let dot = 0;
51
+ let magA = 0;
52
+ let magB = 0;
53
+ for (let i = 0; i < a.length; i++) {
54
+ dot += a[i] * b[i];
55
+ magA += a[i] * a[i];
56
+ magB += b[i] * b[i];
57
+ }
58
+ const denom = Math.sqrt(magA) * Math.sqrt(magB);
59
+ if (denom === 0) return 0;
60
+ const raw = dot / denom;
61
+ if (!Number.isFinite(raw)) return 0;
62
+ if (raw < 0) return 0;
63
+ if (raw > 1) return 1;
64
+ return raw;
65
+ }
66
+
67
+ export function parseWritePathDedupConfig(cfg: Record<string, unknown>): WritePathDedupConfig {
68
+ const rawCandidates = coerceNumber(cfg.semanticDedupCandidates, "semanticDedupCandidates");
69
+ let semanticDedupCandidates = 5;
70
+ if (rawCandidates !== undefined && rawCandidates >= 0) {
71
+ const n = Math.floor(rawCandidates);
72
+ semanticDedupCandidates = rawCandidates > 0 && n === 0 ? 1 : n;
73
+ }
74
+ return {
75
+ semanticDedupEnabled: coerceBooleanLike(cfg.semanticDedupEnabled, "semanticDedupEnabled") !== false,
76
+ semanticDedupThreshold: clamp01(
77
+ coerceNumber(cfg.semanticDedupThreshold, "semanticDedupThreshold"),
78
+ 0.92,
79
+ ),
80
+ semanticDedupCandidates,
81
+ noveltyGateEnabled: coerceBooleanLike(cfg.noveltyGateEnabled, "noveltyGateEnabled") === true,
82
+ noveltyAddThreshold: clamp01(
83
+ coerceNumber(cfg.noveltyAddThreshold, "noveltyAddThreshold"),
84
+ DEFAULT_NOVELTY_ADD_THRESHOLD,
85
+ ),
86
+ noveltyNoopThreshold: clamp01(
87
+ coerceNumber(cfg.noveltyNoopThreshold, "noveltyNoopThreshold"),
88
+ DEFAULT_NOVELTY_NOOP_THRESHOLD,
89
+ ),
90
+ };
91
+ }
92
+
93
+ export function embeddingsFromCosineHits(
94
+ hits: ReadonlyArray<{ id: string; score: number; sourceConnector?: string }>,
95
+ opts: { candidateConnector?: string } = {},
96
+ ): { embedding: number[]; neighborhood: NoveltyNeighbor[] } {
97
+ // Connector-aware scoping (PR #2564 review finding on 54d865cb9): a
98
+ // neighbor from a different (or unattributed) connector must not drive a
99
+ // noop — same contract as the semantic skip gate (PR #1852). Candidates
100
+ // without a connector keep the unscoped neighborhood.
101
+ const candidateConnector = opts.candidateConnector?.trim() || undefined;
102
+ const scoped = candidateConnector
103
+ ? hits.filter((hit) => (hit.sourceConnector?.trim() || undefined) === candidateConnector)
104
+ : hits;
105
+ return {
106
+ embedding: [1, 0],
107
+ neighborhood: scoped.map((hit) => {
108
+ const s = Number.isFinite(hit.score) ? Math.min(1, Math.max(-1, hit.score)) : 0;
109
+ return { id: hit.id, embedding: [s, Math.sqrt(Math.max(0, 1 - s * s))] };
110
+ }),
111
+ };
112
+ }
113
+
114
+ export function scoreNovelty(
115
+ embedding: number[],
116
+ neighborhood: NoveltyNeighbor[],
117
+ thresholds: NoveltyThresholds = {},
118
+ ): NoveltyDecision {
119
+ const addThreshold = clamp01(thresholds.addThreshold ?? DEFAULT_NOVELTY_ADD_THRESHOLD, DEFAULT_NOVELTY_ADD_THRESHOLD);
120
+ const noopThreshold = clamp01(thresholds.noopThreshold ?? DEFAULT_NOVELTY_NOOP_THRESHOLD, DEFAULT_NOVELTY_NOOP_THRESHOLD);
121
+ const k = thresholds.k !== undefined && Number.isFinite(thresholds.k) && thresholds.k > 0
122
+ ? Math.floor(thresholds.k)
123
+ : DEFAULT_NOVELTY_K;
124
+
125
+ if (neighborhood.length === 0) {
126
+ return { score: 1, decision: "add" };
127
+ }
128
+
129
+ const ranked = neighborhood
130
+ .map((neighbor) => ({
131
+ id: neighbor.id,
132
+ cosine: cosine(embedding, neighbor.embedding),
133
+ }))
134
+ .sort((a, b) => b.cosine - a.cosine);
135
+ const nearest = ranked.slice(0, Math.max(1, k));
136
+ const density = nearest.reduce((sum, row) => sum + row.cosine, 0) / nearest.length;
137
+ const score = 1 - density;
138
+ const neighborId = ranked[0]?.id;
139
+
140
+ if (score >= addThreshold) return { score, decision: "add", neighborId };
141
+ if (score <= noopThreshold) return { score, decision: "noop", neighborId };
142
+ return { score, decision: "uncertain", neighborId };
143
+ }
144
+
145
+ export async function applyNoveltyGate(opts: {
146
+ enabled: boolean;
147
+ addThreshold: number;
148
+ noopThreshold: number;
149
+ lookup: () => Promise<{ embedding: number[]; neighborhood: NoveltyNeighbor[] }>;
150
+ }): Promise<NoveltyDecision> {
151
+ if (!opts.enabled) {
152
+ return { score: 0, decision: "uncertain" };
153
+ }
154
+ try {
155
+ const { embedding, neighborhood } = await opts.lookup();
156
+ return scoreNovelty(embedding, neighborhood, {
157
+ addThreshold: opts.addThreshold,
158
+ noopThreshold: opts.noopThreshold,
159
+ });
160
+ } catch {
161
+ return { score: 0, decision: "uncertain" };
162
+ }
163
+ }
@@ -0,0 +1,20 @@
1
+ import assert from "node:assert/strict";
2
+ import { test } from "node:test";
3
+ import { applySpanMode } from "./extraction-span-wire.js";
4
+
5
+ const TEXT = "Alice moved to Seattle";
6
+
7
+ test("applySpanMode: disabled or 0 is identity", () => {
8
+ const span = { text: TEXT, start: 6, end: 11 };
9
+ assert.deepEqual(applySpanMode({ enabled: false, ...span }), { text: TEXT });
10
+ assert.deepEqual(applySpanMode({ enabled: 0, ...span }), { text: TEXT });
11
+ assert.deepEqual(applySpanMode(span), { text: TEXT });
12
+ });
13
+
14
+ test("applySpanMode: enabled slices half-open [start, end)", () => {
15
+ assert.deepEqual(applySpanMode({ enabled: true, text: TEXT, start: 6, end: 11 }), {
16
+ text: "moved",
17
+ start: 6,
18
+ end: 11,
19
+ });
20
+ });
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Extraction seam for span mode (issue #2333 leftover slice).
3
+ *
4
+ * Default off. Callers pass `enabled`. This module does not touch
5
+ * extraction.ts; Phase A still gates production wiring.
6
+ */
7
+
8
+ import { parseSpanOffsets, type ParsedSpan } from "./extraction-span.js";
9
+
10
+ export function applySpanMode(opts: {
11
+ enabled?: boolean | 0 | 1;
12
+ text: string;
13
+ start: number;
14
+ end: number;
15
+ }): ParsedSpan {
16
+ return parseSpanOffsets(opts.text, { start: opts.start, end: opts.end }, opts.enabled);
17
+ }
@@ -0,0 +1,59 @@
1
+ import assert from "node:assert/strict";
2
+ import { test } from "node:test";
3
+ import { parseSpanOffsets } from "./extraction-span.js";
4
+
5
+ const TEXT = "Alice moved to Seattle";
6
+
7
+ test("parseSpanOffsets: disabled or 0 is identity", () => {
8
+ const offsets = { start: 6, end: 11 };
9
+ assert.deepEqual(parseSpanOffsets(TEXT, offsets, false), { text: TEXT });
10
+ assert.deepEqual(parseSpanOffsets(TEXT, offsets, 0), { text: TEXT });
11
+ assert.deepEqual(parseSpanOffsets(TEXT, offsets), { text: TEXT });
12
+ });
13
+
14
+ test("parseSpanOffsets: enabled slices half-open [start, end)", () => {
15
+ assert.deepEqual(parseSpanOffsets(TEXT, { start: 6, end: 11 }, true), {
16
+ text: "moved",
17
+ start: 6,
18
+ end: 11,
19
+ });
20
+ });
21
+
22
+ test("parseSpanOffsets: boundary offsets stay inside the string", () => {
23
+ assert.deepEqual(parseSpanOffsets(TEXT, { start: 0, end: TEXT.length }, true), {
24
+ text: TEXT,
25
+ start: 0,
26
+ end: TEXT.length,
27
+ });
28
+ assert.deepEqual(parseSpanOffsets(TEXT, { start: 0, end: 1 }, true), {
29
+ text: "A",
30
+ start: 0,
31
+ end: 1,
32
+ });
33
+ assert.deepEqual(parseSpanOffsets(TEXT, { start: TEXT.length - 1, end: TEXT.length }, true), {
34
+ text: "e",
35
+ start: TEXT.length - 1,
36
+ end: TEXT.length,
37
+ });
38
+ });
39
+
40
+ test("parseSpanOffsets: reversed and out-of-range offsets reject", () => {
41
+ assert.throws(() => parseSpanOffsets(TEXT, { start: 12, end: 6 }, true), /reversed|out of range|invalid span/i);
42
+ assert.throws(() => parseSpanOffsets(TEXT, { start: -1, end: 6 }, true), /out of range|invalid span/i);
43
+ assert.throws(() => parseSpanOffsets(TEXT, { start: 0, end: TEXT.length + 1 }, true), /out of range|invalid span/i);
44
+ });
45
+
46
+ test("parseSpanOffsets: empty source and empty span", () => {
47
+ assert.deepEqual(parseSpanOffsets("", { start: 0, end: 0 }, false), { text: "" });
48
+ assert.deepEqual(parseSpanOffsets("", { start: 0, end: 0 }, true), {
49
+ text: "",
50
+ start: 0,
51
+ end: 0,
52
+ });
53
+ assert.deepEqual(parseSpanOffsets(TEXT, { start: 6, end: 6 }, true), {
54
+ text: "",
55
+ start: 6,
56
+ end: 6,
57
+ });
58
+ assert.throws(() => parseSpanOffsets("", { start: 0, end: 1 }, true), /out of range|invalid span/i);
59
+ });
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Isolated span-offset parser (issue #2333 first slice).
3
+ *
4
+ * Default off. Extraction wiring waits on the Phase A bench gate.
5
+ */
6
+
7
+ export interface SpanOffsets {
8
+ start: number;
9
+ end: number;
10
+ }
11
+
12
+ export interface ParsedSpan {
13
+ text: string;
14
+ start?: number;
15
+ end?: number;
16
+ }
17
+
18
+ export function parseSpanOffsets(
19
+ text: string,
20
+ offsets: SpanOffsets,
21
+ spanModeEnabled: boolean | 0 | 1 = false,
22
+ ): ParsedSpan {
23
+ if (spanModeEnabled !== true && spanModeEnabled !== 1) {
24
+ return { text };
25
+ }
26
+
27
+ const { start, end } = offsets;
28
+ if (!Number.isInteger(start) || !Number.isInteger(end)) {
29
+ throw new RangeError("invalid span: out of range");
30
+ }
31
+ if (start > end) {
32
+ throw new RangeError("invalid span: reversed");
33
+ }
34
+ if (start < 0 || end > text.length) {
35
+ throw new RangeError("invalid span: out of range");
36
+ }
37
+
38
+ return { text: text.slice(start, end), start, end };
39
+ }
package/src/index.ts CHANGED
@@ -1458,3 +1458,4 @@ export * from "./maintenance/atomic-file.js";
1458
1458
  export * from "./eval-trajectory.js";
1459
1459
  export { MemoryControllerCoordinator, chooseAction, computeEvidenceReportHash, controllerConfigHash, evaluateActiveGates, hashControllerState, verifyEvidenceReport } from "./memory-controller.js";
1460
1460
  export type { ActiveContextAdapter, ActiveContextMessage, ActiveContextPlan, MemoryControllerActionFamily, MemoryControllerChoice, MemoryControllerConfig, MemoryControllerDeps, MemoryControllerEvent, MemoryControllerEvidence, MemoryControllerEvidenceReport, MemoryControllerExecutors, MemoryControllerMode, MemoryControllerPairedSeedEvidence, MemoryControllerReceipt, MemoryControllerRecorder, MemoryControllerReportReader, MemoryControllerRunResult, MemoryControllerState } from "./memory-controller.js";
1461
+ export * from "./recall-navigate.js";
@@ -17,6 +17,7 @@ test("isLocationDayPath matches only the top-level day-file shape", () => {
17
17
 
18
18
  test("isSearchExcludedPath keeps location day documents out of generic search and recall", () => {
19
19
  assert.equal(isSearchExcludedPath("locations/2026-08-17.md"), true);
20
+ assert.equal(isSearchExcludedPath("journal/2026-08-17.md"), true);
20
21
  assert.equal(
21
22
  isSearchExcludedPath("qmd://collection/locations/2026-08-17.md", {}, "qmd"),
22
23
  true,