@remnic/core 9.65.8 → 9.66.1

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 (702) hide show
  1. package/dist/access-admin-ops-surface.d.ts +11 -12
  2. package/dist/access-admin-ops-surface.js +54 -51
  3. package/dist/access-authorization-probe.d.ts +11 -12
  4. package/dist/access-authorization-probe.js +55 -52
  5. package/dist/access-boundary.d.ts +11 -12
  6. package/dist/access-boundary.js +54 -51
  7. package/dist/access-citation-namespace.js +3 -3
  8. package/dist/access-cli.js +132 -125
  9. package/dist/access-cli.js.map +1 -1
  10. package/dist/access-coding-context-resolution.d.ts +1 -2
  11. package/dist/access-coding-context-resolution.js +2 -2
  12. package/dist/access-extraction-force-flush.d.ts +11 -12
  13. package/dist/access-extraction-force-flush.js +54 -51
  14. package/dist/access-health-types.d.ts +1 -2
  15. package/dist/access-http-lcm-compaction.d.ts +11 -12
  16. package/dist/access-http-lifecycle-flush.d.ts +11 -12
  17. package/dist/access-http-offline-stream.d.ts +11 -12
  18. package/dist/access-http-query.d.ts +2 -3
  19. package/dist/access-http-query.js +56 -53
  20. package/dist/access-http.d.ts +12 -13
  21. package/dist/access-http.js +77 -74
  22. package/dist/access-identity-continuity-surface.d.ts +9 -10
  23. package/dist/access-identity-continuity-surface.js +54 -51
  24. package/dist/access-lcm-surface.d.ts +11 -12
  25. package/dist/access-lcm-surface.js +54 -51
  26. package/dist/access-mcp-output-schemas.js +1 -1
  27. package/dist/access-mcp.d.ts +11 -12
  28. package/dist/access-mcp.js +67 -64
  29. package/dist/access-memory-search-fanout.d.ts +2 -3
  30. package/dist/{access-namespace-preflight-CpAOrS-9.d.ts → access-namespace-preflight-50VIkPhB.d.ts} +1 -1
  31. package/dist/access-namespace-preflight.d.ts +3 -4
  32. package/dist/access-namespace-preflight.js +54 -51
  33. package/dist/access-observe-write-surface.d.ts +11 -12
  34. package/dist/access-observe-write-surface.js +54 -51
  35. package/dist/access-offline-manifest.d.ts +9 -10
  36. package/dist/access-offline-manifest.js +15 -15
  37. package/dist/access-operations-batch.js +59 -56
  38. package/dist/access-operations.d.ts +12 -13
  39. package/dist/access-operations.js +64 -61
  40. package/dist/access-recall-concurrency.d.ts +11 -12
  41. package/dist/access-recall-concurrency.js +54 -51
  42. package/dist/access-recall-response.d.ts +11 -12
  43. package/dist/access-recall-response.js +54 -51
  44. package/dist/access-recall-surface.d.ts +11 -12
  45. package/dist/access-recall-surface.js +54 -51
  46. package/dist/access-schema.d.ts +12 -12
  47. package/dist/access-schema.js +5 -5
  48. package/dist/{access-service-Diu61Cfv.d.ts → access-service-C2tV2-uL.d.ts} +8 -8
  49. package/dist/access-service-helpers.d.ts +11 -12
  50. package/dist/access-service.d.ts +11 -12
  51. package/dist/access-service.js +54 -51
  52. package/dist/access-surface-catalog.d.ts +11 -12
  53. package/dist/access-surface-catalog.js +58 -53
  54. package/dist/access-surface-catalog.js.map +1 -1
  55. package/dist/access-wearables-meetings-surface.d.ts +3 -4
  56. package/dist/action-confidence.d.ts +1 -2
  57. package/dist/active-memory-bridge.d.ts +1 -2
  58. package/dist/active-memory-bridge.js +2 -2
  59. package/dist/active-recall.d.ts +1 -2
  60. package/dist/active-recall.js +11 -11
  61. package/dist/adapters/index.js +7 -7
  62. package/dist/adapters/registry.js +3 -3
  63. package/dist/ambient-provenance.d.ts +1 -2
  64. package/dist/artifact-search.d.ts +1 -2
  65. package/dist/{auto-sync-2YPITIWN.js → auto-sync-Q6Q2FVSC.js} +9 -9
  66. package/dist/behavior-learner.d.ts +1 -2
  67. package/dist/behavior-signals.d.ts +1 -2
  68. package/dist/bootstrap.d.ts +9 -10
  69. package/dist/briefing-window.d.ts +2 -3
  70. package/dist/briefing.d.ts +2 -3
  71. package/dist/briefing.js +28 -28
  72. package/dist/buffer-surprise-report.d.ts +1 -2
  73. package/dist/buffer-turn-helpers.d.ts +1 -2
  74. package/dist/buffer.d.ts +2 -3
  75. package/dist/buffer.js +20 -4
  76. package/dist/bulk-import/index.d.ts +3 -4
  77. package/dist/calibration.d.ts +1 -2
  78. package/dist/calibration.js +1 -1
  79. package/dist/capabilities.d.ts +1 -2
  80. package/dist/{capsule-merge-SGIVB3WA.js → capsule-merge-SEHERWWP.js} +4 -4
  81. package/dist/{catalog-9f-vEQLS.d.ts → catalog-C2jA-gLm.d.ts} +1 -1
  82. package/dist/causal-behavior.d.ts +1 -2
  83. package/dist/causal-consolidation.d.ts +1 -2
  84. package/dist/causal-consolidation.js +29 -29
  85. package/dist/causal-trajectory-graph.d.ts +1 -2
  86. package/dist/{chunk-LEPOP46W.js → chunk-227UFSEQ.js} +4 -4
  87. package/dist/{chunk-TFR3HG4K.js → chunk-2FA7U5XY.js} +4 -4
  88. package/dist/{chunk-PO7NXBG2.js → chunk-2GF27PGH.js} +5 -5
  89. package/dist/{chunk-W2BAGGEW.js → chunk-2ITZ74A6.js} +40 -31
  90. package/dist/{chunk-W2BAGGEW.js.map → chunk-2ITZ74A6.js.map} +1 -1
  91. package/dist/{chunk-MY2BC6UE.js → chunk-2X6BGKQL.js} +11 -11
  92. package/dist/{chunk-UEBDCMOO.js → chunk-3TSU662L.js} +3 -3
  93. package/dist/{chunk-XAB6STPO.js → chunk-46XR5FNZ.js} +53 -3
  94. package/dist/chunk-46XR5FNZ.js.map +1 -0
  95. package/dist/{chunk-FP7YTTVO.js → chunk-4OFKZAJG.js} +2 -1
  96. package/dist/chunk-4OFKZAJG.js.map +1 -0
  97. package/dist/{chunk-S5XOSTYM.js → chunk-4XLTUR6R.js} +3 -3
  98. package/dist/{chunk-BWGCOLEL.js → chunk-65JOGLIS.js} +2 -2
  99. package/dist/{chunk-HMZKGHMD.js → chunk-7UOXCCCI.js} +3 -3
  100. package/dist/{chunk-7WOWGRAU.js → chunk-AF5H7TKI.js} +108 -23
  101. package/dist/chunk-AF5H7TKI.js.map +1 -0
  102. package/dist/{chunk-7BDZTALN.js → chunk-AJTG3CP7.js} +12 -2
  103. package/dist/chunk-AJTG3CP7.js.map +1 -0
  104. package/dist/{chunk-2LWQSV6A.js → chunk-AL3UYZ5N.js} +3 -2
  105. package/dist/chunk-AL3UYZ5N.js.map +1 -0
  106. package/dist/{chunk-4F4AQFWL.js → chunk-B4AOWRYF.js} +10 -10
  107. package/dist/{chunk-ODU2CNNX.js → chunk-C5IUOBCN.js} +2 -2
  108. package/dist/{chunk-3A2NJP2U.js → chunk-CHGG74CY.js} +3 -3
  109. package/dist/{chunk-76DIF5KT.js → chunk-CX4OLNIH.js} +2 -2
  110. package/dist/{chunk-Z3YEGSR4.js → chunk-D3UXGE5D.js} +10 -10
  111. package/dist/{chunk-5HK3CJAR.js → chunk-D6Q5EPOV.js} +2 -2
  112. package/dist/{chunk-EGBDFJ36.js → chunk-DD5JFCWM.js} +2 -2
  113. package/dist/{chunk-XBGHAAKR.js → chunk-DDX6KIXF.js} +2 -2
  114. package/dist/{chunk-JIYDRBVZ.js → chunk-DJORULH3.js} +2 -2
  115. package/dist/{chunk-7KQB4EBS.js → chunk-DUAJKRR2.js} +2 -2
  116. package/dist/{chunk-XDL5CYZN.js → chunk-EEOUMG3J.js} +2 -1
  117. package/dist/{chunk-XDL5CYZN.js.map → chunk-EEOUMG3J.js.map} +1 -1
  118. package/dist/{chunk-Q57GOHLF.js → chunk-EGALNSZ4.js} +3 -3
  119. package/dist/{chunk-DPCXDG7G.js → chunk-EH65UV2Z.js} +2 -2
  120. package/dist/{chunk-KCT36JAW.js → chunk-ESNFSSO4.js} +2 -2
  121. package/dist/{chunk-XQ3HXAQH.js → chunk-ET2CNMLD.js} +4 -4
  122. package/dist/{chunk-TUHBYJXL.js → chunk-EWKVYCFP.js} +1 -1
  123. package/dist/{chunk-NPFUNWNX.js → chunk-FFUMTH27.js} +2 -2
  124. package/dist/{chunk-3PKAS6VL.js → chunk-GAJK3DQ5.js} +2 -2
  125. package/dist/{chunk-DA7ITC5Z.js → chunk-GBEOUCBB.js} +2 -2
  126. package/dist/{chunk-UENKPWCS.js → chunk-H2IRSXZN.js} +6 -6
  127. package/dist/{chunk-CFVTRUR3.js → chunk-H6RSANGQ.js} +2 -2
  128. package/dist/chunk-HVAEXYPL.js +98 -0
  129. package/dist/chunk-HVAEXYPL.js.map +1 -0
  130. package/dist/{chunk-EUYWQ7TS.js → chunk-IEZ6CGTW.js} +2 -2
  131. package/dist/{chunk-3SZD4CYO.js → chunk-IGZCAHFL.js} +3 -3
  132. package/dist/{chunk-UPFNQJC7.js → chunk-INUBU6I5.js} +2 -2
  133. package/dist/{chunk-PMVPCZJZ.js → chunk-J2R275FN.js} +3 -3
  134. package/dist/{chunk-UW5NPZJ2.js → chunk-JALOAKSZ.js} +59 -7
  135. package/dist/chunk-JALOAKSZ.js.map +1 -0
  136. package/dist/{chunk-2QSZNTDO.js → chunk-JBPKEARU.js} +7 -7
  137. package/dist/{chunk-3BCULS4U.js → chunk-JKTV3JNX.js} +145 -507
  138. package/dist/chunk-JKTV3JNX.js.map +1 -0
  139. package/dist/{chunk-5ACCD4L7.js → chunk-JRRQ747T.js} +7 -7
  140. package/dist/{chunk-V4IDF3EZ.js → chunk-JTWZKNUH.js} +5 -5
  141. package/dist/{chunk-AZMLH5UT.js → chunk-KI64TTBL.js} +2 -2
  142. package/dist/{chunk-DEACDKE3.js → chunk-KJXCD7VR.js} +112 -87
  143. package/dist/chunk-KJXCD7VR.js.map +1 -0
  144. package/dist/chunk-LJABGXC4.js +267 -0
  145. package/dist/chunk-LJABGXC4.js.map +1 -0
  146. package/dist/{chunk-NPIBN2VL.js → chunk-LK4TOYPU.js} +2 -2
  147. package/dist/{chunk-UTQUEHC7.js → chunk-LUDBXTBJ.js} +8 -8
  148. package/dist/{chunk-PU56CXZA.js → chunk-LYUUA6QB.js} +2 -2
  149. package/dist/{chunk-P36Z4JRA.js → chunk-M5ERTI4I.js} +2 -2
  150. package/dist/{chunk-LDKPDODJ.js → chunk-ME35HVDJ.js} +2 -2
  151. package/dist/{chunk-773TRRGT.js → chunk-MJUCDM3C.js} +2 -2
  152. package/dist/{chunk-OXRRJXPR.js → chunk-MUEGIKKY.js} +476 -1796
  153. package/dist/chunk-MUEGIKKY.js.map +1 -0
  154. package/dist/{chunk-AHPIFKNG.js → chunk-N4F7ZSSG.js} +2 -2
  155. package/dist/{chunk-JOZUBF4A.js → chunk-NACLNNFQ.js} +2 -2
  156. package/dist/{chunk-LC2BDILZ.js → chunk-NBP4EX5N.js} +2 -2
  157. package/dist/{chunk-T7XP6IZE.js → chunk-NFP4KPTA.js} +2 -2
  158. package/dist/{chunk-ZVPVTPGI.js → chunk-NNZFPYYX.js} +4 -4
  159. package/dist/{chunk-LPNCR4QK.js → chunk-NSTNGMSS.js} +14 -14
  160. package/dist/{chunk-5RWZH6PH.js → chunk-NUF7VSEX.js} +2 -2
  161. package/dist/{chunk-7VZFRUQU.js → chunk-O7ERGZDA.js} +5 -5
  162. package/dist/{chunk-HSZMX3ZJ.js → chunk-ODW5GDFE.js} +2 -2
  163. package/dist/{chunk-5DHKCO52.js → chunk-OJUEUQDJ.js} +2 -2
  164. package/dist/{chunk-LOXHYCVS.js → chunk-OMX6TKXH.js} +2 -2
  165. package/dist/{chunk-J2WC5LF4.js → chunk-QBC33MPY.js} +2 -1
  166. package/dist/{chunk-SEEJOGQX.js → chunk-QBNE55VA.js} +4 -4
  167. package/dist/chunk-QJCWK2A7.js +1466 -0
  168. package/dist/chunk-QJCWK2A7.js.map +1 -0
  169. package/dist/{chunk-YEUXERJ6.js → chunk-RDGKVH6T.js} +7 -3
  170. package/dist/{chunk-YEUXERJ6.js.map → chunk-RDGKVH6T.js.map} +1 -1
  171. package/dist/{chunk-JYSN42VN.js → chunk-RPIS5FQ7.js} +237 -183
  172. package/dist/chunk-RPIS5FQ7.js.map +1 -0
  173. package/dist/{chunk-F7XUD3PL.js → chunk-S4CDUXQY.js} +2 -2
  174. package/dist/{chunk-WNXYT4MK.js → chunk-S4Z2OBTX.js} +4 -4
  175. package/dist/{chunk-UL4MKZHI.js → chunk-SN4JXNLL.js} +2 -2
  176. package/dist/{chunk-CAMNRAJF.js → chunk-SZMYGDSM.js} +2 -2
  177. package/dist/chunk-TB2MJRI6.js +866 -0
  178. package/dist/chunk-TB2MJRI6.js.map +1 -0
  179. package/dist/{chunk-XNWXSGHS.js → chunk-TBCDF556.js} +28 -10
  180. package/dist/chunk-TBCDF556.js.map +1 -0
  181. package/dist/{chunk-LKYIOCWL.js → chunk-TCF4MU7L.js} +967 -132
  182. package/dist/chunk-TCF4MU7L.js.map +1 -0
  183. package/dist/chunk-TCQRIIIN.js +202 -0
  184. package/dist/chunk-TCQRIIIN.js.map +1 -0
  185. package/dist/{chunk-7PHI6GUI.js → chunk-TEZ2HTC7.js} +42 -2
  186. package/dist/chunk-TEZ2HTC7.js.map +1 -0
  187. package/dist/{chunk-CPA5NBHN.js → chunk-TNGH4ZYI.js} +2 -2
  188. package/dist/{chunk-F3NVYTTA.js → chunk-TNXNECAN.js} +6 -6
  189. package/dist/{chunk-BEC4YBNA.js → chunk-TVW4C7PV.js} +2 -2
  190. package/dist/{chunk-UFKPQBXH.js → chunk-U62OK7BB.js} +2 -2
  191. package/dist/{chunk-KZIF6XHX.js → chunk-U65VJSCJ.js} +32 -19
  192. package/dist/chunk-U65VJSCJ.js.map +1 -0
  193. package/dist/{chunk-4QEYREAV.js → chunk-U6NGKS32.js} +8 -8
  194. package/dist/{chunk-HRHO3ZNG.js → chunk-UW4RYPWC.js} +2 -2
  195. package/dist/{chunk-AX7UXCHJ.js → chunk-UYA36DQ7.js} +2 -1
  196. package/dist/chunk-UYA36DQ7.js.map +1 -0
  197. package/dist/{chunk-T6ILXUAH.js → chunk-VG4SSPAW.js} +2 -2
  198. package/dist/chunk-VOSWUO3K.js +100 -0
  199. package/dist/chunk-VOSWUO3K.js.map +1 -0
  200. package/dist/chunk-WFCWP4XU.js +17 -0
  201. package/dist/chunk-WFCWP4XU.js.map +1 -0
  202. package/dist/{chunk-H2YSH3DG.js → chunk-WKAXBXVA.js} +2 -2
  203. package/dist/{chunk-SXIMQLGV.js → chunk-WVGXCBOC.js} +2 -2
  204. package/dist/{chunk-UNUMFURP.js → chunk-X5PIDJ3L.js} +3 -3
  205. package/dist/{chunk-CRML27CO.js → chunk-X5YYSAZX.js} +4 -4
  206. package/dist/{chunk-FZEEWOI2.js → chunk-XJJYSX6F.js} +2 -2
  207. package/dist/{chunk-U7EW2W4W.js → chunk-XKNHFDTT.js} +26 -6
  208. package/dist/chunk-XKNHFDTT.js.map +1 -0
  209. package/dist/{chunk-OA2O2GJ4.js → chunk-XOHYGIWF.js} +3 -3
  210. package/dist/{chunk-UG6VXIOK.js → chunk-XSTNGNJP.js} +2 -2
  211. package/dist/{chunk-MINHJ55X.js → chunk-XXW32OL7.js} +1 -1
  212. package/dist/{chunk-MINHJ55X.js.map → chunk-XXW32OL7.js.map} +1 -1
  213. package/dist/{chunk-YDPAE2RD.js → chunk-YFLLGRXO.js} +2 -2
  214. package/dist/{chunk-MDD2RINF.js → chunk-YWPLOJ7T.js} +3 -3
  215. package/dist/{chunk-Q4WONDMJ.js → chunk-YYGZJPOK.js} +2 -2
  216. package/dist/{chunk-GTO56JY5.js → chunk-ZPS724LT.js} +2 -2
  217. package/dist/{chunk-SNOIKAHM.js → chunk-ZZZWEDF4.js} +3 -3
  218. package/dist/{cli-O3F-ht3i.d.ts → cli-CsfFMe6n.d.ts} +5 -5
  219. package/dist/cli.d.ts +13 -14
  220. package/dist/cli.js +101 -96
  221. package/dist/coding/export-okf-codegraph.d.ts +56 -0
  222. package/dist/coding/export-okf-codegraph.js +526 -0
  223. package/dist/coding/export-okf-codegraph.js.map +1 -0
  224. package/dist/coding/pre-action-gate.d.ts +1 -2
  225. package/dist/compounding/engine.d.ts +2 -3
  226. package/dist/compounding/engine.js +29 -29
  227. package/dist/compounding/preference-consolidator.d.ts +1 -2
  228. package/dist/compression-optimizer.d.ts +1 -2
  229. package/dist/config.d.ts +1 -2
  230. package/dist/config.js +11 -11
  231. package/dist/connectors/codex-materialize-runner.d.ts +1 -2
  232. package/dist/connectors/codex-materialize-runner.js +28 -28
  233. package/dist/connectors/codex-materialize.d.ts +1 -2
  234. package/dist/connectors/index.d.ts +1 -2
  235. package/dist/connectors/index.js +28 -28
  236. package/dist/consolidation-provenance-check.d.ts +2 -3
  237. package/dist/consolidation-provenance-check.js +4 -4
  238. package/dist/consolidation-undo.d.ts +2 -3
  239. package/dist/consolidation-undo.js +3 -3
  240. package/dist/contradiction/index.d.ts +3 -4
  241. package/dist/contradiction/index.js +9 -9
  242. package/dist/{contradiction-scan-AKUWPX5N.js → contradiction-scan-NOYMFG66.js} +3 -3
  243. package/dist/converge-config.d.ts +1 -2
  244. package/dist/convergence-refresh.d.ts +2 -3
  245. package/dist/convergence-refresh.js +30 -30
  246. package/dist/conversation-index/backend.d.ts +1 -2
  247. package/dist/conversation-index/backend.js +2 -2
  248. package/dist/conversation-index/chunker.d.ts +1 -2
  249. package/dist/conversation-index/faiss-adapter.d.ts +1 -2
  250. package/dist/conversation-index/indexer.d.ts +1 -2
  251. package/dist/conversation-index/search.d.ts +1 -2
  252. package/dist/corpus-watermark.d.ts +1 -2
  253. package/dist/corpus-watermark.js +30 -30
  254. package/dist/cross-lingual-recall.d.ts +1 -2
  255. package/dist/day-summary.d.ts +1 -2
  256. package/dist/delinearize.d.ts +1 -2
  257. package/dist/dependency-propagation-config.d.ts +1 -2
  258. package/dist/{dependency-propagation-delivery-CL6RWXTA.d.ts → dependency-propagation-delivery-D4WMbOwA.d.ts} +1 -1
  259. package/dist/direct-answer-wiring.d.ts +1 -2
  260. package/dist/direct-answer.d.ts +1 -2
  261. package/dist/embedding-fallback.d.ts +1 -2
  262. package/dist/enrichment/index.d.ts +1 -2
  263. package/dist/entity-origin-fields.d.ts +1 -2
  264. package/dist/entity-retrieval.d.ts +2 -3
  265. package/dist/entity-retrieval.js +28 -28
  266. package/dist/entity-schema.d.ts +1 -2
  267. package/dist/episodic-context.d.ts +1 -2
  268. package/dist/eval-trajectory-contracts.d.ts +1 -2
  269. package/dist/eval-trajectory-store.d.ts +1 -2
  270. package/dist/eval-trajectory.d.ts +1 -2
  271. package/dist/explicit-capture.d.ts +9 -10
  272. package/dist/explicit-capture.js +11 -11
  273. package/dist/external-wiki-access.d.ts +11 -12
  274. package/dist/external-wiki-access.js +55 -52
  275. package/dist/external-wiki-collection-registration.d.ts +1 -2
  276. package/dist/external-wiki-collection.d.ts +1 -2
  277. package/dist/external-wiki-mcp-tools.d.ts +11 -12
  278. package/dist/extraction-error-classification.d.ts +1 -2
  279. package/dist/extraction-faithfulness.d.ts +1 -2
  280. package/dist/extraction-faithfulness.js +2 -2
  281. package/dist/extraction-judge-telemetry.d.ts +1 -2
  282. package/dist/extraction-judge-training.d.ts +1 -2
  283. package/dist/extraction-judge.d.ts +1 -2
  284. package/dist/extraction-judge.js +2 -2
  285. package/dist/extraction-liveness.d.ts +1 -2
  286. package/dist/extraction-normalization.d.ts +1 -2
  287. package/dist/extraction-prompt.d.ts +1 -2
  288. package/dist/extraction-source-grounding-rules.d.ts +1 -2
  289. package/dist/extraction-source-grounding.d.ts +1 -2
  290. package/dist/extraction.d.ts +1 -2
  291. package/dist/extraction.js +37 -34
  292. package/dist/fallback-llm.d.ts +7 -2
  293. package/dist/fallback-llm.js +1 -1
  294. package/dist/{first-start-migration-4NETATFF.js → first-start-migration-KHIMCBIC.js} +3 -3
  295. package/dist/graph-dashboard-diff.d.ts +1 -2
  296. package/dist/graph-dashboard-key.d.ts +1 -2
  297. package/dist/graph-dashboard-parser.d.ts +1 -2
  298. package/dist/graph-edge-reinforcement.d.ts +1 -2
  299. package/dist/graph-path-reconstruction.d.ts +1 -2
  300. package/dist/graph-path-scoring.d.ts +1 -2
  301. package/dist/graph-snapshot.d.ts +1 -2
  302. package/dist/graph.d.ts +1 -2
  303. package/dist/harmonic-retrieval.js +1 -1
  304. package/dist/importance.d.ts +1 -2
  305. package/dist/importers/index.d.ts +1 -2
  306. package/dist/in-flight-reads.d.ts +1 -2
  307. package/dist/{index-C7Xep6S9.d.ts → index-DuJnzwHv.d.ts} +2 -2
  308. package/dist/index.d.ts +364 -26
  309. package/dist/index.js +232 -169
  310. package/dist/intent.d.ts +1 -2
  311. package/dist/lcm/engine.d.ts +1 -2
  312. package/dist/lcm/engine.js +4 -4
  313. package/dist/lcm/index.d.ts +1 -2
  314. package/dist/lcm/index.js +10 -10
  315. package/dist/lcm/tools.d.ts +1 -2
  316. package/dist/lifecycle.d.ts +1 -2
  317. package/dist/live-connectors-runner.d.ts +1 -2
  318. package/dist/local-llm.d.ts +1 -2
  319. package/dist/local-model-endpoint.d.ts +1 -2
  320. package/dist/location/index.d.ts +315 -6
  321. package/dist/location/index.js +151 -19
  322. package/dist/maintenance/memory-governance.d.ts +1 -2
  323. package/dist/maintenance/memory-governance.js +28 -28
  324. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -3
  325. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +28 -28
  326. package/dist/maintenance/rebuild-memory-projection.d.ts +2 -3
  327. package/dist/maintenance/rebuild-memory-projection.js +29 -29
  328. package/dist/{maintenance-CJ-xqFp0.d.ts → maintenance-BBeaeYRR.d.ts} +3 -3
  329. package/dist/mcp-memory-inspector-app.d.ts +11 -12
  330. package/dist/mcp-read-only-tools.js +1 -1
  331. package/dist/memory-action-policy.d.ts +1 -2
  332. package/dist/memory-cache.d.ts +1 -2
  333. package/dist/memory-controller.d.ts +1 -2
  334. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -2
  335. package/dist/memory-projection-mutations.js +3 -3
  336. package/dist/memory-projection-store.d.ts +1 -2
  337. package/dist/memory-projection-store.js +1 -1
  338. package/dist/memory-provenance.d.ts +1 -2
  339. package/dist/memory-snapshot.d.ts +1 -2
  340. package/dist/memory-subject-cli.d.ts +11 -12
  341. package/dist/memory-subject.d.ts +11 -12
  342. package/dist/memory-subject.js +4 -4
  343. package/dist/memory-worth-outcomes.d.ts +2 -3
  344. package/dist/models-json.d.ts +1 -2
  345. package/dist/namespaces/migrate.d.ts +3 -4
  346. package/dist/namespaces/migrate.js +29 -29
  347. package/dist/namespaces/principal.d.ts +1 -2
  348. package/dist/namespaces/search.d.ts +1 -2
  349. package/dist/namespaces/search.js +8 -8
  350. package/dist/namespaces/storage.d.ts +3 -4
  351. package/dist/namespaces/storage.js +28 -28
  352. package/dist/native-knowledge.d.ts +1 -2
  353. package/dist/offline-sync-file-io.js +3 -3
  354. package/dist/offline-sync-impression-drain.d.ts +1 -2
  355. package/dist/offline-sync-impression-drain.js +9 -9
  356. package/dist/offline-sync.js +4 -4
  357. package/dist/operator-doctor-corpus.d.ts +1 -2
  358. package/dist/operator-doctor-corpus.js +31 -31
  359. package/dist/operator-doctor-replica.d.ts +1 -2
  360. package/dist/operator-toolkit.d.ts +3 -4
  361. package/dist/operator-toolkit.js +47 -47
  362. package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -3
  363. package/dist/orchestration/maintenance.d.ts +4 -5
  364. package/dist/orchestration/maintenance.js +42 -41
  365. package/dist/{orchestrator-BsntWxLy.d.ts → orchestrator-CaqnwNwM.d.ts} +8 -8
  366. package/dist/orchestrator.d.ts +9 -10
  367. package/dist/orchestrator.js +132 -125
  368. package/dist/page-versioning.js +3 -3
  369. package/dist/patterns-cli.d.ts +1 -2
  370. package/dist/{pipeline-CVoysPm2.d.ts → pipeline-CrxVjlJr.d.ts} +1 -1
  371. package/dist/policy-runtime.d.ts +1 -2
  372. package/dist/proactive-contention.d.ts +1 -2
  373. package/dist/provenance.d.ts +1 -2
  374. package/dist/{public-http-CuOxlTC2.d.ts → public-http-Cwvl4QZr.d.ts} +1 -1
  375. package/dist/{purge-GB7PZHT2.js → purge-OP6BEDFY.js} +2 -2
  376. package/dist/{qmd-DWMAGA5l.d.ts → qmd-BZgbJm0g.d.ts} +1 -1
  377. package/dist/qmd-preflight.d.ts +2 -3
  378. package/dist/qmd-recall-cache.d.ts +1 -2
  379. package/dist/qmd.d.ts +2 -3
  380. package/dist/recall-concurrency-config.d.ts +1 -2
  381. package/dist/recall-deep.d.ts +37 -0
  382. package/dist/recall-deep.js +81 -0
  383. package/dist/recall-deep.js.map +1 -0
  384. package/dist/recall-disclosure-escalation.d.ts +1 -2
  385. package/dist/recall-explain-renderer.d.ts +1 -2
  386. package/dist/recall-explain-renderer.js +3 -3
  387. package/dist/recall-memory-map.d.ts +1 -2
  388. package/dist/recall-navigate.d.ts +70 -0
  389. package/dist/recall-navigate.js +51 -0
  390. package/dist/recall-navigate.js.map +1 -0
  391. package/dist/recall-planner-llm.d.ts +1 -2
  392. package/dist/recall-planner-llm.js +1 -1
  393. package/dist/recall-state-view-wire.d.ts +14 -0
  394. package/dist/recall-state-view-wire.js +11 -0
  395. package/dist/recall-state-view.d.ts +25 -0
  396. package/dist/recall-state-view.js +22 -0
  397. package/dist/recall-state-view.js.map +1 -0
  398. package/dist/recall-state.d.ts +1 -2
  399. package/dist/recall-tag-filter.d.ts +1 -2
  400. package/dist/recall-timings.d.ts +1 -2
  401. package/dist/recall-xray-cli.d.ts +1 -2
  402. package/dist/recall-xray-cli.js +4 -4
  403. package/dist/recall-xray-renderer.d.ts +1 -2
  404. package/dist/recall-xray-renderer.js +3 -3
  405. package/dist/recall-xray.d.ts +1 -2
  406. package/dist/recall-xray.js +2 -2
  407. package/dist/reconcile/cursor.d.ts +1 -2
  408. package/dist/reconcile/manifest.d.ts +1 -2
  409. package/dist/reconcile/manifest.js +4 -4
  410. package/dist/reconcile/plan.d.ts +1 -2
  411. package/dist/replay/normalizers/chatgpt.d.ts +1 -2
  412. package/dist/replay/normalizers/claude.d.ts +1 -2
  413. package/dist/replay/normalizers/openclaw.d.ts +1 -2
  414. package/dist/replay/normalizers/shared.d.ts +1 -2
  415. package/dist/replay/runner.d.ts +1 -2
  416. package/dist/replay/types.d.ts +1 -2
  417. package/dist/replica-divergence.d.ts +1 -2
  418. package/dist/replica-peers-config.d.ts +1 -2
  419. package/dist/{resolution-XWBPKYFB.js → resolution-4DLI3IOR.js} +10 -10
  420. package/dist/resolution-4DLI3IOR.js.map +1 -0
  421. package/dist/resolve-auth-token.d.ts +1 -2
  422. package/dist/resume-bundles.js +12 -12
  423. package/dist/retrieval-agents.d.ts +2 -3
  424. package/dist/retrieval-tiers.d.ts +1 -2
  425. package/dist/routing/engine.d.ts +1 -2
  426. package/dist/routing/store.d.ts +1 -2
  427. package/dist/salvage-envelope.d.ts +1 -2
  428. package/dist/salvage-envelope.js +6 -6
  429. package/dist/schemas.d.ts +570 -105
  430. package/dist/schemas.js +3 -1
  431. package/dist/{scope-profiles-CPWkW_dI.d.ts → scope-profiles-DFaojvoP.d.ts} +1 -1
  432. package/dist/search/document-scanner.js +1 -1
  433. package/dist/search/embed-helper.d.ts +1 -2
  434. package/dist/search/factory.d.ts +1 -2
  435. package/dist/search/factory.js +7 -7
  436. package/dist/search/index.d.ts +1 -2
  437. package/dist/search/index.js +13 -13
  438. package/dist/search/lancedb-backend.d.ts +1 -2
  439. package/dist/search/lancedb-backend.js +1 -1
  440. package/dist/search/meilisearch-backend.d.ts +1 -2
  441. package/dist/search/meilisearch-backend.js +1 -1
  442. package/dist/search/noop-backend.d.ts +1 -2
  443. package/dist/search/orama-backend.d.ts +1 -2
  444. package/dist/search/orama-backend.js +1 -1
  445. package/dist/search/port.d.ts +1 -2
  446. package/dist/search/remote-backend.d.ts +1 -2
  447. package/dist/secure-store/index.js +3 -3
  448. package/dist/{semantic-consolidation-CNFVBXFc.d.ts → semantic-consolidation-BiX68wZA.d.ts} +1 -1
  449. package/dist/semantic-consolidation.d.ts +2 -3
  450. package/dist/semantic-consolidation.js +29 -29
  451. package/dist/semantic-rule-promotion.js +28 -28
  452. package/dist/semantic-rule-verifier.d.ts +1 -2
  453. package/dist/semantic-rule-verifier.js +28 -28
  454. package/dist/{service-Bb-JIdQ0.d.ts → service-D5h2zZ0M.d.ts} +2 -2
  455. package/dist/session-observer-bands.d.ts +1 -2
  456. package/dist/session-observer-state.d.ts +1 -2
  457. package/dist/shared-context/manager.d.ts +1 -2
  458. package/dist/signal.d.ts +1 -2
  459. package/dist/source-agent-qualifier.d.ts +1 -2
  460. package/dist/source-agent-qualifier.js +35 -32
  461. package/dist/standup/build.d.ts +16 -0
  462. package/dist/standup/build.js +17 -0
  463. package/dist/standup/build.js.map +1 -0
  464. package/dist/{storage-CukrlNKk.d.ts → storage-CtsaojWD.d.ts} +1 -1
  465. package/dist/storage.d.ts +2 -3
  466. package/dist/storage.js +27 -27
  467. package/dist/subject-config.d.ts +1 -2
  468. package/dist/subject-config.js +5 -5
  469. package/dist/summarizer.d.ts +1 -2
  470. package/dist/summarizer.js +2 -2
  471. package/dist/summary-snapshot.d.ts +1 -2
  472. package/dist/support-passport/index.d.ts +16 -17
  473. package/dist/support-passport/index.js +57 -54
  474. package/dist/temporal-supersession.d.ts +2 -3
  475. package/dist/temporal-timeline-recall.d.ts +1 -2
  476. package/dist/temporal-validity.d.ts +1 -2
  477. package/dist/threading.d.ts +1 -2
  478. package/dist/tier-migration.d.ts +2 -3
  479. package/dist/tier-routing.d.ts +1 -2
  480. package/dist/tier-routing.js +2 -2
  481. package/dist/{tier-stats-4B5IJ3NE.js → tier-stats-2TOW3QNL.js} +3 -3
  482. package/dist/topics.d.ts +1 -2
  483. package/dist/transcript.d.ts +1 -2
  484. package/dist/transfer/capsule-import.js +4 -4
  485. package/dist/transfer/export-okf.d.ts +39 -0
  486. package/dist/transfer/export-okf.js +112 -0
  487. package/dist/transfer/export-okf.js.map +1 -0
  488. package/dist/trust-score-stage.d.ts +1 -2
  489. package/dist/trust-score.d.ts +1 -2
  490. package/dist/{types-djxQlxJ7.d.ts → types-CIpfYz1I.d.ts} +132 -12
  491. package/dist/types.d.ts +1 -2
  492. package/dist/types.js +1 -1
  493. package/dist/utility-runtime.d.ts +1 -2
  494. package/dist/verified-recall.js +28 -28
  495. package/dist/who-knows-cli.d.ts +11 -12
  496. package/dist/who-knows-cli.js +29 -29
  497. package/dist/who-knows.d.ts +11 -12
  498. package/dist/who-knows.js +28 -28
  499. package/dist/write-envelope.d.ts +1 -2
  500. package/dist/write-envelope.js +5 -5
  501. package/package.json +34 -3
  502. package/src/access-admin-ops-surface.ts +6 -1
  503. package/src/access-boundary.ts +1 -0
  504. package/src/access-http.ts +3 -1
  505. package/src/access-mcp-output-schemas.ts +1 -0
  506. package/src/access-mcp.ts +3 -3
  507. package/src/access-operations.ts +1 -0
  508. package/src/access-service-offline-file-content.test.ts +63 -0
  509. package/src/access-surface-catalog.ts +2 -0
  510. package/src/activity/config.test.ts +1 -0
  511. package/src/activity/config.ts +66 -1
  512. package/src/activity/index.ts +3 -0
  513. package/src/activity/journal.test.ts +97 -0
  514. package/src/activity/journal.ts +113 -0
  515. package/src/activity/privacy.test.ts +53 -0
  516. package/src/activity/privacy.ts +80 -0
  517. package/src/activity/timeline/build.ts +279 -0
  518. package/src/activity/timeline/categories.ts +111 -0
  519. package/src/activity/timeline/classify.ts +110 -0
  520. package/src/activity/timeline/corrections.ts +145 -0
  521. package/src/activity/timeline/index.ts +8 -0
  522. package/src/activity/timeline/journal-recap.test.ts +113 -0
  523. package/src/activity/timeline/journal-recap.ts +130 -0
  524. package/src/activity/timeline/query.test.ts +198 -0
  525. package/src/activity/timeline/query.ts +313 -0
  526. package/src/activity/timeline/timeline.test.ts +277 -0
  527. package/src/activity/timeline/types.ts +106 -0
  528. package/src/activity/timeline/weekly.test.ts +215 -0
  529. package/src/activity/timeline/weekly.ts +234 -0
  530. package/src/activity/types.ts +20 -0
  531. package/src/activity/vault-publish.test.ts +166 -0
  532. package/src/activity/vault-publish.ts +101 -0
  533. package/src/cli/okf-commands.ts +45 -0
  534. package/src/cli.ts +2 -2
  535. package/src/coding/export-okf-codegraph.test.ts +381 -0
  536. package/src/coding/export-okf-codegraph.ts +565 -0
  537. package/src/config.test.ts +1 -0
  538. package/src/config.ts +2 -22
  539. package/src/dedup/merge-on-write.test.ts +91 -0
  540. package/src/dedup/merge-on-write.ts +75 -0
  541. package/src/dedup/novelty-gate.test.ts +143 -0
  542. package/src/dedup/novelty-gate.ts +163 -0
  543. package/src/extraction-prompt-safety.test.ts +14 -2
  544. package/src/extraction.ts +21 -1
  545. package/src/fallback-llm.test.ts +134 -0
  546. package/src/fallback-llm.ts +77 -5
  547. package/src/location/access-operations.ts +17 -8
  548. package/src/location/backfill.ts +137 -0
  549. package/src/location/config.test.ts +3 -0
  550. package/src/location/config.ts +46 -2
  551. package/src/location/http-glue.ts +1 -1
  552. package/src/location/index.ts +3 -0
  553. package/src/location/intervals.ts +1 -0
  554. package/src/location/matching.test.ts +65 -0
  555. package/src/location/matching.ts +354 -0
  556. package/src/location/mcp-tools.ts +2 -1
  557. package/src/location/recall-exclusion.test.ts +1 -0
  558. package/src/location/surfaces.test.ts +15 -2
  559. package/src/location/surfaces.ts +95 -18
  560. package/src/location/tagging.test.ts +119 -0
  561. package/src/location/tagging.ts +277 -0
  562. package/src/location/types.ts +23 -1
  563. package/src/mcp-read-only-tools.ts +1 -0
  564. package/src/memory-projection-store.ts +3 -1
  565. package/src/okf/cli.ts +18 -5
  566. package/src/okf/config.ts +5 -0
  567. package/src/okf/index-files.test.ts +60 -0
  568. package/src/okf/index-files.ts +114 -0
  569. package/src/okf/render.ts +133 -0
  570. package/src/okf/type-mapping.test.ts +3 -0
  571. package/src/okf/type-mapping.ts +2 -0
  572. package/src/orchestration/extraction-persist.ts +22 -23
  573. package/src/orchestration/extraction-run.ts +2 -1
  574. package/src/orchestration/generic-recall-paths.ts +15 -3
  575. package/src/orchestration/recall-entry.ts +8 -3
  576. package/src/recall-deep.test.ts +72 -0
  577. package/src/recall-deep.ts +113 -0
  578. package/src/recall-navigate.test.ts +84 -0
  579. package/src/recall-navigate.ts +100 -0
  580. package/src/recall-state-view-wire.test.ts +35 -0
  581. package/src/recall-state-view-wire.ts +28 -0
  582. package/src/recall-state-view.test.ts +131 -0
  583. package/src/recall-state-view.ts +138 -0
  584. package/src/schemas.ts +17 -1
  585. package/src/shared-context/governance.test.ts +53 -0
  586. package/src/shared-context/governance.ts +86 -0
  587. package/src/standup/access-operations.ts +14 -0
  588. package/src/standup/build.test.ts +34 -0
  589. package/src/standup/build.ts +115 -0
  590. package/src/standup/http-glue.ts +15 -0
  591. package/src/standup/mcp-tools.ts +16 -0
  592. package/src/support-passport/card-projection.ts +1 -0
  593. package/src/support-passport/card-service-commit-forwarding.test.ts +1 -0
  594. package/src/support-passport/card-service.test.ts +75 -1
  595. package/src/support-passport/card-service.ts +6 -3
  596. package/src/support-passport/card-state.ts +5 -1
  597. package/src/support-passport/offline-sync-guard.ts +14 -1
  598. package/src/transfer/export-okf.test.ts +164 -0
  599. package/src/transfer/export-okf.ts +286 -0
  600. package/src/types.ts +3 -10
  601. package/dist/chunk-2LWQSV6A.js.map +0 -1
  602. package/dist/chunk-3BCULS4U.js.map +0 -1
  603. package/dist/chunk-7BDZTALN.js.map +0 -1
  604. package/dist/chunk-7PHI6GUI.js.map +0 -1
  605. package/dist/chunk-7WOWGRAU.js.map +0 -1
  606. package/dist/chunk-AX7UXCHJ.js.map +0 -1
  607. package/dist/chunk-DEACDKE3.js.map +0 -1
  608. package/dist/chunk-FP7YTTVO.js.map +0 -1
  609. package/dist/chunk-JYSN42VN.js.map +0 -1
  610. package/dist/chunk-KZIF6XHX.js.map +0 -1
  611. package/dist/chunk-LKYIOCWL.js.map +0 -1
  612. package/dist/chunk-OXRRJXPR.js.map +0 -1
  613. package/dist/chunk-U7EW2W4W.js.map +0 -1
  614. package/dist/chunk-UW5NPZJ2.js.map +0 -1
  615. package/dist/chunk-XAB6STPO.js.map +0 -1
  616. package/dist/chunk-XNWXSGHS.js.map +0 -1
  617. package/dist/types-CM86alG1.d.ts +0 -89
  618. /package/dist/{auto-sync-2YPITIWN.js.map → auto-sync-Q6Q2FVSC.js.map} +0 -0
  619. /package/dist/{capsule-merge-SGIVB3WA.js.map → capsule-merge-SEHERWWP.js.map} +0 -0
  620. /package/dist/{chunk-LEPOP46W.js.map → chunk-227UFSEQ.js.map} +0 -0
  621. /package/dist/{chunk-TFR3HG4K.js.map → chunk-2FA7U5XY.js.map} +0 -0
  622. /package/dist/{chunk-PO7NXBG2.js.map → chunk-2GF27PGH.js.map} +0 -0
  623. /package/dist/{chunk-MY2BC6UE.js.map → chunk-2X6BGKQL.js.map} +0 -0
  624. /package/dist/{chunk-UEBDCMOO.js.map → chunk-3TSU662L.js.map} +0 -0
  625. /package/dist/{chunk-S5XOSTYM.js.map → chunk-4XLTUR6R.js.map} +0 -0
  626. /package/dist/{chunk-BWGCOLEL.js.map → chunk-65JOGLIS.js.map} +0 -0
  627. /package/dist/{chunk-HMZKGHMD.js.map → chunk-7UOXCCCI.js.map} +0 -0
  628. /package/dist/{chunk-4F4AQFWL.js.map → chunk-B4AOWRYF.js.map} +0 -0
  629. /package/dist/{chunk-ODU2CNNX.js.map → chunk-C5IUOBCN.js.map} +0 -0
  630. /package/dist/{chunk-3A2NJP2U.js.map → chunk-CHGG74CY.js.map} +0 -0
  631. /package/dist/{chunk-76DIF5KT.js.map → chunk-CX4OLNIH.js.map} +0 -0
  632. /package/dist/{chunk-Z3YEGSR4.js.map → chunk-D3UXGE5D.js.map} +0 -0
  633. /package/dist/{chunk-5HK3CJAR.js.map → chunk-D6Q5EPOV.js.map} +0 -0
  634. /package/dist/{chunk-EGBDFJ36.js.map → chunk-DD5JFCWM.js.map} +0 -0
  635. /package/dist/{chunk-XBGHAAKR.js.map → chunk-DDX6KIXF.js.map} +0 -0
  636. /package/dist/{chunk-JIYDRBVZ.js.map → chunk-DJORULH3.js.map} +0 -0
  637. /package/dist/{chunk-7KQB4EBS.js.map → chunk-DUAJKRR2.js.map} +0 -0
  638. /package/dist/{chunk-Q57GOHLF.js.map → chunk-EGALNSZ4.js.map} +0 -0
  639. /package/dist/{chunk-DPCXDG7G.js.map → chunk-EH65UV2Z.js.map} +0 -0
  640. /package/dist/{chunk-KCT36JAW.js.map → chunk-ESNFSSO4.js.map} +0 -0
  641. /package/dist/{chunk-XQ3HXAQH.js.map → chunk-ET2CNMLD.js.map} +0 -0
  642. /package/dist/{chunk-TUHBYJXL.js.map → chunk-EWKVYCFP.js.map} +0 -0
  643. /package/dist/{chunk-NPFUNWNX.js.map → chunk-FFUMTH27.js.map} +0 -0
  644. /package/dist/{chunk-3PKAS6VL.js.map → chunk-GAJK3DQ5.js.map} +0 -0
  645. /package/dist/{chunk-DA7ITC5Z.js.map → chunk-GBEOUCBB.js.map} +0 -0
  646. /package/dist/{chunk-UENKPWCS.js.map → chunk-H2IRSXZN.js.map} +0 -0
  647. /package/dist/{chunk-CFVTRUR3.js.map → chunk-H6RSANGQ.js.map} +0 -0
  648. /package/dist/{chunk-EUYWQ7TS.js.map → chunk-IEZ6CGTW.js.map} +0 -0
  649. /package/dist/{chunk-3SZD4CYO.js.map → chunk-IGZCAHFL.js.map} +0 -0
  650. /package/dist/{chunk-UPFNQJC7.js.map → chunk-INUBU6I5.js.map} +0 -0
  651. /package/dist/{chunk-PMVPCZJZ.js.map → chunk-J2R275FN.js.map} +0 -0
  652. /package/dist/{chunk-2QSZNTDO.js.map → chunk-JBPKEARU.js.map} +0 -0
  653. /package/dist/{chunk-5ACCD4L7.js.map → chunk-JRRQ747T.js.map} +0 -0
  654. /package/dist/{chunk-V4IDF3EZ.js.map → chunk-JTWZKNUH.js.map} +0 -0
  655. /package/dist/{chunk-AZMLH5UT.js.map → chunk-KI64TTBL.js.map} +0 -0
  656. /package/dist/{chunk-NPIBN2VL.js.map → chunk-LK4TOYPU.js.map} +0 -0
  657. /package/dist/{chunk-UTQUEHC7.js.map → chunk-LUDBXTBJ.js.map} +0 -0
  658. /package/dist/{chunk-PU56CXZA.js.map → chunk-LYUUA6QB.js.map} +0 -0
  659. /package/dist/{chunk-P36Z4JRA.js.map → chunk-M5ERTI4I.js.map} +0 -0
  660. /package/dist/{chunk-LDKPDODJ.js.map → chunk-ME35HVDJ.js.map} +0 -0
  661. /package/dist/{chunk-773TRRGT.js.map → chunk-MJUCDM3C.js.map} +0 -0
  662. /package/dist/{chunk-AHPIFKNG.js.map → chunk-N4F7ZSSG.js.map} +0 -0
  663. /package/dist/{chunk-JOZUBF4A.js.map → chunk-NACLNNFQ.js.map} +0 -0
  664. /package/dist/{chunk-LC2BDILZ.js.map → chunk-NBP4EX5N.js.map} +0 -0
  665. /package/dist/{chunk-T7XP6IZE.js.map → chunk-NFP4KPTA.js.map} +0 -0
  666. /package/dist/{chunk-ZVPVTPGI.js.map → chunk-NNZFPYYX.js.map} +0 -0
  667. /package/dist/{chunk-LPNCR4QK.js.map → chunk-NSTNGMSS.js.map} +0 -0
  668. /package/dist/{chunk-5RWZH6PH.js.map → chunk-NUF7VSEX.js.map} +0 -0
  669. /package/dist/{chunk-7VZFRUQU.js.map → chunk-O7ERGZDA.js.map} +0 -0
  670. /package/dist/{chunk-HSZMX3ZJ.js.map → chunk-ODW5GDFE.js.map} +0 -0
  671. /package/dist/{chunk-5DHKCO52.js.map → chunk-OJUEUQDJ.js.map} +0 -0
  672. /package/dist/{chunk-LOXHYCVS.js.map → chunk-OMX6TKXH.js.map} +0 -0
  673. /package/dist/{chunk-J2WC5LF4.js.map → chunk-QBC33MPY.js.map} +0 -0
  674. /package/dist/{chunk-SEEJOGQX.js.map → chunk-QBNE55VA.js.map} +0 -0
  675. /package/dist/{chunk-F7XUD3PL.js.map → chunk-S4CDUXQY.js.map} +0 -0
  676. /package/dist/{chunk-WNXYT4MK.js.map → chunk-S4Z2OBTX.js.map} +0 -0
  677. /package/dist/{chunk-UL4MKZHI.js.map → chunk-SN4JXNLL.js.map} +0 -0
  678. /package/dist/{chunk-CAMNRAJF.js.map → chunk-SZMYGDSM.js.map} +0 -0
  679. /package/dist/{chunk-CPA5NBHN.js.map → chunk-TNGH4ZYI.js.map} +0 -0
  680. /package/dist/{chunk-F3NVYTTA.js.map → chunk-TNXNECAN.js.map} +0 -0
  681. /package/dist/{chunk-BEC4YBNA.js.map → chunk-TVW4C7PV.js.map} +0 -0
  682. /package/dist/{chunk-UFKPQBXH.js.map → chunk-U62OK7BB.js.map} +0 -0
  683. /package/dist/{chunk-4QEYREAV.js.map → chunk-U6NGKS32.js.map} +0 -0
  684. /package/dist/{chunk-HRHO3ZNG.js.map → chunk-UW4RYPWC.js.map} +0 -0
  685. /package/dist/{chunk-T6ILXUAH.js.map → chunk-VG4SSPAW.js.map} +0 -0
  686. /package/dist/{chunk-H2YSH3DG.js.map → chunk-WKAXBXVA.js.map} +0 -0
  687. /package/dist/{chunk-SXIMQLGV.js.map → chunk-WVGXCBOC.js.map} +0 -0
  688. /package/dist/{chunk-UNUMFURP.js.map → chunk-X5PIDJ3L.js.map} +0 -0
  689. /package/dist/{chunk-CRML27CO.js.map → chunk-X5YYSAZX.js.map} +0 -0
  690. /package/dist/{chunk-FZEEWOI2.js.map → chunk-XJJYSX6F.js.map} +0 -0
  691. /package/dist/{chunk-OA2O2GJ4.js.map → chunk-XOHYGIWF.js.map} +0 -0
  692. /package/dist/{chunk-UG6VXIOK.js.map → chunk-XSTNGNJP.js.map} +0 -0
  693. /package/dist/{chunk-YDPAE2RD.js.map → chunk-YFLLGRXO.js.map} +0 -0
  694. /package/dist/{chunk-MDD2RINF.js.map → chunk-YWPLOJ7T.js.map} +0 -0
  695. /package/dist/{chunk-Q4WONDMJ.js.map → chunk-YYGZJPOK.js.map} +0 -0
  696. /package/dist/{chunk-GTO56JY5.js.map → chunk-ZPS724LT.js.map} +0 -0
  697. /package/dist/{chunk-SNOIKAHM.js.map → chunk-ZZZWEDF4.js.map} +0 -0
  698. /package/dist/{contradiction-scan-AKUWPX5N.js.map → contradiction-scan-NOYMFG66.js.map} +0 -0
  699. /package/dist/{first-start-migration-4NETATFF.js.map → first-start-migration-KHIMCBIC.js.map} +0 -0
  700. /package/dist/{purge-GB7PZHT2.js.map → purge-OP6BEDFY.js.map} +0 -0
  701. /package/dist/{resolution-XWBPKYFB.js.map → recall-state-view-wire.js.map} +0 -0
  702. /package/dist/{tier-stats-4B5IJ3NE.js.map → tier-stats-2TOW3QNL.js.map} +0 -0
@@ -0,0 +1,279 @@
1
+ /**
2
+ * Deterministic timeline-card day builder (issue #2049).
3
+ *
4
+ * Semantics (all half-open [start, end), all UTC internally):
5
+ * - Observations are grouped per capture machine and sorted by
6
+ * (canonical capture instant, contentHash) — never by array position.
7
+ * - Compatibility rule: two consecutive observations on one machine merge
8
+ * into the same card iff they share the exact (app, windowTitle) pair.
9
+ * - Gap rule: a merge happens only when the inter-observation gap is
10
+ * ≤ MERGE_GAP_MS (2 min). A card's end extends from its last observation
11
+ * by at most MAX_DWELL_MS (15 min, matching the digest dwell cap), is
12
+ * clipped by the next observation on the machine, by any user pause, and
13
+ * by the local day end — so cards never overlap on a track.
14
+ * - Idle: any uncovered remainder between consecutive cards on a machine
15
+ * track (which in practice means a gap > MAX_DWELL_MS) becomes a derived
16
+ * idle card with no evidence. The day's leading/trailing uncovered ranges
17
+ * are represented by the absence of cards, not by invented idle.
18
+ * - Pause: user-declared intervals are unioned, clipped to the day, emitted
19
+ * as pause cards, and never overlapped by activity dwell or idle.
20
+ * - Nothing is invented for gaps: idle/pause cards carry no evidence and are
21
+ * flagged by kind; an app/window match never claims user intent.
22
+ *
23
+ * Output is byte-stable: identical inputs produce identical
24
+ * `serializeTimelineDay()` bytes across runs and process restarts.
25
+ */
26
+
27
+ import { createHash } from "node:crypto";
28
+
29
+ import { activityDayWindow } from "../digest.js";
30
+ import { DEFAULT_TIMELINE_CATEGORIES, TIMELINE_RESERVED_IDLE, TIMELINE_RESERVED_PAUSE, validateTimelineCategories } from "./categories.js";
31
+ import { classifyTimelineObservation } from "./classify.js";
32
+ import type { TimelineCard, TimelineCategory, TimelineDay, TimelineObservation, TimelinePause } from "./types.js";
33
+
34
+ export const TIMELINE_FORMAT_VERSION = 1;
35
+
36
+ /** Max inter-observation gap that still merges into one card. */
37
+ export const TIMELINE_MERGE_GAP_MS = 120_000;
38
+ /** Max dwell attributed past a card's last observation (digest parity). */
39
+ export const TIMELINE_MAX_DWELL_MS = 15 * 60_000;
40
+
41
+ export interface TimelineBuildInput {
42
+ /** Local day, YYYY-MM-DD. */
43
+ date: string;
44
+ timezone: string;
45
+ /** Stored observations for the day (e.g. from ActivityStore.listSnapshotsForDay). */
46
+ observations: readonly TimelineObservation[];
47
+ /** User-declared pauses (UTC, half-open); may overlap and extend past the day. */
48
+ pauses?: readonly TimelinePause[];
49
+ /** Registry override; validated. Defaults to the built-in registry. */
50
+ categories?: readonly TimelineCategory[];
51
+ }
52
+
53
+ /** Canonical UTC ISO instant, or the raw string when unparseable (dropped later). */
54
+ function canonicalMs(iso: string): number {
55
+ const parsed = Date.parse(iso);
56
+ return Number.isFinite(parsed) ? parsed : Number.NaN;
57
+ }
58
+
59
+ function isoOf(ms: number): string {
60
+ return new Date(ms).toISOString();
61
+ }
62
+
63
+ /** Content identity of one observation: machine + instant + content hash. */
64
+ function evidenceKeyOf(observation: TimelineObservation): string {
65
+ return `${observation.machine}|${isoOf(canonicalMs(observation.capturedAtUtc))}|${observation.contentHash}`;
66
+ }
67
+
68
+ function stableCardId(identity: string): string {
69
+ return `tlc_${createHash("sha256").update(identity, "utf8").digest("hex").slice(0, 16)}`;
70
+ }
71
+
72
+ function formatDurationMinutes(ms: number): string {
73
+ return `${Math.round(ms / 60_000)}m`;
74
+ }
75
+
76
+ /** Union overlapping/adjacent [start,end) intervals; returns sorted, disjoint ms pairs. */
77
+ function unionIntervals(intervals: readonly (readonly [number, number])[]): Array<[number, number]> {
78
+ const sorted = [...intervals].sort((a, b) => a[0] - b[0] || a[1] - b[1]);
79
+ const merged: Array<[number, number]> = [];
80
+ for (const interval of sorted) {
81
+ const last = merged[merged.length - 1];
82
+ if (last !== undefined && interval[0] <= last[1]) {
83
+ last[1] = Math.max(last[1], interval[1]);
84
+ } else {
85
+ merged.push([interval[0], interval[1]]);
86
+ }
87
+ }
88
+ return merged;
89
+ }
90
+
91
+ /** Remove [cutStart,cutEnd) from [start,end); returns the remaining pieces. */
92
+ function subtractInterval(start: number, end: number, cutStart: number, cutEnd: number): Array<[number, number]> {
93
+ if (cutEnd <= start || cutStart >= end) return [[start, end]];
94
+ const pieces: Array<[number, number]> = [];
95
+ if (cutStart > start) pieces.push([start, cutStart]);
96
+ if (cutEnd < end) pieces.push([cutEnd, end]);
97
+ return pieces;
98
+ }
99
+
100
+ interface MergedObservations {
101
+ machine: string;
102
+ observations: TimelineObservation[];
103
+ }
104
+
105
+ /** Per-machine merge pass: compatibility + gap rules (see module doc). */
106
+ function mergeTrack(
107
+ machine: string,
108
+ track: TimelineObservation[],
109
+ pauses: readonly (readonly [number, number])[],
110
+ ): MergedObservations[] {
111
+ const cards: MergedObservations[] = [];
112
+ let current: TimelineObservation[] = [];
113
+ const pauseStartsAfter = (fromMs: number, toMs: number): boolean =>
114
+ pauses.some(([ps, pe]) => ps >= fromMs && ps < toMs && pe > ps);
115
+ for (const observation of track) {
116
+ const last = current[current.length - 1];
117
+ if (last !== undefined) {
118
+ const gap = canonicalMs(observation.capturedAtUtc) - canonicalMs(last.capturedAtUtc);
119
+ const sameKey = observation.app === last.app && observation.windowTitle === last.windowTitle;
120
+ const pauseBetween = pauseStartsAfter(canonicalMs(last.capturedAtUtc), canonicalMs(observation.capturedAtUtc));
121
+ if (!sameKey || gap > TIMELINE_MERGE_GAP_MS || pauseBetween) {
122
+ cards.push({ machine, observations: current });
123
+ current = [];
124
+ }
125
+ }
126
+ current.push(observation);
127
+ }
128
+ if (current.length > 0) cards.push({ machine, observations: current });
129
+ return cards;
130
+ }
131
+
132
+ /** Build one replayable local day of timeline cards. Pure; throws on bad input. */
133
+ export function buildTimelineDay(input: TimelineBuildInput): TimelineDay {
134
+ const categories = input.categories ?? DEFAULT_TIMELINE_CATEGORIES;
135
+ validateTimelineCategories(categories);
136
+ const window = activityDayWindow(input.date, input.timezone);
137
+ const dayStartMs = Date.parse(window.startUtc);
138
+ const dayEndMs = Date.parse(window.endUtc);
139
+
140
+ // Observations: canonicalize, drop instants outside the day window.
141
+ const observations = input.observations
142
+ .filter((observation) => Number.isFinite(canonicalMs(observation.capturedAtUtc)))
143
+ .filter((observation) => {
144
+ const ms = canonicalMs(observation.capturedAtUtc);
145
+ return ms >= dayStartMs && ms < dayEndMs;
146
+ });
147
+
148
+ // Pauses: validate instants, clip to the day, union overlaps.
149
+ for (const pause of input.pauses ?? []) {
150
+ const startMs = canonicalMs(pause.startUtc);
151
+ const endMs = canonicalMs(pause.endUtc);
152
+ if (!Number.isFinite(startMs) || !Number.isFinite(endMs) || startMs >= endMs) {
153
+ throw new RangeError("timeline pause must be a valid half-open [startUtc, endUtc) interval");
154
+ }
155
+ }
156
+ const pauseIntervals = unionIntervals(
157
+ (input.pauses ?? [])
158
+ .map((pause) => [canonicalMs(pause.startUtc), canonicalMs(pause.endUtc)] as const)
159
+ .map(([startMs, endMs]) => [Math.max(startMs, dayStartMs), Math.min(endMs, dayEndMs)] as const)
160
+ .filter(([startMs, endMs]) => endMs > startMs),
161
+ );
162
+
163
+ // Group per machine; sort by (instant, contentHash) — position-independent.
164
+ const tracks = new Map<string, TimelineObservation[]>();
165
+ for (const observation of observations) {
166
+ const track = tracks.get(observation.machine) ?? [];
167
+ track.push(observation);
168
+ tracks.set(observation.machine, track);
169
+ }
170
+ for (const track of tracks.values()) {
171
+ track.sort(
172
+ (a, b) => canonicalMs(a.capturedAtUtc) - canonicalMs(b.capturedAtUtc) || (a.contentHash < b.contentHash ? -1 : a.contentHash > b.contentHash ? 1 : 0),
173
+ );
174
+ }
175
+
176
+ const cards: TimelineCard[] = [];
177
+ const machines = [...tracks.keys()].sort();
178
+ for (const machine of machines) {
179
+ const track = tracks.get(machine) ?? [];
180
+ const merged = mergeTrack(machine, track, pauseIntervals);
181
+ // [startMs, endMs] per merged card, reused by the idle pass below.
182
+ const trackIntervals: Array<[number, number]> = [];
183
+ for (let index = 0; index < merged.length; index++) {
184
+ const group = merged[index];
185
+ const first = group.observations[0];
186
+ const last = group.observations[group.observations.length - 1];
187
+ const startMs = canonicalMs(first.capturedAtUtc);
188
+ const lastMs = canonicalMs(last.capturedAtUtc);
189
+ const nextObsMs = index + 1 < merged.length ? canonicalMs(merged[index + 1].observations[0].capturedAtUtc) : Number.POSITIVE_INFINITY;
190
+ const pauseStartMs = pauseIntervals.find(([ps]) => ps > lastMs)?.[0] ?? Number.POSITIVE_INFINITY;
191
+ const endMs = Math.max(lastMs, Math.min(lastMs + TIMELINE_MAX_DWELL_MS, nextObsMs, pauseStartMs, dayEndMs));
192
+ trackIntervals.push([startMs, endMs]);
193
+ const evidenceIds = group.observations.map((observation) => observation.id);
194
+ const classification = classifyTimelineObservation(first, categories);
195
+ cards.push({
196
+ id: stableCardId(`activity|${machine}|${evidenceKeyOf(first)}|${evidenceKeyOf(last)}`),
197
+ kind: "activity",
198
+ title: first.windowTitle.length > 0 ? first.windowTitle : first.app,
199
+ summary: `${first.app} · ${machine} · ${evidenceIds.length} obs · ${formatDurationMinutes(endMs - startMs)}`,
200
+ categoryId: classification.categoryId,
201
+ confidence: classification.confidence,
202
+ startUtc: isoOf(startMs),
203
+ endUtc: isoOf(endMs),
204
+ dayKey: input.date,
205
+ timezone: input.timezone,
206
+ machine,
207
+ evidenceIds,
208
+ evidenceRange: { firstKey: evidenceKeyOf(first), lastKey: evidenceKeyOf(last) },
209
+ });
210
+ }
211
+
212
+ // Idle: uncovered remainders between consecutive cards on this track,
213
+ // pauses removed (a pause wins over idle covering the same minutes).
214
+ for (let index = 0; index + 1 < trackIntervals.length; index++) {
215
+ const gapStart = trackIntervals[index][1];
216
+ const gapEnd = trackIntervals[index + 1][0];
217
+ if (gapEnd <= gapStart) continue;
218
+ let pieces: Array<[number, number]> = [[gapStart, gapEnd]];
219
+ for (const [pauseStart, pauseEnd] of pauseIntervals) {
220
+ pieces = pieces.flatMap(([start, end]) => subtractInterval(start, end, pauseStart, pauseEnd));
221
+ }
222
+ for (const [start, end] of pieces) {
223
+ cards.push({
224
+ id: stableCardId(`idle|${machine}|${isoOf(start)}|${isoOf(end)}`),
225
+ kind: "idle",
226
+ title: "Idle",
227
+ summary: `${formatDurationMinutes(end - start)} gap on ${machine}`,
228
+ categoryId: TIMELINE_RESERVED_IDLE,
229
+ confidence: 1,
230
+ startUtc: isoOf(start),
231
+ endUtc: isoOf(end),
232
+ dayKey: input.date,
233
+ timezone: input.timezone,
234
+ machine,
235
+ evidenceIds: [],
236
+ evidenceRange: null,
237
+ });
238
+ }
239
+ }
240
+ }
241
+
242
+ for (const [pauseStart, pauseEnd] of pauseIntervals) {
243
+ const reason = (input.pauses ?? []).find((pause) => canonicalMs(pause.startUtc) === pauseStart)?.reason;
244
+ cards.push({
245
+ id: stableCardId(`pause|${isoOf(pauseStart)}|${isoOf(pauseEnd)}`),
246
+ kind: "pause",
247
+ title: "Paused",
248
+ summary: reason === undefined ? `${formatDurationMinutes(pauseEnd - pauseStart)} user pause` : `${formatDurationMinutes(pauseEnd - pauseStart)} user pause — ${reason}`,
249
+ categoryId: TIMELINE_RESERVED_PAUSE,
250
+ confidence: 1,
251
+ startUtc: isoOf(pauseStart),
252
+ endUtc: isoOf(pauseEnd),
253
+ dayKey: input.date,
254
+ timezone: input.timezone,
255
+ machine: null,
256
+ evidenceIds: [],
257
+ evidenceRange: null,
258
+ });
259
+ }
260
+
261
+ cards.sort((a, b) => a.startUtc < b.startUtc ? -1 : a.startUtc > b.startUtc ? 1 : a.endUtc < b.endUtc ? -1 : a.endUtc > b.endUtc ? 1 : (a.machine ?? "") < (b.machine ?? "") ? -1 : (a.machine ?? "") > (b.machine ?? "") ? 1 : a.id < b.id ? -1 : a.id > b.id ? 1 : 0);
262
+
263
+ return {
264
+ formatVersion: TIMELINE_FORMAT_VERSION,
265
+ date: input.date,
266
+ timezone: input.timezone,
267
+ startUtc: window.startUtc,
268
+ endUtc: window.endUtc,
269
+ cards,
270
+ };
271
+ }
272
+
273
+ /**
274
+ * Canonical byte-stable serialization. Card objects are constructed in a
275
+ * fixed field order, so `JSON.stringify` output is stable across runs.
276
+ */
277
+ export function serializeTimelineDay(day: TimelineDay): string {
278
+ return JSON.stringify(day);
279
+ }
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Timeline category registry (issue #2049): ordered definitions with stable
3
+ * IDs, names, colors, descriptions, and system/idle flags. Reserved system
4
+ * categories (`system.*`) must always be present; unknown activity stays
5
+ * visible in `system.unknown` rather than being silently reassigned.
6
+ */
7
+
8
+ import type { TimelineCategory } from "./types.js";
9
+
10
+ export const TIMELINE_RESERVED_UNKNOWN = "system.unknown";
11
+ export const TIMELINE_RESERVED_IDLE = "system.idle";
12
+ export const TIMELINE_RESERVED_PAUSE = "system.pause";
13
+
14
+ const COLOR_PATTERN = /^#[0-9a-fA-F]{6}$/;
15
+
16
+ function isTimelineCategoryId(id: string): boolean {
17
+ const parts = id.split(".");
18
+ if (parts.length === 0) return false;
19
+ for (const part of parts) {
20
+ if (part.length === 0) return false;
21
+ const first = part.charCodeAt(0);
22
+ if (first < 97 || first > 122) return false;
23
+ for (let i = 1; i < part.length; i += 1) {
24
+ const code = part.charCodeAt(i);
25
+ const ok = (code >= 97 && code <= 122) || (code >= 48 && code <= 57) || code === 45;
26
+ if (!ok) return false;
27
+ }
28
+ }
29
+ return true;
30
+ }
31
+
32
+
33
+ /**
34
+ * Default registry. User category orders step by 10 so a corrected registry
35
+ * can insert between without renumbering; system categories sort last.
36
+ */
37
+ export const DEFAULT_TIMELINE_CATEGORIES: readonly TimelineCategory[] = [
38
+ { id: "development", name: "Development", color: "#3b82f6", description: "Editors, terminals, IDEs, and code forges.", order: 10 },
39
+ { id: "communication", name: "Communication", color: "#f59e0b", description: "Mail, chat, and meetings.", order: 20 },
40
+ { id: "browsing", name: "Browsing", color: "#6366f1", description: "Web browsing without a more specific domain match.", order: 30 },
41
+ { id: "documents", name: "Documents", color: "#10b981", description: "Writing, notes, and PDFs.", order: 40 },
42
+ { id: "design", name: "Design & Media", color: "#ec4899", description: "Design, audio, and video tools.", order: 50 },
43
+ { id: "data", name: "Data & Analysis", color: "#84cc16", description: "Spreadsheets, dashboards, and databases.", order: 60 },
44
+ { id: "admin", name: "Admin", color: "#64748b", description: "File managers, settings, and system utilities.", order: 70 },
45
+ { id: "entertainment", name: "Entertainment", color: "#ef4444", description: "Video, music, and games.", order: 80 },
46
+ { id: TIMELINE_RESERVED_UNKNOWN, name: "Uncategorized", color: "#9ca3af", description: "Activity with no matching classification signal. Kept visible, never silently reassigned.", order: 990, system: true },
47
+ { id: TIMELINE_RESERVED_IDLE, name: "Idle", color: "#d1d5db", description: "Derived gap between cards where no activity was observed.", order: 991, system: true, idle: true },
48
+ { id: TIMELINE_RESERVED_PAUSE, name: "Paused", color: "#a78bfa", description: "User-declared pause interval.", order: 992, system: true },
49
+ ];
50
+
51
+ /**
52
+ * Validate a registry: unique well-formed ids, non-empty names, hex colors,
53
+ * integer orders, reserved categories present and correctly flagged, and the
54
+ * `system.` namespace reserved. Throws with the offending key path.
55
+ */
56
+ export function validateTimelineCategories(categories: readonly TimelineCategory[]): void {
57
+ if (!Array.isArray(categories) || categories.length === 0) {
58
+ throw new RangeError("timeline categories must be a non-empty array");
59
+ }
60
+ const seen = new Set<string>();
61
+ for (const category of categories) {
62
+ if (typeof category.id !== "string" || !isTimelineCategoryId(category.id)) {
63
+ throw new RangeError(`timeline category id must be dotted kebab-case: ${String(category.id)}`);
64
+ }
65
+ if (seen.has(category.id)) {
66
+ throw new RangeError(`timeline category id must be unique: ${category.id}`);
67
+ }
68
+ seen.add(category.id);
69
+ if (typeof category.name !== "string" || category.name.length === 0) {
70
+ throw new RangeError(`timeline category ${category.id}: name must be a non-empty string`);
71
+ }
72
+ if (typeof category.color !== "string" || !COLOR_PATTERN.test(category.color)) {
73
+ throw new RangeError(`timeline category ${category.id}: color must be #RRGGBB`);
74
+ }
75
+ if (typeof category.description !== "string" || category.description.length === 0) {
76
+ throw new RangeError(`timeline category ${category.id}: description must be a non-empty string`);
77
+ }
78
+ if (!Number.isInteger(category.order)) {
79
+ throw new RangeError(`timeline category ${category.id}: order must be an integer`);
80
+ }
81
+ const isReserved = category.id === TIMELINE_RESERVED_UNKNOWN || category.id === TIMELINE_RESERVED_IDLE || category.id === TIMELINE_RESERVED_PAUSE;
82
+ if (isReserved && category.system !== true) {
83
+ throw new RangeError(`timeline category ${category.id} is reserved and must set system: true`);
84
+ }
85
+ if (!isReserved) {
86
+ if (category.id.startsWith("system.")) {
87
+ throw new RangeError(`timeline category id namespace "system." is reserved: ${category.id}`);
88
+ }
89
+ if (category.system === true || category.idle === true) {
90
+ throw new RangeError(`timeline category ${category.id}: only reserved categories may set system/idle flags`);
91
+ }
92
+ }
93
+ }
94
+ const idle = categories.find((category) => category.id === TIMELINE_RESERVED_IDLE);
95
+ if (idle !== undefined && idle.idle !== true) {
96
+ throw new RangeError(`timeline category ${TIMELINE_RESERVED_IDLE} must set idle: true`);
97
+ }
98
+ for (const reserved of [TIMELINE_RESERVED_UNKNOWN, TIMELINE_RESERVED_IDLE, TIMELINE_RESERVED_PAUSE]) {
99
+ if (!categories.some((category) => category.id === reserved)) {
100
+ throw new RangeError(`timeline categories must include the reserved "${reserved}" category`);
101
+ }
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Deterministic presentation order: by `order`, then by id as the equal-order
107
+ * tie-breaker, so two categories sharing an order never swap between runs.
108
+ */
109
+ export function sortTimelineCategories(categories: readonly TimelineCategory[]): TimelineCategory[] {
110
+ return [...categories].sort((a, b) => a.order - b.order || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
111
+ }
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Deterministic first-pass timeline classification (issue #2049).
3
+ *
4
+ * Signal-only: application name, browser domain, and window-title keywords.
5
+ * No LLM, no scoring, no intent inference — an app/window match says what was
6
+ * on screen, never that the user meant it. First matching rule (in declared
7
+ * order: domain, then app, then title) wins; no match stays visible in the
8
+ * reserved `system.unknown` category with confidence 0.
9
+ */
10
+
11
+ import type { TimelineCategory, TimelineObservation } from "./types.js";
12
+ import { TIMELINE_RESERVED_UNKNOWN } from "./categories.js";
13
+
14
+ const DOMAIN_CONFIDENCE = 0.85;
15
+ const APP_CONFIDENCE = 0.9;
16
+ const TITLE_CONFIDENCE = 0.7;
17
+ const UNKNOWN_CONFIDENCE = 0;
18
+
19
+ interface ClassificationRule {
20
+ categoryId: string;
21
+ /** Substring matches against the browser URL host (most specific signal). */
22
+ domains?: readonly string[];
23
+ /** Substring matches against the application name. */
24
+ apps?: readonly string[];
25
+ /** Substring matches against the window title (weakest signal). */
26
+ titles?: readonly string[];
27
+ }
28
+
29
+ /**
30
+ * Ordered rules. Domain rules come first (a browser on github.com is
31
+ * development even though the app is Chrome), then app rules, then title
32
+ * keywords. Order is part of the contract: inserting a rule changes only
33
+ * classifications below it.
34
+ */
35
+ const RULES: readonly ClassificationRule[] = [
36
+ { categoryId: "development", domains: ["github.com", "gitlab.com", "stackoverflow.com", "linear.app", "atlassian.net"] },
37
+ { categoryId: "communication", domains: ["mail.google.com", "gmail.com", "outlook.com", "outlook.office.com", "slack.com"] },
38
+ { categoryId: "design", domains: ["figma.com", "canva.com"] },
39
+ { categoryId: "documents", domains: ["docs.google.com", "notion.so", "dropbox.com"] },
40
+ { categoryId: "entertainment", domains: ["youtube.com", "netflix.com", "spotify.com"] },
41
+ { categoryId: "data", domains: ["metabase", "tableau", "grafana"] },
42
+
43
+ { categoryId: "development", apps: ["code", "cursor", "neovim", "vim", "emacs", "xcode", "intellij", "terminal", "iterm", "warp", "wezterm", "kitty", "alacritty", "zed", "sublime", "datagrip"] },
44
+ { categoryId: "communication", apps: ["slack", "discord", "teams", "mail", "outlook", "thunderbird", "messages", "signal", "whatsapp", "telegram", "zoom", "facetime", "meet"] },
45
+ { categoryId: "design", apps: ["figma", "sketch", "photoshop", "illustrator", "indesign", "premiere", "after effects", "davinci", "blender", "ableton", "logic pro", "final cut"] },
46
+ { categoryId: "documents", apps: ["word", "pages", "notion", "obsidian", "notes", "typora", "bear", "preview", "acrobat"] },
47
+ { categoryId: "data", apps: ["excel", "numbers", "sheets", "tableau"] },
48
+ { categoryId: "admin", apps: ["finder", "settings", "system preferences", "activity monitor", "files", "explorer"] },
49
+ { categoryId: "entertainment", apps: ["spotify", "music", "youtube", "vlc", "quicktime", "steam", "netflix", "podcast", "tv"] },
50
+ { categoryId: "browsing", apps: ["chrome", "safari", "firefox", "edge", "arc", "brave", "browser"] },
51
+
52
+ { categoryId: "development", titles: ["pull request", "merge conflict", "terminal —", "repository"] },
53
+ { categoryId: "communication", titles: ["inbox"] },
54
+ { categoryId: "data", titles: ["spreadsheet", "pivot table"] },
55
+ ];
56
+
57
+ export interface TimelineClassification {
58
+ categoryId: string;
59
+ confidence: number;
60
+ }
61
+
62
+ /**
63
+ * Classify one observation. Throws if a rule targets a category missing from
64
+ * the registry (configuration error must fail loudly, not fall back silently).
65
+ */
66
+ export function classifyTimelineObservation(
67
+ observation: Pick<TimelineObservation, "app" | "windowTitle" | "browserUrl">,
68
+ categories: readonly TimelineCategory[],
69
+ ): TimelineClassification {
70
+ const app = observation.app.toLowerCase();
71
+ const title = observation.windowTitle.toLowerCase();
72
+ const domain = observation.browserUrl === undefined ? "" : hostOf(observation.browserUrl);
73
+ for (const rule of RULES) {
74
+ if (rule.domains !== undefined && domain !== "" && rule.domains.some((pattern) => domain.includes(pattern))) {
75
+ return checkedRule(rule, DOMAIN_CONFIDENCE, categories);
76
+ }
77
+ }
78
+ for (const rule of RULES) {
79
+ if (rule.apps !== undefined && rule.apps.some((pattern) => app.includes(pattern))) {
80
+ return checkedRule(rule, APP_CONFIDENCE, categories);
81
+ }
82
+ }
83
+ for (const rule of RULES) {
84
+ if (rule.titles !== undefined && rule.titles.some((pattern) => title.includes(pattern))) {
85
+ return checkedRule(rule, TITLE_CONFIDENCE, categories);
86
+ }
87
+ }
88
+ return { categoryId: TIMELINE_RESERVED_UNKNOWN, confidence: UNKNOWN_CONFIDENCE };
89
+ }
90
+
91
+ /** Verify the rule's target exists in the registry before returning it. */
92
+ function checkedRule(
93
+ rule: ClassificationRule,
94
+ confidence: number,
95
+ categories: readonly TimelineCategory[],
96
+ ): TimelineClassification {
97
+ if (!categories.some((category) => category.id === rule.categoryId)) {
98
+ throw new RangeError(`timeline classification rule targets unknown category: ${rule.categoryId}`);
99
+ }
100
+ return { categoryId: rule.categoryId, confidence };
101
+ }
102
+
103
+ /** Lowercased hostname of a URL, or "" when unparseable (never throws). */
104
+ function hostOf(url: string): string {
105
+ try {
106
+ return new URL(url).hostname.toLowerCase();
107
+ } catch {
108
+ return url.toLowerCase();
109
+ }
110
+ }
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Timeline correction store (issue #2049): manual card/category edits that
3
+ * survive day rebuilds. Corrections are keyed by the card's stable
4
+ * content-derived id, so rebuilding the same evidence reproduces the same
5
+ * card ids and re-applies the edit; an explicit `reset()` reverts a card to
6
+ * its derived values. Corrections are user edits, not evidence — they live in
7
+ * their own small SQLite file, never in the #1899 snapshot store.
8
+ */
9
+
10
+ import { mkdirSync } from "node:fs";
11
+ import path from "node:path";
12
+
13
+ import { openBetterSqlite3, type BetterSqlite3Database } from "../../runtime/better-sqlite.js";
14
+ import { DEFAULT_TIMELINE_CATEGORIES, validateTimelineCategories } from "./categories.js";
15
+ import type { TimelineCard, TimelineCategory, TimelineCorrection } from "./types.js";
16
+
17
+ export function timelineCorrectionDatabasePath(memoryDir: string): string {
18
+ return path.join(memoryDir, "state", "activity-timeline.sqlite");
19
+ }
20
+
21
+ interface CorrectionRow {
22
+ card_id: string;
23
+ category_id: string | null;
24
+ title: string | null;
25
+ edited_at_utc: string;
26
+ }
27
+
28
+ function rowToCorrection(row: CorrectionRow): TimelineCorrection {
29
+ return {
30
+ cardId: row.card_id,
31
+ categoryId: row.category_id ?? undefined,
32
+ title: row.title ?? undefined,
33
+ editedAtUtc: row.edited_at_utc,
34
+ };
35
+ }
36
+
37
+ export class TimelineCorrectionStore {
38
+ private readonly db: BetterSqlite3Database;
39
+
40
+ constructor(db: BetterSqlite3Database) {
41
+ this.db = db;
42
+ }
43
+
44
+ static open(memoryDir: string): TimelineCorrectionStore {
45
+ mkdirSync(path.join(memoryDir, "state"), { recursive: true });
46
+ const db = openBetterSqlite3(timelineCorrectionDatabasePath(memoryDir));
47
+ db.pragma("journal_mode = WAL");
48
+ db.pragma("busy_timeout = 5000");
49
+ db.exec(`
50
+ CREATE TABLE IF NOT EXISTS timeline_corrections (
51
+ card_id TEXT PRIMARY KEY,
52
+ category_id TEXT,
53
+ title TEXT,
54
+ edited_at_utc TEXT NOT NULL
55
+ );
56
+ `);
57
+ return new TimelineCorrectionStore(db);
58
+ }
59
+
60
+ /**
61
+ * Persist one correction. `categoryId`, when set, must exist in `categories`
62
+ * (defaults to the built-in registry) — an unknown category is a malformed
63
+ * edit and must fail rather than silently strand the card.
64
+ */
65
+ upsert(correction: TimelineCorrection, categories: readonly TimelineCategory[] = DEFAULT_TIMELINE_CATEGORIES): void {
66
+ validateTimelineCategories(categories);
67
+ if (typeof correction.cardId !== "string" || correction.cardId.length === 0) {
68
+ throw new RangeError("timeline correction requires a non-empty cardId");
69
+ }
70
+ if (typeof correction.editedAtUtc !== "string" || Number.isNaN(Date.parse(correction.editedAtUtc))) {
71
+ throw new RangeError("timeline correction requires a valid editedAtUtc instant");
72
+ }
73
+ if ((correction.categoryId === undefined && correction.title === undefined) || (correction.title !== undefined && correction.title.length === 0)) {
74
+ throw new RangeError("timeline correction must set a categoryId and/or a non-empty title");
75
+ }
76
+ if (correction.categoryId !== undefined && !categories.some((category) => category.id === correction.categoryId)) {
77
+ throw new RangeError(`timeline correction targets unknown category: ${correction.categoryId}`);
78
+ }
79
+ this.db
80
+ .prepare(
81
+ `INSERT INTO timeline_corrections (card_id, category_id, title, edited_at_utc)
82
+ VALUES (?, ?, ?, ?)
83
+ ON CONFLICT(card_id) DO UPDATE SET category_id = excluded.category_id, title = excluded.title, edited_at_utc = excluded.edited_at_utc`,
84
+ )
85
+ .run(correction.cardId, correction.categoryId ?? null, correction.title ?? null, correction.editedAtUtc);
86
+ }
87
+
88
+ get(cardId: string): TimelineCorrection | undefined {
89
+ const row = this.db.prepare("SELECT card_id, category_id, title, edited_at_utc FROM timeline_corrections WHERE card_id = ?").get(cardId);
90
+ return row === undefined ? undefined : rowToCorrection(row as CorrectionRow);
91
+ }
92
+
93
+ /** All corrections ordered by card id (deterministic listing). */
94
+ list(): TimelineCorrection[] {
95
+ return this.db
96
+ .prepare("SELECT card_id, category_id, title, edited_at_utc FROM timeline_corrections ORDER BY card_id ASC")
97
+ .all()
98
+ .map((row) => rowToCorrection(row as CorrectionRow));
99
+ }
100
+
101
+ /** Explicitly reset a card to its derived values; true when a correction existed. */
102
+ reset(cardId: string): boolean {
103
+ return this.db.prepare("DELETE FROM timeline_corrections WHERE card_id = ?").run(cardId).changes > 0;
104
+ }
105
+
106
+ close(): void {
107
+ this.db.close();
108
+ }
109
+ }
110
+
111
+ /**
112
+ * Apply corrections to built cards. Overrides title/category, sets confidence
113
+ * to 1 (a human confirmed it), and stamps manual-edit provenance. Uncorrected
114
+ * cards pass through untouched, so serialization stays byte-stable for them.
115
+ */
116
+ export function applyTimelineCorrections(
117
+ cards: readonly TimelineCard[],
118
+ corrections: readonly TimelineCorrection[],
119
+ ): TimelineCard[] {
120
+ const byCardId = new Map(corrections.map((correction) => [correction.cardId, correction]));
121
+ return cards.map((card) => {
122
+ const correction = byCardId.get(card.id);
123
+ if (correction === undefined) return card;
124
+ return {
125
+ id: card.id,
126
+ kind: card.kind,
127
+ title: correction.title ?? card.title,
128
+ summary: card.summary,
129
+ categoryId: correction.categoryId ?? card.categoryId,
130
+ confidence: 1,
131
+ startUtc: card.startUtc,
132
+ endUtc: card.endUtc,
133
+ dayKey: card.dayKey,
134
+ timezone: card.timezone,
135
+ machine: card.machine,
136
+ evidenceIds: card.evidenceIds,
137
+ evidenceRange: card.evidenceRange,
138
+ manualEdit: {
139
+ ...(correction.categoryId !== undefined ? { categoryId: correction.categoryId } : {}),
140
+ ...(correction.title !== undefined ? { title: correction.title } : {}),
141
+ editedAtUtc: correction.editedAtUtc,
142
+ },
143
+ };
144
+ });
145
+ }
@@ -0,0 +1,8 @@
1
+ /** Public entry for the timeline-card layer (issue #2049). */
2
+ export * from "./types.js";
3
+ export * from "./categories.js";
4
+ export * from "./classify.js";
5
+ export * from "./build.js";
6
+ export * from "./corrections.js";
7
+ export * from "./query.js";
8
+ export * from "./journal-recap.js";