@remnic/core 9.65.2 → 9.65.3

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 (449) hide show
  1. package/dist/access-admin-ops-surface.d.ts +44 -44
  2. package/dist/access-admin-ops-surface.js +14 -14
  3. package/dist/access-authorization-probe.d.ts +38 -38
  4. package/dist/access-authorization-probe.js +15 -15
  5. package/dist/access-boundary.d.ts +40 -40
  6. package/dist/access-boundary.js +14 -14
  7. package/dist/access-cli.js +52 -52
  8. package/dist/access-coding-context-resolution.d.ts +3 -1
  9. package/dist/access-extraction-force-flush.d.ts +25 -25
  10. package/dist/access-extraction-force-flush.js +14 -14
  11. package/dist/access-health-types.d.ts +3 -1
  12. package/dist/access-http-lcm-compaction.d.ts +39 -39
  13. package/dist/access-http-lifecycle-flush.d.ts +39 -39
  14. package/dist/access-http-offline-stream.d.ts +25 -25
  15. package/dist/access-http-query.d.ts +4 -2
  16. package/dist/access-http-query.js +16 -16
  17. package/dist/access-http.d.ts +51 -44
  18. package/dist/access-http.js +30 -30
  19. package/dist/access-identity-continuity-surface.d.ts +12 -12
  20. package/dist/access-identity-continuity-surface.js +14 -14
  21. package/dist/access-lcm-surface.d.ts +27 -27
  22. package/dist/access-lcm-surface.js +14 -14
  23. package/dist/access-mcp-admin-tools.d.ts +9 -1
  24. package/dist/access-mcp-admin-tools.js +3 -1
  25. package/dist/access-mcp-output-schemas.js +1 -1
  26. package/dist/access-mcp.d.ts +39 -39
  27. package/dist/access-mcp.js +24 -24
  28. package/dist/access-memory-search-fanout.d.ts +4 -2
  29. package/dist/{access-namespace-preflight-Dhvcl-T0.d.ts → access-namespace-preflight-B7Usyz-K.d.ts} +1 -1
  30. package/dist/access-namespace-preflight.d.ts +5 -3
  31. package/dist/access-namespace-preflight.js +14 -14
  32. package/dist/access-observe-write-surface.d.ts +39 -39
  33. package/dist/access-observe-write-surface.js +14 -14
  34. package/dist/access-offline-manifest.d.ts +12 -12
  35. package/dist/access-operations-batch.js +18 -18
  36. package/dist/access-operations.d.ts +40 -40
  37. package/dist/access-operations.js +21 -21
  38. package/dist/access-recall-concurrency.d.ts +40 -40
  39. package/dist/access-recall-concurrency.js +14 -14
  40. package/dist/access-recall-response.d.ts +24 -24
  41. package/dist/access-recall-response.js +14 -14
  42. package/dist/access-recall-surface.d.ts +24 -24
  43. package/dist/access-recall-surface.js +14 -14
  44. package/dist/access-schema.d.ts +45 -45
  45. package/dist/{access-service-Bke1alZO.d.ts → access-service-DkaIG3n8.d.ts} +219 -75
  46. package/dist/access-service-helpers.d.ts +40 -40
  47. package/dist/access-service.d.ts +47 -47
  48. package/dist/access-service.js +14 -14
  49. package/dist/access-surface-catalog.d.ts +40 -40
  50. package/dist/access-surface-catalog.js +20 -16
  51. package/dist/access-surface-catalog.js.map +1 -1
  52. package/dist/access-wearables-meetings-surface.d.ts +5 -3
  53. package/dist/action-confidence.d.ts +3 -1
  54. package/dist/active-memory-bridge.d.ts +3 -1
  55. package/dist/active-recall.d.ts +3 -1
  56. package/dist/active-recall.js +6 -1
  57. package/dist/active-recall.js.map +1 -1
  58. package/dist/ambient-provenance.d.ts +3 -1
  59. package/dist/artifact-search.d.ts +3 -1
  60. package/dist/behavior-learner.d.ts +3 -1
  61. package/dist/behavior-signals.d.ts +3 -1
  62. package/dist/bootstrap.d.ts +12 -12
  63. package/dist/briefing-window.d.ts +4 -2
  64. package/dist/briefing.d.ts +4 -2
  65. package/dist/briefing.js +3 -3
  66. package/dist/buffer-surprise-report.d.ts +3 -1
  67. package/dist/buffer-turn-helpers.d.ts +3 -1
  68. package/dist/buffer.d.ts +4 -2
  69. package/dist/bulk-import/index.d.ts +5 -3
  70. package/dist/calibration.d.ts +3 -1
  71. package/dist/capabilities.d.ts +3 -1
  72. package/dist/{catalog-DV6qnbr7.d.ts → catalog-CX2BZEJh.d.ts} +1 -1
  73. package/dist/causal-behavior.d.ts +1 -1
  74. package/dist/causal-consolidation.d.ts +3 -1
  75. package/dist/causal-consolidation.js +7 -7
  76. package/dist/causal-trajectory-graph.d.ts +1 -1
  77. package/dist/{chunk-R7JAM2XF.js → chunk-2VXWFYJE.js} +3 -3
  78. package/dist/{chunk-UXO5IMBK.js → chunk-4XDGYCZI.js} +2 -2
  79. package/dist/{chunk-OTHZWLUD.js → chunk-57HVIG5U.js} +2 -2
  80. package/dist/{chunk-EILZG5VC.js → chunk-6TAX66IA.js} +2 -2
  81. package/dist/{chunk-NKKD4ZAU.js → chunk-6VALIZKG.js} +2 -2
  82. package/dist/{chunk-BWLRUMOG.js → chunk-76PL4XLG.js} +435 -1
  83. package/dist/chunk-76PL4XLG.js.map +1 -0
  84. package/dist/{chunk-2E36UXVW.js → chunk-7KFIMGMP.js} +2 -2
  85. package/dist/{chunk-LGO6A7GJ.js → chunk-7QOO4LGC.js} +28 -28
  86. package/dist/{chunk-TBOJ76ER.js → chunk-AB3A7EFH.js} +18 -2
  87. package/dist/{chunk-TBOJ76ER.js.map → chunk-AB3A7EFH.js.map} +1 -1
  88. package/dist/{chunk-DZUJ46DO.js → chunk-AUO2LJ3K.js} +2 -2
  89. package/dist/{chunk-ZO6AXLEH.js → chunk-AYDDB3XI.js} +2 -2
  90. package/dist/{chunk-NTWN6HB2.js → chunk-AYYGRVRP.js} +2 -2
  91. package/dist/{chunk-7YQ4IYS2.js → chunk-AZAA5DNP.js} +2 -2
  92. package/dist/{chunk-4KYOLI6M.js → chunk-BKYPJUQL.js} +120 -14
  93. package/dist/chunk-BKYPJUQL.js.map +1 -0
  94. package/dist/{chunk-Z7PBQPJ4.js → chunk-BQUEAVNW.js} +2 -2
  95. package/dist/{chunk-35NN3ZFA.js → chunk-CTVWELNK.js} +21 -3
  96. package/dist/chunk-CTVWELNK.js.map +1 -0
  97. package/dist/{chunk-5YQ63T4B.js → chunk-D27J626P.js} +2 -2
  98. package/dist/{chunk-LZH5FR2W.js → chunk-DHTQP334.js} +2 -2
  99. package/dist/{chunk-Y7DK7HHJ.js → chunk-E4MVQQVX.js} +2 -2
  100. package/dist/{chunk-JYYBA7TF.js → chunk-EIVIB73I.js} +2 -2
  101. package/dist/{chunk-S2DPMJXH.js → chunk-EV3YFLCB.js} +2 -2
  102. package/dist/{chunk-TZNQUNKL.js → chunk-FC7TIRFS.js} +15 -1
  103. package/dist/chunk-FC7TIRFS.js.map +1 -0
  104. package/dist/{chunk-3I7ASZN3.js → chunk-G57LQRP6.js} +2 -2
  105. package/dist/{chunk-UIN2BWDD.js → chunk-GN55KU2P.js} +2 -2
  106. package/dist/{chunk-PE255F4T.js → chunk-GUXS322H.js} +2 -2
  107. package/dist/{chunk-V3MXUL3D.js → chunk-H5FW4S5Q.js} +319 -643
  108. package/dist/chunk-H5FW4S5Q.js.map +1 -0
  109. package/dist/chunk-I32NKXE2.js +879 -0
  110. package/dist/chunk-I32NKXE2.js.map +1 -0
  111. package/dist/{chunk-YB42WZCY.js → chunk-IQSC3V2E.js} +2 -2
  112. package/dist/{chunk-MN4KB2A4.js → chunk-MBDJJTAT.js} +3 -3
  113. package/dist/{chunk-SQI57UCJ.js → chunk-MRTUN665.js} +2 -2
  114. package/dist/{chunk-SBDCZ2AX.js → chunk-NXKJHSDN.js} +1 -1
  115. package/dist/chunk-NXKJHSDN.js.map +1 -0
  116. package/dist/{chunk-SPUJNJJC.js → chunk-NZWEEALH.js} +2 -2
  117. package/dist/{chunk-2XDWWPTN.js → chunk-OJD4WS2E.js} +2 -2
  118. package/dist/{chunk-ZWXJBFZU.js → chunk-OLWTCWQ2.js} +8 -8
  119. package/dist/{chunk-XRYZRW54.js → chunk-P4DHENRE.js} +2 -2
  120. package/dist/{chunk-J275IYMG.js → chunk-PAYGC3BD.js} +29 -2
  121. package/dist/chunk-PAYGC3BD.js.map +1 -0
  122. package/dist/{chunk-IID2CMUU.js → chunk-PDVQ5JU3.js} +2 -2
  123. package/dist/{chunk-7BY7V4YX.js → chunk-Q4WONDMJ.js} +4 -3
  124. package/dist/{chunk-7BY7V4YX.js.map → chunk-Q4WONDMJ.js.map} +1 -1
  125. package/dist/{chunk-5NM4OH4P.js → chunk-QFMO32TO.js} +3 -3
  126. package/dist/{chunk-SIHSCCUQ.js → chunk-QXIQPCCN.js} +1 -1
  127. package/dist/{chunk-2YI72KM3.js → chunk-R47WINCY.js} +2 -2
  128. package/dist/{chunk-ZQHI2BZB.js → chunk-RK4WXUI2.js} +2 -2
  129. package/dist/{chunk-QOS5LBZN.js → chunk-S7Q5CM7E.js} +2 -2
  130. package/dist/{chunk-GDFVPUJ5.js → chunk-TDKSCV62.js} +2 -2
  131. package/dist/{chunk-OCZIYAE5.js → chunk-TYUS5TLG.js} +3 -3
  132. package/dist/{chunk-GNCCUR6K.js → chunk-URHCUXKI.js} +2 -2
  133. package/dist/{chunk-TF77C7SV.js → chunk-VA5KMSAE.js} +7 -5
  134. package/dist/chunk-VA5KMSAE.js.map +1 -0
  135. package/dist/{chunk-SB7D4BT7.js → chunk-WN5FSGLE.js} +1545 -105
  136. package/dist/chunk-WN5FSGLE.js.map +1 -0
  137. package/dist/{chunk-YLDXWCZP.js → chunk-YF6UHWOV.js} +14 -9
  138. package/dist/chunk-YF6UHWOV.js.map +1 -0
  139. package/dist/{chunk-CT56C22C.js → chunk-Z4RPXHJH.js} +4 -4
  140. package/dist/{cli-cShQ13XG.d.ts → cli-ChKeYMZv.d.ts} +5 -5
  141. package/dist/cli.d.ts +25 -25
  142. package/dist/cli.js +44 -43
  143. package/dist/coding/pre-action-gate.d.ts +2 -60
  144. package/dist/compounding/engine.d.ts +4 -2
  145. package/dist/compounding/engine.js +3 -3
  146. package/dist/compounding/preference-consolidator.d.ts +3 -1
  147. package/dist/compression-optimizer.d.ts +3 -1
  148. package/dist/config.d.ts +3 -1
  149. package/dist/config.js +6 -1
  150. package/dist/connectors/codex-materialize-runner.d.ts +3 -1
  151. package/dist/connectors/codex-materialize-runner.js +3 -3
  152. package/dist/connectors/codex-materialize.d.ts +3 -1
  153. package/dist/connectors/index.d.ts +3 -1
  154. package/dist/connectors/index.js +3 -3
  155. package/dist/consolidation-provenance-check.d.ts +4 -2
  156. package/dist/consolidation-undo.d.ts +4 -2
  157. package/dist/contradiction/index.d.ts +10 -270
  158. package/dist/contradiction/index.js +11 -6
  159. package/dist/{contradiction-review-QKJH5DKD.js → contradiction-review-WRVLRWHS.js} +6 -2
  160. package/dist/{contradiction-scan-VOTQRRSX.js → contradiction-scan-AKUWPX5N.js} +5 -3
  161. package/dist/converge-config.d.ts +3 -1
  162. package/dist/convergence-refresh.d.ts +4 -2
  163. package/dist/convergence-refresh.js +5 -5
  164. package/dist/conversation-index/backend.d.ts +3 -1
  165. package/dist/conversation-index/chunker.d.ts +3 -1
  166. package/dist/conversation-index/faiss-adapter.d.ts +3 -1
  167. package/dist/conversation-index/indexer.d.ts +3 -1
  168. package/dist/conversation-index/search.d.ts +3 -1
  169. package/dist/corpus-watermark.d.ts +3 -1
  170. package/dist/corpus-watermark.js +5 -5
  171. package/dist/cross-lingual-recall.d.ts +3 -1
  172. package/dist/day-summary.d.ts +3 -1
  173. package/dist/delinearize.d.ts +3 -1
  174. package/dist/dependency-propagation-config.d.ts +3 -1
  175. package/dist/{dependency-propagation-delivery-CsGg-VwS.d.ts → dependency-propagation-delivery-B8ZMBBCY.d.ts} +1 -1
  176. package/dist/direct-answer-wiring.d.ts +3 -1
  177. package/dist/direct-answer.d.ts +3 -1
  178. package/dist/embedding-fallback.d.ts +3 -1
  179. package/dist/enrichment/index.d.ts +3 -1
  180. package/dist/entity-origin-fields.d.ts +3 -1
  181. package/dist/entity-retrieval.d.ts +4 -2
  182. package/dist/entity-retrieval.js +3 -3
  183. package/dist/entity-schema.d.ts +3 -1
  184. package/dist/episodic-context.d.ts +3 -1
  185. package/dist/explicit-capture.d.ts +12 -12
  186. package/dist/external-wiki-access.d.ts +40 -40
  187. package/dist/external-wiki-access.js +15 -15
  188. package/dist/external-wiki-collection-registration.d.ts +3 -1
  189. package/dist/external-wiki-collection.d.ts +3 -1
  190. package/dist/external-wiki-mcp-tools.d.ts +40 -40
  191. package/dist/extraction-error-classification.d.ts +3 -1
  192. package/dist/extraction-faithfulness.d.ts +3 -1
  193. package/dist/extraction-judge-telemetry.d.ts +3 -1
  194. package/dist/extraction-judge-training.d.ts +3 -1
  195. package/dist/extraction-judge.d.ts +3 -1
  196. package/dist/extraction-liveness.d.ts +3 -1
  197. package/dist/extraction-normalization.d.ts +3 -1
  198. package/dist/extraction-prompt.d.ts +3 -1
  199. package/dist/extraction-source-grounding-rules.d.ts +3 -1
  200. package/dist/extraction-source-grounding.d.ts +3 -1
  201. package/dist/extraction.d.ts +3 -1
  202. package/dist/extraction.js +3 -3
  203. package/dist/fallback-llm.d.ts +3 -1
  204. package/dist/graph-dashboard-diff.d.ts +3 -1
  205. package/dist/graph-dashboard-key.d.ts +3 -1
  206. package/dist/graph-dashboard-parser.d.ts +3 -1
  207. package/dist/graph-edge-reinforcement.d.ts +3 -1
  208. package/dist/graph-path-reconstruction.d.ts +3 -1
  209. package/dist/graph-path-scoring.d.ts +3 -1
  210. package/dist/graph-snapshot.d.ts +3 -1
  211. package/dist/graph.d.ts +3 -1
  212. package/dist/harmonic-retrieval.js +1 -1
  213. package/dist/importance.d.ts +3 -1
  214. package/dist/importers/index.d.ts +3 -1
  215. package/dist/in-flight-reads.d.ts +3 -1
  216. package/dist/index-CexDrJzC.d.ts +284 -0
  217. package/dist/index.d.ts +251 -29
  218. package/dist/index.js +129 -75
  219. package/dist/intent.d.ts +3 -1
  220. package/dist/lcm/engine.d.ts +3 -1
  221. package/dist/lcm/index.d.ts +3 -1
  222. package/dist/lcm/tools.d.ts +3 -1
  223. package/dist/lifecycle.d.ts +3 -1
  224. package/dist/live-connectors-runner.d.ts +3 -1
  225. package/dist/local-llm.d.ts +3 -1
  226. package/dist/local-model-endpoint.d.ts +3 -1
  227. package/dist/maintenance/memory-governance.d.ts +3 -1
  228. package/dist/maintenance/memory-governance.js +3 -3
  229. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +4 -2
  230. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -3
  231. package/dist/maintenance/rebuild-memory-projection.d.ts +4 -2
  232. package/dist/maintenance/rebuild-memory-projection.js +4 -4
  233. package/dist/{maintenance-jhMpeGne.d.ts → maintenance-nkdtSrVr.d.ts} +3 -3
  234. package/dist/mcp-memory-inspector-app.d.ts +37 -37
  235. package/dist/memory-action-policy.d.ts +3 -1
  236. package/dist/memory-cache.d.ts +3 -1
  237. package/dist/memory-lifecycle-ledger-utils.d.ts +3 -1
  238. package/dist/memory-projection-store.d.ts +3 -1
  239. package/dist/memory-provenance.d.ts +3 -1
  240. package/dist/memory-snapshot.d.ts +3 -1
  241. package/dist/memory-subject-cli.d.ts +40 -40
  242. package/dist/memory-subject.d.ts +42 -42
  243. package/dist/memory-worth-outcomes.d.ts +4 -2
  244. package/dist/models-json.d.ts +3 -1
  245. package/dist/namespaces/migrate.d.ts +5 -3
  246. package/dist/namespaces/migrate.js +4 -4
  247. package/dist/namespaces/principal.d.ts +3 -1
  248. package/dist/namespaces/search.d.ts +3 -1
  249. package/dist/namespaces/storage.d.ts +5 -3
  250. package/dist/namespaces/storage.js +3 -3
  251. package/dist/native-knowledge.d.ts +3 -1
  252. package/dist/offline-sync-impression-drain.d.ts +3 -1
  253. package/dist/operator-doctor-corpus.d.ts +3 -1
  254. package/dist/operator-doctor-corpus.js +6 -6
  255. package/dist/operator-doctor-replica.d.ts +3 -1
  256. package/dist/operator-toolkit.d.ts +5 -3
  257. package/dist/operator-toolkit.js +15 -12
  258. package/dist/orchestration/compression-guideline-coordinator.d.ts +4 -2
  259. package/dist/orchestration/maintenance.d.ts +6 -4
  260. package/dist/orchestration/maintenance.js +9 -9
  261. package/dist/{orchestrator-DyGUC7re.d.ts → orchestrator-Bvq1-RQs.d.ts} +23 -9
  262. package/dist/orchestrator.d.ts +12 -12
  263. package/dist/orchestrator.js +52 -52
  264. package/dist/patterns-cli.d.ts +3 -1
  265. package/dist/{pipeline-C25Oxtp1.d.ts → pipeline-C8vfIiTX.d.ts} +1 -1
  266. package/dist/policy-runtime.d.ts +3 -1
  267. package/dist/proactive-contention.d.ts +3 -1
  268. package/dist/provenance.d.ts +3 -1
  269. package/dist/{public-http-CMe7NQzj.d.ts → public-http-Cy0aYbys.d.ts} +1 -1
  270. package/dist/{qmd-DkDVCbgF.d.ts → qmd-B9p1SZTZ.d.ts} +1 -1
  271. package/dist/qmd-preflight.d.ts +4 -2
  272. package/dist/qmd-recall-cache.d.ts +3 -1
  273. package/dist/qmd.d.ts +4 -2
  274. package/dist/recall-concurrency-config.d.ts +3 -1
  275. package/dist/recall-disclosure-escalation.d.ts +3 -1
  276. package/dist/recall-explain-renderer.d.ts +3 -1
  277. package/dist/recall-explain-renderer.js +3 -3
  278. package/dist/recall-memory-map.d.ts +3 -1
  279. package/dist/recall-planner-llm.d.ts +3 -1
  280. package/dist/recall-state.d.ts +3 -1
  281. package/dist/recall-tag-filter.d.ts +3 -1
  282. package/dist/recall-timings.d.ts +3 -1
  283. package/dist/recall-xray-cli.d.ts +3 -1
  284. package/dist/recall-xray-cli.js +4 -4
  285. package/dist/recall-xray-renderer.d.ts +3 -1
  286. package/dist/recall-xray-renderer.js +3 -3
  287. package/dist/recall-xray.d.ts +3 -1
  288. package/dist/recall-xray.js +2 -2
  289. package/dist/reconcile/cursor.d.ts +3 -1
  290. package/dist/reconcile/manifest.d.ts +3 -1
  291. package/dist/reconcile/plan.d.ts +3 -1
  292. package/dist/replay/normalizers/chatgpt.d.ts +3 -1
  293. package/dist/replay/normalizers/claude.d.ts +3 -1
  294. package/dist/replay/normalizers/openclaw.d.ts +3 -1
  295. package/dist/replay/normalizers/shared.d.ts +3 -1
  296. package/dist/replay/runner.d.ts +3 -1
  297. package/dist/replay/types.d.ts +3 -1
  298. package/dist/replica-divergence.d.ts +3 -1
  299. package/dist/replica-peers-config.d.ts +3 -1
  300. package/dist/{resolution-MFY72STR.js → resolution-4552BNRV.js} +13 -3
  301. package/dist/resolve-auth-token.d.ts +3 -1
  302. package/dist/resume-bundles.js +4 -2
  303. package/dist/retrieval-agents.d.ts +4 -2
  304. package/dist/retrieval-tiers.d.ts +3 -1
  305. package/dist/routing/engine.d.ts +3 -1
  306. package/dist/routing/store.d.ts +3 -1
  307. package/dist/salvage-envelope.d.ts +3 -1
  308. package/dist/schemas.d.ts +44 -44
  309. package/dist/{scope-profiles-B9xMoFO-.d.ts → scope-profiles-DLrRxFWR.d.ts} +1 -1
  310. package/dist/search/embed-helper.d.ts +3 -1
  311. package/dist/search/factory.d.ts +3 -1
  312. package/dist/search/index.d.ts +3 -1
  313. package/dist/search/lancedb-backend.d.ts +3 -1
  314. package/dist/search/meilisearch-backend.d.ts +3 -1
  315. package/dist/search/noop-backend.d.ts +3 -1
  316. package/dist/search/orama-backend.d.ts +3 -1
  317. package/dist/search/port.d.ts +3 -1
  318. package/dist/search/remote-backend.d.ts +3 -1
  319. package/dist/{semantic-TddhF0y7.d.ts → semantic-BalR6EXU.d.ts} +1 -1
  320. package/dist/{semantic-consolidation-C4uykW84.d.ts → semantic-consolidation-DlN6xe20.d.ts} +1 -1
  321. package/dist/semantic-consolidation.d.ts +4 -2
  322. package/dist/semantic-consolidation.js +4 -4
  323. package/dist/semantic-rule-promotion.js +3 -3
  324. package/dist/semantic-rule-verifier.d.ts +3 -1
  325. package/dist/semantic-rule-verifier.js +3 -3
  326. package/dist/{service-DCZDZNcV.d.ts → service-GkYyVfm9.d.ts} +2 -2
  327. package/dist/session-observer-bands.d.ts +3 -1
  328. package/dist/session-observer-state.d.ts +3 -1
  329. package/dist/shared-context/manager.d.ts +3 -1
  330. package/dist/signal.d.ts +3 -1
  331. package/dist/source-agent-qualifier.d.ts +3 -1
  332. package/dist/source-agent-qualifier.js +3 -3
  333. package/dist/{storage-CcKmEjL8.d.ts → storage-BIDzuKIn.d.ts} +1 -1
  334. package/dist/storage.d.ts +4 -2
  335. package/dist/storage.js +2 -2
  336. package/dist/subject-config.d.ts +3 -1
  337. package/dist/summarizer.d.ts +3 -1
  338. package/dist/summary-snapshot.d.ts +3 -1
  339. package/dist/support-passport/index.d.ts +43 -43
  340. package/dist/support-passport/index.js +17 -17
  341. package/dist/temporal-supersession.d.ts +4 -2
  342. package/dist/temporal-timeline-recall.d.ts +3 -1
  343. package/dist/temporal-validity.d.ts +3 -1
  344. package/dist/threading.d.ts +3 -1
  345. package/dist/tier-migration.d.ts +4 -2
  346. package/dist/tier-routing.d.ts +3 -1
  347. package/dist/topics.d.ts +3 -1
  348. package/dist/transcript.d.ts +3 -1
  349. package/dist/transfer/types.d.ts +20 -20
  350. package/dist/trust-score-stage.d.ts +3 -1
  351. package/dist/trust-score.d.ts +3 -1
  352. package/dist/{types-Pi0lfaEt.d.ts → types-BxAcOl5Q.d.ts} +323 -4
  353. package/dist/types.d.ts +3 -1
  354. package/dist/types.js +1 -1
  355. package/dist/utility-runtime.d.ts +3 -1
  356. package/dist/verified-recall.js +3 -3
  357. package/dist/who-knows-cli.d.ts +40 -40
  358. package/dist/who-knows-cli.js +4 -4
  359. package/dist/who-knows.d.ts +42 -42
  360. package/dist/who-knows.js +3 -3
  361. package/dist/write-envelope.d.ts +3 -1
  362. package/package.json +2 -2
  363. package/src/access-boundary.ts +4 -0
  364. package/src/access-http.ts +6 -5
  365. package/src/access-mcp-admin-tools.ts +24 -0
  366. package/src/access-mcp-output-schemas.ts +14 -0
  367. package/src/access-mcp.ts +2 -2
  368. package/src/access-operations-batch.ts +5 -0
  369. package/src/access-service.ts +27 -0
  370. package/src/access-surface-catalog.test.ts +24 -0
  371. package/src/access-surface-catalog.ts +4 -0
  372. package/src/coding/action-gate.test.ts +341 -0
  373. package/src/coding/action-gate.ts +556 -0
  374. package/src/config.ts +5 -0
  375. package/src/contradiction/contradiction-review.ts +50 -4
  376. package/src/contradiction/contradiction-scan.ts +14 -3
  377. package/src/contradiction/resolution.ts +50 -2
  378. package/src/index.ts +4 -3
  379. package/src/orchestration/recall-rerank-coordinator.ts +123 -4
  380. package/src/orchestration/recall-result-formatter.ts +6 -2
  381. package/src/orchestration/recall-search-pipeline.ts +14 -1
  382. package/src/preferences/drift-config.ts +118 -0
  383. package/src/preferences/drift-recall.ts +133 -0
  384. package/src/preferences/drift-types.ts +87 -0
  385. package/src/preferences/index.ts +12 -0
  386. package/src/preferences/preference-drift.test.ts +690 -0
  387. package/src/preferences/preference-drift.ts +724 -0
  388. package/src/review/review-deck-access.test.ts +325 -0
  389. package/src/review/review-deck-http-base.ts +133 -0
  390. package/src/review/review-deck-mutation.test.ts +417 -0
  391. package/src/review/review-deck-mutation.ts +677 -0
  392. package/src/review/review-deck-snapshot.ts +196 -0
  393. package/src/review/review-deck-surface.ts +117 -0
  394. package/src/review/review-deck.test.ts +347 -0
  395. package/src/review/review-deck.ts +311 -0
  396. package/src/storage.ts +4 -6
  397. package/src/types.ts +7 -3
  398. package/dist/chunk-35NN3ZFA.js.map +0 -1
  399. package/dist/chunk-4KYOLI6M.js.map +0 -1
  400. package/dist/chunk-BWLRUMOG.js.map +0 -1
  401. package/dist/chunk-J275IYMG.js.map +0 -1
  402. package/dist/chunk-SB7D4BT7.js.map +0 -1
  403. package/dist/chunk-SBDCZ2AX.js.map +0 -1
  404. package/dist/chunk-TF77C7SV.js.map +0 -1
  405. package/dist/chunk-TZNQUNKL.js.map +0 -1
  406. package/dist/chunk-V3MXUL3D.js.map +0 -1
  407. package/dist/chunk-XCTXS7VY.js +0 -402
  408. package/dist/chunk-XCTXS7VY.js.map +0 -1
  409. package/dist/chunk-YLDXWCZP.js.map +0 -1
  410. /package/dist/{chunk-R7JAM2XF.js.map → chunk-2VXWFYJE.js.map} +0 -0
  411. /package/dist/{chunk-UXO5IMBK.js.map → chunk-4XDGYCZI.js.map} +0 -0
  412. /package/dist/{chunk-OTHZWLUD.js.map → chunk-57HVIG5U.js.map} +0 -0
  413. /package/dist/{chunk-EILZG5VC.js.map → chunk-6TAX66IA.js.map} +0 -0
  414. /package/dist/{chunk-NKKD4ZAU.js.map → chunk-6VALIZKG.js.map} +0 -0
  415. /package/dist/{chunk-2E36UXVW.js.map → chunk-7KFIMGMP.js.map} +0 -0
  416. /package/dist/{chunk-LGO6A7GJ.js.map → chunk-7QOO4LGC.js.map} +0 -0
  417. /package/dist/{chunk-DZUJ46DO.js.map → chunk-AUO2LJ3K.js.map} +0 -0
  418. /package/dist/{chunk-ZO6AXLEH.js.map → chunk-AYDDB3XI.js.map} +0 -0
  419. /package/dist/{chunk-NTWN6HB2.js.map → chunk-AYYGRVRP.js.map} +0 -0
  420. /package/dist/{chunk-7YQ4IYS2.js.map → chunk-AZAA5DNP.js.map} +0 -0
  421. /package/dist/{chunk-Z7PBQPJ4.js.map → chunk-BQUEAVNW.js.map} +0 -0
  422. /package/dist/{chunk-5YQ63T4B.js.map → chunk-D27J626P.js.map} +0 -0
  423. /package/dist/{chunk-LZH5FR2W.js.map → chunk-DHTQP334.js.map} +0 -0
  424. /package/dist/{chunk-Y7DK7HHJ.js.map → chunk-E4MVQQVX.js.map} +0 -0
  425. /package/dist/{chunk-JYYBA7TF.js.map → chunk-EIVIB73I.js.map} +0 -0
  426. /package/dist/{chunk-S2DPMJXH.js.map → chunk-EV3YFLCB.js.map} +0 -0
  427. /package/dist/{chunk-3I7ASZN3.js.map → chunk-G57LQRP6.js.map} +0 -0
  428. /package/dist/{chunk-UIN2BWDD.js.map → chunk-GN55KU2P.js.map} +0 -0
  429. /package/dist/{chunk-PE255F4T.js.map → chunk-GUXS322H.js.map} +0 -0
  430. /package/dist/{chunk-YB42WZCY.js.map → chunk-IQSC3V2E.js.map} +0 -0
  431. /package/dist/{chunk-MN4KB2A4.js.map → chunk-MBDJJTAT.js.map} +0 -0
  432. /package/dist/{chunk-SQI57UCJ.js.map → chunk-MRTUN665.js.map} +0 -0
  433. /package/dist/{chunk-SPUJNJJC.js.map → chunk-NZWEEALH.js.map} +0 -0
  434. /package/dist/{chunk-2XDWWPTN.js.map → chunk-OJD4WS2E.js.map} +0 -0
  435. /package/dist/{chunk-ZWXJBFZU.js.map → chunk-OLWTCWQ2.js.map} +0 -0
  436. /package/dist/{chunk-XRYZRW54.js.map → chunk-P4DHENRE.js.map} +0 -0
  437. /package/dist/{chunk-IID2CMUU.js.map → chunk-PDVQ5JU3.js.map} +0 -0
  438. /package/dist/{chunk-5NM4OH4P.js.map → chunk-QFMO32TO.js.map} +0 -0
  439. /package/dist/{chunk-SIHSCCUQ.js.map → chunk-QXIQPCCN.js.map} +0 -0
  440. /package/dist/{chunk-2YI72KM3.js.map → chunk-R47WINCY.js.map} +0 -0
  441. /package/dist/{chunk-ZQHI2BZB.js.map → chunk-RK4WXUI2.js.map} +0 -0
  442. /package/dist/{chunk-QOS5LBZN.js.map → chunk-S7Q5CM7E.js.map} +0 -0
  443. /package/dist/{chunk-GDFVPUJ5.js.map → chunk-TDKSCV62.js.map} +0 -0
  444. /package/dist/{chunk-OCZIYAE5.js.map → chunk-TYUS5TLG.js.map} +0 -0
  445. /package/dist/{chunk-GNCCUR6K.js.map → chunk-URHCUXKI.js.map} +0 -0
  446. /package/dist/{chunk-CT56C22C.js.map → chunk-Z4RPXHJH.js.map} +0 -0
  447. /package/dist/{contradiction-review-QKJH5DKD.js.map → contradiction-review-WRVLRWHS.js.map} +0 -0
  448. /package/dist/{contradiction-scan-VOTQRRSX.js.map → contradiction-scan-AKUWPX5N.js.map} +0 -0
  449. /package/dist/{resolution-MFY72STR.js.map → resolution-4552BNRV.js.map} +0 -0
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-7T4TOGMS.js";
4
4
  import {
5
5
  defineOperation
6
- } from "./chunk-SB7D4BT7.js";
6
+ } from "./chunk-WN5FSGLE.js";
7
7
 
8
8
  // src/external-wiki-access.ts
9
9
  import { z } from "zod";
@@ -26,4 +26,4 @@ var externalWikiSearchOperation = defineOperation({
26
26
  export {
27
27
  externalWikiSearchOperation
28
28
  };
29
- //# sourceMappingURL=chunk-IID2CMUU.js.map
29
+ //# sourceMappingURL=chunk-PDVQ5JU3.js.map
@@ -6,7 +6,7 @@ import {
6
6
  migrateUnscopedPairsToNamespace,
7
7
  readPair,
8
8
  writePairs
9
- } from "./chunk-35NN3ZFA.js";
9
+ } from "./chunk-CTVWELNK.js";
10
10
  import {
11
11
  extractJsonCandidates
12
12
  } from "./chunk-RGMVMVMF.js";
@@ -548,6 +548,7 @@ export {
548
548
  verdictCacheSize,
549
549
  judgeContradictionPairs,
550
550
  ACTIVE_STATUSES,
551
- runContradictionScan
551
+ runContradictionScan,
552
+ resolveScanStorage
552
553
  };
553
- //# sourceMappingURL=chunk-7BY7V4YX.js.map
554
+ //# sourceMappingURL=chunk-Q4WONDMJ.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/contradiction/contradiction-judge.ts","../src/contradiction/contradiction-scan.ts"],"sourcesContent":["/**\n * Contradiction Judge — LLM-as-judge for semantic contradiction detection (issue #520).\n *\n * Pairs semantically-similar memories and classifies their relationship.\n * Reuses the extraction-judge adapter pattern but with a contradiction-specific\n * prompt and verdict taxonomy.\n *\n * Design constraints:\n * - Default verdict on any failure is \"needs-user\" (rule 48: least-privileged default).\n * - Never auto-resolve; all verdicts enter the review queue.\n * - Content-hash caching avoids redundant LLM calls across runs.\n */\n\nimport { createHash } from \"node:crypto\";\nimport { log } from \"../logger.js\";\nimport type { PluginConfig } from \"../types.js\";\nimport type { LocalLlmClient } from \"../local-llm.js\";\nimport type { FallbackLlmClient } from \"../fallback-llm.js\";\nimport { extractJsonCandidates } from \"../json-extract.js\";\n\n// ── Types ──────────────────────────────────────────────────────────────────────\n\nexport type ContradictionVerdict =\n | \"contradicts\"\n | \"independent\"\n | \"duplicates\"\n | \"needs-user\";\n\nexport interface ContradictionJudgeInput {\n /** Memory ID of the first fact. */\n memoryIdA: string;\n /** Memory ID of the second fact. */\n memoryIdB: string;\n /** Content text of the first fact. */\n textA: string;\n /** Content text of the second fact. */\n textB: string;\n /** Category of the first fact (optional context). */\n categoryA?: string;\n /** Category of the second fact (optional context). */\n categoryB?: string;\n}\n\nexport interface ContradictionJudgeResult {\n /** Memory IDs of the pair. */\n memoryIdA: string;\n memoryIdB: string;\n /** Verdict from the judge. */\n verdict: ContradictionVerdict;\n /** Human-readable rationale. */\n rationale: string;\n /** Confidence in [0, 1]. */\n confidence: number;\n}\n\nexport interface ContradictionJudgeBatchResult {\n /** Results keyed by pair key (\"idA:idB\"). */\n results: Map<string, ContradictionJudgeResult>;\n /** Number served from cache. */\n cached: number;\n /** Number produced by LLM call. */\n judged: number;\n /** Total wall-clock time in ms. */\n elapsed: number;\n}\n\n// ── Prompt ─────────────────────────────────────────────────────────────────────\n\nconst CONTRADICTION_JUDGE_PROMPT = `You are a memory contradiction classifier. You will receive pairs of stored memories and must classify their semantic relationship.\n\nFor each pair, respond with a JSON array where each element has:\n- \"pairKey\": the pairKey provided in the input\n- \"verdict\": one of \"contradicts\", \"independent\", \"duplicates\", \"needs-user\"\n- \"rationale\": one sentence explaining why\n- \"confidence\": number between 0 and 1\n\nVERDICT DEFINITIONS:\n- \"contradicts\": The two memories make claims that cannot both be true. One must be wrong or outdated.\n- \"duplicates\": The two memories convey essentially the same information (near-paraphrase).\n- \"independent\": The memories are topically similar but do not conflict or duplicate.\n- \"needs-user\": Cannot determine with sufficient confidence; requires human review.\n\nIMPORTANT:\n- Be conservative. When in doubt, prefer \"needs-user\" over a wrong classification.\n- Two memories about the same entity/topic are NOT necessarily contradictory.\n- Temporal changes (\"Joshua uses pnpm\" vs \"Joshua switched to npm\") ARE contradictions.\n- Different aspects of the same entity (\"Joshua uses pnpm\" vs \"Joshua works on Remnic\") are \"independent\".`;\n\n// ── Cache ──────────────────────────────────────────────────────────────────────\n\n/** Module-level fallback cache — only used when caller does not supply one. */\nlet defaultVerdictCache: Map<string, ContradictionJudgeResult> = new Map();\nconst CACHE_MAX = 10_000;\n\nfunction pairKey(idA: string, idB: string): string {\n const sorted = [idA, idB].sort();\n return `${sorted[0]}:${sorted[1]}`;\n}\n\nfunction contentHash(a: ContradictionJudgeInput): string {\n // Sort each side pair to be order-independent (matching pairKey behavior)\n const sides = [\n { text: a.textA.trim(), category: (a.categoryA ?? \"\").trim() },\n { text: a.textB.trim(), category: (a.categoryB ?? \"\").trim() },\n ].sort((left, right) => {\n const leftKey = JSON.stringify(left);\n const rightKey = JSON.stringify(right);\n return leftKey.localeCompare(rightKey);\n });\n const normalized = JSON.stringify(sides);\n return createHash(\"sha256\").update(normalized).digest(\"hex\").slice(0, 16);\n}\n\nexport function createVerdictCache(): Map<string, ContradictionJudgeResult> {\n return new Map();\n}\n\nexport function clearVerdictCache(): void {\n defaultVerdictCache.clear();\n}\n\nexport function verdictCacheSize(): number {\n return defaultVerdictCache.size;\n}\n\n// ── Public API ──────────────────────────────────────────────────────────────────\n\n/**\n * Judge a batch of memory pairs for contradiction.\n *\n * Uses content-hash caching to skip pairs already judged in a prior run.\n * On any LLM failure, all unresolved pairs default to \"needs-user\".\n */\nexport async function judgeContradictionPairs(\n pairs: ContradictionJudgeInput[],\n config: PluginConfig,\n localLlm: LocalLlmClient | null,\n fallbackLlm: FallbackLlmClient | null,\n cache?: Map<string, ContradictionJudgeResult>,\n): Promise<ContradictionJudgeBatchResult> {\n const startTime = Date.now();\n const results = new Map<string, ContradictionJudgeResult>();\n const activeCache = cache ?? defaultVerdictCache;\n let cached = 0;\n let judged = 0;\n\n // Partition into cached vs needs-judging\n const toJudge: ContradictionJudgeInput[] = [];\n for (const pair of pairs) {\n const key = pairKey(pair.memoryIdA, pair.memoryIdB);\n const hash = contentHash(pair);\n const cachedResult = activeCache.get(hash);\n if (cachedResult) {\n results.set(key, { ...cachedResult, memoryIdA: pair.memoryIdA, memoryIdB: pair.memoryIdB });\n cached++;\n } else {\n toJudge.push(pair);\n }\n }\n\n if (toJudge.length === 0) {\n return { results, cached, judged, elapsed: Date.now() - startTime };\n }\n\n // Build the prompt with all pairs\n const pairDescriptions = toJudge.map((p, i) => {\n const pk = pairKey(p.memoryIdA, p.memoryIdB);\n const catA = p.categoryA ? ` [${p.categoryA}]` : \"\";\n const catB = p.categoryB ? ` [${p.categoryB}]` : \"\";\n return `Pair ${i + 1} (pairKey: \"${pk}\"):${catA} \"${p.textA}\"${catB} \"${p.textB}\"`;\n });\n\n const userMessage = `Classify these ${toJudge.length} memory pair(s):\\n\\n${pairDescriptions.join(\"\\n\\n\")}`;\n\n // Try LLM call\n let llmResponse: string | null = null;\n\n if (localLlm) {\n try {\n llmResponse = await callLlm(localLlm, config, userMessage);\n } catch (err) {\n log.warn(\"[contradiction-judge] local LLM call failed: %s\", err instanceof Error ? err.message : err);\n }\n }\n\n if (!llmResponse && fallbackLlm) {\n try {\n llmResponse = await callLlm(fallbackLlm, config, userMessage);\n } catch (err) {\n log.warn(\"[contradiction-judge] fallback LLM call failed: %s\", err instanceof Error ? err.message : err);\n }\n }\n\n // Parse response or default to needs-user\n if (llmResponse) {\n const candidates = extractJsonCandidates(llmResponse);\n const parsed = parseJudgeResponse(candidates, toJudge);\n\n for (const result of parsed) {\n const key = pairKey(result.memoryIdA, result.memoryIdB);\n results.set(key, result);\n\n // Update cache\n const input = toJudge.find(\n (p) => pairKey(p.memoryIdA, p.memoryIdB) === key,\n );\n if (input) {\n const hash = contentHash(input);\n if (activeCache.size >= CACHE_MAX) {\n const firstKey = activeCache.keys().next().value;\n if (firstKey !== undefined) activeCache.delete(firstKey);\n }\n activeCache.set(hash, result);\n }\n judged++;\n }\n } else {\n // All unresolved → needs-user (rule 48)\n for (const pair of toJudge) {\n const key = pairKey(pair.memoryIdA, pair.memoryIdB);\n const result: ContradictionJudgeResult = {\n memoryIdA: pair.memoryIdA,\n memoryIdB: pair.memoryIdB,\n verdict: \"needs-user\",\n rationale: \"LLM call failed; requires manual review\",\n confidence: 0,\n };\n results.set(key, result);\n judged++;\n }\n }\n\n return { results, cached, judged, elapsed: Date.now() - startTime };\n}\n\n// ── Internals ──────────────────────────────────────────────────────────────────\n\nasync function callLlm(\n client: LocalLlmClient | FallbackLlmClient,\n config: PluginConfig,\n userMessage: string,\n): Promise<string> {\n const messages: Array<{ role: \"user\" | \"assistant\" | \"system\"; content: string }> = [\n { role: \"system\", content: CONTRADICTION_JUDGE_PROMPT },\n { role: \"user\", content: userMessage },\n ];\n if (\"chatCompletion\" in client && typeof client.chatCompletion === \"function\") {\n const result = await client.chatCompletion(messages, {\n temperature: 0.1,\n maxTokens: 4096,\n operation: \"contradiction-judge\",\n });\n return result?.content ?? \"\";\n }\n // FallbackLlmClient — try OpenAI-compatible chat completions\n if (\"complete\" in client && typeof (client as Record<string, unknown>).complete === \"function\") {\n const result = await (client as { complete: (msg: Array<{ role: string; content: string }>) => Promise<{ content: string }> }).complete(messages);\n return result.content ?? \"\";\n }\n return \"\";\n}\n\nfunction parseJudgeResponse(\n candidates: string[],\n inputs: ContradictionJudgeInput[],\n): ContradictionJudgeResult[] {\n const VALID_VERDICTS: ContradictionVerdict[] = [\"contradicts\", \"independent\", \"duplicates\", \"needs-user\"];\n let conservativeFallback: ContradictionJudgeResult[] | null = null;\n\n for (const candidate of candidates) {\n try {\n const parsed = JSON.parse(candidate);\n const items = Array.isArray(parsed) ? parsed : [parsed];\n const results: ContradictionJudgeResult[] = [];\n const matchedKeys = new Set<string>();\n\n for (const item of items) {\n if (!item || typeof item !== \"object\") continue;\n\n const verdict = typeof item.verdict === \"string\" && VALID_VERDICTS.includes(item.verdict as ContradictionVerdict)\n ? (item.verdict as ContradictionVerdict)\n : \"needs-user\";\n\n const pairKeyVal = typeof item.pairKey === \"string\" && item.pairKey.length > 0\n ? item.pairKey\n : null;\n const input = pairKeyVal\n ? inputs.find((p) => pairKey(p.memoryIdA, p.memoryIdB) === pairKeyVal)\n : null;\n\n if (!input) continue;\n\n matchedKeys.add(pairKey(input.memoryIdA, input.memoryIdB));\n\n const confidence = typeof item.confidence === \"number\"\n ? Math.min(1, Math.max(0, item.confidence))\n : 0.5;\n\n results.push({\n memoryIdA: input.memoryIdA,\n memoryIdB: input.memoryIdB,\n verdict,\n rationale: typeof item.rationale === \"string\" ? item.rationale : \"No rationale provided\",\n confidence,\n });\n }\n\n // Backfill any inputs the LLM omitted with needs-user\n for (const inp of inputs) {\n const key = pairKey(inp.memoryIdA, inp.memoryIdB);\n if (!matchedKeys.has(key)) {\n results.push({\n memoryIdA: inp.memoryIdA,\n memoryIdB: inp.memoryIdB,\n verdict: \"needs-user\",\n rationale: \"LLM response omitted this pair\",\n confidence: 0,\n });\n }\n }\n\n if (matchedKeys.size > 0) return results;\n if (results.length > 0 && conservativeFallback === null) {\n conservativeFallback = results;\n }\n } catch {\n continue;\n }\n }\n\n if (conservativeFallback !== null) return conservativeFallback;\n\n // All parse attempts failed → needs-user for every input\n return inputs.map((p) => ({\n memoryIdA: p.memoryIdA,\n memoryIdB: p.memoryIdB,\n verdict: \"needs-user\" as ContradictionVerdict,\n rationale: \"Failed to parse judge response\",\n confidence: 0,\n }));\n}\n\nexport { pairKey as _pairKey, contentHash as _contentHash };\n","/**\n * Contradiction Scan — pair generator + scan driver (issue #520).\n *\n * Nightly cron that pairs semantically-similar active memories within\n * the same namespace, sends candidate pairs to the LLM-as-judge\n * contradiction classifier, and drops contradicting pairs into a\n * review queue for user resolution.\n *\n * Pair generation (cheap pre-filter):\n * 1. Find candidate peers via embedding cosine >= similarityFloor.\n * 2. Restrict to pairs sharing at least one entityRef OR overlapping\n * topic tokens >= topicOverlapFloor.\n * 3. Skip pairs already judged independent/both-valid within cooldown.\n * 4. Cap per-run work at maxPairsPerRun.\n */\n\nimport { resolveNamespaceCapabilities } from \"../capabilities.js\";\nimport type { StorageManager } from \"../storage.js\";\nimport type { PluginConfig, MemoryFile, MemoryStatus } from \"../types.js\";\nimport type { SemanticDedupLookup } from \"../dedup/semantic.js\";\nimport { log } from \"../logger.js\";\nimport { judgeContradictionPairs, type ContradictionJudgeInput } from \"./contradiction-judge.js\";\nimport {\n writePairs,\n readPair,\n isCoolingDown,\n memoryHashesChanged,\n computeMemoryContentHash,\n computePairId,\n migrateUnscopedPairsToNamespace,\n type ContradictionPair,\n} from \"./contradiction-review.js\";\nimport type { LocalLlmClient } from \"../local-llm.js\";\nimport type { FallbackLlmClient } from \"../fallback-llm.js\";\nimport { isSupportPassportPrivateMemory } from \"../support-passport/card-projection.js\";\n\n// ── Types ──────────────────────────────────────────────────────────────────────\n\n/** The set of statuses that represent \"live\" memories eligible for scanning. */\nexport const ACTIVE_STATUSES: Set<MemoryStatus> = new Set([\"active\"]);\n\n/** High-value taxonomy buckets to scan. */\nconst SCAN_CATEGORIES = new Set([\n \"decision\",\n \"principle\",\n \"rule\",\n \"entity\",\n \"fact\",\n \"preference\",\n]);\n\nexport interface ScanResult {\n /** Total active memories scanned. */\n scanned: number;\n /** Candidate pairs generated by the pre-filter. */\n candidates: number;\n /** Pairs sent to judge. */\n judged: number;\n /** Pairs written to review queue. */\n queued: number;\n /** Pairs skipped due to cooldown. */\n cooledDown: number;\n /** Total wall-clock time in ms. */\n elapsedMs: number;\n}\n\nexport interface ScanStorageResolution {\n storage: StorageManager;\n namespace?: string;\n}\n\nexport interface ScanDependencies {\n storage: StorageManager;\n config: PluginConfig;\n memoryDir: string;\n /** Pre-built embedding lookup. When provided, used as-is for Strategy 3. */\n embeddingLookup?: SemanticDedupLookup;\n /**\n * Factory to build a namespace-scoped embedding lookup.\n * When provided, takes precedence over `embeddingLookup`.\n * The scan driver passes its own `storage` so the lookup queries the correct index.\n */\n embeddingLookupFactory?: (storage: StorageManager) => SemanticDedupLookup | undefined;\n /** Resolver for namespace-scoped storage. Required for scans when namespaces are enabled. */\n storageForNamespace?: (\n namespace: string | undefined,\n ) => StorageManager | ScanStorageResolution | Promise<StorageManager | ScanStorageResolution>;\n localLlm: LocalLlmClient | null;\n fallbackLlm: FallbackLlmClient | null;\n namespace?: string;\n}\n\n// ── Main scan driver ───────────────────────────────────────────────────────────\n\n/**\n * Run a contradiction scan over the memory corpus.\n *\n * This is the entry point called by the nightly cron and by the CLI.\n */\nexport async function runContradictionScan(deps: ScanDependencies): Promise<ScanResult> {\n const startTime = Date.now();\n const { config, memoryDir, embeddingLookup, embeddingLookupFactory, localLlm, fallbackLlm } = deps;\n const requestedNamespace = normalizeScanNamespace(deps.namespace);\n const scanConfig = config.contradictionScan;\n\n if (!scanConfig.enabled) {\n log.info(\"[contradiction-scan] disabled by config\");\n return { scanned: 0, candidates: 0, judged: 0, queued: 0, cooledDown: 0, elapsedMs: 0 };\n }\n\n const { storage: scanStorage, namespace } = await resolveScanStorage(deps, requestedNamespace);\n if (resolveNamespaceCapabilities(config).namespaces && namespace !== undefined && isDefaultNamespaceScan(config, requestedNamespace, namespace)) {\n const migrated = migrateUnscopedPairsToNamespace(memoryDir, namespace, { cooldownDays: scanConfig.cooldownDays });\n if (migrated > 0) {\n log.info(\"[contradiction-scan] migrated %d legacy unscoped review pairs to namespace %s\", migrated, namespace);\n }\n }\n\n // Prefer the factory (which uses the scan's own storage for correct namespace scoping)\n // over a pre-built lookup (which may use default-namespace storage).\n const scopedEmbeddingLookup = embeddingLookupFactory\n ? embeddingLookupFactory(scanStorage)\n : embeddingLookup;\n\n // 1. Load active memories in scan categories\n const memories = await loadEligibleMemories(scanStorage);\n log.info(\"[contradiction-scan] loaded %d eligible memories\", memories.length);\n\n if (memories.length < 2) {\n return { scanned: memories.length, candidates: 0, judged: 0, queued: 0, cooledDown: 0, elapsedMs: Date.now() - startTime };\n }\n\n // 2. Prepare exact existing-pair lookup for cooldown checking.\n // Pair IDs are deterministic, so lookup the candidate's file directly instead\n // of paging through the review queue and risking a bounded-list miss.\n const existingPairCache = new Map<string, ContradictionPair | undefined>();\n const getExistingPair = (pairId: string): ContradictionPair | undefined => {\n if (!existingPairCache.has(pairId)) {\n existingPairCache.set(pairId, readPair(memoryDir, pairId) ?? undefined);\n }\n return existingPairCache.get(pairId);\n };\n\n // 3. Generate candidate pairs\n const candidates = await generatePairs(memories, getExistingPair, scanConfig, namespace, scopedEmbeddingLookup);\n const cooledDown = candidates.skipped;\n log.info(\"[contradiction-scan] generated %d candidates (%d cooled down)\", candidates.pairs.length, cooledDown);\n\n if (candidates.pairs.length === 0) {\n return {\n scanned: memories.length,\n candidates: 0,\n judged: 0,\n queued: 0,\n cooledDown,\n elapsedMs: Date.now() - startTime,\n };\n }\n\n // 4. Build judge inputs. Candidate generation already preserves strategy\n // priority and caps work at maxPairsPerRun.\n const judgeInputs: ContradictionJudgeInput[] = candidates.pairs.map((pair) => ({\n memoryIdA: pair.idA,\n memoryIdB: pair.idB,\n textA: pair.textA,\n textB: pair.textB,\n categoryA: pair.categoryA,\n categoryB: pair.categoryB,\n }));\n\n // 6. Send to judge (per-scan cache avoids module-level singleton leak)\n const scanCache = new Map<string, import(\"./contradiction-judge.js\").ContradictionJudgeResult>();\n const judgeResult = await judgeContradictionPairs(judgeInputs, config, localLlm, fallbackLlm, scanCache);\n log.info(\"[contradiction-scan] judge completed: %d judged, %d cached in %dms\", judgeResult.judged, judgeResult.cached, judgeResult.elapsed);\n\n // 7. Write to review queue\n const queueEntries: Array<Omit<ContradictionPair, \"pairId\"> & { memoryIds: [string, string] }> = [];\n const currentMemoryHashes = memoryContentHashMap(memories);\n for (const [key, result] of judgeResult.results) {\n queueEntries.push({\n memoryIds: [result.memoryIdA, result.memoryIdB],\n verdict: result.verdict,\n rationale: result.rationale,\n confidence: result.confidence,\n detectedAt: new Date().toISOString(),\n // Set lastReviewedAt for non-actionable verdicts so cooldown prevents re-judging\n lastReviewedAt: result.verdict === \"independent\" ? new Date().toISOString() : undefined,\n memoryContentHashes: pairMemoryContentHashes(result.memoryIdA, result.memoryIdB, currentMemoryHashes),\n namespace,\n });\n }\n\n const written = writePairs(memoryDir, queueEntries, { cooldownDays: scanConfig.cooldownDays });\n const elapsed = Date.now() - startTime;\n log.info(\"[contradiction-scan] complete: %d queued in %dms\", written.length, elapsed);\n\n return {\n scanned: memories.length,\n candidates: candidates.pairs.length,\n judged: judgeResult.judged,\n queued: written.length,\n cooledDown,\n elapsedMs: elapsed,\n };\n}\n\n// ── Pair generation ────────────────────────────────────────────────────────────\n\ninterface CandidatePair {\n idA: string;\n idB: string;\n textA: string;\n textB: string;\n categoryA?: string;\n categoryB?: string;\n}\n\ninterface PairGenResult {\n pairs: CandidatePair[];\n skipped: number;\n}\n\nasync function generatePairs(\n memories: MemoryFile[],\n getExistingPair: (pairId: string) => ContradictionPair | undefined,\n scanConfig: PluginConfig[\"contradictionScan\"],\n namespace: string | undefined,\n embeddingLookup?: SemanticDedupLookup,\n): Promise<PairGenResult> {\n const pairs: CandidatePair[] = [];\n let skipped = 0;\n const seen = new Set<string>();\n const maxPairs = Math.max(0, Math.floor(scanConfig.maxPairsPerRun));\n if (maxPairs === 0) return { pairs, skipped };\n\n const orderedMemories = [...memories].sort(compareMemoryId);\n const currentMemoryHashes = memoryContentHashMap(orderedMemories);\n\n const pushCandidate = (pair: CandidatePair): void => {\n if (pairs.length < maxPairs) pairs.push(pair);\n };\n\n const hasCapacity = (): boolean => pairs.length < maxPairs;\n const isSkippedByCooldown = (existing: ContradictionPair | undefined): boolean => {\n if (!existing || !isCoolingDown(existing, scanConfig.cooldownDays)) return false;\n return !memoryHashesChanged(\"\", existing, (memoryId) => currentMemoryHashes.get(memoryId) ?? null);\n };\n\n // Build index by entityRef for fast lookup\n const byEntity = new Map<string, MemoryFile[]>();\n for (const mem of orderedMemories) {\n const entity = mem.frontmatter.entityRef;\n if (entity) {\n const existing = byEntity.get(entity) ?? [];\n existing.push(mem);\n byEntity.set(entity, existing);\n }\n }\n\n // Strategy 1: Entity-ref based pairing (high precision)\n entityPairs:\n for (const entity of [...byEntity.keys()].sort()) {\n const group = byEntity.get(entity) ?? [];\n if (group.length < 2) continue;\n for (let i = 0; i < group.length; i++) {\n for (let j = i + 1; j < group.length; j++) {\n if (!hasCapacity()) break entityPairs;\n const a = group[i];\n const b = group[j];\n const pairId = computePairId(a.frontmatter.id!, b.frontmatter.id!, namespace);\n\n if (seen.has(pairId)) continue;\n seen.add(pairId);\n\n // Check cooldown\n const existing = getExistingPair(pairId);\n if (isSkippedByCooldown(existing)) {\n skipped++;\n continue;\n }\n\n pushCandidate({\n idA: a.frontmatter.id!,\n idB: b.frontmatter.id!,\n textA: a.content,\n textB: b.content,\n categoryA: a.frontmatter.category as string | undefined,\n categoryB: b.frontmatter.category as string | undefined,\n });\n }\n }\n }\n\n // Strategy 2: Tag/topic overlap for memories without a shared entityRef\n topicPairs:\n for (let i = 0; i < orderedMemories.length; i++) {\n for (let j = i + 1; j < orderedMemories.length; j++) {\n if (!hasCapacity()) break topicPairs;\n const a = orderedMemories[i];\n const b = orderedMemories[j];\n if (shareEntityRef(a, b)) continue;\n const overlap = jaccardOverlap(\n (a.frontmatter.tags as string[]) ?? [],\n (b.frontmatter.tags as string[]) ?? [],\n );\n\n if (overlap < scanConfig.topicOverlapFloor) continue;\n\n const pairId = computePairId(a.frontmatter.id!, b.frontmatter.id!, namespace);\n if (seen.has(pairId)) continue;\n seen.add(pairId);\n\n const existing = getExistingPair(pairId);\n if (isSkippedByCooldown(existing)) {\n skipped++;\n continue;\n }\n\n pushCandidate({\n idA: a.frontmatter.id!,\n idB: b.frontmatter.id!,\n textA: a.content,\n textB: b.content,\n categoryA: a.frontmatter.category as string | undefined,\n categoryB: b.frontmatter.category as string | undefined,\n });\n }\n }\n\n // Strategy 3: Embedding cosine similarity (enforces similarityFloor config)\n if (embeddingLookup && hasCapacity()) {\n const memoryById = new Map(orderedMemories.map((m) => [m.frontmatter.id!, m]));\n embeddingPairs:\n for (const mem of orderedMemories) {\n if (!hasCapacity()) break;\n const id = mem.frontmatter.id!;\n try {\n const hits = (await embeddingLookup(mem.content, 20)).sort((a, b) =>\n b.score - a.score || a.id.localeCompare(b.id),\n );\n for (const hit of hits) {\n if (!hasCapacity()) break embeddingPairs;\n if (hit.score < scanConfig.similarityFloor) continue;\n if (hit.id === id) continue;\n const peer = memoryById.get(hit.id);\n if (!peer) continue;\n\n const pairId = computePairId(id, hit.id, namespace);\n if (seen.has(pairId)) continue;\n seen.add(pairId);\n\n const existing = getExistingPair(pairId);\n if (isSkippedByCooldown(existing)) {\n skipped++;\n continue;\n }\n\n pushCandidate({\n idA: id,\n idB: hit.id,\n textA: mem.content,\n textB: peer.content,\n categoryA: mem.frontmatter.category as string | undefined,\n categoryB: peer.frontmatter.category as string | undefined,\n });\n }\n } catch {\n // Embedding backend unavailable — skip, entity-ref/tag strategies already covered\n }\n }\n }\n\n return { pairs, skipped };\n}\n\n// ── Helpers ────────────────────────────────────────────────────────────────────\n\nfunction normalizeScanNamespace(namespace: string | undefined): string | undefined {\n const trimmed = namespace?.trim();\n return trimmed ? trimmed : undefined;\n}\n\nasync function resolveScanStorage(\n deps: ScanDependencies,\n namespace: string | undefined,\n): Promise<ScanStorageResolution> {\n if (!resolveNamespaceCapabilities(deps.config).namespaces) {\n const defaultNamespace = normalizeScanNamespace(deps.config.defaultNamespace);\n if (namespace && namespace !== defaultNamespace) {\n throw new Error(`unsupported namespace: ${namespace}`);\n }\n return { storage: deps.storage, namespace: undefined };\n }\n\n if (deps.storageForNamespace) {\n const resolved = await deps.storageForNamespace(namespace);\n if (isScanStorageResolution(resolved)) {\n return {\n storage: resolved.storage,\n namespace: normalizeScanNamespace(resolved.namespace) ?? fallbackResolvedNamespace(deps, namespace),\n };\n }\n if (!isStorageManagerLike(resolved)) {\n throw new Error(\"storageForNamespace must return a StorageManager or { storage: StorageManager, namespace?: string }\");\n }\n return {\n storage: resolved,\n namespace: fallbackResolvedNamespace(deps, namespace),\n };\n }\n\n throw new Error(\n \"contradiction scans require storageForNamespace when namespaces are enabled so callers can enforce namespace access\",\n );\n}\n\nfunction isScanStorageResolution(value: StorageManager | ScanStorageResolution): value is ScanStorageResolution {\n if (isStorageManagerLike(value)) return false;\n if (typeof value !== \"object\" || value === null) return false;\n const candidate = value as { storage?: unknown };\n return isStorageManagerLike(candidate.storage);\n}\n\nfunction isStorageManagerLike(value: unknown): value is StorageManager {\n if (typeof value !== \"object\" || value === null) return false;\n const candidate = value as { readAllMemories?: unknown };\n return typeof candidate.readAllMemories === \"function\";\n}\n\nfunction fallbackResolvedNamespace(deps: ScanDependencies, namespace: string | undefined): string | undefined {\n if (namespace) return namespace;\n return resolveNamespaceCapabilities(deps.config).namespaces ? deps.config.defaultNamespace : undefined;\n}\n\nfunction isDefaultNamespaceScan(\n config: PluginConfig,\n requestedNamespace: string | undefined,\n resolvedNamespace: string,\n): boolean {\n if (requestedNamespace === undefined) return true;\n return requestedNamespace === config.defaultNamespace || resolvedNamespace === config.defaultNamespace;\n}\n\nasync function loadEligibleMemories(storage: StorageManager): Promise<MemoryFile[]> {\n let all: MemoryFile[];\n try {\n all = await storage.readAllMemories();\n } catch {\n return [];\n }\n\n return all.filter((mem) => {\n const fm = mem.frontmatter;\n if (isSupportPassportPrivateMemory(mem)) return false;\n // Only active memories (rule 53: explicit ACTIVE_STATUSES set)\n const status = (fm.status as MemoryStatus) ?? \"active\";\n if (!ACTIVE_STATUSES.has(status)) return false;\n\n // Only scan high-value categories\n const category = fm.category as string | undefined;\n if (category && !SCAN_CATEGORIES.has(category)) return false;\n\n // Must have content\n if (!mem.content || mem.content.trim().length === 0) return false;\n\n // Must have an ID\n if (!fm.id) return false;\n\n return true;\n });\n}\n\nfunction jaccardOverlap(a: string[], b: string[]): number {\n if (a.length === 0 && b.length === 0) return 0;\n const setA = new Set(a.map((t) => t.toLowerCase()));\n const setB = new Set(b.map((t) => t.toLowerCase()));\n let intersection = 0;\n for (const item of setA) {\n if (setB.has(item)) intersection++;\n }\n const union = setA.size + setB.size - intersection;\n return union === 0 ? 0 : intersection / union;\n}\n\nfunction shareEntityRef(a: MemoryFile, b: MemoryFile): boolean {\n const entityA = a.frontmatter.entityRef?.trim();\n const entityB = b.frontmatter.entityRef?.trim();\n return Boolean(entityA && entityB && entityA === entityB);\n}\n\nfunction compareMemoryId(a: MemoryFile, b: MemoryFile): number {\n return (a.frontmatter.id ?? \"\").localeCompare(b.frontmatter.id ?? \"\");\n}\n\nfunction memoryContentHashMap(memories: MemoryFile[]): Map<string, string> {\n const hashes = new Map<string, string>();\n for (const memory of memories) {\n const id = memory.frontmatter.id;\n if (!id) continue;\n hashes.set(id, computeMemoryContentHash(memory.content, memory.frontmatter.category as string | undefined));\n }\n return hashes;\n}\n\nfunction pairMemoryContentHashes(\n memoryIdA: string,\n memoryIdB: string,\n currentMemoryHashes: Map<string, string>,\n): Record<string, string> | undefined {\n const hashA = currentMemoryHashes.get(memoryIdA);\n const hashB = currentMemoryHashes.get(memoryIdB);\n if (!hashA || !hashB) return undefined;\n return {\n [memoryIdA]: hashA,\n [memoryIdB]: hashB,\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/contradiction/contradiction-judge.ts","../src/contradiction/contradiction-scan.ts"],"sourcesContent":["/**\n * Contradiction Judge — LLM-as-judge for semantic contradiction detection (issue #520).\n *\n * Pairs semantically-similar memories and classifies their relationship.\n * Reuses the extraction-judge adapter pattern but with a contradiction-specific\n * prompt and verdict taxonomy.\n *\n * Design constraints:\n * - Default verdict on any failure is \"needs-user\" (rule 48: least-privileged default).\n * - Never auto-resolve; all verdicts enter the review queue.\n * - Content-hash caching avoids redundant LLM calls across runs.\n */\n\nimport { createHash } from \"node:crypto\";\nimport { log } from \"../logger.js\";\nimport type { PluginConfig } from \"../types.js\";\nimport type { LocalLlmClient } from \"../local-llm.js\";\nimport type { FallbackLlmClient } from \"../fallback-llm.js\";\nimport { extractJsonCandidates } from \"../json-extract.js\";\n\n// ── Types ──────────────────────────────────────────────────────────────────────\n\nexport type ContradictionVerdict =\n | \"contradicts\"\n | \"independent\"\n | \"duplicates\"\n | \"needs-user\";\n\nexport interface ContradictionJudgeInput {\n /** Memory ID of the first fact. */\n memoryIdA: string;\n /** Memory ID of the second fact. */\n memoryIdB: string;\n /** Content text of the first fact. */\n textA: string;\n /** Content text of the second fact. */\n textB: string;\n /** Category of the first fact (optional context). */\n categoryA?: string;\n /** Category of the second fact (optional context). */\n categoryB?: string;\n}\n\nexport interface ContradictionJudgeResult {\n /** Memory IDs of the pair. */\n memoryIdA: string;\n memoryIdB: string;\n /** Verdict from the judge. */\n verdict: ContradictionVerdict;\n /** Human-readable rationale. */\n rationale: string;\n /** Confidence in [0, 1]. */\n confidence: number;\n}\n\nexport interface ContradictionJudgeBatchResult {\n /** Results keyed by pair key (\"idA:idB\"). */\n results: Map<string, ContradictionJudgeResult>;\n /** Number served from cache. */\n cached: number;\n /** Number produced by LLM call. */\n judged: number;\n /** Total wall-clock time in ms. */\n elapsed: number;\n}\n\n// ── Prompt ─────────────────────────────────────────────────────────────────────\n\nconst CONTRADICTION_JUDGE_PROMPT = `You are a memory contradiction classifier. You will receive pairs of stored memories and must classify their semantic relationship.\n\nFor each pair, respond with a JSON array where each element has:\n- \"pairKey\": the pairKey provided in the input\n- \"verdict\": one of \"contradicts\", \"independent\", \"duplicates\", \"needs-user\"\n- \"rationale\": one sentence explaining why\n- \"confidence\": number between 0 and 1\n\nVERDICT DEFINITIONS:\n- \"contradicts\": The two memories make claims that cannot both be true. One must be wrong or outdated.\n- \"duplicates\": The two memories convey essentially the same information (near-paraphrase).\n- \"independent\": The memories are topically similar but do not conflict or duplicate.\n- \"needs-user\": Cannot determine with sufficient confidence; requires human review.\n\nIMPORTANT:\n- Be conservative. When in doubt, prefer \"needs-user\" over a wrong classification.\n- Two memories about the same entity/topic are NOT necessarily contradictory.\n- Temporal changes (\"Joshua uses pnpm\" vs \"Joshua switched to npm\") ARE contradictions.\n- Different aspects of the same entity (\"Joshua uses pnpm\" vs \"Joshua works on Remnic\") are \"independent\".`;\n\n// ── Cache ──────────────────────────────────────────────────────────────────────\n\n/** Module-level fallback cache — only used when caller does not supply one. */\nlet defaultVerdictCache: Map<string, ContradictionJudgeResult> = new Map();\nconst CACHE_MAX = 10_000;\n\nfunction pairKey(idA: string, idB: string): string {\n const sorted = [idA, idB].sort();\n return `${sorted[0]}:${sorted[1]}`;\n}\n\nfunction contentHash(a: ContradictionJudgeInput): string {\n // Sort each side pair to be order-independent (matching pairKey behavior)\n const sides = [\n { text: a.textA.trim(), category: (a.categoryA ?? \"\").trim() },\n { text: a.textB.trim(), category: (a.categoryB ?? \"\").trim() },\n ].sort((left, right) => {\n const leftKey = JSON.stringify(left);\n const rightKey = JSON.stringify(right);\n return leftKey.localeCompare(rightKey);\n });\n const normalized = JSON.stringify(sides);\n return createHash(\"sha256\").update(normalized).digest(\"hex\").slice(0, 16);\n}\n\nexport function createVerdictCache(): Map<string, ContradictionJudgeResult> {\n return new Map();\n}\n\nexport function clearVerdictCache(): void {\n defaultVerdictCache.clear();\n}\n\nexport function verdictCacheSize(): number {\n return defaultVerdictCache.size;\n}\n\n// ── Public API ──────────────────────────────────────────────────────────────────\n\n/**\n * Judge a batch of memory pairs for contradiction.\n *\n * Uses content-hash caching to skip pairs already judged in a prior run.\n * On any LLM failure, all unresolved pairs default to \"needs-user\".\n */\nexport async function judgeContradictionPairs(\n pairs: ContradictionJudgeInput[],\n config: PluginConfig,\n localLlm: LocalLlmClient | null,\n fallbackLlm: FallbackLlmClient | null,\n cache?: Map<string, ContradictionJudgeResult>,\n): Promise<ContradictionJudgeBatchResult> {\n const startTime = Date.now();\n const results = new Map<string, ContradictionJudgeResult>();\n const activeCache = cache ?? defaultVerdictCache;\n let cached = 0;\n let judged = 0;\n\n // Partition into cached vs needs-judging\n const toJudge: ContradictionJudgeInput[] = [];\n for (const pair of pairs) {\n const key = pairKey(pair.memoryIdA, pair.memoryIdB);\n const hash = contentHash(pair);\n const cachedResult = activeCache.get(hash);\n if (cachedResult) {\n results.set(key, { ...cachedResult, memoryIdA: pair.memoryIdA, memoryIdB: pair.memoryIdB });\n cached++;\n } else {\n toJudge.push(pair);\n }\n }\n\n if (toJudge.length === 0) {\n return { results, cached, judged, elapsed: Date.now() - startTime };\n }\n\n // Build the prompt with all pairs\n const pairDescriptions = toJudge.map((p, i) => {\n const pk = pairKey(p.memoryIdA, p.memoryIdB);\n const catA = p.categoryA ? ` [${p.categoryA}]` : \"\";\n const catB = p.categoryB ? ` [${p.categoryB}]` : \"\";\n return `Pair ${i + 1} (pairKey: \"${pk}\"):${catA} \"${p.textA}\"${catB} \"${p.textB}\"`;\n });\n\n const userMessage = `Classify these ${toJudge.length} memory pair(s):\\n\\n${pairDescriptions.join(\"\\n\\n\")}`;\n\n // Try LLM call\n let llmResponse: string | null = null;\n\n if (localLlm) {\n try {\n llmResponse = await callLlm(localLlm, config, userMessage);\n } catch (err) {\n log.warn(\"[contradiction-judge] local LLM call failed: %s\", err instanceof Error ? err.message : err);\n }\n }\n\n if (!llmResponse && fallbackLlm) {\n try {\n llmResponse = await callLlm(fallbackLlm, config, userMessage);\n } catch (err) {\n log.warn(\"[contradiction-judge] fallback LLM call failed: %s\", err instanceof Error ? err.message : err);\n }\n }\n\n // Parse response or default to needs-user\n if (llmResponse) {\n const candidates = extractJsonCandidates(llmResponse);\n const parsed = parseJudgeResponse(candidates, toJudge);\n\n for (const result of parsed) {\n const key = pairKey(result.memoryIdA, result.memoryIdB);\n results.set(key, result);\n\n // Update cache\n const input = toJudge.find(\n (p) => pairKey(p.memoryIdA, p.memoryIdB) === key,\n );\n if (input) {\n const hash = contentHash(input);\n if (activeCache.size >= CACHE_MAX) {\n const firstKey = activeCache.keys().next().value;\n if (firstKey !== undefined) activeCache.delete(firstKey);\n }\n activeCache.set(hash, result);\n }\n judged++;\n }\n } else {\n // All unresolved → needs-user (rule 48)\n for (const pair of toJudge) {\n const key = pairKey(pair.memoryIdA, pair.memoryIdB);\n const result: ContradictionJudgeResult = {\n memoryIdA: pair.memoryIdA,\n memoryIdB: pair.memoryIdB,\n verdict: \"needs-user\",\n rationale: \"LLM call failed; requires manual review\",\n confidence: 0,\n };\n results.set(key, result);\n judged++;\n }\n }\n\n return { results, cached, judged, elapsed: Date.now() - startTime };\n}\n\n// ── Internals ──────────────────────────────────────────────────────────────────\n\nasync function callLlm(\n client: LocalLlmClient | FallbackLlmClient,\n config: PluginConfig,\n userMessage: string,\n): Promise<string> {\n const messages: Array<{ role: \"user\" | \"assistant\" | \"system\"; content: string }> = [\n { role: \"system\", content: CONTRADICTION_JUDGE_PROMPT },\n { role: \"user\", content: userMessage },\n ];\n if (\"chatCompletion\" in client && typeof client.chatCompletion === \"function\") {\n const result = await client.chatCompletion(messages, {\n temperature: 0.1,\n maxTokens: 4096,\n operation: \"contradiction-judge\",\n });\n return result?.content ?? \"\";\n }\n // FallbackLlmClient — try OpenAI-compatible chat completions\n if (\"complete\" in client && typeof (client as Record<string, unknown>).complete === \"function\") {\n const result = await (client as { complete: (msg: Array<{ role: string; content: string }>) => Promise<{ content: string }> }).complete(messages);\n return result.content ?? \"\";\n }\n return \"\";\n}\n\nfunction parseJudgeResponse(\n candidates: string[],\n inputs: ContradictionJudgeInput[],\n): ContradictionJudgeResult[] {\n const VALID_VERDICTS: ContradictionVerdict[] = [\"contradicts\", \"independent\", \"duplicates\", \"needs-user\"];\n let conservativeFallback: ContradictionJudgeResult[] | null = null;\n\n for (const candidate of candidates) {\n try {\n const parsed = JSON.parse(candidate);\n const items = Array.isArray(parsed) ? parsed : [parsed];\n const results: ContradictionJudgeResult[] = [];\n const matchedKeys = new Set<string>();\n\n for (const item of items) {\n if (!item || typeof item !== \"object\") continue;\n\n const verdict = typeof item.verdict === \"string\" && VALID_VERDICTS.includes(item.verdict as ContradictionVerdict)\n ? (item.verdict as ContradictionVerdict)\n : \"needs-user\";\n\n const pairKeyVal = typeof item.pairKey === \"string\" && item.pairKey.length > 0\n ? item.pairKey\n : null;\n const input = pairKeyVal\n ? inputs.find((p) => pairKey(p.memoryIdA, p.memoryIdB) === pairKeyVal)\n : null;\n\n if (!input) continue;\n\n matchedKeys.add(pairKey(input.memoryIdA, input.memoryIdB));\n\n const confidence = typeof item.confidence === \"number\"\n ? Math.min(1, Math.max(0, item.confidence))\n : 0.5;\n\n results.push({\n memoryIdA: input.memoryIdA,\n memoryIdB: input.memoryIdB,\n verdict,\n rationale: typeof item.rationale === \"string\" ? item.rationale : \"No rationale provided\",\n confidence,\n });\n }\n\n // Backfill any inputs the LLM omitted with needs-user\n for (const inp of inputs) {\n const key = pairKey(inp.memoryIdA, inp.memoryIdB);\n if (!matchedKeys.has(key)) {\n results.push({\n memoryIdA: inp.memoryIdA,\n memoryIdB: inp.memoryIdB,\n verdict: \"needs-user\",\n rationale: \"LLM response omitted this pair\",\n confidence: 0,\n });\n }\n }\n\n if (matchedKeys.size > 0) return results;\n if (results.length > 0 && conservativeFallback === null) {\n conservativeFallback = results;\n }\n } catch {\n continue;\n }\n }\n\n if (conservativeFallback !== null) return conservativeFallback;\n\n // All parse attempts failed → needs-user for every input\n return inputs.map((p) => ({\n memoryIdA: p.memoryIdA,\n memoryIdB: p.memoryIdB,\n verdict: \"needs-user\" as ContradictionVerdict,\n rationale: \"Failed to parse judge response\",\n confidence: 0,\n }));\n}\n\nexport { pairKey as _pairKey, contentHash as _contentHash };\n","/**\n * Contradiction Scan — pair generator + scan driver (issue #520).\n *\n * Nightly cron that pairs semantically-similar active memories within\n * the same namespace, sends candidate pairs to the LLM-as-judge\n * contradiction classifier, and drops contradicting pairs into a\n * review queue for user resolution.\n *\n * Pair generation (cheap pre-filter):\n * 1. Find candidate peers via embedding cosine >= similarityFloor.\n * 2. Restrict to pairs sharing at least one entityRef OR overlapping\n * topic tokens >= topicOverlapFloor.\n * 3. Skip pairs already judged independent/both-valid within cooldown.\n * 4. Cap per-run work at maxPairsPerRun.\n */\n\nimport { resolveNamespaceCapabilities } from \"../capabilities.js\";\nimport type { StorageManager } from \"../storage.js\";\nimport type { PluginConfig, MemoryFile, MemoryStatus } from \"../types.js\";\nimport type { SemanticDedupLookup } from \"../dedup/semantic.js\";\nimport { log } from \"../logger.js\";\nimport { judgeContradictionPairs, type ContradictionJudgeInput } from \"./contradiction-judge.js\";\nimport {\n writePairs,\n readPair,\n isCoolingDown,\n memoryHashesChanged,\n computeMemoryContentHash,\n computePairId,\n migrateUnscopedPairsToNamespace,\n type ContradictionPair,\n} from \"./contradiction-review.js\";\nimport type { LocalLlmClient } from \"../local-llm.js\";\nimport type { FallbackLlmClient } from \"../fallback-llm.js\";\nimport { isSupportPassportPrivateMemory } from \"../support-passport/card-projection.js\";\n\n// ── Types ──────────────────────────────────────────────────────────────────────\n\n/** The set of statuses that represent \"live\" memories eligible for scanning. */\nexport const ACTIVE_STATUSES: Set<MemoryStatus> = new Set([\"active\"]);\n\n/** High-value taxonomy buckets to scan. */\nconst SCAN_CATEGORIES = new Set([\n \"decision\",\n \"principle\",\n \"rule\",\n \"entity\",\n \"fact\",\n \"preference\",\n]);\n\nexport interface ScanResult {\n /** Total active memories scanned. */\n scanned: number;\n /** Candidate pairs generated by the pre-filter. */\n candidates: number;\n /** Pairs sent to judge. */\n judged: number;\n /** Pairs written to review queue. */\n queued: number;\n /** Pairs skipped due to cooldown. */\n cooledDown: number;\n /** Total wall-clock time in ms. */\n elapsedMs: number;\n}\n\nexport interface ScanStorageResolution {\n storage: StorageManager;\n namespace?: string;\n}\n\nexport interface ScanDependencies {\n storage: StorageManager;\n config: PluginConfig;\n memoryDir: string;\n /** Pre-built embedding lookup. When provided, used as-is for Strategy 3. */\n embeddingLookup?: SemanticDedupLookup;\n /**\n * Factory to build a namespace-scoped embedding lookup.\n * When provided, takes precedence over `embeddingLookup`.\n * The scan driver passes its own `storage` so the lookup queries the correct index.\n */\n embeddingLookupFactory?: (storage: StorageManager) => SemanticDedupLookup | undefined;\n /** Resolver for namespace-scoped storage. Required for scans when namespaces are enabled. */\n storageForNamespace?: (\n namespace: string | undefined,\n ) => StorageManager | ScanStorageResolution | Promise<StorageManager | ScanStorageResolution>;\n localLlm: LocalLlmClient | null;\n fallbackLlm: FallbackLlmClient | null;\n namespace?: string;\n}\n\n// ── Main scan driver ───────────────────────────────────────────────────────────\n\n/**\n * Run a contradiction scan over the memory corpus.\n *\n * This is the entry point called by the nightly cron and by the CLI.\n */\nexport async function runContradictionScan(deps: ScanDependencies): Promise<ScanResult> {\n const startTime = Date.now();\n const { config, memoryDir, embeddingLookup, embeddingLookupFactory, localLlm, fallbackLlm } = deps;\n const requestedNamespace = normalizeScanNamespace(deps.namespace);\n const scanConfig = config.contradictionScan;\n\n if (!scanConfig.enabled) {\n log.info(\"[contradiction-scan] disabled by config\");\n return { scanned: 0, candidates: 0, judged: 0, queued: 0, cooledDown: 0, elapsedMs: 0 };\n }\n\n const { storage: scanStorage, namespace } = await resolveScanStorage(deps, requestedNamespace);\n if (resolveNamespaceCapabilities(config).namespaces && namespace !== undefined && isDefaultNamespaceScan(config, requestedNamespace, namespace)) {\n const migrated = migrateUnscopedPairsToNamespace(memoryDir, namespace, { cooldownDays: scanConfig.cooldownDays });\n if (migrated > 0) {\n log.info(\"[contradiction-scan] migrated %d legacy unscoped review pairs to namespace %s\", migrated, namespace);\n }\n }\n\n // Prefer the factory (which uses the scan's own storage for correct namespace scoping)\n // over a pre-built lookup (which may use default-namespace storage).\n const scopedEmbeddingLookup = embeddingLookupFactory\n ? embeddingLookupFactory(scanStorage)\n : embeddingLookup;\n\n // 1. Load active memories in scan categories\n const memories = await loadEligibleMemories(scanStorage);\n log.info(\"[contradiction-scan] loaded %d eligible memories\", memories.length);\n\n if (memories.length < 2) {\n return { scanned: memories.length, candidates: 0, judged: 0, queued: 0, cooledDown: 0, elapsedMs: Date.now() - startTime };\n }\n\n // 2. Prepare exact existing-pair lookup for cooldown checking.\n // Pair IDs are deterministic, so lookup the candidate's file directly instead\n // of paging through the review queue and risking a bounded-list miss.\n const existingPairCache = new Map<string, ContradictionPair | undefined>();\n const getExistingPair = (pairId: string): ContradictionPair | undefined => {\n if (!existingPairCache.has(pairId)) {\n existingPairCache.set(pairId, readPair(memoryDir, pairId) ?? undefined);\n }\n return existingPairCache.get(pairId);\n };\n\n // 3. Generate candidate pairs\n const candidates = await generatePairs(memories, getExistingPair, scanConfig, namespace, scopedEmbeddingLookup);\n const cooledDown = candidates.skipped;\n log.info(\"[contradiction-scan] generated %d candidates (%d cooled down)\", candidates.pairs.length, cooledDown);\n\n if (candidates.pairs.length === 0) {\n return {\n scanned: memories.length,\n candidates: 0,\n judged: 0,\n queued: 0,\n cooledDown,\n elapsedMs: Date.now() - startTime,\n };\n }\n\n // 4. Build judge inputs. Candidate generation already preserves strategy\n // priority and caps work at maxPairsPerRun.\n const judgeInputs: ContradictionJudgeInput[] = candidates.pairs.map((pair) => ({\n memoryIdA: pair.idA,\n memoryIdB: pair.idB,\n textA: pair.textA,\n textB: pair.textB,\n categoryA: pair.categoryA,\n categoryB: pair.categoryB,\n }));\n\n // 6. Send to judge (per-scan cache avoids module-level singleton leak)\n const scanCache = new Map<string, import(\"./contradiction-judge.js\").ContradictionJudgeResult>();\n const judgeResult = await judgeContradictionPairs(judgeInputs, config, localLlm, fallbackLlm, scanCache);\n log.info(\"[contradiction-scan] judge completed: %d judged, %d cached in %dms\", judgeResult.judged, judgeResult.cached, judgeResult.elapsed);\n\n // 7. Write to review queue\n const queueEntries: Array<Omit<ContradictionPair, \"pairId\"> & { memoryIds: [string, string] }> = [];\n const currentMemoryHashes = memoryContentHashMap(memories);\n for (const [key, result] of judgeResult.results) {\n queueEntries.push({\n memoryIds: [result.memoryIdA, result.memoryIdB],\n verdict: result.verdict,\n rationale: result.rationale,\n confidence: result.confidence,\n detectedAt: new Date().toISOString(),\n // Set lastReviewedAt for non-actionable verdicts so cooldown prevents re-judging\n lastReviewedAt: result.verdict === \"independent\" ? new Date().toISOString() : undefined,\n memoryContentHashes: pairMemoryContentHashes(result.memoryIdA, result.memoryIdB, currentMemoryHashes),\n namespace,\n });\n }\n\n const written = writePairs(memoryDir, queueEntries, { cooldownDays: scanConfig.cooldownDays });\n const elapsed = Date.now() - startTime;\n log.info(\"[contradiction-scan] complete: %d queued in %dms\", written.length, elapsed);\n\n return {\n scanned: memories.length,\n candidates: candidates.pairs.length,\n judged: judgeResult.judged,\n queued: written.length,\n cooledDown,\n elapsedMs: elapsed,\n };\n}\n\n// ── Pair generation ────────────────────────────────────────────────────────────\n\ninterface CandidatePair {\n idA: string;\n idB: string;\n textA: string;\n textB: string;\n categoryA?: string;\n categoryB?: string;\n}\n\ninterface PairGenResult {\n pairs: CandidatePair[];\n skipped: number;\n}\n\nasync function generatePairs(\n memories: MemoryFile[],\n getExistingPair: (pairId: string) => ContradictionPair | undefined,\n scanConfig: PluginConfig[\"contradictionScan\"],\n namespace: string | undefined,\n embeddingLookup?: SemanticDedupLookup,\n): Promise<PairGenResult> {\n const pairs: CandidatePair[] = [];\n let skipped = 0;\n const seen = new Set<string>();\n const maxPairs = Math.max(0, Math.floor(scanConfig.maxPairsPerRun));\n if (maxPairs === 0) return { pairs, skipped };\n\n const orderedMemories = [...memories].sort(compareMemoryId);\n const currentMemoryHashes = memoryContentHashMap(orderedMemories);\n\n const pushCandidate = (pair: CandidatePair): void => {\n if (pairs.length < maxPairs) pairs.push(pair);\n };\n\n const hasCapacity = (): boolean => pairs.length < maxPairs;\n const isSkippedByCooldown = (existing: ContradictionPair | undefined): boolean => {\n if (!existing || !isCoolingDown(existing, scanConfig.cooldownDays)) return false;\n return !memoryHashesChanged(\"\", existing, (memoryId) => currentMemoryHashes.get(memoryId) ?? null);\n };\n\n // Build index by entityRef for fast lookup\n const byEntity = new Map<string, MemoryFile[]>();\n for (const mem of orderedMemories) {\n const entity = mem.frontmatter.entityRef;\n if (entity) {\n const existing = byEntity.get(entity) ?? [];\n existing.push(mem);\n byEntity.set(entity, existing);\n }\n }\n\n // Strategy 1: Entity-ref based pairing (high precision)\n entityPairs:\n for (const entity of [...byEntity.keys()].sort()) {\n const group = byEntity.get(entity) ?? [];\n if (group.length < 2) continue;\n for (let i = 0; i < group.length; i++) {\n for (let j = i + 1; j < group.length; j++) {\n if (!hasCapacity()) break entityPairs;\n const a = group[i];\n const b = group[j];\n const pairId = computePairId(a.frontmatter.id!, b.frontmatter.id!, namespace);\n\n if (seen.has(pairId)) continue;\n seen.add(pairId);\n\n // Check cooldown\n const existing = getExistingPair(pairId);\n if (isSkippedByCooldown(existing)) {\n skipped++;\n continue;\n }\n\n pushCandidate({\n idA: a.frontmatter.id!,\n idB: b.frontmatter.id!,\n textA: a.content,\n textB: b.content,\n categoryA: a.frontmatter.category as string | undefined,\n categoryB: b.frontmatter.category as string | undefined,\n });\n }\n }\n }\n\n // Strategy 2: Tag/topic overlap for memories without a shared entityRef\n topicPairs:\n for (let i = 0; i < orderedMemories.length; i++) {\n for (let j = i + 1; j < orderedMemories.length; j++) {\n if (!hasCapacity()) break topicPairs;\n const a = orderedMemories[i];\n const b = orderedMemories[j];\n if (shareEntityRef(a, b)) continue;\n const overlap = jaccardOverlap(\n (a.frontmatter.tags as string[]) ?? [],\n (b.frontmatter.tags as string[]) ?? [],\n );\n\n if (overlap < scanConfig.topicOverlapFloor) continue;\n\n const pairId = computePairId(a.frontmatter.id!, b.frontmatter.id!, namespace);\n if (seen.has(pairId)) continue;\n seen.add(pairId);\n\n const existing = getExistingPair(pairId);\n if (isSkippedByCooldown(existing)) {\n skipped++;\n continue;\n }\n\n pushCandidate({\n idA: a.frontmatter.id!,\n idB: b.frontmatter.id!,\n textA: a.content,\n textB: b.content,\n categoryA: a.frontmatter.category as string | undefined,\n categoryB: b.frontmatter.category as string | undefined,\n });\n }\n }\n\n // Strategy 3: Embedding cosine similarity (enforces similarityFloor config)\n if (embeddingLookup && hasCapacity()) {\n const memoryById = new Map(orderedMemories.map((m) => [m.frontmatter.id!, m]));\n embeddingPairs:\n for (const mem of orderedMemories) {\n if (!hasCapacity()) break;\n const id = mem.frontmatter.id!;\n try {\n const hits = (await embeddingLookup(mem.content, 20)).sort((a, b) =>\n b.score - a.score || a.id.localeCompare(b.id),\n );\n for (const hit of hits) {\n if (!hasCapacity()) break embeddingPairs;\n if (hit.score < scanConfig.similarityFloor) continue;\n if (hit.id === id) continue;\n const peer = memoryById.get(hit.id);\n if (!peer) continue;\n\n const pairId = computePairId(id, hit.id, namespace);\n if (seen.has(pairId)) continue;\n seen.add(pairId);\n\n const existing = getExistingPair(pairId);\n if (isSkippedByCooldown(existing)) {\n skipped++;\n continue;\n }\n\n pushCandidate({\n idA: id,\n idB: hit.id,\n textA: mem.content,\n textB: peer.content,\n categoryA: mem.frontmatter.category as string | undefined,\n categoryB: peer.frontmatter.category as string | undefined,\n });\n }\n } catch {\n // Embedding backend unavailable — skip, entity-ref/tag strategies already covered\n }\n }\n }\n\n return { pairs, skipped };\n}\n\n// ── Helpers ────────────────────────────────────────────────────────────────────\n\nfunction normalizeScanNamespace(namespace: string | undefined): string | undefined {\n const trimmed = namespace?.trim();\n return trimmed ? trimmed : undefined;\n}\n\n/**\n * Resolve the namespace-scoped storage a scan must read and write through.\n *\n * Exported and narrowed to the fields it actually reads so sibling scans\n * (preference drift, issue #2371) share ONE namespace resolver rather than\n * re-deriving the read/write namespace independently — the divergence the\n * namespace/ACL scenario matrix in AGENTS.md exists to prevent.\n */\nexport async function resolveScanStorage(\n deps: Pick<ScanDependencies, \"config\" | \"storage\" | \"storageForNamespace\">,\n namespace: string | undefined,\n): Promise<ScanStorageResolution> {\n if (!resolveNamespaceCapabilities(deps.config).namespaces) {\n const defaultNamespace = normalizeScanNamespace(deps.config.defaultNamespace);\n if (namespace && namespace !== defaultNamespace) {\n throw new Error(`unsupported namespace: ${namespace}`);\n }\n return { storage: deps.storage, namespace: undefined };\n }\n\n if (deps.storageForNamespace) {\n const resolved = await deps.storageForNamespace(namespace);\n if (isScanStorageResolution(resolved)) {\n return {\n storage: resolved.storage,\n namespace: normalizeScanNamespace(resolved.namespace) ?? fallbackResolvedNamespace(deps, namespace),\n };\n }\n if (!isStorageManagerLike(resolved)) {\n throw new Error(\"storageForNamespace must return a StorageManager or { storage: StorageManager, namespace?: string }\");\n }\n return {\n storage: resolved,\n namespace: fallbackResolvedNamespace(deps, namespace),\n };\n }\n\n throw new Error(\n \"contradiction scans require storageForNamespace when namespaces are enabled so callers can enforce namespace access\",\n );\n}\n\nfunction isScanStorageResolution(value: StorageManager | ScanStorageResolution): value is ScanStorageResolution {\n if (isStorageManagerLike(value)) return false;\n if (typeof value !== \"object\" || value === null) return false;\n const candidate = value as { storage?: unknown };\n return isStorageManagerLike(candidate.storage);\n}\n\nfunction isStorageManagerLike(value: unknown): value is StorageManager {\n if (typeof value !== \"object\" || value === null) return false;\n const candidate = value as { readAllMemories?: unknown };\n return typeof candidate.readAllMemories === \"function\";\n}\n\nfunction fallbackResolvedNamespace(\n deps: Pick<ScanDependencies, \"config\">,\n namespace: string | undefined,\n): string | undefined {\n if (namespace) return namespace;\n return resolveNamespaceCapabilities(deps.config).namespaces ? deps.config.defaultNamespace : undefined;\n}\n\nfunction isDefaultNamespaceScan(\n config: PluginConfig,\n requestedNamespace: string | undefined,\n resolvedNamespace: string,\n): boolean {\n if (requestedNamespace === undefined) return true;\n return requestedNamespace === config.defaultNamespace || resolvedNamespace === config.defaultNamespace;\n}\n\nasync function loadEligibleMemories(storage: StorageManager): Promise<MemoryFile[]> {\n let all: MemoryFile[];\n try {\n all = await storage.readAllMemories();\n } catch {\n return [];\n }\n\n return all.filter((mem) => {\n const fm = mem.frontmatter;\n if (isSupportPassportPrivateMemory(mem)) return false;\n // Only active memories (rule 53: explicit ACTIVE_STATUSES set)\n const status = (fm.status as MemoryStatus) ?? \"active\";\n if (!ACTIVE_STATUSES.has(status)) return false;\n\n // Only scan high-value categories\n const category = fm.category as string | undefined;\n if (category && !SCAN_CATEGORIES.has(category)) return false;\n\n // Must have content\n if (!mem.content || mem.content.trim().length === 0) return false;\n\n // Must have an ID\n if (!fm.id) return false;\n\n return true;\n });\n}\n\nfunction jaccardOverlap(a: string[], b: string[]): number {\n if (a.length === 0 && b.length === 0) return 0;\n const setA = new Set(a.map((t) => t.toLowerCase()));\n const setB = new Set(b.map((t) => t.toLowerCase()));\n let intersection = 0;\n for (const item of setA) {\n if (setB.has(item)) intersection++;\n }\n const union = setA.size + setB.size - intersection;\n return union === 0 ? 0 : intersection / union;\n}\n\nfunction shareEntityRef(a: MemoryFile, b: MemoryFile): boolean {\n const entityA = a.frontmatter.entityRef?.trim();\n const entityB = b.frontmatter.entityRef?.trim();\n return Boolean(entityA && entityB && entityA === entityB);\n}\n\nfunction compareMemoryId(a: MemoryFile, b: MemoryFile): number {\n return (a.frontmatter.id ?? \"\").localeCompare(b.frontmatter.id ?? \"\");\n}\n\nfunction memoryContentHashMap(memories: MemoryFile[]): Map<string, string> {\n const hashes = new Map<string, string>();\n for (const memory of memories) {\n const id = memory.frontmatter.id;\n if (!id) continue;\n hashes.set(id, computeMemoryContentHash(memory.content, memory.frontmatter.category as string | undefined));\n }\n return hashes;\n}\n\nfunction pairMemoryContentHashes(\n memoryIdA: string,\n memoryIdB: string,\n currentMemoryHashes: Map<string, string>,\n): Record<string, string> | undefined {\n const hashA = currentMemoryHashes.get(memoryIdA);\n const hashB = currentMemoryHashes.get(memoryIdB);\n if (!hashA || !hashB) return undefined;\n return {\n [memoryIdA]: hashA,\n [memoryIdB]: hashB,\n };\n}\n"],"mappings":"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","names":[]}
@@ -7,10 +7,10 @@ import {
7
7
  import {
8
8
  listMemoryGovernanceRuns,
9
9
  readMemoryGovernanceRunArtifact
10
- } from "./chunk-JYYBA7TF.js";
10
+ } from "./chunk-EIVIB73I.js";
11
11
  import {
12
12
  StorageManager
13
- } from "./chunk-J275IYMG.js";
13
+ } from "./chunk-PAYGC3BD.js";
14
14
  import {
15
15
  normalizeProjectionPreview,
16
16
  normalizeProjectionTags
@@ -1005,4 +1005,4 @@ export {
1005
1005
  verifyMemoryProjection,
1006
1006
  repairMemoryProjection
1007
1007
  };
1008
- //# sourceMappingURL=chunk-5NM4OH4P.js.map
1008
+ //# sourceMappingURL=chunk-QFMO32TO.js.map
@@ -296,4 +296,4 @@ async function searchHarmonicRetrieval(options) {
296
296
  export {
297
297
  searchHarmonicRetrieval
298
298
  };
299
- //# sourceMappingURL=chunk-SIHSCCUQ.js.map
299
+ //# sourceMappingURL=chunk-QXIQPCCN.js.map
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-JCWY73FK.js";
8
8
  import {
9
9
  StorageManager
10
- } from "./chunk-J275IYMG.js";
10
+ } from "./chunk-PAYGC3BD.js";
11
11
  import {
12
12
  parseContinuityImprovementLoops
13
13
  } from "./chunk-LDXUBPMO.js";
@@ -1283,4 +1283,4 @@ export {
1283
1283
  defaultTierMigrationCycleBudget,
1284
1284
  CompoundingEngine
1285
1285
  };
1286
- //# sourceMappingURL=chunk-2YI72KM3.js.map
1286
+ //# sourceMappingURL=chunk-R47WINCY.js.map
@@ -5,7 +5,7 @@ import {
5
5
  } from "./chunk-5JMAGU26.js";
6
6
  import {
7
7
  runPostConsolidationMaterialize
8
- } from "./chunk-QOS5LBZN.js";
8
+ } from "./chunk-S7Q5CM7E.js";
9
9
  import {
10
10
  isSemanticConsolidationLlmOperator
11
11
  } from "./chunk-G7D6GZ5J.js";
@@ -220,4 +220,4 @@ export {
220
220
  buildExtensionsBlockForConsolidation,
221
221
  materializeAfterSemanticConsolidation
222
222
  };
223
- //# sourceMappingURL=chunk-ZQHI2BZB.js.map
223
+ //# sourceMappingURL=chunk-RK4WXUI2.js.map
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-RDFF2NAU.js";
5
5
  import {
6
6
  StorageManager
7
- } from "./chunk-J275IYMG.js";
7
+ } from "./chunk-PAYGC3BD.js";
8
8
  import {
9
9
  excludeSupportPassportPrivateMemories
10
10
  } from "./chunk-XDL5CYZN.js";
@@ -138,4 +138,4 @@ export {
138
138
  runCodexMaterialize,
139
139
  runPostConsolidationMaterialize
140
140
  };
141
- //# sourceMappingURL=chunk-QOS5LBZN.js.map
141
+ //# sourceMappingURL=chunk-S7Q5CM7E.js.map
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-KJTKLXTH.js";
4
4
  import {
5
5
  StorageManager
6
- } from "./chunk-J275IYMG.js";
6
+ } from "./chunk-PAYGC3BD.js";
7
7
  import {
8
8
  copyExistingFileToBackup,
9
9
  writeFileAtomically
@@ -260,4 +260,4 @@ export {
260
260
  backupExistingLedger,
261
261
  rebuildMemoryLifecycleLedger
262
262
  };
263
- //# sourceMappingURL=chunk-GDFVPUJ5.js.map
263
+ //# sourceMappingURL=chunk-TDKSCV62.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  externalWikiSearchOperation
3
- } from "./chunk-IID2CMUU.js";
3
+ } from "./chunk-PDVQ5JU3.js";
4
4
  import {
5
5
  memoryStoreRequestSchema
6
6
  } from "./chunk-W675UJCZ.js";
@@ -10,7 +10,7 @@ import {
10
10
  DELTA_SUBCOMMANDS,
11
11
  defineOperation,
12
12
  isCodegraphToolName
13
- } from "./chunk-SB7D4BT7.js";
13
+ } from "./chunk-WN5FSGLE.js";
14
14
  import {
15
15
  serializeMutations,
16
16
  withHeldFileLock
@@ -1818,4 +1818,4 @@ export {
1818
1818
  codegraphIngestTracesOperation,
1819
1819
  REGISTERED_OPERATIONS
1820
1820
  };
1821
- //# sourceMappingURL=chunk-OCZIYAE5.js.map
1821
+ //# sourceMappingURL=chunk-TYUS5TLG.js.map
@@ -11,7 +11,7 @@ import {
11
11
  } from "./chunk-NOB2T2FC.js";
12
12
  import {
13
13
  parseConfig
14
- } from "./chunk-BWLRUMOG.js";
14
+ } from "./chunk-76PL4XLG.js";
15
15
  import {
16
16
  resolveObjectiveStateStoreDir,
17
17
  validateObjectiveStateSnapshot
@@ -268,4 +268,4 @@ export {
268
268
  recordResumeBundle,
269
269
  getResumeBundleStatus
270
270
  };
271
- //# sourceMappingURL=chunk-GNCCUR6K.js.map
271
+ //# sourceMappingURL=chunk-URHCUXKI.js.map
@@ -17,18 +17,19 @@ import {
17
17
  validateRequest
18
18
  } from "./chunk-W675UJCZ.js";
19
19
  import {
20
+ MCP_ADMIN_OPS_MIGRATED_OPERATIONS,
20
21
  MCP_ADMIN_OPS_TOOLS,
21
22
  MCP_GIT_CONTEXT_SCHEMA_PROPS_IGNORED
22
- } from "./chunk-TBOJ76ER.js";
23
+ } from "./chunk-AB3A7EFH.js";
23
24
  import {
24
25
  applyToolOutputSchemas
25
- } from "./chunk-TZNQUNKL.js";
26
+ } from "./chunk-FC7TIRFS.js";
26
27
  import {
27
28
  getOperation
28
- } from "./chunk-SB7D4BT7.js";
29
+ } from "./chunk-WN5FSGLE.js";
29
30
  import {
30
31
  WHO_KNOWS_MCP_TOOLS
31
- } from "./chunk-SPUJNJJC.js";
32
+ } from "./chunk-NZWEEALH.js";
32
33
  import {
33
34
  PROMOTION_CANDIDATES_MCP_TOOLS
34
35
  } from "./chunk-RIAM7DND.js";
@@ -1676,6 +1677,7 @@ var MCP_MIGRATED_OPERATIONS = {
1676
1677
  "engram.dreams_status": "dreams_status",
1677
1678
  "engram.dreams_run": "dreams_run",
1678
1679
  ...SUPPORT_PASSPORT_MCP_MIGRATED_OPERATIONS,
1680
+ ...MCP_ADMIN_OPS_MIGRATED_OPERATIONS,
1679
1681
  "engram.memory_chat": "chat_message"
1680
1682
  };
1681
1683
  var STRICT_MCP_SCHEMA_KEYS = {
@@ -3962,4 +3964,4 @@ export {
3962
3964
  MCP_MIGRATED_OPERATIONS,
3963
3965
  EngramMcpServer
3964
3966
  };
3965
- //# sourceMappingURL=chunk-TF77C7SV.js.map
3967
+ //# sourceMappingURL=chunk-VA5KMSAE.js.map