@remnic/core 9.69.45 → 9.69.47

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 (603) hide show
  1. package/dist/access-admin-ops-surface.d.ts +15 -14
  2. package/dist/access-admin-ops-surface.js +40 -39
  3. package/dist/access-audit.js +2 -2
  4. package/dist/access-authorization-probe.d.ts +15 -14
  5. package/dist/access-authorization-probe.js +41 -40
  6. package/dist/access-boundary.d.ts +15 -14
  7. package/dist/access-boundary.js +40 -39
  8. package/dist/access-cli.js +110 -104
  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 +15 -14
  12. package/dist/access-extraction-force-flush.js +40 -39
  13. package/dist/access-health-types.d.ts +1 -1
  14. package/dist/access-http-briefing.d.ts +15 -14
  15. package/dist/access-http-briefing.js +41 -40
  16. package/dist/access-http-lcm-compaction.d.ts +15 -14
  17. package/dist/access-http-lifecycle-flush.d.ts +15 -14
  18. package/dist/access-http-offline-stream.d.ts +15 -14
  19. package/dist/access-http-query.d.ts +2 -2
  20. package/dist/access-http-query.js +42 -41
  21. package/dist/access-http.d.ts +16 -15
  22. package/dist/access-http.js +64 -60
  23. package/dist/access-identity-continuity-surface.d.ts +11 -11
  24. package/dist/access-identity-continuity-surface.js +40 -39
  25. package/dist/access-lcm-surface.d.ts +15 -14
  26. package/dist/access-lcm-surface.js +40 -39
  27. package/dist/access-mcp-output-schemas.js +1 -1
  28. package/dist/access-mcp-shared-context-tools.d.ts +15 -14
  29. package/dist/access-mcp.d.ts +15 -14
  30. package/dist/access-mcp.js +53 -50
  31. package/dist/access-memory-search-fanout.d.ts +2 -2
  32. package/dist/{access-namespace-preflight-DDnsN22V.d.ts → access-namespace-preflight-CetF9ziA.d.ts} +1 -1
  33. package/dist/access-namespace-preflight.d.ts +3 -3
  34. package/dist/access-namespace-preflight.js +40 -39
  35. package/dist/access-observe-transcript.d.ts +11 -11
  36. package/dist/access-observe-write-category.d.ts +3 -3
  37. package/dist/access-observe-write-surface.d.ts +15 -14
  38. package/dist/access-observe-write-surface.js +40 -39
  39. package/dist/access-offline-manifest.d.ts +11 -11
  40. package/dist/access-offline-manifest.js +2 -2
  41. package/dist/access-operations-batch.js +42 -41
  42. package/dist/access-operations.d.ts +16 -15
  43. package/dist/access-operations.js +49 -47
  44. package/dist/access-recall-concurrency.d.ts +15 -14
  45. package/dist/access-recall-concurrency.js +40 -39
  46. package/dist/access-recall-response.d.ts +15 -14
  47. package/dist/access-recall-response.js +40 -39
  48. package/dist/access-recall-surface.d.ts +15 -14
  49. package/dist/access-recall-surface.js +40 -39
  50. package/dist/access-schema.d.ts +1 -1
  51. package/dist/{access-service-CDteK_Gt.d.ts → access-service-BXYrJ3pO.d.ts} +13 -10
  52. package/dist/access-service-helpers.d.ts +15 -14
  53. package/dist/access-service.d.ts +15 -14
  54. package/dist/access-service.js +40 -39
  55. package/dist/access-surface-catalog.d.ts +15 -14
  56. package/dist/access-surface-catalog.js +48 -41
  57. package/dist/access-surface-catalog.js.map +1 -1
  58. package/dist/access-wearables-meetings-surface.d.ts +4 -4
  59. package/dist/action-confidence.d.ts +1 -1
  60. package/dist/active-memory-bridge.d.ts +1 -1
  61. package/dist/active-recall.d.ts +1 -1
  62. package/dist/active-recall.js +3 -2
  63. package/dist/active-recall.js.map +1 -1
  64. package/dist/activity/digest.d.ts +1 -1
  65. package/dist/adapters/index.js +4 -4
  66. package/dist/adapters/registry.js +2 -2
  67. package/dist/ambient-provenance.d.ts +1 -1
  68. package/dist/artifact-search.d.ts +1 -1
  69. package/dist/background-generation.d.ts +1 -1
  70. package/dist/behavior-learner.d.ts +1 -1
  71. package/dist/behavior-signals.d.ts +1 -1
  72. package/dist/bootstrap.d.ts +11 -11
  73. package/dist/briefing-window.d.ts +2 -2
  74. package/dist/briefing.d.ts +2 -2
  75. package/dist/briefing.js +13 -13
  76. package/dist/buffer-surprise-report.d.ts +1 -1
  77. package/dist/buffer-turn-helpers.d.ts +1 -1
  78. package/dist/buffer.d.ts +2 -2
  79. package/dist/buffer.js +5 -5
  80. package/dist/bulk-import/index.d.ts +3 -3
  81. package/dist/calibration.d.ts +1 -1
  82. package/dist/capabilities.d.ts +1 -1
  83. package/dist/{catalog-Dl2hYqpS.d.ts → catalog-Bns9zpl3.d.ts} +1 -1
  84. package/dist/causal-behavior.d.ts +1 -1
  85. package/dist/causal-consolidation.d.ts +1 -1
  86. package/dist/causal-consolidation.js +14 -14
  87. package/dist/causal-trajectory-graph.d.ts +1 -1
  88. package/dist/{chunk-OREGA7GY.js → chunk-2JFSQWFH.js} +5 -5
  89. package/dist/chunk-2JFSQWFH.js.map +1 -0
  90. package/dist/{chunk-C3MCMFNV.js → chunk-2QX65IEC.js} +2 -2
  91. package/dist/{chunk-HBGSZ62Z.js → chunk-3RKVSECD.js} +8 -8
  92. package/dist/{chunk-7LKXP4QG.js → chunk-44BILQ7U.js} +85 -43
  93. package/dist/chunk-44BILQ7U.js.map +1 -0
  94. package/dist/{chunk-R4HFCATE.js → chunk-4LPIVP77.js} +2 -2
  95. package/dist/{chunk-PW4HTWXL.js → chunk-55XWRL6F.js} +2 -2
  96. package/dist/{chunk-E5VOKZQV.js → chunk-5KBI2MOC.js} +1 -1
  97. package/dist/{chunk-ZQ533JDE.js → chunk-6A6HSXWV.js} +2 -2
  98. package/dist/{chunk-4HTQ76O4.js → chunk-7SJCSDQ3.js} +2 -2
  99. package/dist/{chunk-A2YN3FR4.js → chunk-7YUX52XZ.js} +3 -3
  100. package/dist/{chunk-NKDQXDFL.js → chunk-AS4YKT75.js} +36 -26
  101. package/dist/chunk-AS4YKT75.js.map +1 -0
  102. package/dist/{chunk-LQVXSRAJ.js → chunk-B4EGAHHS.js} +2 -2
  103. package/dist/{chunk-EUP4AXIW.js → chunk-B6VDWDFN.js} +2 -2
  104. package/dist/{chunk-Z5YNVWRD.js → chunk-BMENHAJL.js} +2 -2
  105. package/dist/{chunk-5ZXGH2ZL.js → chunk-BXOPUJ3W.js} +2 -2
  106. package/dist/{chunk-J6NEOCQC.js → chunk-CD7VTZIG.js} +2 -2
  107. package/dist/{chunk-EC5SVM6H.js → chunk-DE4ZGH2N.js} +2 -2
  108. package/dist/{chunk-2LRO73MN.js → chunk-DRLZB3CN.js} +2 -2
  109. package/dist/{chunk-SHEHQBCG.js → chunk-DUJYRVUD.js} +638 -45
  110. package/dist/chunk-DUJYRVUD.js.map +1 -0
  111. package/dist/{chunk-Q4MI2KCG.js → chunk-EGOWY342.js} +2 -2
  112. package/dist/chunk-EIB4FJVR.js +46 -0
  113. package/dist/chunk-EIB4FJVR.js.map +1 -0
  114. package/dist/{chunk-W44T2KHG.js → chunk-EWBDJQ5Y.js} +3 -3
  115. package/dist/{chunk-JMBTNVMW.js → chunk-FGRJJBFO.js} +2 -2
  116. package/dist/{chunk-F3TURDFG.js → chunk-FPB5LQWW.js} +4 -1
  117. package/dist/{chunk-F3TURDFG.js.map → chunk-FPB5LQWW.js.map} +1 -1
  118. package/dist/{chunk-OOBUWMPY.js → chunk-G2SJRFGP.js} +6 -6
  119. package/dist/{chunk-WGZHSQDV.js → chunk-G2XZFGYN.js} +4 -4
  120. package/dist/{chunk-JPNUKKSL.js → chunk-GGROFIYX.js} +2 -2
  121. package/dist/chunk-GXJSLNYO.js +74 -0
  122. package/dist/chunk-GXJSLNYO.js.map +1 -0
  123. package/dist/{chunk-VA5QRTZX.js → chunk-HG74GEVY.js} +2 -2
  124. package/dist/chunk-HMDYSGY6.js +54 -0
  125. package/dist/chunk-HMDYSGY6.js.map +1 -0
  126. package/dist/{chunk-WUUGE7QC.js → chunk-HS75MCQF.js} +4 -4
  127. package/dist/{chunk-DO6R3LIE.js → chunk-I6IJDTRP.js} +2 -2
  128. package/dist/{chunk-T3F2HWIG.js → chunk-IO7K7GES.js} +2 -2
  129. package/dist/{chunk-6II55MXS.js → chunk-JXLEQIJ7.js} +2 -2
  130. package/dist/{chunk-4XTSKGLX.js → chunk-JYXLW22X.js} +3 -3
  131. package/dist/chunk-LI4APB6M.js +218 -0
  132. package/dist/chunk-LI4APB6M.js.map +1 -0
  133. package/dist/{chunk-IFULZYYQ.js → chunk-LIAM7U2J.js} +2 -2
  134. package/dist/{chunk-LZAJONO5.js → chunk-LIDJWAQV.js} +2 -2
  135. package/dist/{chunk-B55FYF6F.js → chunk-LYMJ36UI.js} +2 -2
  136. package/dist/chunk-M4DB6ZNN.js +87 -0
  137. package/dist/chunk-M4DB6ZNN.js.map +1 -0
  138. package/dist/{chunk-5TKHJ5RW.js → chunk-MMQVWKFY.js} +17 -13
  139. package/dist/chunk-MMQVWKFY.js.map +1 -0
  140. package/dist/{chunk-IAT5WFEU.js → chunk-MNG536IS.js} +261 -797
  141. package/dist/chunk-MNG536IS.js.map +1 -0
  142. package/dist/{chunk-AOMUIF3R.js → chunk-MQT3WP3F.js} +2 -2
  143. package/dist/{chunk-F6AYWLRN.js → chunk-NE45P3OF.js} +2 -2
  144. package/dist/{chunk-5XTILJRI.js → chunk-NMA7RQPR.js} +2 -2
  145. package/dist/{chunk-46A4RGBC.js → chunk-OS4JVTHR.js} +3 -3
  146. package/dist/{chunk-W6YDAIVB.js → chunk-OSTXIFZW.js} +13 -2
  147. package/dist/chunk-OSTXIFZW.js.map +1 -0
  148. package/dist/chunk-P3YNEMYY.js +212 -0
  149. package/dist/chunk-P3YNEMYY.js.map +1 -0
  150. package/dist/{chunk-C3YEB7CR.js → chunk-PA67GXYJ.js} +5 -5
  151. package/dist/{chunk-NGAFYIHQ.js → chunk-PPJLJD2D.js} +2 -2
  152. package/dist/{chunk-AG6PANBG.js → chunk-PXJ6HE2W.js} +11 -11
  153. package/dist/{chunk-BOWAP64Q.js → chunk-QB4VXCFN.js} +2 -2
  154. package/dist/{chunk-L63M2PE4.js → chunk-QGAKUOKU.js} +2 -2
  155. package/dist/{chunk-T2ZNUWUY.js → chunk-QKFYJVDG.js} +2 -2
  156. package/dist/{chunk-YHSEUZV5.js → chunk-QLCMOHRE.js} +2 -2
  157. package/dist/{chunk-Q4AUIFUA.js → chunk-QMWKENNK.js} +4 -4
  158. package/dist/{chunk-UJXNBZYJ.js → chunk-R4JTUTU6.js} +12 -5
  159. package/dist/chunk-R4JTUTU6.js.map +1 -0
  160. package/dist/{chunk-TFS5FAAC.js → chunk-ROBGBT3D.js} +213 -77
  161. package/dist/chunk-ROBGBT3D.js.map +1 -0
  162. package/dist/{chunk-TNQR7N52.js → chunk-S3YM4SZQ.js} +2 -1
  163. package/dist/chunk-S3YM4SZQ.js.map +1 -0
  164. package/dist/{chunk-RW4QNB4J.js → chunk-S45INSV3.js} +3 -1
  165. package/dist/{chunk-RW4QNB4J.js.map → chunk-S45INSV3.js.map} +1 -1
  166. package/dist/{chunk-HVGCQMTQ.js → chunk-SJ7ZNUXB.js} +2 -2
  167. package/dist/{chunk-WCQ7L54B.js → chunk-SK6HEQTW.js} +2 -2
  168. package/dist/{chunk-PGAB2V53.js → chunk-SMBWBEE7.js} +2 -2
  169. package/dist/{chunk-SPN5YFXN.js → chunk-SS33RR4F.js} +8 -8
  170. package/dist/{chunk-NRFUYVW7.js → chunk-T3T5HTZZ.js} +2 -2
  171. package/dist/{chunk-KG2OOAFF.js → chunk-TQSCR5DU.js} +6 -6
  172. package/dist/{chunk-7K5Q6COX.js → chunk-TVVEYCNW.js} +4 -4
  173. package/dist/{chunk-ZLVURGAJ.js → chunk-V2XNMIAM.js} +2 -2
  174. package/dist/{chunk-AS2NOPDM.js → chunk-V7IONNTJ.js} +2 -2
  175. package/dist/{chunk-OFBJD3V5.js → chunk-VV5GCNKG.js} +2 -2
  176. package/dist/{chunk-MDYZCPNQ.js → chunk-WL3PGPGU.js} +2 -2
  177. package/dist/{chunk-66YUOI53.js → chunk-WQW6KPVC.js} +1 -1
  178. package/dist/chunk-WQW6KPVC.js.map +1 -0
  179. package/dist/{chunk-2AV75BJW.js → chunk-WVI43D54.js} +24 -1
  180. package/dist/chunk-WVI43D54.js.map +1 -0
  181. package/dist/{chunk-N6I257OM.js → chunk-WYU66IVZ.js} +3 -3
  182. package/dist/{chunk-A7GQBJP5.js → chunk-X2NFFBTO.js} +4 -4
  183. package/dist/{chunk-D3DJYGU2.js → chunk-XEHLYA5Z.js} +3 -3
  184. package/dist/{chunk-JIWZVOQM.js → chunk-XKHRNAK7.js} +2 -2
  185. package/dist/{chunk-VW5TGNJN.js → chunk-XXLH6KFO.js} +2 -2
  186. package/dist/{chunk-WMTYEQO5.js → chunk-XZUHXKM3.js} +2 -2
  187. package/dist/{chunk-K4KE5MYE.js → chunk-Y5VT7BIT.js} +2 -2
  188. package/dist/{chunk-M7ECD3KN.js → chunk-YOSLKZLZ.js} +2 -2
  189. package/dist/{chunk-K75H7FSO.js → chunk-YXWMZAAN.js} +2 -2
  190. package/dist/{chunk-DSHSQGSN.js → chunk-ZEIJQ4I3.js} +2 -2
  191. package/dist/{cli-CZDhIcxu.d.ts → cli-B8YyIrPR.d.ts} +5 -5
  192. package/dist/cli.d.ts +17 -16
  193. package/dist/cli.js +81 -76
  194. package/dist/coding/export-okf-codegraph.d.ts +1 -1
  195. package/dist/coding/export-okf-codegraph.js +12 -12
  196. package/dist/coding/pre-action-gate.d.ts +1 -1
  197. package/dist/compounding/engine.d.ts +2 -2
  198. package/dist/compounding/engine.js +13 -13
  199. package/dist/compounding/preference-consolidator.d.ts +1 -1
  200. package/dist/compression-optimizer.d.ts +1 -1
  201. package/dist/config.d.ts +1 -1
  202. package/dist/config.js +3 -2
  203. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  204. package/dist/connectors/codex-materialize-runner.js +13 -13
  205. package/dist/connectors/codex-materialize.d.ts +1 -1
  206. package/dist/connectors/index.d.ts +1 -1
  207. package/dist/connectors/index.js +13 -13
  208. package/dist/consolidation-provenance-check.d.ts +2 -2
  209. package/dist/consolidation-undo.d.ts +2 -2
  210. package/dist/contradiction/index.d.ts +4 -4
  211. package/dist/converge-config.d.ts +1 -1
  212. package/dist/convergence-refresh.d.ts +2 -2
  213. package/dist/convergence-refresh.js +15 -15
  214. package/dist/conversation-index/backend.d.ts +1 -1
  215. package/dist/conversation-index/chunker.d.ts +1 -1
  216. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  217. package/dist/conversation-index/indexer.d.ts +1 -1
  218. package/dist/conversation-index/search.d.ts +1 -1
  219. package/dist/corpus-watermark.d.ts +1 -1
  220. package/dist/corpus-watermark.js +15 -15
  221. package/dist/cross-lingual-recall.d.ts +1 -1
  222. package/dist/day-summary.d.ts +1 -1
  223. package/dist/deep-recall-http-glue.d.ts +15 -14
  224. package/dist/deep-recall-mcp-tools.d.ts +15 -14
  225. package/dist/deep-recall-policy-llm.d.ts +2 -2
  226. package/dist/deep-recall-seeds.d.ts +1 -1
  227. package/dist/deep-recall.js +2 -2
  228. package/dist/delinearize.d.ts +1 -1
  229. package/dist/dependency-propagation-config.d.ts +1 -1
  230. package/dist/{dependency-propagation-delivery-BXaUoVUf.d.ts → dependency-propagation-delivery-B-LvcDaq.d.ts} +1 -1
  231. package/dist/direct-answer-wiring.d.ts +1 -1
  232. package/dist/direct-answer.d.ts +1 -1
  233. package/dist/embedding-fallback.d.ts +1 -1
  234. package/dist/enrichment/index.d.ts +1 -1
  235. package/dist/entity-origin-fields.d.ts +1 -1
  236. package/dist/entity-retrieval.d.ts +2 -2
  237. package/dist/entity-retrieval.js +13 -13
  238. package/dist/entity-schema.d.ts +1 -1
  239. package/dist/episodic-context.d.ts +1 -1
  240. package/dist/eval-trajectory-contracts.d.ts +1 -1
  241. package/dist/eval-trajectory-store.d.ts +1 -1
  242. package/dist/eval-trajectory.d.ts +1 -1
  243. package/dist/explicit-capture.d.ts +11 -11
  244. package/dist/explicit-capture.js +2 -2
  245. package/dist/external-wiki-access.d.ts +15 -14
  246. package/dist/external-wiki-access.js +41 -40
  247. package/dist/external-wiki-collection-registration.d.ts +1 -1
  248. package/dist/external-wiki-collection.d.ts +1 -1
  249. package/dist/external-wiki-mcp-tools.d.ts +15 -14
  250. package/dist/extraction-error-classification.d.ts +1 -1
  251. package/dist/extraction-evidence-class.d.ts +142 -0
  252. package/dist/extraction-evidence-class.js +113 -0
  253. package/dist/extraction-evidence-class.js.map +1 -0
  254. package/dist/extraction-faithfulness.d.ts +2 -2
  255. package/dist/extraction-judge-telemetry.d.ts +2 -2
  256. package/dist/extraction-judge-training.d.ts +2 -2
  257. package/dist/extraction-judge.d.ts +2 -2
  258. package/dist/extraction-liveness.d.ts +1 -1
  259. package/dist/extraction-normalization.d.ts +1 -1
  260. package/dist/extraction-prompt.d.ts +1 -1
  261. package/dist/extraction-source-grounding-rules.d.ts +1 -1
  262. package/dist/extraction-source-grounding.d.ts +1 -1
  263. package/dist/extraction-source-grounding.js +2 -2
  264. package/dist/extraction-span-config.d.ts +1 -1
  265. package/dist/extraction-span-materialize.d.ts +1 -1
  266. package/dist/extraction-span-wire.d.ts +1 -1
  267. package/dist/extraction.d.ts +2 -2
  268. package/dist/extraction.js +21 -21
  269. package/dist/fallback-llm-codex-subscription.d.ts +1 -1
  270. package/dist/fallback-llm.d.ts +1 -1
  271. package/dist/{generic-recall-paths-BkVVEoeO.d.ts → generic-recall-paths-Bfc7zigS.d.ts} +1 -1
  272. package/dist/graph-append-error.d.ts +1 -1
  273. package/dist/graph-dashboard-diff.d.ts +1 -1
  274. package/dist/graph-dashboard-key.d.ts +1 -1
  275. package/dist/graph-dashboard-parser.d.ts +1 -1
  276. package/dist/graph-edge-reinforcement.d.ts +1 -1
  277. package/dist/graph-jsonl.d.ts +1 -1
  278. package/dist/graph-path-reconstruction.d.ts +1 -1
  279. package/dist/graph-path-scoring.d.ts +1 -1
  280. package/dist/graph-snapshot.d.ts +1 -1
  281. package/dist/graph.d.ts +1 -1
  282. package/dist/harmonic-retrieval.js +1 -1
  283. package/dist/importance.d.ts +1 -1
  284. package/dist/importers/index.d.ts +1 -1
  285. package/dist/importers/test-utils.d.ts +1 -1
  286. package/dist/in-flight-reads.d.ts +1 -1
  287. package/dist/{index-TBPe6NvB.d.ts → index-C7IA1DxB.d.ts} +3 -3
  288. package/dist/index.d.ts +121 -30
  289. package/dist/index.js +170 -123
  290. package/dist/intent.d.ts +1 -1
  291. package/dist/lcm/engine.d.ts +1 -1
  292. package/dist/lcm/engine.js +2 -2
  293. package/dist/lcm/index.d.ts +1 -1
  294. package/dist/lcm/index.js +4 -4
  295. package/dist/lcm/tools.d.ts +1 -1
  296. package/dist/lifecycle.d.ts +1 -1
  297. package/dist/live-connectors-runner.d.ts +1 -1
  298. package/dist/{local-llm-DdrhmecM.d.ts → local-llm-DH4tWtck.d.ts} +1 -1
  299. package/dist/local-llm-helpers.d.ts +2 -2
  300. package/dist/local-llm.d.ts +2 -2
  301. package/dist/local-llm.js +2 -2
  302. package/dist/local-model-endpoint.d.ts +1 -1
  303. package/dist/location/index.d.ts +5 -5
  304. package/dist/location/index.js +15 -15
  305. package/dist/maintenance/memory-governance.d.ts +1 -1
  306. package/dist/maintenance/memory-governance.js +13 -13
  307. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
  308. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +13 -13
  309. package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
  310. package/dist/maintenance/rebuild-memory-projection.js +14 -14
  311. package/dist/{maintenance-B813YFWJ.d.ts → maintenance-n6yeTQhR.d.ts} +4 -4
  312. package/dist/mcp-memory-inspector-app.d.ts +15 -14
  313. package/dist/mcp-read-only-tools.js +1 -1
  314. package/dist/memory-action-policy.d.ts +1 -1
  315. package/dist/memory-age.d.ts +100 -0
  316. package/dist/memory-age.js +22 -0
  317. package/dist/memory-age.js.map +1 -0
  318. package/dist/memory-browse-http-glue.d.ts +170 -0
  319. package/dist/memory-browse-http-glue.js +9 -0
  320. package/dist/memory-browse-http-glue.js.map +1 -0
  321. package/dist/memory-browse-mcp-tools.d.ts +160 -0
  322. package/dist/memory-browse-mcp-tools.js +8 -0
  323. package/dist/memory-browse-mcp-tools.js.map +1 -0
  324. package/dist/memory-browse-operations.d.ts +2 -0
  325. package/dist/memory-browse-operations.js +246 -0
  326. package/dist/memory-browse-operations.js.map +1 -0
  327. package/dist/memory-browse.d.ts +113 -0
  328. package/dist/memory-browse.js +49 -0
  329. package/dist/memory-browse.js.map +1 -0
  330. package/dist/memory-cache.d.ts +1 -1
  331. package/dist/memory-controller.d.ts +1 -1
  332. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  333. package/dist/memory-projection-store.d.ts +1 -1
  334. package/dist/memory-provenance.d.ts +1 -1
  335. package/dist/memory-snapshot.d.ts +1 -1
  336. package/dist/memory-subject-cli.d.ts +15 -14
  337. package/dist/memory-subject.d.ts +15 -14
  338. package/dist/memory-worth-outcomes.d.ts +2 -2
  339. package/dist/models-json.d.ts +1 -1
  340. package/dist/namespaces/migrate.d.ts +3 -3
  341. package/dist/namespaces/migrate.js +14 -14
  342. package/dist/namespaces/principal.d.ts +1 -1
  343. package/dist/namespaces/search.d.ts +1 -1
  344. package/dist/namespaces/search.js +6 -6
  345. package/dist/namespaces/storage.d.ts +3 -3
  346. package/dist/namespaces/storage.js +13 -13
  347. package/dist/native-knowledge.d.ts +1 -1
  348. package/dist/offline-sync-impression-drain.d.ts +1 -1
  349. package/dist/operator-doctor-corpus.d.ts +1 -1
  350. package/dist/operator-doctor-corpus.js +16 -16
  351. package/dist/operator-doctor-replica.d.ts +1 -1
  352. package/dist/operator-toolkit.d.ts +3 -3
  353. package/dist/operator-toolkit.js +23 -22
  354. package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
  355. package/dist/orchestration/maintenance.d.ts +4 -4
  356. package/dist/orchestration/maintenance.js +23 -23
  357. package/dist/{orchestrator-BCvQavIS.d.ts → orchestrator-Cirjo3ZB.d.ts} +10 -10
  358. package/dist/orchestrator.d.ts +11 -11
  359. package/dist/orchestrator.js +112 -106
  360. package/dist/patterns-cli.d.ts +1 -1
  361. package/dist/{pipeline-4lqKJZ_0.d.ts → pipeline-DK79FrgH.d.ts} +1 -1
  362. package/dist/policy-runtime.d.ts +1 -1
  363. package/dist/proactive-contention.d.ts +2 -2
  364. package/dist/provenance.d.ts +77 -2
  365. package/dist/provenance.js +7 -3
  366. package/dist/{public-http-NH72a6aa.d.ts → public-http-VB85y0ZH.d.ts} +1 -1
  367. package/dist/{qmd-DnoWaXKb.d.ts → qmd-BT0ErlRS.d.ts} +1 -1
  368. package/dist/qmd-preflight.d.ts +2 -2
  369. package/dist/qmd-recall-cache.d.ts +1 -1
  370. package/dist/qmd.d.ts +2 -2
  371. package/dist/qmd.js +4 -4
  372. package/dist/recall-concurrency-config.d.ts +1 -1
  373. package/dist/recall-disclosure-escalation.d.ts +1 -1
  374. package/dist/recall-explain-renderer.d.ts +1 -1
  375. package/dist/recall-explain-renderer.js +3 -3
  376. package/dist/recall-memory-map.d.ts +1 -1
  377. package/dist/recall-navigate-access.d.ts +1 -1
  378. package/dist/recall-navigate-access.js +2 -2
  379. package/dist/recall-navigate-disclosure.d.ts +1 -1
  380. package/dist/recall-navigate-disclosure.js +2 -2
  381. package/dist/recall-navigate.d.ts +1 -1
  382. package/dist/recall-navigate.js +2 -2
  383. package/dist/recall-navigation-http-glue.d.ts +15 -14
  384. package/dist/recall-navigation-mcp-tools.d.ts +15 -14
  385. package/dist/recall-navigation-operations.js +41 -40
  386. package/dist/recall-navigation-renderer.d.ts +1 -1
  387. package/dist/recall-navigation.d.ts +1 -1
  388. package/dist/recall-navigation.js +40 -39
  389. package/dist/recall-planner-llm.d.ts +1 -1
  390. package/dist/recall-state-view-admission.d.ts +2 -2
  391. package/dist/recall-state-view-admission.js +5 -5
  392. package/dist/recall-state-view-anchors.d.ts +1 -1
  393. package/dist/recall-state.d.ts +1 -1
  394. package/dist/recall-tag-filter.d.ts +1 -1
  395. package/dist/recall-timings.d.ts +1 -1
  396. package/dist/recall-xray-cli.d.ts +1 -1
  397. package/dist/recall-xray-cli.js +4 -4
  398. package/dist/recall-xray-renderer.d.ts +1 -1
  399. package/dist/recall-xray-renderer.js +3 -3
  400. package/dist/recall-xray.d.ts +1 -1
  401. package/dist/recall-xray.js +2 -2
  402. package/dist/reconcile/cursor.d.ts +1 -1
  403. package/dist/reconcile/manifest.d.ts +4 -1
  404. package/dist/reconcile/manifest.js +1 -1
  405. package/dist/reconcile/plan.d.ts +1 -1
  406. package/dist/replay/normalizers/chatgpt.d.ts +1 -1
  407. package/dist/replay/normalizers/claude.d.ts +1 -1
  408. package/dist/replay/normalizers/openclaw.d.ts +1 -1
  409. package/dist/replay/normalizers/shared.d.ts +1 -1
  410. package/dist/replay/runner.d.ts +1 -1
  411. package/dist/replay/types.d.ts +1 -1
  412. package/dist/replica-divergence.d.ts +1 -1
  413. package/dist/replica-peers-config.d.ts +1 -1
  414. package/dist/resolve-auth-token.d.ts +1 -1
  415. package/dist/resume-bundles.js +4 -3
  416. package/dist/retrieval-agents.d.ts +2 -2
  417. package/dist/retrieval-tiers.d.ts +1 -1
  418. package/dist/routing/engine.d.ts +1 -1
  419. package/dist/routing/store.d.ts +1 -1
  420. package/dist/salvage-envelope.d.ts +1 -1
  421. package/dist/{scope-profiles-crazXegZ.d.ts → scope-profiles-BgPQx9iE.d.ts} +1 -1
  422. package/dist/search/embed-helper.d.ts +1 -1
  423. package/dist/search/factory.d.ts +1 -1
  424. package/dist/search/factory.js +5 -5
  425. package/dist/search/index.d.ts +1 -1
  426. package/dist/search/index.js +9 -9
  427. package/dist/search/lancedb-backend.d.ts +1 -1
  428. package/dist/search/meilisearch-backend.d.ts +1 -1
  429. package/dist/search/noop-backend.d.ts +1 -1
  430. package/dist/search/orama-backend.d.ts +1 -1
  431. package/dist/search/port.d.ts +1 -1
  432. package/dist/search/remote-backend.d.ts +1 -1
  433. package/dist/{semantic-consolidation-B09JI9WM.d.ts → semantic-consolidation-BrAWKVcm.d.ts} +1 -1
  434. package/dist/semantic-consolidation.d.ts +2 -2
  435. package/dist/semantic-consolidation.js +14 -14
  436. package/dist/semantic-rule-promotion.js +13 -13
  437. package/dist/semantic-rule-verifier.d.ts +1 -1
  438. package/dist/semantic-rule-verifier.js +13 -13
  439. package/dist/{service-Echc5Xso.d.ts → service-CqHOTg87.d.ts} +2 -2
  440. package/dist/session-observer-bands.d.ts +1 -1
  441. package/dist/session-observer-state.d.ts +1 -1
  442. package/dist/shared-context/manager.d.ts +1 -1
  443. package/dist/signal.d.ts +1 -1
  444. package/dist/source-agent-qualifier.d.ts +1 -1
  445. package/dist/source-agent-qualifier.js +17 -17
  446. package/dist/standing-memory-block.d.ts +77 -0
  447. package/dist/standing-memory-block.js +40 -0
  448. package/dist/standing-memory-block.js.map +1 -0
  449. package/dist/standup/build.js +13 -13
  450. package/dist/{storage-ClkHCQSE.d.ts → storage-mD2YQ8_2.d.ts} +17 -3
  451. package/dist/storage.d.ts +2 -2
  452. package/dist/storage.js +12 -12
  453. package/dist/subject-config.d.ts +1 -1
  454. package/dist/summarizer.d.ts +1 -1
  455. package/dist/summarizer.js +3 -3
  456. package/dist/summary-snapshot.d.ts +1 -1
  457. package/dist/support-passport/index.d.ts +18 -17
  458. package/dist/support-passport/index.js +43 -42
  459. package/dist/{tagging-ksktJ60G.d.ts → tagging-CiAVA-ID.d.ts} +2 -2
  460. package/dist/temporal-supersession.d.ts +2 -2
  461. package/dist/temporal-timeline-recall.d.ts +1 -1
  462. package/dist/temporal-validity.d.ts +1 -1
  463. package/dist/threading.d.ts +1 -1
  464. package/dist/tier-migration.d.ts +2 -2
  465. package/dist/tier-routing.d.ts +1 -1
  466. package/dist/topics.d.ts +1 -1
  467. package/dist/transcript.d.ts +1 -1
  468. package/dist/transfer/export-okf.d.ts +1 -1
  469. package/dist/transfer/export-okf.js +13 -13
  470. package/dist/trust-score-stage.d.ts +1 -1
  471. package/dist/trust-score.d.ts +1 -1
  472. package/dist/{types-nmhnJpxx.d.ts → types-DgDaoY61.d.ts} +6 -0
  473. package/dist/types.d.ts +1 -1
  474. package/dist/types.js +1 -1
  475. package/dist/utility-runtime.d.ts +1 -1
  476. package/dist/verified-recall.js +13 -13
  477. package/dist/who-knows-cli.d.ts +15 -14
  478. package/dist/who-knows-cli.js +14 -14
  479. package/dist/who-knows.d.ts +15 -14
  480. package/dist/who-knows.js +13 -13
  481. package/dist/write-envelope.d.ts +1 -1
  482. package/package.json +2 -2
  483. package/src/access-boundary.ts +3 -0
  484. package/src/access-http.ts +2 -2
  485. package/src/access-mcp-output-schemas.ts +25 -0
  486. package/src/access-mcp.ts +3 -3
  487. package/src/access-operations.ts +2 -0
  488. package/src/access-service.ts +6 -1
  489. package/src/access-surface-catalog.test.ts +20 -0
  490. package/src/access-surface-catalog.ts +6 -0
  491. package/src/activity/timeline/index.ts +1 -0
  492. package/src/activity/timeline/journal-recap.test.ts +17 -0
  493. package/src/activity/timeline/journal-recap.ts +19 -6
  494. package/src/activity/timeline/recap-export-range.test.ts +289 -0
  495. package/src/activity/timeline/recap-export-range.ts +169 -0
  496. package/src/activity/timeline/recap-export.test.ts +73 -1
  497. package/src/activity/timeline/recap-export.ts +57 -4
  498. package/src/cli/memory-browse-commands.ts +77 -0
  499. package/src/cli.ts +2 -2
  500. package/src/config.ts +11 -0
  501. package/src/dedup/merge.test.ts +185 -8
  502. package/src/extraction-evidence-class.test.ts +355 -0
  503. package/src/extraction-evidence-class.ts +241 -0
  504. package/src/index.ts +1 -0
  505. package/src/mcp-read-only-tools.ts +3 -0
  506. package/src/memory-age.test.ts +106 -0
  507. package/src/memory-age.ts +196 -0
  508. package/src/memory-browse-http-glue.ts +93 -0
  509. package/src/memory-browse-mcp-tools.ts +57 -0
  510. package/src/memory-browse-operations.ts +88 -0
  511. package/src/memory-browse-surface.test.ts +500 -0
  512. package/src/memory-browse.ts +316 -0
  513. package/src/orchestration/recall-search-pipeline.test.ts +207 -1
  514. package/src/orchestration/recall-search-pipeline.ts +13 -9
  515. package/src/orchestration/semantic-merge-commit-effects.ts +31 -9
  516. package/src/orchestration/semantic-merge-persist.ts +16 -5
  517. package/src/provenance.ts +3 -3
  518. package/src/reconcile/manifest.test.ts +27 -0
  519. package/src/reconcile/manifest.ts +7 -0
  520. package/src/standing-memory-block.test.ts +262 -0
  521. package/src/standing-memory-block.ts +331 -0
  522. package/src/storage/cas-revision-host.ts +22 -0
  523. package/src/storage/cas-revision-store.test.ts +44 -1
  524. package/src/storage/cas-revision-store.ts +23 -0
  525. package/src/storage/tombstone-blocked-capture-sync.ts +26 -1
  526. package/src/storage-frontmatter-cas.test.ts +49 -1
  527. package/src/storage.ts +1 -1
  528. package/src/types.ts +6 -0
  529. package/dist/chunk-2AV75BJW.js.map +0 -1
  530. package/dist/chunk-5TKHJ5RW.js.map +0 -1
  531. package/dist/chunk-66YUOI53.js.map +0 -1
  532. package/dist/chunk-7LKXP4QG.js.map +0 -1
  533. package/dist/chunk-IAT5WFEU.js.map +0 -1
  534. package/dist/chunk-NKDQXDFL.js.map +0 -1
  535. package/dist/chunk-OREGA7GY.js.map +0 -1
  536. package/dist/chunk-SHEHQBCG.js.map +0 -1
  537. package/dist/chunk-TFS5FAAC.js.map +0 -1
  538. package/dist/chunk-TNQR7N52.js.map +0 -1
  539. package/dist/chunk-UJXNBZYJ.js.map +0 -1
  540. package/dist/chunk-W6YDAIVB.js.map +0 -1
  541. /package/dist/{chunk-C3MCMFNV.js.map → chunk-2QX65IEC.js.map} +0 -0
  542. /package/dist/{chunk-HBGSZ62Z.js.map → chunk-3RKVSECD.js.map} +0 -0
  543. /package/dist/{chunk-R4HFCATE.js.map → chunk-4LPIVP77.js.map} +0 -0
  544. /package/dist/{chunk-PW4HTWXL.js.map → chunk-55XWRL6F.js.map} +0 -0
  545. /package/dist/{chunk-E5VOKZQV.js.map → chunk-5KBI2MOC.js.map} +0 -0
  546. /package/dist/{chunk-ZQ533JDE.js.map → chunk-6A6HSXWV.js.map} +0 -0
  547. /package/dist/{chunk-4HTQ76O4.js.map → chunk-7SJCSDQ3.js.map} +0 -0
  548. /package/dist/{chunk-A2YN3FR4.js.map → chunk-7YUX52XZ.js.map} +0 -0
  549. /package/dist/{chunk-LQVXSRAJ.js.map → chunk-B4EGAHHS.js.map} +0 -0
  550. /package/dist/{chunk-EUP4AXIW.js.map → chunk-B6VDWDFN.js.map} +0 -0
  551. /package/dist/{chunk-Z5YNVWRD.js.map → chunk-BMENHAJL.js.map} +0 -0
  552. /package/dist/{chunk-5ZXGH2ZL.js.map → chunk-BXOPUJ3W.js.map} +0 -0
  553. /package/dist/{chunk-J6NEOCQC.js.map → chunk-CD7VTZIG.js.map} +0 -0
  554. /package/dist/{chunk-EC5SVM6H.js.map → chunk-DE4ZGH2N.js.map} +0 -0
  555. /package/dist/{chunk-2LRO73MN.js.map → chunk-DRLZB3CN.js.map} +0 -0
  556. /package/dist/{chunk-Q4MI2KCG.js.map → chunk-EGOWY342.js.map} +0 -0
  557. /package/dist/{chunk-W44T2KHG.js.map → chunk-EWBDJQ5Y.js.map} +0 -0
  558. /package/dist/{chunk-JMBTNVMW.js.map → chunk-FGRJJBFO.js.map} +0 -0
  559. /package/dist/{chunk-OOBUWMPY.js.map → chunk-G2SJRFGP.js.map} +0 -0
  560. /package/dist/{chunk-WGZHSQDV.js.map → chunk-G2XZFGYN.js.map} +0 -0
  561. /package/dist/{chunk-JPNUKKSL.js.map → chunk-GGROFIYX.js.map} +0 -0
  562. /package/dist/{chunk-VA5QRTZX.js.map → chunk-HG74GEVY.js.map} +0 -0
  563. /package/dist/{chunk-WUUGE7QC.js.map → chunk-HS75MCQF.js.map} +0 -0
  564. /package/dist/{chunk-DO6R3LIE.js.map → chunk-I6IJDTRP.js.map} +0 -0
  565. /package/dist/{chunk-T3F2HWIG.js.map → chunk-IO7K7GES.js.map} +0 -0
  566. /package/dist/{chunk-6II55MXS.js.map → chunk-JXLEQIJ7.js.map} +0 -0
  567. /package/dist/{chunk-4XTSKGLX.js.map → chunk-JYXLW22X.js.map} +0 -0
  568. /package/dist/{chunk-IFULZYYQ.js.map → chunk-LIAM7U2J.js.map} +0 -0
  569. /package/dist/{chunk-LZAJONO5.js.map → chunk-LIDJWAQV.js.map} +0 -0
  570. /package/dist/{chunk-B55FYF6F.js.map → chunk-LYMJ36UI.js.map} +0 -0
  571. /package/dist/{chunk-AOMUIF3R.js.map → chunk-MQT3WP3F.js.map} +0 -0
  572. /package/dist/{chunk-F6AYWLRN.js.map → chunk-NE45P3OF.js.map} +0 -0
  573. /package/dist/{chunk-5XTILJRI.js.map → chunk-NMA7RQPR.js.map} +0 -0
  574. /package/dist/{chunk-46A4RGBC.js.map → chunk-OS4JVTHR.js.map} +0 -0
  575. /package/dist/{chunk-C3YEB7CR.js.map → chunk-PA67GXYJ.js.map} +0 -0
  576. /package/dist/{chunk-NGAFYIHQ.js.map → chunk-PPJLJD2D.js.map} +0 -0
  577. /package/dist/{chunk-AG6PANBG.js.map → chunk-PXJ6HE2W.js.map} +0 -0
  578. /package/dist/{chunk-BOWAP64Q.js.map → chunk-QB4VXCFN.js.map} +0 -0
  579. /package/dist/{chunk-L63M2PE4.js.map → chunk-QGAKUOKU.js.map} +0 -0
  580. /package/dist/{chunk-T2ZNUWUY.js.map → chunk-QKFYJVDG.js.map} +0 -0
  581. /package/dist/{chunk-YHSEUZV5.js.map → chunk-QLCMOHRE.js.map} +0 -0
  582. /package/dist/{chunk-Q4AUIFUA.js.map → chunk-QMWKENNK.js.map} +0 -0
  583. /package/dist/{chunk-HVGCQMTQ.js.map → chunk-SJ7ZNUXB.js.map} +0 -0
  584. /package/dist/{chunk-WCQ7L54B.js.map → chunk-SK6HEQTW.js.map} +0 -0
  585. /package/dist/{chunk-PGAB2V53.js.map → chunk-SMBWBEE7.js.map} +0 -0
  586. /package/dist/{chunk-SPN5YFXN.js.map → chunk-SS33RR4F.js.map} +0 -0
  587. /package/dist/{chunk-NRFUYVW7.js.map → chunk-T3T5HTZZ.js.map} +0 -0
  588. /package/dist/{chunk-KG2OOAFF.js.map → chunk-TQSCR5DU.js.map} +0 -0
  589. /package/dist/{chunk-7K5Q6COX.js.map → chunk-TVVEYCNW.js.map} +0 -0
  590. /package/dist/{chunk-ZLVURGAJ.js.map → chunk-V2XNMIAM.js.map} +0 -0
  591. /package/dist/{chunk-AS2NOPDM.js.map → chunk-V7IONNTJ.js.map} +0 -0
  592. /package/dist/{chunk-OFBJD3V5.js.map → chunk-VV5GCNKG.js.map} +0 -0
  593. /package/dist/{chunk-MDYZCPNQ.js.map → chunk-WL3PGPGU.js.map} +0 -0
  594. /package/dist/{chunk-N6I257OM.js.map → chunk-WYU66IVZ.js.map} +0 -0
  595. /package/dist/{chunk-A7GQBJP5.js.map → chunk-X2NFFBTO.js.map} +0 -0
  596. /package/dist/{chunk-D3DJYGU2.js.map → chunk-XEHLYA5Z.js.map} +0 -0
  597. /package/dist/{chunk-JIWZVOQM.js.map → chunk-XKHRNAK7.js.map} +0 -0
  598. /package/dist/{chunk-VW5TGNJN.js.map → chunk-XXLH6KFO.js.map} +0 -0
  599. /package/dist/{chunk-WMTYEQO5.js.map → chunk-XZUHXKM3.js.map} +0 -0
  600. /package/dist/{chunk-K4KE5MYE.js.map → chunk-Y5VT7BIT.js.map} +0 -0
  601. /package/dist/{chunk-M7ECD3KN.js.map → chunk-YOSLKZLZ.js.map} +0 -0
  602. /package/dist/{chunk-K75H7FSO.js.map → chunk-YXWMZAAN.js.map} +0 -0
  603. /package/dist/{chunk-DSHSQGSN.js.map → chunk-ZEIJQ4I3.js.map} +0 -0
@@ -0,0 +1,355 @@
1
+ import assert from "node:assert/strict";
2
+ import { test } from "node:test";
3
+ import {
4
+ EVIDENCE_CLASSES,
5
+ applyEvidenceClassRules,
6
+ classifyEvidenceClasses,
7
+ deriveFactEvidenceClass,
8
+ deriveTurnEvidenceClass,
9
+ echoQuoteKey,
10
+ evidenceTurnInput,
11
+ type EvidenceClass,
12
+ type EvidenceClassTurnInput,
13
+ } from "./extraction-evidence-class.js";
14
+
15
+ function turn(overrides: Partial<EvidenceClassTurnInput> & Pick<EvidenceClassTurnInput, "content">): EvidenceClassTurnInput {
16
+ return { role: "assistant", ...overrides };
17
+ }
18
+
19
+ // ---------------------------------------------------------------------------
20
+ // Deterministic turn-class derivation — table-driven across all classes
21
+ // ---------------------------------------------------------------------------
22
+
23
+ const DERIVATION_TABLE: ReadonlyArray<{
24
+ label: string;
25
+ input: Partial<EvidenceClassTurnInput>;
26
+ expected: EvidenceClass;
27
+ }> = [
28
+ { label: "user role", input: { role: "user" }, expected: "user" },
29
+ { label: "user role despite stray tool flags", input: { role: "user", toolResult: true, toolCall: true }, expected: "user" },
30
+ { label: "assistant with tool result", input: { role: "assistant", toolResult: true }, expected: "tool" },
31
+ { label: "assistant with tool result outranks tool call", input: { role: "assistant", toolResult: true, toolCall: true }, expected: "tool" },
32
+ { label: "assistant with tool call only", input: { role: "assistant", toolCall: true }, expected: "action" },
33
+ { label: "assistant prose", input: { role: "assistant" }, expected: "agent" },
34
+ { label: "explicit false flags", input: { role: "assistant", toolResult: false, toolCall: false }, expected: "agent" },
35
+ ];
36
+
37
+ test("deriveTurnEvidenceClass: table-driven classes", () => {
38
+ for (const row of DERIVATION_TABLE) {
39
+ const input = turn({ content: "x", ...row.input });
40
+ assert.equal(
41
+ deriveTurnEvidenceClass(input),
42
+ row.expected,
43
+ `${row.label}: expected ${row.expected}`,
44
+ );
45
+ }
46
+ });
47
+
48
+ test("deriveTurnEvidenceClass: same input always yields the same class (determinism regression)", () => {
49
+ for (const row of DERIVATION_TABLE) {
50
+ const input = turn({ content: "x", ...row.input });
51
+ const first = deriveTurnEvidenceClass(input);
52
+ for (let i = 0; i < 50; i++) {
53
+ assert.equal(deriveTurnEvidenceClass(input), first, `${row.label}: call ${i} diverged`);
54
+ }
55
+ // A structurally identical clone must not change the class either.
56
+ const clone = turn({ content: "x", ...row.input });
57
+ assert.equal(deriveTurnEvidenceClass(clone), first, `${row.label}: clone diverged`);
58
+ }
59
+ });
60
+
61
+ test("deriveTurnEvidenceClass: unrelated fields never change the class", () => {
62
+ const base = turn({ content: "deploy finished", role: "user" });
63
+ const first = deriveTurnEvidenceClass(base);
64
+ const noisy: EvidenceClassTurnInput = {
65
+ ...base,
66
+ content: "completely different content of a different length",
67
+ };
68
+ assert.equal(deriveTurnEvidenceClass(noisy), first);
69
+ });
70
+
71
+ // ---------------------------------------------------------------------------
72
+ // Buffer-turn adapter — tool part flags map mechanically
73
+ // ---------------------------------------------------------------------------
74
+
75
+ test("evidenceTurnInput: tool_result part flags the turn as machine output", () => {
76
+ const input = evidenceTurnInput({
77
+ role: "assistant",
78
+ content: "exit 0, 3 files changed",
79
+ parts: [{ kind: "tool_result" }, { kind: "text" }],
80
+ });
81
+ assert.equal(input.toolResult, true);
82
+ assert.equal(input.toolCall, undefined);
83
+ assert.equal(deriveTurnEvidenceClass(input), "tool");
84
+ });
85
+
86
+ test("evidenceTurnInput: tool_call part flags an invocation", () => {
87
+ const input = evidenceTurnInput({
88
+ role: "assistant",
89
+ content: "running the test suite",
90
+ parts: [{ kind: "tool_call" }],
91
+ });
92
+ assert.equal(input.toolCall, true);
93
+ assert.equal(deriveTurnEvidenceClass(input), "action");
94
+ });
95
+
96
+ test("evidenceTurnInput: plain parts derive agent prose", () => {
97
+ const input = evidenceTurnInput({
98
+ role: "assistant",
99
+ content: "I think this looks fine",
100
+ parts: [{ kind: "text" }],
101
+ });
102
+ assert.equal(deriveTurnEvidenceClass(input), "agent");
103
+ });
104
+
105
+ test("evidenceTurnInput: user role passes through", () => {
106
+ const input = evidenceTurnInput({ role: "user", content: "ship it Friday" });
107
+ assert.deepEqual(input, { role: "user", content: "ship it Friday" });
108
+ assert.equal(deriveTurnEvidenceClass(input), "user");
109
+ });
110
+
111
+ // ---------------------------------------------------------------------------
112
+ // Fact-level span classification — reuses the provenance matcher
113
+ // ---------------------------------------------------------------------------
114
+
115
+ const USER_TURN = turn({ role: "user", content: "we renewed the license for 40 seats" });
116
+ const TOOL_TURN = turn({ role: "assistant", toolResult: true, content: "invoice total: 40 seats, $12,800 per year" });
117
+ const AGENT_TURN = turn({ role: "assistant", content: "the team seems happy with the current vendor" });
118
+
119
+ test("classifyEvidenceClasses: quote located in a user turn classifies user", () => {
120
+ const classes = classifyEvidenceClasses({
121
+ quote: "renewed the license",
122
+ turns: [USER_TURN, TOOL_TURN, AGENT_TURN],
123
+ });
124
+ assert.deepEqual(classes, ["user"]);
125
+ });
126
+
127
+ test("classifyEvidenceClasses: quote in tool output classifies tool", () => {
128
+ const classes = classifyEvidenceClasses({
129
+ quote: "$12,800 per year",
130
+ turns: [USER_TURN, TOOL_TURN, AGENT_TURN],
131
+ });
132
+ assert.deepEqual(classes, ["tool"]);
133
+ });
134
+
135
+ test("classifyEvidenceClasses: quote echoed in user and agent turns returns canonical order", () => {
136
+ const shared = turn({ role: "user", content: "the cache TTL is 300 seconds" });
137
+ const echo = turn({ role: "assistant", content: "as noted, the cache TTL is 300 seconds" });
138
+ const classes = classifyEvidenceClasses({ quote: "the cache TTL is 300 seconds", turns: [echo, shared] });
139
+ assert.deepEqual(classes, ["user", "agent"], "input order must not leak into output order");
140
+ });
141
+
142
+ test("classifyEvidenceClasses: leading prompt role label is stripped before matching", () => {
143
+ const classes = classifyEvidenceClasses({
144
+ quote: "[user] we renewed the license",
145
+ turns: [USER_TURN],
146
+ });
147
+ assert.deepEqual(classes, ["user"]);
148
+ });
149
+
150
+ test("classifyEvidenceClasses: whitespace and case differences still locate (shared matcher)", () => {
151
+ const classes = classifyEvidenceClasses({
152
+ quote: "Invoice Total: 40 SEATS",
153
+ turns: [TOOL_TURN],
154
+ });
155
+ assert.deepEqual(classes, ["tool"]);
156
+ });
157
+
158
+ test("classifyEvidenceClasses: no quote and unlocatable quote both yield no classes", () => {
159
+ assert.deepEqual(classifyEvidenceClasses({ quote: "", turns: [USER_TURN] }), []);
160
+ assert.deepEqual(classifyEvidenceClasses({ quote: undefined, turns: [USER_TURN] }), []);
161
+ assert.deepEqual(classifyEvidenceClasses({ quote: "never said this", turns: [USER_TURN] }), []);
162
+ });
163
+
164
+ test("classifyEvidenceClasses: determinism regression over repeated and reordered calls", () => {
165
+ const input = { quote: "the cache TTL is 300 seconds", turns: [USER_TURN, TOOL_TURN, AGENT_TURN] };
166
+ const first = classifyEvidenceClasses(input);
167
+ for (let i = 0; i < 50; i++) {
168
+ assert.deepEqual(classifyEvidenceClasses(input), first, `call ${i} diverged`);
169
+ }
170
+ const reordered = { quote: input.quote, turns: [...input.turns].reverse() };
171
+ assert.deepEqual(classifyEvidenceClasses(reordered), first, "turn order must not change the class set");
172
+ });
173
+
174
+ // ---------------------------------------------------------------------------
175
+ // Fact-level single class — strongest present license wins
176
+ // ---------------------------------------------------------------------------
177
+
178
+ test("deriveFactEvidenceClass: strongest class present wins in fixed order", () => {
179
+ assert.equal(deriveFactEvidenceClass(["user", "agent"]), "user");
180
+ assert.equal(deriveFactEvidenceClass(["tool", "agent"]), "tool");
181
+ assert.equal(deriveFactEvidenceClass(["action", "agent"]), "action");
182
+ assert.equal(deriveFactEvidenceClass(["agent"]), "agent");
183
+ });
184
+
185
+ test("deriveFactEvidenceClass: no located span means agent-asserted", () => {
186
+ assert.equal(deriveFactEvidenceClass([]), "agent");
187
+ });
188
+
189
+ test("deriveFactEvidenceClass: every class round-trips through the canonical order", () => {
190
+ const all = EVIDENCE_CLASSES.slice();
191
+ for (const cls of all) {
192
+ assert.equal(deriveFactEvidenceClass([cls, "agent"]), cls);
193
+ }
194
+ });
195
+
196
+ // ---------------------------------------------------------------------------
197
+ // Deterministic post-extraction rules — each case a smuggling attempt
198
+ // ---------------------------------------------------------------------------
199
+
200
+ test("rule: agent-asserted user decision never passes (assertion loop)", () => {
201
+ // The agent asserts the human decided something; the only surviving span is
202
+ // agent prose. This is the self-reinforcing loop the rules must break.
203
+ const findings = applyEvidenceClassRules({
204
+ content: "The user decided to migrate the database to Postgres",
205
+ category: "decision",
206
+ evidenceClasses: ["agent"],
207
+ });
208
+ assert.equal(findings.length, 1);
209
+ assert.equal(findings[0]!.rule, "user_attribution_without_user_span");
210
+ assert.equal(findings[0]!.action, "refuse");
211
+ });
212
+
213
+ test("rule: user decision backed by a user span passes the attribution gate", () => {
214
+ const findings = applyEvidenceClassRules({
215
+ content: "The user decided to migrate the database to Postgres",
216
+ category: "decision",
217
+ evidenceClasses: ["user"],
218
+ });
219
+ assert.deepEqual(findings, []);
220
+ });
221
+
222
+ test("rule: agent-own decision honestly attributed is not refused", () => {
223
+ const findings = applyEvidenceClassRules({
224
+ content: "The agent chose the conservative retry policy",
225
+ category: "decision",
226
+ subject: "agent",
227
+ evidenceClasses: ["agent"],
228
+ });
229
+ assert.deepEqual(findings, []);
230
+ });
231
+
232
+ test("rule: preference and commitment are decision-like too", () => {
233
+ for (const category of ["preference", "commitment"]) {
234
+ const findings = applyEvidenceClassRules({ content: "wants weekly digests", category, evidenceClasses: ["agent"] });
235
+ assert.equal(findings[0]?.rule, "user_attribution_without_user_span", category);
236
+ }
237
+ const factCategory = applyEvidenceClassRules({ content: "wants weekly digests", category: "fact", evidenceClasses: ["agent"] });
238
+ assert.deepEqual(factCategory, [], "plain facts are not user attributions");
239
+ });
240
+
241
+ test("rule: number without tool or action evidence is demoted", () => {
242
+ const findings = applyEvidenceClassRules({
243
+ content: "The cluster holds 5000 documents",
244
+ category: "fact",
245
+ evidenceClasses: ["agent"],
246
+ });
247
+ assert.equal(findings.length, 1);
248
+ assert.equal(findings[0]!.rule, "numeric_without_tool_evidence");
249
+ assert.equal(findings[0]!.action, "demote");
250
+ });
251
+
252
+ test("rule: number with tool evidence passes", () => {
253
+ assert.deepEqual(
254
+ applyEvidenceClassRules({ content: "The cluster holds 5000 documents", category: "fact", evidenceClasses: ["tool"] }),
255
+ [],
256
+ );
257
+ });
258
+
259
+ test("rule: number with action evidence passes", () => {
260
+ assert.deepEqual(
261
+ applyEvidenceClassRules({ content: "The cluster holds 5000 documents", category: "fact", evidenceClasses: ["action"] }),
262
+ [],
263
+ );
264
+ });
265
+
266
+ test("rule: number in a user-spanned fact still demotes — the human is not a licit number source", () => {
267
+ const findings = applyEvidenceClassRules({
268
+ content: "We bought 40 seats",
269
+ category: "fact",
270
+ evidenceClasses: ["user"],
271
+ });
272
+ assert.equal(findings[0]?.rule, "numeric_without_tool_evidence");
273
+ });
274
+
275
+ test("rule: no evidence classes at all demotes numeric content", () => {
276
+ const findings = applyEvidenceClassRules({ content: "cost is 5000", category: "fact", evidenceClasses: [] });
277
+ assert.equal(findings[0]?.rule, "numeric_without_tool_evidence");
278
+ });
279
+
280
+ test("rule: echo of existing store content is refused", () => {
281
+ const existing = new Set([echoQuoteKey("the cache TTL is 300 seconds")]);
282
+ const findings = applyEvidenceClassRules({
283
+ content: "The cache TTL is 300 seconds",
284
+ category: "fact",
285
+ evidenceClasses: ["tool"],
286
+ quoteKeys: [echoQuoteKey("the cache TTL is 300 seconds")],
287
+ existingQuoteKeys: existing,
288
+ });
289
+ assert.equal(findings.length, 1);
290
+ assert.equal(findings[0]!.rule, "echo_of_existing_content");
291
+ assert.equal(findings[0]!.action, "refuse");
292
+ });
293
+
294
+ test("rule: one fresh quote survives echo suppression", () => {
295
+ const existing = new Set([echoQuoteKey("old quote")]);
296
+ const findings = applyEvidenceClassRules({
297
+ content: "something new",
298
+ category: "fact",
299
+ evidenceClasses: ["tool"],
300
+ quoteKeys: [echoQuoteKey("old quote"), echoQuoteKey("a brand new observation")],
301
+ existingQuoteKeys: existing,
302
+ });
303
+ assert.deepEqual(findings, []);
304
+ });
305
+
306
+ test("rule: no quote keys or no index means echo rule stays silent", () => {
307
+ assert.deepEqual(
308
+ applyEvidenceClassRules({ content: "x", category: "fact", evidenceClasses: ["tool"] }),
309
+ [],
310
+ );
311
+ assert.deepEqual(
312
+ applyEvidenceClassRules({
313
+ content: "x", category: "fact", evidenceClasses: ["tool"], quoteKeys: [echoQuoteKey("q")],
314
+ }),
315
+ [],
316
+ );
317
+ });
318
+
319
+ test("rule: combined smuggling — agent-asserted decision carrying a number", () => {
320
+ const findings = applyEvidenceClassRules({
321
+ content: "The user approved a budget of 9000 for the migration",
322
+ category: "decision",
323
+ evidenceClasses: ["agent"],
324
+ });
325
+ assert.deepEqual(
326
+ findings.map((f) => f.rule),
327
+ ["numeric_without_tool_evidence", "user_attribution_without_user_span"],
328
+ );
329
+ });
330
+
331
+ test("rule: same input always yields the same findings (determinism regression)", () => {
332
+ const input = {
333
+ content: "The user approved a budget of 9000 for the migration",
334
+ category: "decision" as const,
335
+ evidenceClasses: ["agent"] as const,
336
+ quoteKeys: [echoQuoteKey("q1")] as const,
337
+ existingQuoteKeys: new Set([echoQuoteKey("q1")]),
338
+ };
339
+ const first = applyEvidenceClassRules(input);
340
+ for (let i = 0; i < 50; i++) {
341
+ assert.deepEqual(applyEvidenceClassRules(input), first, `call ${i} diverged`);
342
+ }
343
+ // Findings order is canonical (rule id order), not input-order dependent.
344
+ assert.deepEqual(first.map((f) => f.rule), [
345
+ "numeric_without_tool_evidence",
346
+ "user_attribution_without_user_span",
347
+ "echo_of_existing_content",
348
+ ]);
349
+ });
350
+
351
+ test("echoQuoteKey is case- and whitespace-insensitive and stable", () => {
352
+ assert.equal(echoQuoteKey("The Cache TTL"), echoQuoteKey("the cache ttl"));
353
+ assert.equal(echoQuoteKey("x"), echoQuoteKey("x"));
354
+ assert.equal(echoQuoteKey(" spaced out "), "spaced out");
355
+ });
@@ -0,0 +1,241 @@
1
+ /**
2
+ * Deterministic evidence provenance classes (issue #2973).
3
+ *
4
+ * Every extracted candidate is backed by spans located in buffered turns.
5
+ * The CLASS of a span — whose words it records — decides what the span can
6
+ * license (learned from distill-kura's measured self-reinforcing assertion
7
+ * loop: an agent asserts, the extractor records, the next agent reads it back
8
+ * as ground truth and repeats it with more confidence):
9
+ *
10
+ * - `user`: the human's own words. Licenses user attributions.
11
+ * - `tool`: machine output. The ONLY licit source for numbers.
12
+ * - `action`: a tool was invoked. Weaker than reading its output.
13
+ * - `agent`: agent prose. Licenses a first-person judgement, never a
14
+ * bare fact.
15
+ *
16
+ * Derivation is pure and total: turn role plus tool-part flags in, one class
17
+ * out, no clock, no randomness, no I/O. The same input always yields the
18
+ * same class. Span matching reuses `locateQuoteOffsets` /
19
+ * `stripLeadingRolePrefix` from `provenance.ts` so class location and
20
+ * provenance building can never disagree (issue #1575 pitfall: one matcher,
21
+ * not two).
22
+ *
23
+ * The post-extraction rules (`applyEvidenceClassRules`) are deterministic
24
+ * string/flag checks — no LLM — designed to run before the judge. Each
25
+ * returns a stable rule id for shadow-mode telemetry. Not yet wired into the
26
+ * extraction pipeline; see the issue's rollout plan.
27
+ */
28
+
29
+ import { locateQuoteOffsets, stripLeadingRolePrefix } from "./provenance.js";
30
+ import type { MemorySubject } from "./types.js";
31
+ import { collapseWhitespace } from "./whitespace.js";
32
+
33
+ export type EvidenceClass = "user" | "tool" | "action" | "agent";
34
+
35
+ /** Canonical class order: strongest license first. Fixed; never reorder. */
36
+ export const EVIDENCE_CLASSES: readonly EvidenceClass[] = ["user", "tool", "action", "agent"];
37
+
38
+ /**
39
+ * A buffered turn reduced to what class derivation needs. Callers map
40
+ * `BufferTurn`s via {@link evidenceTurnInput}; `role` and the tool flags are
41
+ * the only fields that influence the class.
42
+ */
43
+ export interface EvidenceClassTurnInput {
44
+ content: string;
45
+ role: "user" | "assistant";
46
+ /** Turn carries machine output (a tool_result part). */
47
+ toolResult?: boolean;
48
+ /** Turn records a tool invocation (a tool_call part). */
49
+ toolCall?: boolean;
50
+ }
51
+
52
+ /**
53
+ * Derive a turn's evidence class. Total and deterministic:
54
+ * - `role: "user"` → `"user"` (the human's words, regardless of stray
55
+ * part flags a connector may attach).
56
+ * - `role: "assistant"` with `toolResult` → `"tool"`; machine output
57
+ * outranks the invocation that produced it.
58
+ * - else with `toolCall` → `"action"`.
59
+ * - else → `"agent"` (agent prose — the weakest license).
60
+ */
61
+ export function deriveTurnEvidenceClass(turnInput: EvidenceClassTurnInput): EvidenceClass {
62
+ if (turnInput.role === "user") return "user";
63
+ if (turnInput.toolResult === true) return "tool";
64
+ if (turnInput.toolCall === true) return "action";
65
+ return "agent";
66
+ }
67
+
68
+ /**
69
+ * Map a buffered turn (structural subset of `BufferTurn`) to
70
+ * {@link EvidenceClassTurnInput}. Tool flags derive mechanically from part
71
+ * kinds — no content inspection, no heuristics.
72
+ */
73
+ export function evidenceTurnInput(bufferTurn: {
74
+ role: "user" | "assistant";
75
+ content: string;
76
+ parts?: ReadonlyArray<{ kind: string }>;
77
+ }): EvidenceClassTurnInput {
78
+ let toolResult = false;
79
+ let toolCall = false;
80
+ if (bufferTurn.parts) {
81
+ for (const part of bufferTurn.parts) {
82
+ if (part.kind === "tool_result") toolResult = true;
83
+ else if (part.kind === "tool_call") toolCall = true;
84
+ }
85
+ }
86
+ return {
87
+ role: bufferTurn.role,
88
+ content: bufferTurn.content,
89
+ ...(toolResult ? { toolResult: true } : {}),
90
+ ...(toolCall ? { toolCall: true } : {}),
91
+ };
92
+ }
93
+
94
+ /**
95
+ * Resolve which quote `buildFactProvenance` would search for: the raw quote
96
+ * when it matches at least one turn, else the leading prompt role label
97
+ * stripped (mirrors the raw-preferred contract in `provenance.ts`).
98
+ */
99
+ function resolveSearchableQuote(
100
+ quote: string | null | undefined,
101
+ turns: ReadonlyArray<EvidenceClassTurnInput>,
102
+ ): string {
103
+ const rawQuote = typeof quote === "string" ? quote.trim() : "";
104
+ if (rawQuote.length === 0) return "";
105
+ const stripped = stripLeadingRolePrefix(rawQuote);
106
+ if (rawQuote === stripped) return rawQuote;
107
+ const rawMatches = turns.some(
108
+ (t) => typeof t?.content === "string" && t.content.length > 0 && locateQuoteOffsets(rawQuote, t.content).matched,
109
+ );
110
+ return rawMatches ? rawQuote : stripped;
111
+ }
112
+
113
+ /**
114
+ * Classify the evidence backing a fact: the classes of every turn in which
115
+ * its quote was located, in canonical `EVIDENCE_CLASSES` order regardless of
116
+ * turn order. Deterministic — the same `(quote, turns)` pair always yields
117
+ * the same array. An absent or unlocatable quote yields `[]` (no evidence
118
+ * class; the extractor's own assertion is all that backs the fact).
119
+ */
120
+ export function classifyEvidenceClasses(input: {
121
+ quote: string | null | undefined;
122
+ turns: ReadonlyArray<EvidenceClassTurnInput>;
123
+ }): EvidenceClass[] {
124
+ const quote = resolveSearchableQuote(input.quote, input.turns);
125
+ if (quote.length === 0) return [];
126
+ const present = new Set<EvidenceClass>();
127
+ for (const turn of input.turns) {
128
+ if (!turn || typeof turn.content !== "string" || turn.content.length === 0) continue;
129
+ if (locateQuoteOffsets(quote, turn.content).matched) {
130
+ present.add(deriveTurnEvidenceClass(turn));
131
+ }
132
+ }
133
+ return EVIDENCE_CLASSES.filter((cls) => present.has(cls));
134
+ }
135
+
136
+ /**
137
+ * Collapse a fact's evidence classes to the single strongest license present.
138
+ * No located span (`[]`) collapses to `"agent"`: the fact is agent-asserted.
139
+ */
140
+ export function deriveFactEvidenceClass(classes: readonly EvidenceClass[]): EvidenceClass {
141
+ for (const cls of EVIDENCE_CLASSES) {
142
+ if (classes.includes(cls)) return cls;
143
+ }
144
+ return "agent";
145
+ }
146
+
147
+ // ---------------------------------------------------------------------------
148
+ // Deterministic post-extraction rules (no LLM; run before the judge)
149
+ // ---------------------------------------------------------------------------
150
+
151
+ export type EvidenceRuleId =
152
+ | "numeric_without_tool_evidence"
153
+ | "user_attribution_without_user_span"
154
+ | "echo_of_existing_content";
155
+
156
+ export interface EvidenceRuleFinding {
157
+ rule: EvidenceRuleId;
158
+ /** `demote` routes the fact to `pending_review`; `refuse` drops it. */
159
+ action: "demote" | "refuse";
160
+ reason: string;
161
+ }
162
+
163
+ /** Categories that attribute a choice or commitment to the modeled subject. */
164
+ const DECISION_LIKE_CATEGORIES: Record<string, true> = {
165
+ decision: true,
166
+ preference: true,
167
+ commitment: true,
168
+ };
169
+
170
+ /**
171
+ * Normalize a quote for echo comparison. Casefold plus whitespace collapse —
172
+ * the same normalization `locateQuoteOffsets` matches with, via the single
173
+ * shared normalizer in `whitespace.ts`.
174
+ */
175
+ export function echoQuoteKey(quote: string): string {
176
+ return collapseWhitespace(quote.toLowerCase());
177
+ }
178
+
179
+ /**
180
+ * Apply the three deterministic evidence rules to one extracted fact.
181
+ * Pure; findings come back in canonical rule-id order. A fact triggers:
182
+ *
183
+ * 1. `numeric_without_tool_evidence` — content carries a digit but no
184
+ * `tool`/`action` span backs it. The human and the agent are both
185
+ * illicit sources for numbers; demote to review rather than refuse
186
+ * (the number may be real — it is just unproven).
187
+ * 2. `user_attribution_without_user_span` — a decision-like fact about the
188
+ * user (absent `subject` reads as `"user"`, mirroring the promotion
189
+ * guard's fail-closed default) with no `user` span. This is the
190
+ * assertion-loop gate: an agent-asserted "the user decided X" is
191
+ * refused, never promoted to active.
192
+ * 3. `echo_of_existing_content` — every quote backing the fact already
193
+ * exists in the store index, so the "evidence" is the store reading
194
+ * itself back through a tool result. Refused: not new material.
195
+ */
196
+ export function applyEvidenceClassRules(input: {
197
+ content: string;
198
+ category?: string;
199
+ subject?: MemorySubject;
200
+ evidenceClasses?: readonly EvidenceClass[];
201
+ /** Normalized keys (`echoQuoteKey`) of the fact's surviving quotes. */
202
+ quoteKeys?: readonly string[];
203
+ /** Normalized keys of quotes already present in the content-hash index. */
204
+ existingQuoteKeys?: ReadonlySet<string>;
205
+ }): EvidenceRuleFinding[] {
206
+ const classes = input.evidenceClasses ?? [];
207
+ const findings: EvidenceRuleFinding[] = [];
208
+
209
+ if (/\d/.test(input.content) && !classes.some((c) => c === "tool" || c === "action")) {
210
+ findings.push({
211
+ rule: "numeric_without_tool_evidence",
212
+ action: "demote",
213
+ reason: "content carries a number but no tool or action evidence span backs it",
214
+ });
215
+ }
216
+
217
+ const decisionLike = input.category !== undefined && DECISION_LIKE_CATEGORIES[input.category] === true;
218
+ const subject = input.subject ?? "user";
219
+ if (decisionLike && subject === "user" && !classes.includes("user")) {
220
+ findings.push({
221
+ rule: "user_attribution_without_user_span",
222
+ action: "refuse",
223
+ reason: "decision-like fact about the user with no user-role evidence span",
224
+ });
225
+ }
226
+
227
+ const quoteKeys = input.quoteKeys ?? [];
228
+ if (
229
+ quoteKeys.length > 0
230
+ && input.existingQuoteKeys !== undefined
231
+ && quoteKeys.every((key) => input.existingQuoteKeys!.has(key))
232
+ ) {
233
+ findings.push({
234
+ rule: "echo_of_existing_content",
235
+ action: "refuse",
236
+ reason: "every evidence quote already exists in the store (echo, not new material)",
237
+ });
238
+ }
239
+
240
+ return findings;
241
+ }
package/src/index.ts CHANGED
@@ -49,6 +49,7 @@ export { searchWithGenericExclusion } from "./access-memory-search-fanout.js";
49
49
  export * from "./model-registry.js";
50
50
  export * from "./contradiction/index.js";
51
51
  export * from "./recall-state-view.js";
52
+ export * from "./standing-memory-block.js";
52
53
 
53
54
  export {
54
55
  buildEvidencePack,
@@ -30,6 +30,9 @@ export const MCP_READ_ONLY_TOOL_SUFFIXES: Readonly<Record<string, true>> = {
30
30
  deep_recall: true,
31
31
  memory_expand: true,
32
32
  memory_traverse: true,
33
+ memory_ls: true,
34
+ memory_tree: true,
35
+ memory_find: true,
33
36
  standup: true,
34
37
  action_confidence: true,
35
38
  capsule_list: true,