@remnic/core 9.4.2 → 9.6.0

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 (379) hide show
  1. package/dist/access-admin-ops-surface.d.ts +6 -6
  2. package/dist/access-admin-ops-surface.js +28 -28
  3. package/dist/access-boundary.d.ts +27 -8
  4. package/dist/access-boundary.js +33 -29
  5. package/dist/access-cli.js +83 -81
  6. package/dist/access-cli.js.map +1 -1
  7. package/dist/access-http.d.ts +52 -6
  8. package/dist/access-http.js +40 -38
  9. package/dist/access-identity-continuity-surface.d.ts +5 -5
  10. package/dist/access-identity-continuity-surface.js +28 -28
  11. package/dist/access-lcm-surface.d.ts +6 -6
  12. package/dist/access-lcm-surface.js +28 -28
  13. package/dist/access-mcp.d.ts +16 -6
  14. package/dist/access-mcp.js +37 -35
  15. package/dist/access-observe-write-surface.d.ts +6 -6
  16. package/dist/access-observe-write-surface.js +28 -28
  17. package/dist/access-operations-batch.js +33 -32
  18. package/dist/access-operations.d.ts +9 -9
  19. package/dist/access-operations.js +35 -34
  20. package/dist/access-recall-surface.d.ts +6 -6
  21. package/dist/access-recall-surface.js +28 -28
  22. package/dist/access-schema.d.ts +4 -4
  23. package/dist/access-schema.js +4 -4
  24. package/dist/{access-service-m-2VO_Ig.d.ts → access-service-CXJaql3A.d.ts} +4 -4
  25. package/dist/access-service.d.ts +6 -6
  26. package/dist/access-service.js +28 -28
  27. package/dist/access-surface-catalog.d.ts +6 -6
  28. package/dist/access-surface-catalog.js +1 -0
  29. package/dist/access-surface-catalog.js.map +1 -1
  30. package/dist/access-token-capabilities.d.ts +174 -0
  31. package/dist/access-token-capabilities.js +33 -0
  32. package/dist/action-confidence.d.ts +1 -1
  33. package/dist/active-memory-bridge.d.ts +1 -1
  34. package/dist/active-recall.d.ts +1 -1
  35. package/dist/active-recall.js +2 -2
  36. package/dist/adapters/index.js +4 -4
  37. package/dist/adapters/registry.js +2 -2
  38. package/dist/{auto-sync-HMHQHUAG.js → auto-sync-4A5YBWYO.js} +4 -4
  39. package/dist/behavior-learner.d.ts +1 -1
  40. package/dist/behavior-signals.d.ts +1 -1
  41. package/dist/bootstrap.d.ts +5 -5
  42. package/dist/briefing.d.ts +2 -2
  43. package/dist/briefing.js +9 -9
  44. package/dist/buffer-surprise-report.d.ts +1 -1
  45. package/dist/buffer.d.ts +2 -2
  46. package/dist/calibration.d.ts +1 -1
  47. package/dist/capabilities.d.ts +1 -1
  48. package/dist/{capsule-crypto-CZJSLEFG.js → capsule-crypto-RAARDY3M.js} +2 -2
  49. package/dist/capsule-crypto-RAARDY3M.js.map +1 -0
  50. package/dist/{catalog-BxWokdC2.d.ts → catalog-C9cu67Ig.d.ts} +1 -1
  51. package/dist/causal-behavior.d.ts +1 -1
  52. package/dist/causal-behavior.js +5 -5
  53. package/dist/causal-chain.js +3 -3
  54. package/dist/causal-consolidation.d.ts +1 -1
  55. package/dist/causal-consolidation.js +13 -13
  56. package/dist/causal-retrieval.js +3 -3
  57. package/dist/causal-trajectory-graph.d.ts +1 -1
  58. package/dist/causal-trajectory.js +1 -1
  59. package/dist/{chunk-6ZIETXZ2.js → chunk-23JFRB73.js} +2 -2
  60. package/dist/{chunk-IC6QX5TC.js → chunk-3XIY7MDQ.js} +6 -6
  61. package/dist/{chunk-FZGGZAAU.js → chunk-4GNEDXDI.js} +146 -2
  62. package/dist/chunk-4GNEDXDI.js.map +1 -0
  63. package/dist/{chunk-LOR6ZM5R.js → chunk-4LV23CHK.js} +2 -2
  64. package/dist/{chunk-E2SPGGUI.js → chunk-4OKLXWDZ.js} +13 -6
  65. package/dist/chunk-4OKLXWDZ.js.map +1 -0
  66. package/dist/{chunk-AER6MT24.js → chunk-6SXVCD7W.js} +2 -2
  67. package/dist/{chunk-OHDJ34CC.js → chunk-72WG5QKN.js} +2 -2
  68. package/dist/{chunk-CZAZX7JP.js → chunk-7MW3CVLD.js} +4 -4
  69. package/dist/{chunk-CXLNZXG5.js → chunk-7XGSIUP5.js} +1 -1
  70. package/dist/{chunk-CZAA5N5S.js → chunk-AYZJID4S.js} +2 -2
  71. package/dist/{chunk-M7XQSUBB.js → chunk-B3ABVQ36.js} +116 -9
  72. package/dist/chunk-B3ABVQ36.js.map +1 -0
  73. package/dist/{chunk-6BISDEN6.js → chunk-BEM4D2QG.js} +14 -14
  74. package/dist/{chunk-ZPOROUTX.js → chunk-CYWA2CXR.js} +5 -5
  75. package/dist/{chunk-M5QKGHCR.js → chunk-CYWCKFCL.js} +5 -5
  76. package/dist/chunk-D7FOKIY5.js +173 -0
  77. package/dist/chunk-D7FOKIY5.js.map +1 -0
  78. package/dist/{chunk-4BFRBP45.js → chunk-DEG5ULFJ.js} +2 -2
  79. package/dist/{chunk-JLR3JSTL.js → chunk-DS7MM2ES.js} +3 -3
  80. package/dist/{chunk-2BFLDH5F.js → chunk-EEIROWEG.js} +2 -2
  81. package/dist/{chunk-5QZDMSSN.js → chunk-FKCRGLRD.js} +237 -82
  82. package/dist/{chunk-5QZDMSSN.js.map → chunk-FKCRGLRD.js.map} +1 -1
  83. package/dist/{chunk-X4A62ET7.js → chunk-H2DXDQCQ.js} +17 -17
  84. package/dist/{chunk-27FLVMDC.js → chunk-HLN7RROI.js} +7 -7
  85. package/dist/chunk-IC2TCZJ2.js +54 -0
  86. package/dist/chunk-IC2TCZJ2.js.map +1 -0
  87. package/dist/{chunk-2U2A5HF4.js → chunk-J3XHPFEU.js} +6 -6
  88. package/dist/{chunk-AKUCU7CI.js → chunk-JI5AVXYO.js} +5 -5
  89. package/dist/{chunk-KCJ5H6XQ.js → chunk-JSNVWNGX.js} +2 -2
  90. package/dist/{chunk-7Z2DZNWN.js → chunk-KL4UAXUY.js} +43 -2
  91. package/dist/{chunk-7Z2DZNWN.js.map → chunk-KL4UAXUY.js.map} +1 -1
  92. package/dist/{chunk-FLVL4L3L.js → chunk-KTULX4YO.js} +4 -4
  93. package/dist/{chunk-ILFJ7AVS.js → chunk-LADFWYHY.js} +35 -21
  94. package/dist/chunk-LADFWYHY.js.map +1 -0
  95. package/dist/{chunk-437S3G37.js → chunk-LNQUAJNC.js} +1 -1
  96. package/dist/{chunk-EPGWWCZF.js → chunk-LR5DZ56F.js} +6 -6
  97. package/dist/{chunk-YDSWRD33.js → chunk-N3JDIRBW.js} +4 -4
  98. package/dist/{chunk-OUMTBFSQ.js → chunk-NKCPUHCI.js} +5 -5
  99. package/dist/{chunk-7QWMTOIF.js → chunk-P454KXD6.js} +112 -34
  100. package/dist/chunk-P454KXD6.js.map +1 -0
  101. package/dist/{chunk-DR6PEJU3.js → chunk-PCLIWBGD.js} +44 -59
  102. package/dist/chunk-PCLIWBGD.js.map +1 -0
  103. package/dist/{chunk-BGTAL46Y.js → chunk-PNLFN2PZ.js} +2 -2
  104. package/dist/{chunk-P6SYWE4G.js → chunk-PVUJ6WVV.js} +10 -10
  105. package/dist/{chunk-YPEMNNNY.js → chunk-RGK27ELN.js} +6 -6
  106. package/dist/{chunk-2QSZNTDO.js → chunk-RKNJBZ55.js} +4 -4
  107. package/dist/{chunk-66FLU5BT.js → chunk-SIRPLF54.js} +6 -6
  108. package/dist/{chunk-M7GGMGMZ.js → chunk-SVOHGUMI.js} +1202 -126
  109. package/dist/chunk-SVOHGUMI.js.map +1 -0
  110. package/dist/{chunk-HRCACVHL.js → chunk-TLUDFPZL.js} +2 -2
  111. package/dist/{chunk-2FOD2YY3.js → chunk-UFUKHGZD.js} +236 -103
  112. package/dist/chunk-UFUKHGZD.js.map +1 -0
  113. package/dist/{chunk-2MR3MFQB.js → chunk-UPSAT4PY.js} +2 -2
  114. package/dist/{chunk-4P4626RY.js → chunk-UTRJFDP2.js} +4 -4
  115. package/dist/{chunk-CGS7UKWM.js → chunk-VCW74PNH.js} +2 -2
  116. package/dist/{chunk-5GPPACXK.js → chunk-VSMRDBFT.js} +2 -1
  117. package/dist/{chunk-NG7YBCJO.js → chunk-XCL57M6Q.js} +4 -4
  118. package/dist/{chunk-CLX5VDNY.js → chunk-Y4RKAQZ7.js} +4 -4
  119. package/dist/{chunk-DGYCWCQ7.js → chunk-Y7UNNAZD.js} +2 -2
  120. package/dist/{chunk-EZ25VE3G.js → chunk-YNDLCWXS.js} +4 -4
  121. package/dist/{chunk-XN3TUUX2.js → chunk-YQB32INI.js} +2 -2
  122. package/dist/{cli-EiBBOt3r.d.ts → cli-CqdPA6z9.d.ts} +3 -3
  123. package/dist/cli.d.ts +7 -7
  124. package/dist/cli.js +61 -59
  125. package/dist/compounding/engine.d.ts +2 -2
  126. package/dist/compounding/engine.js +9 -9
  127. package/dist/compounding/preference-consolidator.d.ts +1 -1
  128. package/dist/compression-optimizer.d.ts +1 -1
  129. package/dist/config.d.ts +1 -1
  130. package/dist/config.js +2 -2
  131. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  132. package/dist/connectors/codex-materialize-runner.js +9 -9
  133. package/dist/connectors/codex-materialize.d.ts +1 -1
  134. package/dist/connectors/index.d.ts +1 -1
  135. package/dist/connectors/index.js +13 -11
  136. package/dist/consolidation-provenance-check.d.ts +2 -2
  137. package/dist/consolidation-undo.d.ts +2 -2
  138. package/dist/contradiction/index.d.ts +2 -2
  139. package/dist/contradiction/index.js +4 -4
  140. package/dist/conversation-index/backend.d.ts +1 -1
  141. package/dist/conversation-index/backend.js +2 -2
  142. package/dist/conversation-index/chunker.d.ts +1 -1
  143. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  144. package/dist/conversation-index/indexer.d.ts +1 -1
  145. package/dist/conversation-index/search.d.ts +1 -1
  146. package/dist/dashboard-runtime.js +2 -2
  147. package/dist/day-summary.d.ts +1 -1
  148. package/dist/delinearize.d.ts +1 -1
  149. package/dist/direct-answer-wiring.d.ts +1 -1
  150. package/dist/direct-answer.d.ts +1 -1
  151. package/dist/embedding-fallback.d.ts +1 -1
  152. package/dist/enrichment/index.d.ts +1 -1
  153. package/dist/entity-retrieval.d.ts +2 -2
  154. package/dist/entity-retrieval.js +9 -9
  155. package/dist/entity-schema.d.ts +1 -1
  156. package/dist/explicit-capture.d.ts +5 -5
  157. package/dist/extraction-faithfulness.d.ts +1 -1
  158. package/dist/extraction-judge-telemetry.d.ts +1 -1
  159. package/dist/extraction-judge-training.d.ts +1 -1
  160. package/dist/extraction-judge.d.ts +1 -1
  161. package/dist/extraction.d.ts +1 -1
  162. package/dist/fallback-llm.d.ts +1 -1
  163. package/dist/{first-start-migration-DY6YCRC2.js → first-start-migration-VBJQL6OI.js} +5 -5
  164. package/dist/graph-dashboard-diff.d.ts +1 -1
  165. package/dist/graph-dashboard-key.d.ts +1 -1
  166. package/dist/graph-dashboard-parser.d.ts +1 -1
  167. package/dist/graph-edge-reinforcement.d.ts +1 -1
  168. package/dist/graph-snapshot.d.ts +1 -1
  169. package/dist/graph.d.ts +1 -1
  170. package/dist/identity-continuity.d.ts +1 -1
  171. package/dist/importance.d.ts +1 -1
  172. package/dist/index.d.ts +271 -17
  173. package/dist/index.js +163 -99
  174. package/dist/intent.d.ts +1 -1
  175. package/dist/lcm/engine.d.ts +1 -1
  176. package/dist/lcm/engine.js +2 -2
  177. package/dist/lcm/index.d.ts +1 -1
  178. package/dist/lcm/index.js +2 -2
  179. package/dist/lcm/tools.d.ts +1 -1
  180. package/dist/lifecycle.d.ts +1 -1
  181. package/dist/live-connectors-runner.d.ts +1 -1
  182. package/dist/local-llm.d.ts +1 -1
  183. package/dist/local-model-endpoint.d.ts +1 -1
  184. package/dist/maintenance/memory-governance.d.ts +1 -1
  185. package/dist/maintenance/memory-governance.js +10 -10
  186. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +9 -9
  187. package/dist/maintenance/rebuild-memory-projection.js +11 -11
  188. package/dist/mcp-memory-inspector-app.d.ts +6 -6
  189. package/dist/mcp-read-only-tools.d.ts +16 -0
  190. package/dist/mcp-read-only-tools.js +8 -0
  191. package/dist/mcp-read-only-tools.js.map +1 -0
  192. package/dist/memory-action-policy.d.ts +1 -1
  193. package/dist/memory-cache.d.ts +1 -1
  194. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  195. package/dist/memory-projection-store.d.ts +1 -1
  196. package/dist/memory-provenance.d.ts +1 -1
  197. package/dist/memory-worth-outcomes.d.ts +2 -2
  198. package/dist/models-json.d.ts +1 -1
  199. package/dist/namespaces/migrate.d.ts +3 -3
  200. package/dist/namespaces/migrate.js +19 -19
  201. package/dist/namespaces/principal.d.ts +1 -1
  202. package/dist/namespaces/search.d.ts +1 -1
  203. package/dist/namespaces/search.js +10 -10
  204. package/dist/namespaces/storage.d.ts +3 -3
  205. package/dist/namespaces/storage.js +9 -9
  206. package/dist/native-knowledge.d.ts +1 -1
  207. package/dist/operator-toolkit.d.ts +2 -2
  208. package/dist/operator-toolkit.js +25 -25
  209. package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
  210. package/dist/orchestration/maintenance.d.ts +2 -2
  211. package/dist/orchestration/maintenance.js +11 -11
  212. package/dist/{orchestrator-B2Y28Z9t.d.ts → orchestrator-CWFrT8AF.d.ts} +91 -60
  213. package/dist/orchestrator.d.ts +5 -5
  214. package/dist/orchestrator.js +85 -83
  215. package/dist/patterns-cli.d.ts +1 -1
  216. package/dist/policy-runtime.d.ts +1 -1
  217. package/dist/provenance.d.ts +1 -1
  218. package/dist/{qmd-Db9mOkzB.d.ts → qmd--fnPMK60.d.ts} +1 -1
  219. package/dist/qmd-preflight.d.ts +2 -2
  220. package/dist/qmd-recall-cache.d.ts +1 -1
  221. package/dist/qmd.d.ts +2 -2
  222. package/dist/recall-disclosure-escalation.d.ts +1 -1
  223. package/dist/recall-explain-renderer.d.ts +1 -1
  224. package/dist/recall-planner-llm.d.ts +1 -1
  225. package/dist/recall-state.d.ts +1 -1
  226. package/dist/recall-tag-filter.d.ts +1 -1
  227. package/dist/recall-timings.d.ts +1 -1
  228. package/dist/recall-xray-cli.d.ts +1 -1
  229. package/dist/recall-xray-renderer.d.ts +1 -1
  230. package/dist/recall-xray.d.ts +1 -1
  231. package/dist/resolve-auth-token.d.ts +1 -1
  232. package/dist/resume-bundles.js +4 -4
  233. package/dist/retrieval-agents.d.ts +2 -2
  234. package/dist/retrieval-tiers.d.ts +1 -1
  235. package/dist/routing/engine.d.ts +1 -1
  236. package/dist/routing/store.d.ts +1 -1
  237. package/dist/schemas.d.ts +22 -22
  238. package/dist/search/document-scanner.js +2 -2
  239. package/dist/search/embed-helper.d.ts +1 -1
  240. package/dist/search/factory.d.ts +1 -1
  241. package/dist/search/factory.js +9 -9
  242. package/dist/search/index.d.ts +1 -1
  243. package/dist/search/index.js +13 -13
  244. package/dist/search/lancedb-backend.d.ts +1 -1
  245. package/dist/search/lancedb-backend.js +3 -3
  246. package/dist/search/meilisearch-backend.d.ts +1 -1
  247. package/dist/search/meilisearch-backend.js +3 -3
  248. package/dist/search/noop-backend.d.ts +1 -1
  249. package/dist/search/orama-backend.d.ts +1 -1
  250. package/dist/search/orama-backend.js +3 -3
  251. package/dist/search/port.d.ts +1 -1
  252. package/dist/search/remote-backend.d.ts +1 -1
  253. package/dist/{semantic-consolidation-BDVIbLRw.d.ts → semantic-consolidation-O5lMZ4LG.d.ts} +1 -1
  254. package/dist/semantic-consolidation.d.ts +2 -2
  255. package/dist/semantic-consolidation.js +11 -11
  256. package/dist/semantic-rule-promotion.js +9 -9
  257. package/dist/semantic-rule-verifier.d.ts +1 -1
  258. package/dist/semantic-rule-verifier.js +10 -10
  259. package/dist/session-observer-bands.d.ts +1 -1
  260. package/dist/session-observer-state.d.ts +1 -1
  261. package/dist/shared-context/manager.d.ts +1 -1
  262. package/dist/signal.d.ts +1 -1
  263. package/dist/storage-C1maCNbc.d.ts +1591 -0
  264. package/dist/storage.d.ts +5 -1239
  265. package/dist/storage.js +8 -8
  266. package/dist/summarizer.d.ts +1 -1
  267. package/dist/summary-snapshot.d.ts +1 -1
  268. package/dist/temporal-supersession.d.ts +2 -2
  269. package/dist/temporal-validity.d.ts +1 -1
  270. package/dist/threading.d.ts +1 -1
  271. package/dist/tier-migration.d.ts +2 -2
  272. package/dist/tier-routing.d.ts +1 -1
  273. package/dist/{tier-stats-TG6GUZ6N.js → tier-stats-5XF4UBRQ.js} +4 -4
  274. package/dist/tokens.d.ts +17 -2
  275. package/dist/tokens.js +3 -1
  276. package/dist/topics.d.ts +1 -1
  277. package/dist/transcript.d.ts +1 -1
  278. package/dist/transfer/backup.js +2 -2
  279. package/dist/transfer/capsule-export.js +3 -3
  280. package/dist/transfer/capsule-import.js +3 -3
  281. package/dist/transfer/types.d.ts +12 -12
  282. package/dist/trust-score-stage.d.ts +1 -1
  283. package/dist/trust-score.d.ts +1 -1
  284. package/dist/{types-ljkd82rn.d.ts → types-CGgcNWCG.d.ts} +31 -1
  285. package/dist/types.d.ts +1 -1
  286. package/dist/utility-runtime.d.ts +1 -1
  287. package/dist/verified-recall.js +10 -10
  288. package/package.json +2 -2
  289. package/src/access-boundary.test.ts +62 -0
  290. package/src/access-boundary.ts +165 -126
  291. package/src/access-http.test.ts +781 -0
  292. package/src/access-http.ts +334 -108
  293. package/src/access-mcp.test.ts +264 -0
  294. package/src/access-mcp.ts +45 -70
  295. package/src/access-operations-batch.ts +35 -12
  296. package/src/access-surface-catalog.test.ts +22 -14
  297. package/src/access-surface-catalog.ts +6 -3
  298. package/src/access-token-capabilities.test.ts +844 -0
  299. package/src/access-token-capabilities.ts +391 -0
  300. package/src/chat/chat-mcp.test.ts +232 -0
  301. package/src/chat/chat-session.ts +34 -0
  302. package/src/cli-wearables-fuse.test.ts +197 -0
  303. package/src/cli.ts +25 -0
  304. package/src/index.ts +14 -0
  305. package/src/mcp-read-only-tools.ts +61 -0
  306. package/src/storage.ts +16 -0
  307. package/src/tokens.ts +32 -3
  308. package/src/wearables/cli.test.ts +102 -0
  309. package/src/wearables/cli.ts +65 -0
  310. package/src/wearables/config.test.ts +32 -0
  311. package/src/wearables/config.ts +52 -0
  312. package/src/wearables/day-store.test.ts +246 -0
  313. package/src/wearables/day-store.ts +272 -3
  314. package/src/wearables/fusion/cluster.ts +230 -0
  315. package/src/wearables/fusion/fuse.ts +218 -0
  316. package/src/wearables/fusion/fusion.test.ts +2575 -0
  317. package/src/wearables/fusion/index.ts +50 -0
  318. package/src/wearables/fusion/reconcile.ts +831 -0
  319. package/src/wearables/fusion/reconstruct.ts +251 -0
  320. package/src/wearables/fusion/store.ts +480 -0
  321. package/src/wearables/fusion/types.ts +228 -0
  322. package/src/wearables/index.ts +41 -0
  323. package/src/wearables/service.test.ts +1030 -2
  324. package/src/wearables/service.ts +258 -16
  325. package/src/wearables/speakers.test.ts +128 -0
  326. package/src/wearables/speakers.ts +58 -4
  327. package/src/wearables/storage-io.test.ts +146 -0
  328. package/src/wearables/types.ts +31 -0
  329. package/dist/chunk-2FOD2YY3.js.map +0 -1
  330. package/dist/chunk-7QWMTOIF.js.map +0 -1
  331. package/dist/chunk-DR6PEJU3.js.map +0 -1
  332. package/dist/chunk-E2SPGGUI.js.map +0 -1
  333. package/dist/chunk-FZGGZAAU.js.map +0 -1
  334. package/dist/chunk-ILFJ7AVS.js.map +0 -1
  335. package/dist/chunk-M7GGMGMZ.js.map +0 -1
  336. package/dist/chunk-M7XQSUBB.js.map +0 -1
  337. /package/dist/{capsule-crypto-CZJSLEFG.js.map → access-token-capabilities.js.map} +0 -0
  338. /package/dist/{auto-sync-HMHQHUAG.js.map → auto-sync-4A5YBWYO.js.map} +0 -0
  339. /package/dist/{chunk-6ZIETXZ2.js.map → chunk-23JFRB73.js.map} +0 -0
  340. /package/dist/{chunk-IC6QX5TC.js.map → chunk-3XIY7MDQ.js.map} +0 -0
  341. /package/dist/{chunk-LOR6ZM5R.js.map → chunk-4LV23CHK.js.map} +0 -0
  342. /package/dist/{chunk-AER6MT24.js.map → chunk-6SXVCD7W.js.map} +0 -0
  343. /package/dist/{chunk-OHDJ34CC.js.map → chunk-72WG5QKN.js.map} +0 -0
  344. /package/dist/{chunk-CZAZX7JP.js.map → chunk-7MW3CVLD.js.map} +0 -0
  345. /package/dist/{chunk-CXLNZXG5.js.map → chunk-7XGSIUP5.js.map} +0 -0
  346. /package/dist/{chunk-CZAA5N5S.js.map → chunk-AYZJID4S.js.map} +0 -0
  347. /package/dist/{chunk-6BISDEN6.js.map → chunk-BEM4D2QG.js.map} +0 -0
  348. /package/dist/{chunk-ZPOROUTX.js.map → chunk-CYWA2CXR.js.map} +0 -0
  349. /package/dist/{chunk-M5QKGHCR.js.map → chunk-CYWCKFCL.js.map} +0 -0
  350. /package/dist/{chunk-4BFRBP45.js.map → chunk-DEG5ULFJ.js.map} +0 -0
  351. /package/dist/{chunk-JLR3JSTL.js.map → chunk-DS7MM2ES.js.map} +0 -0
  352. /package/dist/{chunk-2BFLDH5F.js.map → chunk-EEIROWEG.js.map} +0 -0
  353. /package/dist/{chunk-X4A62ET7.js.map → chunk-H2DXDQCQ.js.map} +0 -0
  354. /package/dist/{chunk-27FLVMDC.js.map → chunk-HLN7RROI.js.map} +0 -0
  355. /package/dist/{chunk-2U2A5HF4.js.map → chunk-J3XHPFEU.js.map} +0 -0
  356. /package/dist/{chunk-AKUCU7CI.js.map → chunk-JI5AVXYO.js.map} +0 -0
  357. /package/dist/{chunk-KCJ5H6XQ.js.map → chunk-JSNVWNGX.js.map} +0 -0
  358. /package/dist/{chunk-FLVL4L3L.js.map → chunk-KTULX4YO.js.map} +0 -0
  359. /package/dist/{chunk-437S3G37.js.map → chunk-LNQUAJNC.js.map} +0 -0
  360. /package/dist/{chunk-EPGWWCZF.js.map → chunk-LR5DZ56F.js.map} +0 -0
  361. /package/dist/{chunk-YDSWRD33.js.map → chunk-N3JDIRBW.js.map} +0 -0
  362. /package/dist/{chunk-OUMTBFSQ.js.map → chunk-NKCPUHCI.js.map} +0 -0
  363. /package/dist/{chunk-BGTAL46Y.js.map → chunk-PNLFN2PZ.js.map} +0 -0
  364. /package/dist/{chunk-P6SYWE4G.js.map → chunk-PVUJ6WVV.js.map} +0 -0
  365. /package/dist/{chunk-YPEMNNNY.js.map → chunk-RGK27ELN.js.map} +0 -0
  366. /package/dist/{chunk-2QSZNTDO.js.map → chunk-RKNJBZ55.js.map} +0 -0
  367. /package/dist/{chunk-66FLU5BT.js.map → chunk-SIRPLF54.js.map} +0 -0
  368. /package/dist/{chunk-HRCACVHL.js.map → chunk-TLUDFPZL.js.map} +0 -0
  369. /package/dist/{chunk-2MR3MFQB.js.map → chunk-UPSAT4PY.js.map} +0 -0
  370. /package/dist/{chunk-4P4626RY.js.map → chunk-UTRJFDP2.js.map} +0 -0
  371. /package/dist/{chunk-CGS7UKWM.js.map → chunk-VCW74PNH.js.map} +0 -0
  372. /package/dist/{chunk-5GPPACXK.js.map → chunk-VSMRDBFT.js.map} +0 -0
  373. /package/dist/{chunk-NG7YBCJO.js.map → chunk-XCL57M6Q.js.map} +0 -0
  374. /package/dist/{chunk-CLX5VDNY.js.map → chunk-Y4RKAQZ7.js.map} +0 -0
  375. /package/dist/{chunk-DGYCWCQ7.js.map → chunk-Y7UNNAZD.js.map} +0 -0
  376. /package/dist/{chunk-EZ25VE3G.js.map → chunk-YNDLCWXS.js.map} +0 -0
  377. /package/dist/{chunk-XN3TUUX2.js.map → chunk-YQB32INI.js.map} +0 -0
  378. /package/dist/{first-start-migration-DY6YCRC2.js.map → first-start-migration-VBJQL6OI.js.map} +0 -0
  379. /package/dist/{tier-stats-TG6GUZ6N.js.map → tier-stats-5XF4UBRQ.js.map} +0 -0
@@ -0,0 +1,1591 @@
1
+ import { M as MemoryFile, P as PluginConfig, u as MemoryStatus, t as MemoryCategory, ae as ImportanceScore, ar as MemoryLink, p as MemoryFrontmatter, F as FaithfulnessFrontmatter, J as ProvenanceSource, a7 as EntityStructuredSection, as as BufferState, at as MetaState, a2 as MemoryActionEvent, w as MemoryLifecycleEvent, X as BufferSurpriseEvent, B as BehaviorSignalEvent, a3 as CompressionGuidelineOptimizerState, aa as ContinuityIncidentOpenInput, a8 as ContinuityIncidentRecord, a9 as ContinuityIncidentCloseInput, ab as ContinuityImprovementLoop, ad as ContinuityLoopUpsertInput, ac as ContinuityLoopReviewInput, au as FileHygieneConfig, av as EntityRelationship, aw as EntityActivityEntry, E as EntityFile, ax as AccessTrackingEntry, v as MemoryProjectionCurrentState, ay as MemorySummary, ap as TopicScore, az as EntityTimelineEntry } from './types-CGgcNWCG.js';
2
+ import { VersioningConfig } from './page-versioning.js';
3
+ import { ConsolidationOperator } from './consolidation-operator.js';
4
+ import { ProjectedMemoryBrowseOptions, ProjectedMemoryBrowsePage, readProjectedGovernanceRecord } from './memory-projection-store.js';
5
+ import './structured-attributes.js';
6
+
7
+ /**
8
+ * Wearable cross-source fusion — shared types (issue #1810).
9
+ *
10
+ * Fusion merges same-day conversations from multiple enabled wearable
11
+ * sources into `FusedWearableConversation` artifacts: one reconciled
12
+ * timeline per real-world conversation, with per-segment source
13
+ * provenance and unresolved conflicts surfaced as `disagreements[]`.
14
+ *
15
+ * Everything in this module is DETERMINISTIC — no LLM calls. LLM-assisted
16
+ * reconciliation, memory-extraction over fused artifacts, and full
17
+ * segment-level alignment are deferred follow-ups (see PR body).
18
+ */
19
+ /**
20
+ * One normalized segment fed into fusion. Speaker labels are already
21
+ * resolved through the speaker registry (`resolveSpeaker`), and text is
22
+ * post-cleanup + post-redaction — fusion consumes the same material day
23
+ * transcripts store, never raw provider output.
24
+ */
25
+ interface FusionSegmentInput {
26
+ /** Resolved speaker label (e.g. "Jane", "Me (you)", "Speaker 0"). */
27
+ speaker: string;
28
+ /** Whether this speaker is the wearer. */
29
+ isSelf: boolean;
30
+ /** Utterance text. */
31
+ text: string;
32
+ /** ISO 8601 start, when known. */
33
+ startIso?: string;
34
+ /** ISO 8601 end, when known. */
35
+ endIso?: string;
36
+ }
37
+ /** One normalized conversation fed into fusion. */
38
+ interface FusionConversationInput {
39
+ /** Source id this conversation came from. */
40
+ source: string;
41
+ /** Provider-stable conversation id within that source. */
42
+ conversationId: string;
43
+ /** Provider title, when available. */
44
+ title?: string;
45
+ /** Provider summary, when available. */
46
+ summary?: string;
47
+ /** ISO 8601 conversation start. */
48
+ startIso: string;
49
+ /** ISO 8601 conversation end, when known. */
50
+ endIso?: string;
51
+ /** Ordered normalized segments. */
52
+ segments: FusionSegmentInput[];
53
+ }
54
+ /** Why a particular source's text was chosen for a fused segment. */
55
+ type SegmentPickReason = "only-source" | "higher-trust" | "more-complete" | "tie-break";
56
+ /** Kind of unresolved conflict surfaced during reconciliation. */
57
+ type DisagreementKind = "asr-text" | "speaker" | "timestamp";
58
+ /** Per-segment record of where the chosen text came from and what else was considered. */
59
+ interface FusedSegmentProvenance {
60
+ /** Source id the chosen text came from. */
61
+ source: string;
62
+ /** Conversation id within that source. */
63
+ conversationId: string;
64
+ /** Trust weight of the chosen source at reconciliation time (0..1). */
65
+ sourceTrust: number;
66
+ /** Why this source won the pick. */
67
+ reason: SegmentPickReason;
68
+ /** Other sources that offered a candidate text for this window/speaker. */
69
+ alternatives: Array<{
70
+ source: string;
71
+ text: string;
72
+ }>;
73
+ /** The chosen source's ORIGINAL start time (ISO), when known. The fused
74
+ * segment is emitted on the group/window ANCHOR timeline position so
75
+ * pre-sorted chronology stays valid even when the higher-trust source's
76
+ * clock is later than the anchor; this preserves WHERE the chosen text
77
+ * was actually recorded for provenance/traceability. */
78
+ sourceStartIso?: string;
79
+ /** The chosen source's ORIGINAL end time (ISO), when known (see sourceStartIso). */
80
+ sourceEndIso?: string;
81
+ }
82
+ /** One reconciled utterance in a fused conversation. */
83
+ interface FusedSegment {
84
+ /** Reconciled speaker label. */
85
+ speaker: string;
86
+ /** Whether this speaker is the wearer. */
87
+ isSelf: boolean;
88
+ /** Reconciled utterance text. */
89
+ text: string;
90
+ /** Window start (ISO), when known. */
91
+ startIso?: string;
92
+ /** Window end (ISO), when known. */
93
+ endIso?: string;
94
+ /** 0..1 confidence in this segment's text + attribution. */
95
+ confidence: number;
96
+ provenance: FusedSegmentProvenance;
97
+ }
98
+ /** An unresolved conflict that reconciliation could not settle deterministically. */
99
+ interface FusedDisagreement {
100
+ kind: DisagreementKind;
101
+ /**
102
+ * What the disagreement concerns — an ISO window anchor, a speaker
103
+ * label, or "(no timestamp)" for un-timestamped windows.
104
+ */
105
+ subject: string;
106
+ /** The conflicting candidates that could not be auto-resolved. */
107
+ candidates: Array<{
108
+ source: string;
109
+ value: string;
110
+ }>;
111
+ /** Best-effort provisional winner; marked uncertain, NOT authoritative. */
112
+ provisional?: {
113
+ source: string;
114
+ value: string;
115
+ };
116
+ }
117
+ /** A reconciled speaker that appears in the fused conversation. */
118
+ interface FusedSpeaker {
119
+ /** Display label. */
120
+ label: string;
121
+ /** Whether this speaker is the wearer. */
122
+ isSelf: boolean;
123
+ /**
124
+ * 0..1 — lowered when a speaker could not be confidently matched
125
+ * across sources (e.g. a generic diarization label seen in one
126
+ * source only).
127
+ */
128
+ confidence: number;
129
+ /** Source ids that produced this speaker. */
130
+ sources: string[];
131
+ }
132
+ /** Record of one source conversation that fed a fused conversation. */
133
+ interface FusedContribution {
134
+ source: string;
135
+ conversationId: string;
136
+ startIso: string;
137
+ endIso?: string;
138
+ segmentCount: number;
139
+ }
140
+ /** How a fused conversation was assembled. */
141
+ interface FusedConversationProvenance {
142
+ /** Source conversations that fed this cluster. */
143
+ contributions: FusedContribution[];
144
+ /** Max gap (ms) two conversations could span and still merge. */
145
+ proximityGapMs: number;
146
+ /** Max drift (ms) for two segments to align across sources. */
147
+ windowToleranceMs: number;
148
+ /** Clustering method (deterministic, time-proximity based). */
149
+ method: "time-proximity";
150
+ }
151
+ /**
152
+ * A real-world conversation reconstructed from one or more wearable
153
+ * sources recording at the same time. The fused artifact.
154
+ */
155
+ interface FusedWearableConversation {
156
+ /** Stable content-hash id (deterministic from inputs; idempotent). */
157
+ id: string;
158
+ /** YYYY-MM-DD the conversation was recorded. */
159
+ date: string;
160
+ /** Earliest start across contributing sources. */
161
+ startIso: string;
162
+ /** Latest end across contributing sources, when known. */
163
+ endIso?: string;
164
+ /** Source ids that contributed at least one conversation. */
165
+ sources: string[];
166
+ /** Reconciled speakers (deduped across sources). */
167
+ speakers: FusedSpeaker[];
168
+ /** Provider title, when any source supplied one. */
169
+ title?: string;
170
+ /** Provider summary, when any source supplied one. */
171
+ summary?: string;
172
+ /** Aligned, reconciled segments in chronological order. */
173
+ segments: FusedSegment[];
174
+ /** Unresolved conflicts surfaced during reconciliation. */
175
+ disagreements: FusedDisagreement[];
176
+ provenance: FusedConversationProvenance;
177
+ }
178
+ /** Options for a fusion pass. */
179
+ interface FusionOptions {
180
+ /** Max gap (ms) between conversations to merge into one cluster. */
181
+ proximityGapMs?: number;
182
+ /** Max drift (ms) for two segments to align across sources. */
183
+ windowToleranceMs?: number;
184
+ /** Per-source trust weights (unknown sources default to 0.8). */
185
+ sourceTrust?: Record<string, number>;
186
+ }
187
+ /** Result of fusing one day across all sources. */
188
+ interface FusionDayResult {
189
+ date: string;
190
+ conversations: FusedWearableConversation[];
191
+ /** Distinct source ids that contributed any conversation. */
192
+ sources: string[];
193
+ /** SHA-256 over the canonical input serialization + effective fusion config (idempotency key). */
194
+ contentHash: string;
195
+ }
196
+ /** Frontmatter persisted on a fused-day derived file. */
197
+ interface FusedDayMeta {
198
+ kind: "wearable-fusion";
199
+ date: string;
200
+ sourceCount: number;
201
+ conversationCount: number;
202
+ contentHash: string;
203
+ /**
204
+ * SHA-256 over the canonical serialized body (`hashFusionBody`). Stored
205
+ * so the skip-unchanged path can detect a body whose bytes drifted from
206
+ * the recomputed artifact even when `contentHash` + conversation count
207
+ * still match — forcing a self-repair rewrite on body-level corruption.
208
+ */
209
+ bodyHash: string;
210
+ fusedAt: string;
211
+ }
212
+ /** A parsed fused-day derived file. */
213
+ interface FusedDayFile {
214
+ meta: FusedDayMeta;
215
+ conversations: FusedWearableConversation[];
216
+ /**
217
+ * False when the JSON body failed to parse (truncated/corrupt). A
218
+ * legitimately empty (`[]`) body parses fine — parseOk stays true — so
219
+ * callers can distinguish "nothing to fuse" from a broken file and force
220
+ * a self-repair rewrite even when the frontmatter hash matches and the
221
+ * parsed conversation count is also zero.
222
+ */
223
+ parseOk: boolean;
224
+ }
225
+
226
+ /**
227
+ * Wearable cross-source fusion — derived-day file serialization.
228
+ *
229
+ * One derived file per fused day, stored ALONGSIDE raw source transcripts
230
+ * (under the wearables tree) but never overwriting them. Format mirrors
231
+ * the day-transcript convention: YAML frontmatter (`kind:
232
+ * wearable-fusion`) + a JSON body carrying the structured
233
+ * `FusedWearableConversation[]`. The frontmatter `contentHash` is the
234
+ * idempotency key derived from inputs plus the effective fusion config,
235
+ * so an unchanged re-run (same inputs AND config) produces a
236
+ * byte-identical file.
237
+ */
238
+
239
+ declare const FUSION_KIND: "wearable-fusion";
240
+ /** Hash the canonical JSON body for idempotent skip-unchanged checks. */
241
+ declare function hashFusionBody(conversations: readonly FusedWearableConversation[]): string;
242
+ declare function composeFusionDayMeta(date: string, conversations: readonly FusedWearableConversation[], sources: readonly string[], contentHash: string, fusedAt: string): FusedDayMeta;
243
+ /** Serialize meta + conversations into the persisted file format. */
244
+ declare function serializeFusionDay(meta: FusedDayMeta, conversations: readonly FusedWearableConversation[]): string;
245
+ /**
246
+ * Parse a persisted fused-day file. Returns null when the content does
247
+ * not look like a fusion artifact (wrong kind / missing frontmatter) so
248
+ * callers can distinguish "not fused" from a malformed file. A non-null
249
+ * result carries `parseOk`: false when the JSON body failed to parse, was
250
+ * not an array, or held a malformed element (conversations is empty in
251
+ * that case), true for a well-formed (incl. legitimately-empty `[]`)
252
+ * body — so the skip-unchanged path can force a self-repair rewrite
253
+ * regardless of the recomputed conversation count or body hash.
254
+ */
255
+ declare function parseFusionDay(raw: string): FusedDayFile | null;
256
+ /**
257
+ * Encrypted-at-rest + atomic file IO the fusion artifact store needs.
258
+ * Satisfied by StorageManager (which owns the secure-store key + atomic
259
+ * write path) and injected so this module performs NO direct fs — the
260
+ * derived files inherit the same encrypted-at-rest + atomic-write
261
+ * semantics as raw day transcripts without this module knowing the key.
262
+ */
263
+ interface FusionFileIo {
264
+ writeFile(filePath: string, content: string): Promise<void>;
265
+ /** Read a file; rejects with ENOENT when it is absent. */
266
+ readFile(filePath: string): Promise<string>;
267
+ /** Directory entries; rejects with ENOENT when the directory is absent. */
268
+ readDir(dirPath: string): Promise<string[]>;
269
+ /** Remove a file; rejects with ENOENT when it is absent. */
270
+ deleteFile(filePath: string): Promise<void>;
271
+ /**
272
+ * Resolve a path through symlinks (node:fs/promises realpath); rejects
273
+ * with ENOENT when the path is absent. Used by the symlink-containment
274
+ * guard so a symlinked `_fusion` dir (or a symlinked wearables root)
275
+ * that resolves outside the memory dir is rejected before any
276
+ * read/write/delete (AGENTS.md #3).
277
+ */
278
+ realpath(filePath: string): Promise<string>;
279
+ /**
280
+ * Stat a path WITHOUT following a trailing symlink
281
+ * (node:fs/promises lstat); rejects with ENOENT when the path is
282
+ * absent. Used to detect a pre-existing symlink at the fusion
283
+ * artifact directory itself, which is rejected even when its
284
+ * target resolves inside the memory dir (issue #1849).
285
+ */
286
+ lstat(filePath: string): Promise<{
287
+ isSymbolicLink: boolean;
288
+ }>;
289
+ }
290
+ /**
291
+ * Owns the derived fused-day artifact files under
292
+ * `<wearablesDir>/_fusion/<YYYY-MM-DD>.md`. Path construction, date
293
+ * validation, and newest-first listing live here (relocated out of the
294
+ * root storage module — issue #1810 ratchet); the bytes flow through the
295
+ * injected secure IO.
296
+ */
297
+ declare class FusionArtifactStore {
298
+ private readonly wearablesDir;
299
+ private readonly memoryDir;
300
+ private readonly io;
301
+ constructor(wearablesDir: string, memoryDir: string, io: FusionFileIo);
302
+ fusedDayPath(date: string): string;
303
+ writeFusedDay(date: string, serialized: string): Promise<void>;
304
+ /** Read a stored fused-day artifact; null when absent. */
305
+ readFusedDay(date: string): Promise<string | null>;
306
+ /**
307
+ * Remove a stored fused-day artifact. Idempotent: a no-op when the
308
+ * artifact is already absent. Used to clear a now-stale derived file
309
+ * before a fusion run that deliberately refuses to fuse (e.g. a day
310
+ * whose sources later conflict on timezone) so fusedConversations()
311
+ * does not keep serving a stale view (issue #1849).
312
+ */
313
+ deleteFusedDay(date: string): Promise<void>;
314
+ /** List dates with stored fused artifacts, newest first. */
315
+ listFusedDays(): Promise<string[]>;
316
+ /**
317
+ * Reject a symlinked/traversing fusion artifact path before any IO. The
318
+ * fusion dir (`<wearablesDir>/_fusion`) and its parents are followed
319
+ * directly by the secure IO; a symlink placed there (attacker-writable
320
+ * or a malformed memory dir) would otherwise be followed and
321
+ * read/write/delete outside the allowed root (AGENTS.md pattern #3).
322
+ *
323
+ * Containment is anchored to the real MEMORY-DIR root, not the
324
+ * wearables dir, AND the wearables root is checked explicitly: if
325
+ * `wearablesDir` itself is a symlink that resolves outside memoryDir, a
326
+ * leaf candidate like `<wearablesDir>/_fusion/<date>.md` may not yet
327
+ * exist (so its realpath ENOENT-skips) and the write would silently
328
+ * create the file inside the symlinked escape target. Checking
329
+ * `wearablesDir` itself — which resolves through the symlink when it
330
+ * exists — closes that gap, while the per-leaf checks catch a nested
331
+ * `_fusion` or per-file symlink. Absent paths are allowed (a fresh
332
+ * write creates them lexically under the root; only a path that
333
+ * resolves to an existing target can redirect IO). Mirrors
334
+ * `assertPathInsideRoot` in the storage walkers.
335
+ */
336
+ private assertPathContained;
337
+ /**
338
+ * Refuse a pre-existing symbolic link at the `<wearablesDir>/_fusion`
339
+ * directory. Unlike `assertNoEscape` (which follows the link and only
340
+ * rejects when the target lands outside the memory dir), this catches a
341
+ * fusion root that aliases an in-bounds path — e.g. a `_fusion` link
342
+ * pointed at a raw source transcript — so fusion IO never writes
343
+ * through it and overwrites the aliased file. Absent dirs are allowed
344
+ * (a fresh write creates a real directory lexically under the root).
345
+ */
346
+ private assertFusionDirNotSymlinked;
347
+ /**
348
+ * Refuse a candidate whose realpath escapes the memory root. Absent
349
+ * candidates are allowed: a missing path cannot yet redirect IO, and
350
+ * the secure write creates it lexically under the root.
351
+ */
352
+ private assertNoEscape;
353
+ }
354
+
355
+ /** Why a tombstone was emitted. */
356
+ type TombstoneReason = "correction" | "supersession" | "retraction" | "contradiction_resolution";
357
+ /** Who emitted the tombstone. */
358
+ type TombstoneCreatedBy = "user_correction" | "contradiction_resolution" | "supersession" | "chat";
359
+ /** Tier that matched on lookup. */
360
+ type TombstoneMatchTier = "exact" | "normalized" | "keyed" | "semantic";
361
+ /**
362
+ * A single append-only tombstone log entry.
363
+ *
364
+ * `kind: "tombstone"` blocks; `kind: "revocation"` re-allows. The log is
365
+ * never rewritten — the NEWEST matching entry wins at lookup (rule 25).
366
+ */
367
+ interface TombstoneEntry {
368
+ /** Stable tombstone id (`tomb-<ts>-<rand>`). */
369
+ id: string;
370
+ kind: "tombstone" | "revocation";
371
+ reason: TombstoneReason;
372
+ /** The memory that was retired. */
373
+ sourceMemoryId: string;
374
+ /** sha256 of the retired memory's rawContent (rule 23). */
375
+ contentHash: string;
376
+ /** `ContentHashIndex.normalizeContent(rawContent)` — the pre-hash form. */
377
+ normalizedText: string;
378
+ entityRef?: string;
379
+ /** Structured-attribute supersession key when one existed. */
380
+ supersessionKey?: string;
381
+ /** Namespace scope (rule 42). */
382
+ namespace: string;
383
+ createdAt: string;
384
+ createdBy: TombstoneCreatedBy;
385
+ /** For `kind: "revocation"`: the tombstone id being revoked. */
386
+ revokes?: string;
387
+ }
388
+ /** A positive block decision returned by `TombstoneStore.lookup`. */
389
+ interface TombstoneMatch {
390
+ tombstoneId: string;
391
+ matchedTier: TombstoneMatchTier;
392
+ reason: TombstoneReason;
393
+ }
394
+ /** Inputs to a lookup. At least one discriminator must be present.
395
+ *
396
+ * Issue #1579 thread Ociag/Oci-W: `supersessionKeys` (plural) lets the write
397
+ * chokepoint check EVERY derived key, not just the first. Emitters register
398
+ * one tombstone per matched key (temporal-supersession, rebuild), so a block
399
+ * can live on any later key; querying only `supersessionKeys[0]` missed it
400
+ * and the retired fact resurrected as active. `supersessionKey` (singular)
401
+ * remains for direct/unit callers; `lookup` checks the union of both. */
402
+ interface TombstoneLookupQuery {
403
+ contentHash?: string;
404
+ normalizedText?: string;
405
+ entityRef?: string;
406
+ /** Single supersession key (direct/unit callers). */
407
+ supersessionKey?: string;
408
+ /** All derived supersession keys (write chokepoint). The keyed tier is
409
+ * checked for each; the first active match wins. */
410
+ supersessionKeys?: string[];
411
+ namespace: string;
412
+ }
413
+ /** Configuration for a tombstone store instance. */
414
+ interface TombstoneStoreOptions {
415
+ enabled: boolean;
416
+ semanticMatch: boolean;
417
+ semanticThreshold: number;
418
+ /** sha256 of raw content — wired to `ContentHashIndex.computeHash`. */
419
+ hashContent: (raw: string) => string;
420
+ /** Normalize raw content — wired to `ContentHashIndex.normalizeContent`. */
421
+ normalizeText: (raw: string) => string;
422
+ /**
423
+ * Optional cosine similarity in [0, 1] for the semantic tier. When
424
+ * undefined or when `semanticMatch` is false, the semantic tier is
425
+ * skipped entirely.
426
+ */
427
+ semanticSimilarity?: (a: string, b: string) => number;
428
+ /**
429
+ * Cross-process write-lock timings for the tombstone JSONL mutation lock
430
+ * (issue #1639). The secure-store append is a read-merge-write (read
431
+ * encrypted → decrypt → concat → re-encrypt → atomic rename), so two
432
+ * Remnic processes appending concurrently can each read the same contents
433
+ * and the last writer drops the other's entry — breaking the
434
+ * non-resurrection invariant. The lock serializes the mutation across
435
+ * processes. When omitted, defaults that fit the short tombstone critical
436
+ * section (mirroring the summary-snapshot lock): staleMs 30s, maxWaitMs 5s,
437
+ * heartbeatMs floor(staleMs/3).
438
+ */
439
+ readonly lockStaleMs?: number;
440
+ readonly lockMaxWaitMs?: number;
441
+ readonly lockHeartbeatMs?: number;
442
+ }
443
+ /** Injected file I/O — the StorageManager wires its secure-store-aware
444
+ * implementations so tombstones are encrypted at rest alongside other state.
445
+ * `stat` is optional; when provided the store tracks the file mtime itself and
446
+ * runs a cross-process staleness probe on each access (#1579). */
447
+ interface TombstoneFileIo {
448
+ read: (filePath: string) => Promise<string>;
449
+ append: (filePath: string, content: string) => Promise<void>;
450
+ write: (filePath: string, content: string) => Promise<void>;
451
+ stat?: (filePath: string) => {
452
+ mtimeMs: number;
453
+ };
454
+ }
455
+ /** Aggregate stats for `remnic doctor`. */
456
+ interface TombstoneStats {
457
+ count: number;
458
+ revoked: number;
459
+ lastAppendAt: string | null;
460
+ corruptedLines: number;
461
+ /** Whether the in-memory index matches the on-disk file (rebuild check). */
462
+ loaded: boolean;
463
+ }
464
+ /**
465
+ * The instance-scoped tombstone store. One per StorageManager (rule 11),
466
+ * namespace-scoped via `namespace` + the on-disk path (rule 42).
467
+ *
468
+ * The in-memory index is built lazily on first access and invalidated on
469
+ * append + by the StorageManager's cache-invalidation chokepoint (rule 25).
470
+ */
471
+ declare class TombstoneStore {
472
+ private readonly filePath;
473
+ private readonly namespace;
474
+ private readonly options;
475
+ private readonly io;
476
+ private entries;
477
+ /** contentHash → tombstone id (newest) — exact tier. */
478
+ private readonly byHash;
479
+ /** normalizedText → tombstone id (newest) — normalized tier. */
480
+ private readonly byNormalized;
481
+ /** entityRef\0supersessionKey → tombstone id (newest) — keyed tier. */
482
+ private readonly byKey;
483
+ /** Tombstone ids that have a later revocation entry. */
484
+ private readonly revokedIds;
485
+ /** id → entry index (newest only, for revocation lookups). */
486
+ private readonly byId;
487
+ private loaded;
488
+ private loadPromise;
489
+ private corruptedLines;
490
+ private lastAppendAt;
491
+ /**
492
+ * Last-seen mtime of the JSONL file (cross-process staleness probe, #1579).
493
+ * Tracked inside the store so the StorageManager wiring stays thin. When the
494
+ * file's mtime advances past this value between accesses, the in-memory index
495
+ * is stale (a peer process appended) and is reloaded before the next lookup.
496
+ */
497
+ private fileMtimeMs;
498
+ constructor(filePath: string, namespace: string, options: TombstoneStoreOptions, io: TombstoneFileIo);
499
+ /**
500
+ * Resolved cross-process write-lock timings (issue #1639). Defaults mirror
501
+ * the summary-snapshot lock: a tombstone append critical section is
502
+ * sub-second, so a stale lock older than 30s is a crashed holder; bounded
503
+ * acquisition gives up after 5s and strict-fails rather than clobbering a
504
+ * concurrent writer (which would reintroduce the lost-write race this lock
505
+ * closes).
506
+ */
507
+ private readonly lockStaleMs;
508
+ private readonly lockMaxWaitMs;
509
+ private readonly lockHeartbeatMs;
510
+ /**
511
+ * Sibling advisory lockfile: `<tombstones>.jsonl` → `<tombstones>.lock`.
512
+ * Shared by append, revoke, and rebuild so every JSONL mutation serializes
513
+ * against the others across processes (issue #1639: "shared with rebuilds").
514
+ */
515
+ private get lockPath();
516
+ /** Lazy load + build the in-memory index. Idempotent. */
517
+ load(): Promise<void>;
518
+ private loadInternal;
519
+ private resetIndex;
520
+ /**
521
+ * Index an entry. Later entries (higher array index = newer createdAt)
522
+ * OVERRIDE earlier ones at each tier key — the newest matching entry wins
523
+ * (rule 25). Revocation entries mark their target as revoked.
524
+ */
525
+ private indexEntry;
526
+ /** Invalidate the in-memory cache (rule 25). The next access reloads. */
527
+ invalidate(): void;
528
+ /**
529
+ * Cross-process staleness probe (#1579). If the file's mtime advanced since
530
+ * the last load/own-write, a peer process appended and our in-memory index is
531
+ * stale — invalidate AND reload in place so the next lookup sees the new
532
+ * entries. Best-effort: a stat error is swallowed (the loaded index is
533
+ * retained rather than crashing the write path). No-op when no `stat` was
534
+ * injected or when the mtime is unchanged. After our own append/revoke/rebuild
535
+ * `markWritten` records the new mtime, so this probe does not fire for our
536
+ * own writes (only for peer-process appends).
537
+ */
538
+ ensureFreshAgainstDisk(): Promise<void>;
539
+ /**
540
+ * Record the file mtime after THIS process writes (append / revoke / rebuild)
541
+ * so `ensureFreshAgainstDisk` does not treat our own write as a peer append
542
+ * and throw away the just-updated in-memory index (#1579 — avoids a needless
543
+ * invalidate+reload in the hot write path).
544
+ */
545
+ private markWritten;
546
+ private recordFileMtime;
547
+ /**
548
+ * Append a tombstone entry. Serialized via `serializeMutations` keyed by
549
+ * file path so concurrent appends do not interleave, with rejection recovery
550
+ * (rule 40 — a single failed append never poisons the chain). The in-memory
551
+ * index is updated AFTER the durable append succeeds.
552
+ *
553
+ * Returns the new tombstone id.
554
+ */
555
+ appendTombstone(input: {
556
+ reason: TombstoneReason;
557
+ createdBy: TombstoneCreatedBy;
558
+ sourceMemoryId: string;
559
+ rawContent: string;
560
+ entityRef?: string;
561
+ supersessionKey?: string;
562
+ createdAt?: string;
563
+ /**
564
+ * Pre-computed canonical contentHash from the retired memory's frontmatter.
565
+ * When provided, used directly so the tombstone's exact tier matches the
566
+ * hash writeMemory computes on re-extraction (issue #1579 review: cited
567
+ * facts must not slip past the chokepoint because the emitter hashed the
568
+ * citation-annotated body instead of the canonical source).
569
+ */
570
+ contentHash?: string;
571
+ }): Promise<string>;
572
+ /**
573
+ * Append a revocation entry referencing `tombstoneId`. The log is
574
+ * append-only; lookup treats a revoked tombstone as re-allowed (rule 25).
575
+ */
576
+ revoke(tombstoneId: string, createdBy: TombstoneCreatedBy): Promise<string>;
577
+ private serializeAppend;
578
+ /**
579
+ * Acquire the cross-process tombstone write lock and run `task` under it
580
+ * (issue #1639). Strict-fail on acquisition timeout: the secure-store append
581
+ * is a read-merge-write, so a best-effort unlocked run would clobber a
582
+ * concurrent writer — reintroducing the lost-write race this lock closes.
583
+ * The thrown error surfaces to the caller (rule 34: never silently drop);
584
+ * rebuild recovers the tombstone on the next maintenance cycle.
585
+ *
586
+ * In-process callers are already serialized by serializeMutations (one key
587
+ * for append/revoke/rebuild), so this lock only contends across processes —
588
+ * the single-process daemon (default deployment) acquires it immediately.
589
+ */
590
+ private withWriteLock;
591
+ /**
592
+ * Look up whether `query` is blocked by an active (non-revoked) tombstone.
593
+ * Tiers are checked in order: exact (contentHash) → normalized → keyed →
594
+ * semantic (off by default). Returns the first active match, or `null`.
595
+ *
596
+ * Namespace isolation (rule 42): only entries with `namespace === query.namespace`
597
+ * match. The store is per-namespace, so this is belt-and-suspenders.
598
+ */
599
+ lookup(query: TombstoneLookupQuery): TombstoneMatch | null;
600
+ /** Aggregate stats for the doctor / x-ray surfaces. */
601
+ stats(): TombstoneStats;
602
+ /** Read-only snapshot of all entries (for rebuild + tests). */
603
+ snapshot(): readonly TombstoneEntry[];
604
+ /**
605
+ * Rebuild the in-memory index + JSONL from the supplied retired-memory
606
+ * records + existing entries (preserving revocations). Byte-stable: entries
607
+ * are sorted by (createdAt, id) before write (rule 38).
608
+ *
609
+ * Returns the count of tombstone entries written.
610
+ */
611
+ rebuild(retiredMemories: ReadonlyArray<RetiredMemoryRecord>): Promise<number>;
612
+ }
613
+ /** A retired memory projected into the shape `TombstoneStore.rebuild` consumes. */
614
+ interface RetiredMemoryRecord {
615
+ memoryId: string;
616
+ rawContent: string;
617
+ entityRef?: string;
618
+ supersessionKey?: string;
619
+ reason: TombstoneReason;
620
+ createdBy: TombstoneCreatedBy;
621
+ createdAt: string;
622
+ /** Canonical contentHash from the retired memory's frontmatter (#1579). */
623
+ contentHash?: string;
624
+ }
625
+
626
+ interface ReextractJobRequest {
627
+ memoryId: string;
628
+ model: string;
629
+ requestedAt: string;
630
+ source: "cli-migrate";
631
+ }
632
+ interface MemoryLifecycleEventWriteOptions {
633
+ at?: Date;
634
+ actor?: string;
635
+ reasonCode?: string;
636
+ ruleVersion?: string;
637
+ relatedMemoryIds?: string[];
638
+ correlationId?: string;
639
+ }
640
+ declare function parseFrontmatterStringValue(rawValue: string | undefined): string | undefined;
641
+ declare function parseFrontmatter(raw: string): {
642
+ frontmatter: MemoryFrontmatter;
643
+ content: string;
644
+ } | null;
645
+ declare function normalizeFrontmatterForPath(frontmatter: MemoryFrontmatter, pathRel: string, content?: string): MemoryFrontmatter;
646
+ /**
647
+ * Normalize an entity name to a canonical form.
648
+ * Strips non-alphanumeric chars, collapses hyphens, removes type prefix duplication.
649
+ * e.g. "My Project" → "my-project"
650
+ *
651
+ * Checks caller-provided user aliases first, then built-in aliases. Alias
652
+ * tables are instance state on StorageManager (issue #1534) — use
653
+ * `storageManager.normalizeEntityName(raw, type)` when normalizing within a
654
+ * store, or pass `storageManager.entityAliases` explicitly. Without an
655
+ * aliases argument only the built-in structural aliases apply.
656
+ */
657
+ declare function normalizeEntityName(raw: string, type: string, aliases?: Readonly<Record<string, string>>): string;
658
+ /**
659
+ * Content-hash dedup index for facts.
660
+ * Normalizes content (lowercase, strip punctuation, collapse whitespace),
661
+ * computes SHA-256, and stores hashes in a line-delimited file.
662
+ * Prevents writing semantically identical facts.
663
+ */
664
+ declare class ContentHashIndex {
665
+ private hashes;
666
+ private dirty;
667
+ private readonly filePath;
668
+ private readonly secureStoreKeyProvider;
669
+ private readonly secureStoreWriteKeyProvider;
670
+ private readonly memoryDir;
671
+ constructor(stateDir: string, secureStoreKeyProvider?: () => Buffer | null, secureStoreWriteKeyProvider?: () => Buffer | null, memoryDir?: string);
672
+ /** Load existing hashes from disk. Safe to call multiple times. */
673
+ load(): Promise<void>;
674
+ /** Check if content already exists in the index. */
675
+ has(content: string): boolean;
676
+ /** Add content hash to the index. */
677
+ add(content: string): void;
678
+ get size(): number;
679
+ /** Clear all loaded hashes so the next save rewrites the index from scratch. */
680
+ clear(): void;
681
+ /** Persist index to disk if changed. */
682
+ save(): Promise<void>;
683
+ /** Remove a hash from the index (used when archiving/deleting). */
684
+ remove(content: string): void;
685
+ /**
686
+ * Remove a pre-computed SHA-256 hash directly from the index without
687
+ * re-hashing. Use this when the caller already holds the stored hash
688
+ * (e.g. `memory.frontmatter.contentHash`) to avoid the double-hash bug
689
+ * where `remove(hash)` would compute `hash(hash)` and never match the
690
+ * entry.
691
+ */
692
+ removeByHash(hash: string): void;
693
+ /**
694
+ * Add a pre-computed SHA-256 hash directly to the index without re-hashing.
695
+ * Use this when the caller already holds the stored hash
696
+ * (e.g. `memory.frontmatter.contentHash`) so that the index records the raw
697
+ * content hash rather than re-hashing the citation-annotated body.
698
+ *
699
+ * @internal Only called from `StorageManager.ensureFactHashIndexAuthoritative`.
700
+ * Not part of the public API — prefer `add(content)` for external callers.
701
+ */
702
+ addByHash(hash: string): void;
703
+ /** Normalize content (delegates to content-hash.ts for a single source of truth). */
704
+ static normalizeContent(content: string): string;
705
+ /** Compute SHA-256 hash (delegates to content-hash.ts for a single source of truth). */
706
+ static computeHash(content: string): string;
707
+ }
708
+
709
+ declare function normalizeAttributePairs(pairs: Record<string, string>): string;
710
+ declare function normalizeStructuredSectionFacts(facts: string[]): string[];
711
+ declare function compileEntityFacts(timeline: EntityTimelineEntry[], structuredSections: EntityStructuredSection[]): string[];
712
+ declare function compareEntityTimestamps(left?: string, right?: string): number;
713
+ declare function countEntityStructuredFacts(entity: EntityFile): number;
714
+ declare function fingerprintEntityStructuredFacts(entity: Pick<EntityFile, "structuredSections">): string | undefined;
715
+ declare function isEntitySynthesisStale(entity: EntityFile): boolean;
716
+ /**
717
+ * Parse an entity markdown file into a structured EntityFile.
718
+ * Backward compatible: old files without new sections get empty arrays.
719
+ */
720
+ declare function parseEntityFile(content: string, entitySchemas?: PluginConfig["entitySchemas"]): EntityFile;
721
+ /**
722
+ * Serialize an EntityFile back to markdown.
723
+ * Writes the compiled-truth + timeline format while remaining parse-compatible
724
+ * with the legacy in-memory `summary` and `facts` fields.
725
+ */
726
+ declare function serializeEntityFile(entity: EntityFile, entitySchemas?: PluginConfig["entitySchemas"]): string;
727
+ declare function buildEntitySchemaCacheKey(entitySchemas?: PluginConfig["entitySchemas"]): string;
728
+ /**
729
+ * Full-schema type guard for a `BUFFER_SURPRISE` telemetry row
730
+ * (issue #563 PR 3).
731
+ *
732
+ * The reader applies `limit` over the count of VALID rows, so
733
+ * applying only a partial check (e.g. "has a finite surpriseScore")
734
+ * and then deferring the rest of validation to
735
+ * `reportBufferSurpriseDistribution` would silently count
736
+ * schema-incomplete rows toward the limit, pushing genuinely-valid
737
+ * earlier rows out of the report window. Validate everything the
738
+ * downstream report requires at read time so the limit semantics and
739
+ * the distribution semantics stay consistent.
740
+ */
741
+ declare function isValidBufferSurpriseEvent(value: unknown): value is BufferSurpriseEvent;
742
+ /** Result of {@link StorageManager.writeMemory} (issue #1645). Carries the
743
+ * persisted id PLUS the non-resurrection tombstone-block outcome (#1579) so
744
+ * post-write callers can observe it — NEVER a silent no-op (rule 34). */
745
+ interface MemoryWriteResult {
746
+ /** The persisted memory id. */
747
+ id: string;
748
+ /** True when the #1579 tombstone chokepoint downgraded this write to
749
+ * `pending_review` + `blockedBy`. Callers gate active post-write work on this. */
750
+ tombstoneBlocked: boolean;
751
+ /** The tombstone id that blocked the write, when `tombstoneBlocked`. */
752
+ blockedBy?: string;
753
+ }
754
+ declare class StorageManager {
755
+ private readonly baseDir;
756
+ private readonly entitySchemas?;
757
+ private knowledgeIndexCache;
758
+ private artifactIndexCache;
759
+ /** Read by storage/entity-store.ts (decomposition), hence not `private`. */
760
+ static readonly KNOWLEDGE_INDEX_CACHE_TTL_MS = 600000;
761
+ /** Read by storage/memory-read-store.ts (decomposition). */
762
+ static readonly ARTIFACT_INDEX_CACHE_TTL_MS = 60000;
763
+ private static readonly artifactWriteVersionByDir;
764
+ private static readonly memoryStatusVersionByDir;
765
+ private static readonly secureStoreEntityCacheKeyIds;
766
+ private static nextSecureStoreEntityCacheKeyId;
767
+ private static readonly coldWriteVersionByDir;
768
+ private static readonly allMemoriesInFlight;
769
+ /** Read by storage/memory-read-store.ts (decomposition). */
770
+ static readonly COLD_SCAN_CACHE_TTL_MS = 30000;
771
+ /** Read by storage/memory-read-store.ts (decomposition). */
772
+ static readonly coldMemoriesCache: Map<string, {
773
+ memories: MemoryFile[];
774
+ loadedAt: number;
775
+ coldVersion: number;
776
+ }>;
777
+ /** Read by storage/memory-read-store.ts (decomposition). */
778
+ static readonly QUESTIONS_CACHE_TTL_MS = 60000;
779
+ /** Read by storage/memory-read-store.ts (decomposition). */
780
+ static readonly questionsCache: Map<string, {
781
+ questions: Array<{
782
+ id: string;
783
+ question: string;
784
+ context: string;
785
+ priority: number;
786
+ resolved: boolean;
787
+ created: string;
788
+ filePath: string;
789
+ }>;
790
+ loadedAt: number;
791
+ }>;
792
+ private factHashIndex;
793
+ private factHashIndexLoadPromise;
794
+ private factHashIndexAuthoritative;
795
+ private factHashIndexAuthoritativePromise;
796
+ private readonly secureAppendChains;
797
+ private offlineSyncDigestCache;
798
+ private offlineSyncDigestCacheLoadPromise;
799
+ private offlineSyncDigestCacheWriteChain;
800
+ private offlineSyncDigestCacheWriteTimer;
801
+ /** Optional: set by the orchestrator after construction to enable template-aware citation stripping during legacy hash rebuild. */
802
+ citationTemplate: string;
803
+ /** Post-write catalog hook (#1522). Installed by the namespace router; fire-and-forget. */
804
+ onCatalogWrite?: () => void;
805
+ private notifyCatalogWrite;
806
+ private tombstoneStore;
807
+ private tombstoneStoreLoadPromise;
808
+ private tombstonesConfig;
809
+ /** Page-versioning configuration. Set by the orchestrator after construction. */
810
+ private _versioningConfig;
811
+ /** Set the page-versioning configuration. When `enabled` is false (default), all versioning calls are no-ops. */
812
+ setVersioningConfig(config: VersioningConfig): void;
813
+ /**
814
+ * At-rest encryption key (issue #690 PR 3/4).
815
+ *
816
+ * When non-null, every memory file read is decrypted and every write
817
+ * is encrypted using the secure-fs layer. When null, the storage
818
+ * layer operates in plain-text mode (legacy/unencrypted store).
819
+ *
820
+ * Set by the orchestrator after init/unlock; cleared on lock.
821
+ * The key buffer is NEVER logged or serialized.
822
+ */
823
+ private _secureStoreKey;
824
+ /**
825
+ * When true (and `_secureStoreKey` is non-null), new writes are
826
+ * encrypted. Set to false to pause encryption of new writes while
827
+ * still decrypting existing files.
828
+ */
829
+ private _secureStoreEncryptOnWrite;
830
+ /**
831
+ * When true, the secure-store is configured as required — writes
832
+ * MUST be encrypted and a locked store MUST reject writes rather
833
+ * than silently falling back to plaintext. Set by the orchestrator
834
+ * from `resolveRecallAuxiliaryCapabilities(config).secureStore`.
835
+ */
836
+ private _secureStoreRequired;
837
+ /**
838
+ * Set or clear the at-rest encryption key.
839
+ *
840
+ * Pass a 32-byte Buffer to enable encryption; pass null to clear
841
+ * (lock) the store. The caller is responsible for key lifecycle —
842
+ * this method does not zero the buffer on replacement; the keyring
843
+ * module (`keyring.ts`) owns zeroization.
844
+ */
845
+ setSecureStoreKey(key: Buffer | null, encryptOnWrite?: boolean): void;
846
+ private getEntityCacheSecureStoreKey;
847
+ /**
848
+ * Mark the secure-store as required for this storage instance.
849
+ * When required and locked, writes throw SecureStoreLockedError
850
+ * rather than silently writing plaintext.
851
+ */
852
+ setSecureStoreRequired(required: boolean): void;
853
+ /** Return true iff the secure-store key is currently set (store is unlocked). */
854
+ isSecureStoreUnlocked(): boolean;
855
+ /**
856
+ * Resolve the effective write key.
857
+ *
858
+ * - If `_secureStoreEncryptOnWrite` is false: returns null (plain write).
859
+ * - If `_secureStoreEncryptOnWrite` is true AND key is set: returns key.
860
+ * - If `_secureStoreEncryptOnWrite` is true AND key is null AND
861
+ * `_secureStoreRequired` is true: throws SecureStoreLockedError so the
862
+ * write fails loudly rather than silently writing plaintext (P1 finding
863
+ * from Cursor review of PR #767).
864
+ * - If `_secureStoreEncryptOnWrite` is true AND key is null AND
865
+ * `_secureStoreRequired` is false: returns null (unencrypted store).
866
+ */
867
+ private resolveWriteKey;
868
+ /**
869
+ * Snapshot the current content of a page before overwriting.
870
+ * No-op when versioning is disabled or the file does not yet exist.
871
+ */
872
+ private snapshotBeforeWrite;
873
+ /**
874
+ * Consolidation provenance helper (issue #561 PR 2).
875
+ *
876
+ * Captures the current on-disk content of a source memory as a
877
+ * page-version snapshot so the downstream consolidated write can record a
878
+ * `derived_from` pointer that actually resolves. Returns the
879
+ * `"<relative-path>:<versionId>"` entry expected by the `derived_from`
880
+ * frontmatter field.
881
+ *
882
+ * Returns `null` when versioning is disabled (snapshots would not be
883
+ * created), when the file does not exist (nothing to snapshot), or when
884
+ * the snapshot write itself fails (best-effort — callers skip the entry
885
+ * rather than block the consolidation).
886
+ */
887
+ snapshotForProvenance(filePath: string): Promise<string | null>;
888
+ constructor(baseDir: string, entitySchemas?: PluginConfig["entitySchemas"]);
889
+ /**
890
+ * The LIVE class object of this instance (issue #1809 review of the
891
+ * storage decomposition): extracted store modules must read/write the
892
+ * shared static caches (questionsCache, coldMemoriesCache, ...) through
893
+ * the SAME class binding the host methods use. Referencing the imported
894
+ * `StorageManager` symbol from a split bundle chunk can yield a second
895
+ * class copy with its own statics, split-braining the caches
896
+ * (resolveQuestion clears copy A while readQuestions reads copy B).
897
+ */
898
+ get storageManagerClass(): typeof StorageManager;
899
+ /** The root directory of this storage instance. */
900
+ /** MemoryReadStore (storage.ts decomposition). Lazy; selfDeps live wiring. */
901
+ private _memoryReadStore;
902
+ private get memoryReadStore();
903
+ /** EntityStore (storage.ts decomposition). Lazy; selfDeps live wiring. */
904
+ private _entityStore;
905
+ private get entityStore();
906
+ /** IdentityContinuityStore (storage.ts decomposition). Lazy; selfDeps live wiring. */
907
+ private _identityContinuityStore;
908
+ private get identityContinuityStore();
909
+ get dir(): string;
910
+ private identityFilePath;
911
+ private versionFilePath;
912
+ private bumpSharedVersion;
913
+ private readSharedVersion;
914
+ private bumpMemoryStatusVersion;
915
+ getMemoryStatusVersion(): number;
916
+ private bumpArtifactWriteVersion;
917
+ private getArtifactWriteVersion;
918
+ private get wearablesDir();
919
+ /**
920
+ * Resolve the on-disk path for a source/day transcript. Throws on
921
+ * malformed inputs — source ids and dates reach this from CLI/MCP/HTTP
922
+ * surfaces and must never become path traversal.
923
+ */
924
+ wearableTranscriptPath(sourceId: string, date: string): string;
925
+ writeWearableDayTranscript(sourceId: string, date: string, serialized: string): Promise<void>;
926
+ /** Read a stored day transcript; null when the day has no file. */
927
+ readWearableDayTranscript(sourceId: string, date: string): Promise<string | null>;
928
+ listWearableTranscriptDays(sourceId?: string): Promise<Array<{
929
+ source: string;
930
+ date: string;
931
+ }>>;
932
+ private _fusionStore?;
933
+ /** Derived fusion-day IO; file IO lives in wearables/fusion (#1810). */
934
+ fusionArtifactStore(): FusionArtifactStore;
935
+ /**
936
+ * Locate a wearable-sourced memory by exact (trimmed) content,
937
+ * ignoring the "[Attributes: ...]" suffix writeMemory appends for
938
+ * structuredAttributes — callers pass the raw fact text. Used by the
939
+ * smart trust pipeline to find an earlier borderline write when the
940
+ * same fact re-extracts with stronger evidence.
941
+ */
942
+ findWearableMemoryByContent(content: string): Promise<{
943
+ id: string;
944
+ status: MemoryStatus | undefined;
945
+ } | null>;
946
+ /**
947
+ * Promote a pending_review wearable memory to active in place,
948
+ * merging updated trust evidence into structuredAttributes. Returns
949
+ * false when the memory is missing or no longer pending_review (a
950
+ * concurrent review decision wins), or when the row is tombstone-blocked
951
+ * (`blockedBy` — issue #1579 threads OcuDx/Ocu1l): writeMemoryFrontmatter
952
+ * bypasses the writeMemory chokepoint, so a blocked row must first be
953
+ * cleared via revokeTombstone before promotion can proceed.
954
+ */
955
+ promoteWearableMemory(id: string, attributeUpdates: Record<string, string>, confidence?: number): Promise<boolean>;
956
+ /**
957
+ * Demote a pending_review wearable memory to rejected when a re-pass
958
+ * produced an explicit judge-reject verdict, merging the evidence.
959
+ * Returns false when the memory is missing or no longer
960
+ * pending_review — active rows are NEVER auto-demoted (operator
961
+ * approvals and accrued recall signals win; contradiction scans and
962
+ * supersession own active-row retirement).
963
+ */
964
+ demoteWearableMemory(id: string, attributeUpdates: Record<string, string>): Promise<boolean>;
965
+ private get factsDir();
966
+ private get correctionsDir();
967
+ private get proceduresDir();
968
+ private get reasoningTracesDir();
969
+ private get entitiesDir();
970
+ private resolveEntityFilePath;
971
+ private readStorageSecureFile;
972
+ private writeStorageSecureFile;
973
+ private writeStorageSecureFileChunks;
974
+ private assertManagedStoragePath;
975
+ readOfflineSyncFile(filePath: string): Promise<Buffer>;
976
+ digestOfflineSyncFile(filePath: string): Promise<{
977
+ sha256: string;
978
+ bytes: number;
979
+ }>;
980
+ private loadOfflineSyncDigestCache;
981
+ private readOfflineSyncDigestCache;
982
+ private rememberOfflineSyncDigest;
983
+ private scheduleOfflineSyncDigestCacheWrite;
984
+ private queueOfflineSyncDigestCacheWrite;
985
+ private offlineSyncFileIsEncrypted;
986
+ writeOfflineSyncFile(filePath: string, content: Buffer): Promise<void>;
987
+ writeOfflineSyncStagingFile(filePath: string, content: Buffer): Promise<void>;
988
+ writeOfflineSyncFileChunks(filePath: string, chunks: AsyncIterable<Buffer>): Promise<void>;
989
+ deleteOfflineSyncFile(filePath: string): Promise<void>;
990
+ private invalidateAfterOfflineSyncMutation;
991
+ createContentHashIndex(): ContentHashIndex;
992
+ private appendStorageSecureFile;
993
+ private appendStorageSecureFileUnlocked;
994
+ private get stateDir();
995
+ private get offlineSyncDigestCachePath();
996
+ private get entitySynthesisQueuePath();
997
+ private get factHashIndexReadyPath();
998
+ /**
999
+ * The on-disk tombstone log path. Lives under `<stateDir>/tombstones.jsonl`
1000
+ * so it is co-located with the fact-hash index and encrypted at rest when
1001
+ * the secure-store is enabled (the StorageManager's secure read/write
1002
+ * helpers are injected into the store).
1003
+ */
1004
+ private get tombstonesPath();
1005
+ /**
1006
+ * Configure the tombstone invariant for this storage instance. Installed
1007
+ * by the orchestrator after construction (same pattern as
1008
+ * `setVersioningConfig` / `citationTemplate`). When `enabled` is false
1009
+ * (default until the orchestrator wires config), the chokepoint check is a
1010
+ * no-op — pre-feature behavior for rollback safety (rule 30).
1011
+ */
1012
+ setTombstonesConfig(config: {
1013
+ enabled: boolean;
1014
+ semanticMatch: boolean;
1015
+ semanticThreshold: number;
1016
+ namespace: string;
1017
+ }): void;
1018
+ private buildTombstoneStore;
1019
+ /**
1020
+ * Lazily load the tombstone store. Mirrors the fact-hash-index lazy-load
1021
+ * pattern: a single in-flight load promise dedups concurrent first-access.
1022
+ * The cross-process staleness probe lives inside the store now (#1579): on
1023
+ * each cached access it stats its own file and invalidates if a peer process
1024
+ * appended, so the next lookup reloads from disk. If the probe just
1025
+ * invalidated the store, fall through to the reload branch — returning null
1026
+ * here was the original regression (the chokepoint threw and failed OPEN).
1027
+ */
1028
+ getTombstoneStore(): Promise<TombstoneStore>;
1029
+ /**
1030
+ * Whether tombstones are enabled on this storage. Callers that need to
1031
+ * distinguish "tombstones disabled" (null return is expected) from
1032
+ * "persistence failed" (appendTombstone swallows store errors and also
1033
+ * returns null) use this to fail closed when enabled (#1580 review OgIqp).
1034
+ */
1035
+ isTombstonesEnabled(): boolean;
1036
+ /**
1037
+ * Append a tombstone for a retired memory (issue #1579 emitters).
1038
+ * Best-effort: a tombstone append failure MUST NOT fail the supersession /
1039
+ * correction that triggered it (gotcha #13 / rule 34). The memory is
1040
+ * already retired on disk; the tombstone is the non-resurrection guard.
1041
+ */
1042
+ appendTombstone(input: {
1043
+ reason: TombstoneReason;
1044
+ createdBy: TombstoneCreatedBy;
1045
+ sourceMemoryId: string;
1046
+ rawContent: string;
1047
+ entityRef?: string;
1048
+ supersessionKey?: string;
1049
+ createdAt?: string;
1050
+ /** Canonical contentHash from the retired memory's frontmatter (#1579). */
1051
+ contentHash?: string;
1052
+ }): Promise<string | null>;
1053
+ /**
1054
+ * Revoke a tombstone (re-allow the content). Used by the review-queue
1055
+ * approval path when an operator approves a blocked memory.
1056
+ */
1057
+ revokeTombstone(tombstoneId: string, createdBy: TombstoneCreatedBy): Promise<string | null>;
1058
+ /** Aggregate tombstone stats for `remnic doctor`. */
1059
+ getTombstoneStats(): Promise<TombstoneStats | null>;
1060
+ /**
1061
+ * Rebuild the tombstone log from retired memories on disk. Exposed for
1062
+ * `remnic doctor --rebuild-tombstones` and tests.
1063
+ */
1064
+ rebuildTombstonesFromFiles(): Promise<number>;
1065
+ private getFactHashIndex;
1066
+ private ensureFactHashIndexAuthoritative;
1067
+ private get questionsDir();
1068
+ private get artifactsDir();
1069
+ private get identityDir();
1070
+ private get identityAnchorPath();
1071
+ private get identityIncidentsDir();
1072
+ private get identityAuditsWeeklyDir();
1073
+ private get identityAuditsMonthlyDir();
1074
+ private get identityImprovementLoopsPath();
1075
+ private get identityReflectionsPath();
1076
+ private get profilePath();
1077
+ private get memoryActionsPath();
1078
+ private get memoryLifecycleLedgerPath();
1079
+ private get compressionGuidelinesPath();
1080
+ private get compressionGuidelineDraftPath();
1081
+ private get compressionGuidelineStatePath();
1082
+ private get compressionGuidelineDraftStatePath();
1083
+ private get behaviorSignalsPath();
1084
+ /**
1085
+ * Buffer surprise telemetry ledger (issue #563 PR 3).
1086
+ *
1087
+ * Append-only JSONL of per-turn `BUFFER_SURPRISE` events emitted by
1088
+ * `SmartBuffer` when `bufferSurpriseTriggerEnabled` is on. Each row
1089
+ * captures the score, the threshold in force at the time, whether the
1090
+ * turn caused an extract_now upgrade, and the buffer size. Kept in
1091
+ * `state/` alongside the other append-only ledgers so cleanup and
1092
+ * governance sweeps can treat it uniformly.
1093
+ */
1094
+ private get bufferSurpriseLedgerPath();
1095
+ /**
1096
+ * Entity alias table loaded from THIS store's config/aliases.json.
1097
+ * Instance-scoped on purpose (issue #1534): multiple StorageManager
1098
+ * instances in one process (namespaces, hosted profiles, tenants) must
1099
+ * never share alias state — the previous module-level table let whichever
1100
+ * store loaded last rewrite every other store's canonical entity ids.
1101
+ */
1102
+ private userAliases;
1103
+ normalizeEntityName(raw: string, type: string): string;
1104
+ /**
1105
+ * Read-only view of this store's user alias table, for call sites that
1106
+ * normalize outside the manager (pass it to the free `normalizeEntityName`).
1107
+ */
1108
+ get entityAliases(): Readonly<Record<string, string>>;
1109
+ /**
1110
+ * Reload user-defined entity aliases from config/aliases.json in the memory
1111
+ * store. File format: { "variant": "canonical", ... }. The constructor
1112
+ * already loads aliases, so this is only needed to pick up file changes
1113
+ * (e.g. orchestrator.initialize() re-running on a live instance).
1114
+ * Non-object payloads and non-string or empty alias values are ignored.
1115
+ */
1116
+ loadAliases(): Promise<void>;
1117
+ private loadAliasesSync;
1118
+ ensureDirectories(): Promise<void>;
1119
+ /**
1120
+ * Resolve the on-disk write path for a memory of the given category, creating
1121
+ * the target directory. Category routing goes through the shared
1122
+ * `getCategoryDir()` chokepoint (utils/category-dir.ts → CATEGORY_DIR_MAP) so
1123
+ * decision/preference/moment/etc. outputs land in their dedicated dirs
1124
+ * (`decisions/`, `preferences/`, ...) instead of collapsing into `facts/`
1125
+ * (issue #1546; CLAUDE.md rule 39). `correction` keeps its historical flat
1126
+ * layout (no `<date>` subdir) as the corrections pipeline expects; every other
1127
+ * category — including `fact`/`entity`, which fall back to `facts/` — is dated
1128
+ * as `<dir>/<date>/`. Read/scan/reindex already iterate every category dir
1129
+ * (RECALL_FALLBACK_DIRS; QMD scans baseDir recursively), so writes stay found.
1130
+ */
1131
+ private resolveCategoryWritePath;
1132
+ writeMemory(category: MemoryCategory, content: string, options?: {
1133
+ actor?: string;
1134
+ confidence?: number;
1135
+ tags?: string[];
1136
+ entityRef?: string;
1137
+ source?: string;
1138
+ supersedes?: string;
1139
+ lineage?: string[];
1140
+ importance?: ImportanceScore;
1141
+ links?: MemoryLink[];
1142
+ intentGoal?: string;
1143
+ intentActionType?: string;
1144
+ intentEntityTypes?: string[];
1145
+ artifactType?: MemoryFrontmatter["artifactType"];
1146
+ sourceMemoryId?: string;
1147
+ sourceTurnId?: string;
1148
+ memoryKind?: MemoryFrontmatter["memoryKind"];
1149
+ expiresAt?: string;
1150
+ validAt?: string;
1151
+ observedAt?: string;
1152
+ eventTimeSource?: "extracted" | "assumed";
1153
+ invalidAt?: string;
1154
+ structuredAttributes?: Record<string, string>;
1155
+ /**
1156
+ * When provided, this string is used as the source for the fact-content
1157
+ * dedup hash index instead of the persisted body (`content`).
1158
+ *
1159
+ * Use this when the persisted body differs from the canonical fact text
1160
+ * — for example when `content` is a citation-annotated variant of a raw
1161
+ * fact. Passing the raw fact as `contentHashSource` ensures that
1162
+ * `hasFactContentHash(rawFact)` returns `true` after the write, so
1163
+ * subsequent extractions of the same logical fact are correctly deduped
1164
+ * even when their citation timestamp differs.
1165
+ */
1166
+ contentHashSource?: string;
1167
+ status?: MemoryStatus;
1168
+ /**
1169
+ * Consolidation provenance (issue #561 PR 2). When the caller is a
1170
+ * consolidation / supersession / dedup-merge path, these fields wire
1171
+ * the page-version snapshots the new memory was derived from and the
1172
+ * operator that produced it. Persisted onto frontmatter as
1173
+ * `derived_from` + `derived_via`; validated at serialize time.
1174
+ */
1175
+ derivedFrom?: string[];
1176
+ derivedVia?: ConsolidationOperator;
1177
+ /**
1178
+ * Faithfulness gate verdict (issue #1576). When provided, persisted to
1179
+ * frontmatter so downstream readers (TrustScore #1577, review queue)
1180
+ * can consume it. Absent = gate was off or fact predates #1576.
1181
+ */
1182
+ faithfulness?: FaithfulnessFrontmatter;
1183
+ /**
1184
+ * Claim-level provenance spans (issue #1575 PR 2). When provided,
1185
+ * persisted to frontmatter so downstream readers (memory_get, x-ray,
1186
+ * faithfulness gate #1576) can consume them. Absent = fact predates
1187
+ * #1575 or provenance was disabled.
1188
+ */
1189
+ sources?: ProvenanceSource[];
1190
+ provenance?: "verified" | "unverified" | "none";
1191
+ }): Promise<MemoryWriteResult>;
1192
+ hasFactContentHash(content: string): Promise<boolean>;
1193
+ private factContentHashForRemoval;
1194
+ private addActiveFactContentHash;
1195
+ /**
1196
+ * Re-register a fact's contentHash in the dedup index after a tombstone
1197
+ * block is lifted on approval (issue #1579 thread ObnTy). `writeMemory`
1198
+ * skips hash-index registration for tombstone-blocked facts (rule 44); when
1199
+ * the review queue later promotes such a fact back to `status: active`, the
1200
+ * hash must enter the index or the next extraction of the same content
1201
+ * creates a second active fact. Reads the memory by id so the caller (the
1202
+ * review CLI) does not need to re-parse the file. No-op for non-facts or
1203
+ * facts that are not active.
1204
+ */
1205
+ restoreFactHashAfterApproval(memoryId: string): Promise<void>;
1206
+ private syncFactHashIndexAfterRewrite;
1207
+ removeFactContentHashesForMemories(memories: MemoryFile[]): Promise<void>;
1208
+ isFactContentHashAuthoritative(): Promise<boolean>;
1209
+ writeArtifact(quote: string, options?: {
1210
+ actor?: string;
1211
+ tags?: string[];
1212
+ confidence?: number;
1213
+ artifactType?: MemoryFrontmatter["artifactType"];
1214
+ sourceMemoryId?: string;
1215
+ sourceTurnId?: string;
1216
+ intentGoal?: string;
1217
+ intentActionType?: string;
1218
+ intentEntityTypes?: string[];
1219
+ }): Promise<string>;
1220
+ private readAllArtifactsCached;
1221
+ searchArtifacts(query: string, maxResults: number): Promise<MemoryFile[]>;
1222
+ writeEntity(name: string, type: string, facts: string[], options?: {
1223
+ timestamp?: string;
1224
+ source?: string;
1225
+ sessionKey?: string;
1226
+ principal?: string;
1227
+ structuredSections?: EntityStructuredSection[];
1228
+ }): Promise<string>;
1229
+ readProfile(): Promise<string>;
1230
+ writeProfile(content: string): Promise<void>;
1231
+ /**
1232
+ * Normalize a string for fuzzy profile dedup: lowercase, strip punctuation, collapse whitespace.
1233
+ */
1234
+ private static normalizeForDedup;
1235
+ /**
1236
+ * Check if a new bullet is a fuzzy duplicate of any existing bullet.
1237
+ * Returns true if the new bullet should be skipped.
1238
+ */
1239
+ private static isFuzzyDuplicate;
1240
+ appendToProfile(updates: string[]): Promise<void>;
1241
+ /** Check if profile.md exceeds the max line cap and needs LLM consolidation */
1242
+ profileNeedsConsolidation(triggerLines?: number): Promise<boolean>;
1243
+ readAllMemories(): Promise<MemoryFile[]>;
1244
+ /** Invalidate the readAllMemories() cache after writes that add/remove memories. */
1245
+ /** Public cache invalidation for callers that need authoritative disk reads
1246
+ * (e.g. projection verify/rebuild). */
1247
+ invalidateAllMemoriesCacheForDir(): void;
1248
+ /** Invalidate only the cache layers affected by direct tier file deletes. */
1249
+ invalidateMemoryCachesForTiers(tiers: Iterable<"hot" | "cold" | "archive">): void;
1250
+ /** Clear ALL static caches. Use in tests that write files directly
1251
+ * (bypassing StorageManager.writeMemory) to avoid stale reads. */
1252
+ static clearAllStaticCaches(): void;
1253
+ /** Cancel any in-flight concurrent read so the next readAllMemories()
1254
+ * starts a fresh disk scan and sees the just-written data.
1255
+ *
1256
+ * Finding UvBq (PR #402 round-11): this method intentionally does NOT
1257
+ * invalidate the cold-scan cache. Ordinary hot-tier writes (writeMemory)
1258
+ * do not change cold-tier content, so evicting the cold cache on every hot
1259
+ * write was defeating the burst-dedup optimisation — the cold cache was
1260
+ * cleared before applyTemporalSupersession ran, causing a full cold-tree
1261
+ * disk scan on every write in a burst. Cold cache invalidation is handled
1262
+ * exclusively by invalidateColdMemoriesCache(), which is called only when
1263
+ * cold content actually changes (hot→cold demotions, writeMemoryFileAtomic
1264
+ * inside cold/, archiveMemory, etc.). */
1265
+ private invalidateAllMemoriesCache;
1266
+ /**
1267
+ * Invalidate the cold-scan cache for this storage root and bump the
1268
+ * on-disk cold-version sentinel so that other processes (gateway, CLI) see
1269
+ * the change immediately on their next readAllColdMemories() call.
1270
+ *
1271
+ * Must be called whenever a memory is written INTO the cold tier — hot→cold
1272
+ * demotion, atomic writes inside cold/, archiving a cold memory, etc.
1273
+ * NOT called on ordinary hot-tier writes (those don't change cold contents).
1274
+ *
1275
+ * Finding UvUy (PR #402 round-11): bumping the sentinel here makes the
1276
+ * per-process in-memory cache safe across process boundaries.
1277
+ */
1278
+ private invalidateColdMemoriesCache;
1279
+ /** Return the current cold-write version counter for this storage root.
1280
+ * Reads the on-disk sentinel (state/cold-write.log) so it reflects writes
1281
+ * made by other processes. */
1282
+ private readColdWriteVersion;
1283
+ /** Bump the on-disk cold-write version sentinel and update the in-process
1284
+ * fallback map. Called by invalidateColdMemoriesCache(). */
1285
+ private bumpColdWriteVersion;
1286
+ private normalizeMemoryReadBatchSize;
1287
+ private collectActiveMemoryPaths;
1288
+ private readParsedMemoriesFromPaths;
1289
+ private readWindowUpdatedMs;
1290
+ private filterWindowPathsByUpdatedAfter;
1291
+ private orderWindowPaths;
1292
+ private readWindowBoundedBatch;
1293
+ readMemoriesWindow(options?: {
1294
+ maxMemories?: number;
1295
+ batchSize?: number;
1296
+ updatedAfter?: Date;
1297
+ }): Promise<{
1298
+ memories: MemoryFile[];
1299
+ filePaths: string[];
1300
+ }>;
1301
+ private _readAllMemoriesFromDisk;
1302
+ readAllColdMemories(): Promise<MemoryFile[]>;
1303
+ /**
1304
+ * Read archived memory markdown files under archive/.
1305
+ * Used by long-term recall fallback when hot recall has no hits.
1306
+ */
1307
+ readArchivedMemories(): Promise<MemoryFile[]>;
1308
+ readMemoryByPath(filePath: string): Promise<MemoryFile | null>;
1309
+ private resolveTierRootDir;
1310
+ private resolveMemoryDateDir;
1311
+ private isArtifactMemory;
1312
+ buildTierMemoryPath(memory: MemoryFile, tier: "hot" | "cold"): string;
1313
+ private writeMemoryFileAtomic;
1314
+ moveMemoryToPath(memory: MemoryFile, targetPath: string): Promise<void>;
1315
+ migrateMemoryToTier(memory: MemoryFile, targetTier: "hot" | "cold"): Promise<{
1316
+ changed: boolean;
1317
+ targetPath: string;
1318
+ }>;
1319
+ private get archiveDir();
1320
+ /**
1321
+ * Archive a memory by moving it from facts/ to archive/YYYY-MM-DD/.
1322
+ * Updates frontmatter with archived status before moving.
1323
+ * Returns the new file path on success, null on failure.
1324
+ */
1325
+ archiveMemory(memory: MemoryFile, lifecycle?: MemoryLifecycleEventWriteOptions): Promise<string | null>;
1326
+ readEntities(): Promise<string[]>;
1327
+ readEntity(name: string): Promise<string>;
1328
+ listEntityNames(): Promise<string[]>;
1329
+ /**
1330
+ * Find an existing entity that fuzzy-matches the proposed name.
1331
+ * Returns the existing entity filename (without .md) or null if no match.
1332
+ *
1333
+ * Matching priority:
1334
+ * 1. Exact normalized match (handled by normalizeEntityName already)
1335
+ * 2. Dehyphenated match: "jane-doe" vs "janedoe"
1336
+ * 3. Substring containment: "handle-janedoe" contains "janedoe"
1337
+ * 4. Levenshtein ≤ 2 on dehyphenated names
1338
+ */
1339
+ findMatchingEntity(proposedName: string, type: string): Promise<string | null>;
1340
+ invalidateMemory(id: string): Promise<boolean>;
1341
+ updateMemory(id: string, newContent: string, options?: {
1342
+ supersedes?: string;
1343
+ lineage?: string[];
1344
+ actor?: string;
1345
+ }): Promise<boolean>;
1346
+ /**
1347
+ * Update frontmatter fields without changing memory content.
1348
+ * Returns false when the memory is not found.
1349
+ */
1350
+ writeMemoryFrontmatter(memory: MemoryFile, patch: Partial<MemoryFrontmatter>, lifecycle?: MemoryLifecycleEventWriteOptions): Promise<boolean>;
1351
+ /**
1352
+ * Update frontmatter by memory ID.
1353
+ * Prefer writeMemoryFrontmatter(memory, patch) in batch loops to avoid full-corpus rescans.
1354
+ */
1355
+ updateMemoryFrontmatter(id: string, patch: Partial<MemoryFrontmatter>): Promise<boolean>;
1356
+ /** Remove memories past their TTL expiresAt date */
1357
+ cleanExpiredTTL(): Promise<MemoryFile[]>;
1358
+ loadBuffer(): Promise<BufferState>;
1359
+ saveBuffer(state: BufferState): Promise<void>;
1360
+ loadMeta(): Promise<MetaState>;
1361
+ saveMeta(state: MetaState): Promise<void>;
1362
+ appendMemoryActionEvents(events: MemoryActionEvent[]): Promise<number>;
1363
+ appendMemoryLifecycleEvents(events: MemoryLifecycleEvent[]): Promise<number>;
1364
+ appendBufferSurpriseEvents(events: BufferSurpriseEvent[]): Promise<number>;
1365
+ readBufferSurpriseEvents(options?: {
1366
+ limit?: number;
1367
+ }): Promise<BufferSurpriseEvent[]>;
1368
+ appendBehaviorSignals(events: BehaviorSignalEvent[]): Promise<number>;
1369
+ appendReextractJobs(events: ReextractJobRequest[]): Promise<number>;
1370
+ readReextractJobs(limit?: number): Promise<ReextractJobRequest[]>;
1371
+ readBehaviorSignals(limit?: number): Promise<BehaviorSignalEvent[]>;
1372
+ readMemoryActionEvents(limit?: number): Promise<MemoryActionEvent[]>;
1373
+ readMemoryActionEventRows(limit?: number): Promise<Array<{
1374
+ line: number;
1375
+ event: MemoryActionEvent;
1376
+ }>>;
1377
+ readAllMemoryLifecycleEvents(): Promise<MemoryLifecycleEvent[]>;
1378
+ readMemoryLifecycleEvents(limit?: number): Promise<MemoryLifecycleEvent[]>;
1379
+ writeCompressionGuidelines(content: string): Promise<void>;
1380
+ readCompressionGuidelines(): Promise<string | null>;
1381
+ writeCompressionGuidelineDraft(content: string): Promise<void>;
1382
+ readCompressionGuidelineDraft(): Promise<string | null>;
1383
+ writeCompressionGuidelineOptimizerState(state: CompressionGuidelineOptimizerState): Promise<void>;
1384
+ writeCompressionGuidelineDraftState(state: CompressionGuidelineOptimizerState): Promise<void>;
1385
+ readCompressionGuidelineOptimizerState(): Promise<CompressionGuidelineOptimizerState | null>;
1386
+ readCompressionGuidelineDraftState(): Promise<CompressionGuidelineOptimizerState | null>;
1387
+ activateCompressionGuidelineDraft(options?: {
1388
+ expectedContentHash?: string;
1389
+ expectedGuidelineVersion?: number;
1390
+ }): Promise<boolean>;
1391
+ private readCompressionGuidelineStateFile;
1392
+ writeIdentityAnchor(content: string): Promise<void>;
1393
+ readIdentityAnchor(): Promise<string | null>;
1394
+ appendContinuityIncident(input: ContinuityIncidentOpenInput): Promise<ContinuityIncidentRecord>;
1395
+ readContinuityIncidents(limit?: number, state?: "open" | "closed" | "all"): Promise<ContinuityIncidentRecord[]>;
1396
+ closeContinuityIncident(id: string, closure: ContinuityIncidentCloseInput): Promise<ContinuityIncidentRecord | null>;
1397
+ writeIdentityAudit(period: "weekly" | "monthly", key: string, content: string): Promise<string>;
1398
+ readIdentityAudit(period: "weekly" | "monthly", key: string): Promise<string | null>;
1399
+ writeIdentityImprovementLoops(content: string): Promise<void>;
1400
+ readIdentityImprovementLoops(): Promise<string | null>;
1401
+ readIdentityImprovementLoopRegister(): Promise<ContinuityImprovementLoop[]>;
1402
+ upsertIdentityImprovementLoop(input: ContinuityLoopUpsertInput): Promise<ContinuityImprovementLoop>;
1403
+ reviewIdentityImprovementLoop(id: string, input: ContinuityLoopReviewInput): Promise<ContinuityImprovementLoop | null>;
1404
+ private generateId;
1405
+ writeQuestion(question: string, context: string, priority: number): Promise<string>;
1406
+ readQuestions(opts?: {
1407
+ unresolvedOnly?: boolean;
1408
+ }): Promise<Array<{
1409
+ id: string;
1410
+ question: string;
1411
+ context: string;
1412
+ priority: number;
1413
+ resolved: boolean;
1414
+ created: string;
1415
+ filePath: string;
1416
+ }>>;
1417
+ /** Invalidate the questions cache (call after writing a question). */
1418
+ invalidateQuestionsCache(): void;
1419
+ private parseQuestionFile;
1420
+ private extractFrontmatterValue;
1421
+ resolveQuestion(id: string): Promise<boolean>;
1422
+ readIdentity(workspaceDir: string, namespace?: string): Promise<string>;
1423
+ writeIdentity(workspaceDir: string, content: string, namespace?: string): Promise<void>;
1424
+ /** Max size for IDENTITY.md before we stop appending reflections (15KB leaves room under 20KB gateway limit) */
1425
+ private static readonly IDENTITY_MAX_BYTES;
1426
+ /** Minimum interval between reflections (1 hour) */
1427
+ private static readonly REFLECTION_COOLDOWN_MS;
1428
+ appendToIdentity(workspaceDir: string, reflection: string, opts?: {
1429
+ hygiene?: FileHygieneConfig;
1430
+ namespace?: string;
1431
+ }): Promise<void>;
1432
+ readIdentityReflections(): Promise<string | null>;
1433
+ writeIdentityReflections(content: string): Promise<void>;
1434
+ appendIdentityReflection(reflection: string): Promise<void>;
1435
+ /**
1436
+ * Add a relationship to an entity file.
1437
+ * Deduplicates by target+label.
1438
+ */
1439
+ addEntityRelationship(name: string, rel: EntityRelationship): Promise<void>;
1440
+ /**
1441
+ * Add an activity entry to an entity file.
1442
+ * Prepends to the beginning, prunes oldest entries beyond maxEntries.
1443
+ */
1444
+ addEntityActivity(name: string, entry: EntityActivityEntry, maxEntries: number): Promise<void>;
1445
+ /**
1446
+ * Add an alias to an entity file. Deduplicates.
1447
+ */
1448
+ addEntityAlias(name: string, alias: string): Promise<void>;
1449
+ updateEntitySynthesis(name: string, synthesis: string, options?: {
1450
+ entityUpdatedAt?: string;
1451
+ synthesisStructuredFactCount?: number;
1452
+ synthesisStructuredFactDigest?: string;
1453
+ synthesisTimelineCount?: number;
1454
+ updatedAt?: string;
1455
+ incrementVersion?: boolean;
1456
+ }): Promise<void>;
1457
+ /**
1458
+ * Backward-compatible alias for legacy callers/tests.
1459
+ */
1460
+ updateEntitySummary(name: string, summary: string): Promise<void>;
1461
+ readEntitySynthesisQueue(): Promise<string[]>;
1462
+ refreshEntitySynthesisQueue(): Promise<string[]>;
1463
+ removeEntitySynthesisQueueEntries(entityNames: string[]): Promise<void>;
1464
+ migrateEntityFilesToCompiledTruthTimeline(): Promise<{
1465
+ total: number;
1466
+ migrated: number;
1467
+ }>;
1468
+ readAllEntityFiles(): Promise<EntityFile[]>;
1469
+ /**
1470
+ * Score an entity based on recency, frequency, activity, type priority,
1471
+ * and relationship density.
1472
+ *
1473
+ * score = recency*0.40 + frequency*0.25 + activity*0.15 + typePriority*0.10 + relationshipDensity*0.10
1474
+ */
1475
+ static scoreEntity(entity: EntityFile, now: Date): number;
1476
+ buildKnowledgeIndex(config: PluginConfig, overrides?: {
1477
+ maxEntities?: number;
1478
+ maxChars?: number;
1479
+ }): Promise<{
1480
+ result: string;
1481
+ cached: boolean;
1482
+ }>;
1483
+ /** Invalidate the Knowledge Index cache (call after entity mutations). */
1484
+ invalidateKnowledgeIndexCache(): void;
1485
+ /** Max lines for profile.md before LLM consolidation triggers */
1486
+ private static readonly PROFILE_MAX_LINES;
1487
+ mergeFragmentedEntities(): Promise<number>;
1488
+ cleanExpiredCommitments(decayDays: number): Promise<MemoryFile[]>;
1489
+ /**
1490
+ * Flush batched access tracking updates to disk.
1491
+ * Called during consolidation or when buffer exceeds max size.
1492
+ */
1493
+ flushAccessTracking(entries: AccessTrackingEntry[]): Promise<number>;
1494
+ /**
1495
+ * Get a memory by its ID.
1496
+ */
1497
+ getMemoryById(id: string): Promise<MemoryFile | null>;
1498
+ /**
1499
+ * Check which of the given memory IDs actually exist on disk.
1500
+ *
1501
+ * Uses a lightweight directory scan (collectActiveMemoryPaths) that reads
1502
+ * file names without parsing frontmatter — much cheaper than readAllMemories()
1503
+ * for simple existence checks like citation usage tracking.
1504
+ *
1505
+ * Returns the subset of `ids` that correspond to real memory files.
1506
+ */
1507
+ filterExistingMemoryIds(ids: string[]): Promise<Set<string>>;
1508
+ getProjectedMemoryState(id: string): Promise<MemoryProjectionCurrentState | null>;
1509
+ browseProjectedMemories(options: ProjectedMemoryBrowseOptions): Promise<ProjectedMemoryBrowsePage | null>;
1510
+ getProjectedGovernanceRecord(): Promise<ReturnType<typeof readProjectedGovernanceRecord>>;
1511
+ private toProjectedCurrentState;
1512
+ getMemoryTimeline(memoryId: string, limit?: number): Promise<MemoryLifecycleEvent[]>;
1513
+ /**
1514
+ * Write a memory chunk with parent reference.
1515
+ * Chunk IDs follow format: {parentId}-chunk-{index}
1516
+ */
1517
+ writeChunk(parentId: string, chunkIndex: number, chunkTotal: number, category: MemoryCategory, content: string, options?: {
1518
+ confidence?: number;
1519
+ tags?: string[];
1520
+ entityRef?: string;
1521
+ source?: string;
1522
+ importance?: ImportanceScore;
1523
+ intentGoal?: string;
1524
+ intentActionType?: string;
1525
+ intentEntityTypes?: string[];
1526
+ memoryKind?: MemoryFrontmatter["memoryKind"];
1527
+ validAt?: string;
1528
+ /** Lifecycle status (issue #1576): pending_review chunks stay out of active recall. */
1529
+ status?: MemoryStatus;
1530
+ /**
1531
+ * Tombstone block provenance (issue #1645): when the parent fact was
1532
+ * tombstone-blocked, propagate the tombstone id onto each chunk so an
1533
+ * independently-surfaced chunk (memory_get/x-ray/doctor) reveals the block
1534
+ * and the chunk stays pending_review, never an active resurrection.
1535
+ */
1536
+ blockedBy?: string;
1537
+ /** Faithfulness gate verdict (issue #1576), propagated from the parent fact. */
1538
+ faithfulness?: FaithfulnessFrontmatter;
1539
+ /** Claim-level provenance spans (issue #1575 PR 2), propagated from the parent fact so a chunk surfaced independently (memory_get/x-ray) preserves them (chatgpt-codex-connector thread Ocvmo). */
1540
+ sources?: ProvenanceSource[];
1541
+ /** Coarse provenance tag (issue #1575 PR 2), propagated from the parent. */
1542
+ provenance?: "verified" | "unverified" | "none";
1543
+ invalidAt?: string;
1544
+ observedAt?: string;
1545
+ eventTimeSource?: "extracted" | "assumed";
1546
+ }): Promise<string>;
1547
+ /**
1548
+ * Get all chunks for a given parent memory ID.
1549
+ * Returns chunks sorted by chunkIndex.
1550
+ */
1551
+ getChunksForParent(parentId: string): Promise<MemoryFile[]>;
1552
+ /**
1553
+ * Mark a memory as superseded by another.
1554
+ * Updates the old memory's status and adds the supersededBy link.
1555
+ */
1556
+ supersedeMemory(oldMemoryId: string, newMemoryId: string, reason: string): Promise<boolean>;
1557
+ private get summariesDir();
1558
+ /**
1559
+ * Write a memory summary.
1560
+ */
1561
+ writeSummary(summary: MemorySummary): Promise<void>;
1562
+ /**
1563
+ * Get all summaries.
1564
+ */
1565
+ readSummaries(): Promise<MemorySummary[]>;
1566
+ /**
1567
+ * Archive memories (mark as archived, not delete).
1568
+ */
1569
+ archiveMemories(memoryIds: string[], summaryId: string): Promise<number>;
1570
+ /**
1571
+ * Save topic scores to meta.json.
1572
+ */
1573
+ saveTopics(topics: TopicScore[]): Promise<void>;
1574
+ /**
1575
+ * Load topic scores from meta.json.
1576
+ */
1577
+ loadTopics(): Promise<{
1578
+ topics: TopicScore[];
1579
+ updatedAt: string | null;
1580
+ }>;
1581
+ /**
1582
+ * Add links to an existing memory.
1583
+ */
1584
+ addLinksToMemory(memoryId: string, links: MemoryLink[], lifecycle?: MemoryLifecycleEventWriteOptions): Promise<boolean>;
1585
+ private summarizeLifecycleState;
1586
+ private frontmatterPatchEventType;
1587
+ private appendGeneratedMemoryLifecycleEvent;
1588
+ private appendGeneratedMemoryLifecycleEventFailOpen;
1589
+ }
1590
+
1591
+ export { countEntityStructuredFacts as A, fingerprintEntityStructuredFacts as B, ContentHashIndex as C, type DisagreementKind as D, isEntitySynthesisStale as E, FusionArtifactStore as F, isValidBufferSurpriseEvent as G, normalizeEntityName as H, normalizeFrontmatterForPath as I, normalizeStructuredSectionFacts as J, parseFrontmatter as K, parseFrontmatterStringValue as L, type MemoryWriteResult as M, type ReextractJobRequest as R, StorageManager as S, type FusedWearableConversation as a, type FusionConversationInput as b, type FusedSpeaker as c, type FusedSegment as d, type FusedDisagreement as e, type FusionOptions as f, type FusionDayResult as g, FUSION_KIND as h, type FusedContribution as i, type FusedConversationProvenance as j, type FusedDayFile as k, type FusedDayMeta as l, type FusedSegmentProvenance as m, type FusionSegmentInput as n, type SegmentPickReason as o, composeFusionDayMeta as p, hashFusionBody as q, normalizeAttributePairs as r, parseEntityFile as s, parseFusionDay as t, serializeEntityFile as u, serializeFusionDay as v, type MemoryLifecycleEventWriteOptions as w, buildEntitySchemaCacheKey as x, compareEntityTimestamps as y, compileEntityFacts as z };