@remnic/core 9.65.8 → 9.66.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 (637) hide show
  1. package/dist/access-admin-ops-surface.d.ts +11 -12
  2. package/dist/access-admin-ops-surface.js +49 -46
  3. package/dist/access-authorization-probe.d.ts +11 -12
  4. package/dist/access-authorization-probe.js +50 -47
  5. package/dist/access-boundary.d.ts +11 -12
  6. package/dist/access-boundary.js +49 -46
  7. package/dist/access-citation-namespace.js +3 -3
  8. package/dist/access-cli.js +111 -106
  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 +49 -46
  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 +51 -48
  20. package/dist/access-http.d.ts +12 -13
  21. package/dist/access-http.js +68 -65
  22. package/dist/access-identity-continuity-surface.d.ts +9 -10
  23. package/dist/access-identity-continuity-surface.js +49 -46
  24. package/dist/access-lcm-surface.d.ts +11 -12
  25. package/dist/access-lcm-surface.js +49 -46
  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 +62 -59
  29. package/dist/access-memory-search-fanout.d.ts +2 -3
  30. package/dist/{access-namespace-preflight-CpAOrS-9.d.ts → access-namespace-preflight-CLWUoMyW.d.ts} +1 -1
  31. package/dist/access-namespace-preflight.d.ts +3 -4
  32. package/dist/access-namespace-preflight.js +49 -46
  33. package/dist/access-observe-write-surface.d.ts +11 -12
  34. package/dist/access-observe-write-surface.js +49 -46
  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 +54 -51
  38. package/dist/access-operations.d.ts +17 -18
  39. package/dist/access-operations.js +59 -56
  40. package/dist/access-recall-concurrency.d.ts +11 -12
  41. package/dist/access-recall-concurrency.js +49 -46
  42. package/dist/access-recall-response.d.ts +11 -12
  43. package/dist/access-recall-response.js +49 -46
  44. package/dist/access-recall-surface.d.ts +11 -12
  45. package/dist/access-recall-surface.js +49 -46
  46. package/dist/access-schema.d.ts +83 -83
  47. package/dist/access-schema.js +7 -7
  48. package/dist/{access-service-Diu61Cfv.d.ts → access-service-CEUE1Isj.d.ts} +66 -66
  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 +49 -46
  52. package/dist/access-surface-catalog.d.ts +11 -12
  53. package/dist/access-surface-catalog.js +53 -48
  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/ambient-provenance.d.ts +1 -2
  62. package/dist/artifact-search.d.ts +1 -2
  63. package/dist/{auto-sync-2YPITIWN.js → auto-sync-Q6Q2FVSC.js} +9 -9
  64. package/dist/behavior-learner.d.ts +1 -2
  65. package/dist/behavior-signals.d.ts +1 -2
  66. package/dist/bootstrap.d.ts +9 -10
  67. package/dist/briefing-window.d.ts +2 -3
  68. package/dist/briefing.d.ts +2 -3
  69. package/dist/briefing.js +23 -23
  70. package/dist/buffer-surprise-report.d.ts +1 -2
  71. package/dist/buffer-turn-helpers.d.ts +1 -2
  72. package/dist/buffer.d.ts +2 -3
  73. package/dist/buffer.js +20 -4
  74. package/dist/bulk-import/index.d.ts +3 -4
  75. package/dist/calibration.d.ts +1 -2
  76. package/dist/calibration.js +1 -1
  77. package/dist/capabilities.d.ts +1 -2
  78. package/dist/{capsule-merge-SGIVB3WA.js → capsule-merge-SEHERWWP.js} +4 -4
  79. package/dist/{catalog-9f-vEQLS.d.ts → catalog-D1HgugTA.d.ts} +1 -1
  80. package/dist/causal-behavior.d.ts +1 -2
  81. package/dist/causal-consolidation.d.ts +1 -2
  82. package/dist/causal-consolidation.js +24 -24
  83. package/dist/causal-trajectory-graph.d.ts +1 -2
  84. package/dist/{chunk-LEPOP46W.js → chunk-227UFSEQ.js} +4 -4
  85. package/dist/{chunk-NPFUNWNX.js → chunk-23CVL7HS.js} +2 -2
  86. package/dist/{chunk-PO7NXBG2.js → chunk-2GF27PGH.js} +5 -5
  87. package/dist/{chunk-MY2BC6UE.js → chunk-2LBAFHOQ.js} +11 -11
  88. package/dist/{chunk-AZMLH5UT.js → chunk-33MFRY25.js} +2 -2
  89. package/dist/{chunk-UEBDCMOO.js → chunk-3TSU662L.js} +3 -3
  90. package/dist/{chunk-CAMNRAJF.js → chunk-4FHRZD5T.js} +2 -2
  91. package/dist/{chunk-FP7YTTVO.js → chunk-4OFKZAJG.js} +2 -1
  92. package/dist/chunk-4OFKZAJG.js.map +1 -0
  93. package/dist/{chunk-S5XOSTYM.js → chunk-4STAANV7.js} +3 -3
  94. package/dist/{chunk-LKYIOCWL.js → chunk-56IV4J5W.js} +546 -96
  95. package/dist/chunk-56IV4J5W.js.map +1 -0
  96. package/dist/{chunk-4F4AQFWL.js → chunk-6CEGSTBD.js} +10 -10
  97. package/dist/{chunk-JYSN42VN.js → chunk-6QDXA26G.js} +235 -181
  98. package/dist/chunk-6QDXA26G.js.map +1 -0
  99. package/dist/{chunk-MDD2RINF.js → chunk-6RUHELWR.js} +3 -3
  100. package/dist/{chunk-WNXYT4MK.js → chunk-72OIT7KS.js} +4 -4
  101. package/dist/{chunk-KQAFEZQX.js → chunk-7LCGFUMB.js} +4 -4
  102. package/dist/{chunk-SNOIKAHM.js → chunk-7UTDHQZ5.js} +3 -3
  103. package/dist/{chunk-5HK3CJAR.js → chunk-7XOG75AU.js} +3 -3
  104. package/dist/{chunk-7BDZTALN.js → chunk-AJTG3CP7.js} +12 -2
  105. package/dist/chunk-AJTG3CP7.js.map +1 -0
  106. package/dist/{chunk-2LWQSV6A.js → chunk-AL3UYZ5N.js} +3 -2
  107. package/dist/chunk-AL3UYZ5N.js.map +1 -0
  108. package/dist/{chunk-UPFNQJC7.js → chunk-CN4VKV3S.js} +2 -2
  109. package/dist/{chunk-PMVPCZJZ.js → chunk-CTCGHNWN.js} +6 -6
  110. package/dist/{chunk-EGBDFJ36.js → chunk-DD5JFCWM.js} +2 -2
  111. package/dist/{chunk-XBGHAAKR.js → chunk-DDX6KIXF.js} +2 -2
  112. package/dist/{chunk-JIYDRBVZ.js → chunk-DJORULH3.js} +2 -2
  113. package/dist/{chunk-UENKPWCS.js → chunk-DMEHOEC7.js} +6 -6
  114. package/dist/{chunk-7KQB4EBS.js → chunk-DUAJKRR2.js} +2 -2
  115. package/dist/{chunk-XDL5CYZN.js → chunk-EEOUMG3J.js} +2 -1
  116. package/dist/{chunk-XDL5CYZN.js.map → chunk-EEOUMG3J.js.map} +1 -1
  117. package/dist/{chunk-SEEJOGQX.js → chunk-EFQCDJZ2.js} +4 -4
  118. package/dist/{chunk-Q57GOHLF.js → chunk-EGALNSZ4.js} +3 -3
  119. package/dist/{chunk-KCT36JAW.js → chunk-ESNFSSO4.js} +2 -2
  120. package/dist/{chunk-XQ3HXAQH.js → chunk-ET2CNMLD.js} +4 -4
  121. package/dist/{chunk-PU56CXZA.js → chunk-EZSCW4EM.js} +2 -2
  122. package/dist/{chunk-HMZKGHMD.js → chunk-FESUGFIL.js} +3 -3
  123. package/dist/{chunk-3A2NJP2U.js → chunk-FKKGCGYL.js} +3 -3
  124. package/dist/{chunk-BWGCOLEL.js → chunk-FTTJRVB7.js} +2 -2
  125. package/dist/{chunk-ODU2CNNX.js → chunk-FYWLSFFS.js} +2 -2
  126. package/dist/{chunk-W2BAGGEW.js → chunk-GEJKYA7D.js} +33 -24
  127. package/dist/{chunk-W2BAGGEW.js.map → chunk-GEJKYA7D.js.map} +1 -1
  128. package/dist/chunk-GSKINLAK.js +267 -0
  129. package/dist/chunk-GSKINLAK.js.map +1 -0
  130. package/dist/{chunk-3PKAS6VL.js → chunk-GX6FTSYH.js} +2 -2
  131. package/dist/{chunk-76DIF5KT.js → chunk-H7VDIF2V.js} +2 -2
  132. package/dist/{chunk-F7XUD3PL.js → chunk-HJXA6ZM7.js} +2 -2
  133. package/dist/{chunk-4QEYREAV.js → chunk-HNPE66LB.js} +2 -2
  134. package/dist/{chunk-P36Z4JRA.js → chunk-I5VB44ZK.js} +2 -2
  135. package/dist/{chunk-EUYWQ7TS.js → chunk-IEZ6CGTW.js} +2 -2
  136. package/dist/{chunk-OXRRJXPR.js → chunk-IHGMRDEE.js} +275 -1678
  137. package/dist/chunk-IHGMRDEE.js.map +1 -0
  138. package/dist/{chunk-5DHKCO52.js → chunk-IVIAHQBR.js} +2 -2
  139. package/dist/{chunk-TFR3HG4K.js → chunk-J3OND5QT.js} +4 -4
  140. package/dist/{chunk-UW5NPZJ2.js → chunk-JALOAKSZ.js} +59 -7
  141. package/dist/chunk-JALOAKSZ.js.map +1 -0
  142. package/dist/{chunk-5ACCD4L7.js → chunk-JRRQ747T.js} +7 -7
  143. package/dist/{chunk-V4IDF3EZ.js → chunk-JTWZKNUH.js} +5 -5
  144. package/dist/chunk-K66OY4EI.js +202 -0
  145. package/dist/chunk-K66OY4EI.js.map +1 -0
  146. package/dist/{chunk-XAB6STPO.js → chunk-KODXCHXJ.js} +17 -3
  147. package/dist/chunk-KODXCHXJ.js.map +1 -0
  148. package/dist/{chunk-KZIF6XHX.js → chunk-KXIXO76C.js} +28 -15
  149. package/dist/chunk-KXIXO76C.js.map +1 -0
  150. package/dist/{chunk-5RWZH6PH.js → chunk-L4X4PJYK.js} +2 -2
  151. package/dist/{chunk-UTQUEHC7.js → chunk-LUDBXTBJ.js} +8 -8
  152. package/dist/{chunk-XNWXSGHS.js → chunk-MAH64N55.js} +28 -10
  153. package/dist/chunk-MAH64N55.js.map +1 -0
  154. package/dist/{chunk-LDKPDODJ.js → chunk-ME35HVDJ.js} +2 -2
  155. package/dist/{chunk-DPCXDG7G.js → chunk-MJRGVXPQ.js} +2 -2
  156. package/dist/{chunk-773TRRGT.js → chunk-MJUCDM3C.js} +2 -2
  157. package/dist/{chunk-T6ILXUAH.js → chunk-MN5NOOI7.js} +2 -2
  158. package/dist/{chunk-AHPIFKNG.js → chunk-N4F7ZSSG.js} +2 -2
  159. package/dist/{chunk-JOZUBF4A.js → chunk-NACLNNFQ.js} +2 -2
  160. package/dist/{chunk-LC2BDILZ.js → chunk-NBP4EX5N.js} +2 -2
  161. package/dist/{chunk-ZVPVTPGI.js → chunk-NNZFPYYX.js} +4 -4
  162. package/dist/{chunk-DA7ITC5Z.js → chunk-O57GM3FR.js} +2 -2
  163. package/dist/{chunk-7VZFRUQU.js → chunk-O7ERGZDA.js} +5 -5
  164. package/dist/{chunk-3SZD4CYO.js → chunk-OAJMQKQR.js} +3 -3
  165. package/dist/{chunk-HSZMX3ZJ.js → chunk-ODW5GDFE.js} +2 -2
  166. package/dist/{chunk-7WOWGRAU.js → chunk-PEBH5DCK.js} +10 -7
  167. package/dist/{chunk-7WOWGRAU.js.map → chunk-PEBH5DCK.js.map} +1 -1
  168. package/dist/{chunk-J2WC5LF4.js → chunk-QBC33MPY.js} +2 -1
  169. package/dist/{chunk-T7XP6IZE.js → chunk-QCRJMU5V.js} +2 -2
  170. package/dist/chunk-QJCWK2A7.js +1466 -0
  171. package/dist/chunk-QJCWK2A7.js.map +1 -0
  172. package/dist/{chunk-YEUXERJ6.js → chunk-RDGKVH6T.js} +7 -3
  173. package/dist/{chunk-YEUXERJ6.js.map → chunk-RDGKVH6T.js.map} +1 -1
  174. package/dist/{chunk-OA2O2GJ4.js → chunk-RZ3IZIJG.js} +3 -3
  175. package/dist/{chunk-UL4MKZHI.js → chunk-SN4JXNLL.js} +2 -2
  176. package/dist/chunk-TB2MJRI6.js +866 -0
  177. package/dist/chunk-TB2MJRI6.js.map +1 -0
  178. package/dist/{chunk-7PHI6GUI.js → chunk-TEZ2HTC7.js} +42 -2
  179. package/dist/chunk-TEZ2HTC7.js.map +1 -0
  180. package/dist/{chunk-CPA5NBHN.js → chunk-TNGH4ZYI.js} +2 -2
  181. package/dist/{chunk-F3NVYTTA.js → chunk-TNXNECAN.js} +6 -6
  182. package/dist/{chunk-BEC4YBNA.js → chunk-TVW4C7PV.js} +2 -2
  183. package/dist/{chunk-UFKPQBXH.js → chunk-U62OK7BB.js} +2 -2
  184. package/dist/{chunk-AX7UXCHJ.js → chunk-UYA36DQ7.js} +2 -1
  185. package/dist/chunk-UYA36DQ7.js.map +1 -0
  186. package/dist/{chunk-DEACDKE3.js → chunk-VCKWULAK.js} +112 -87
  187. package/dist/chunk-VCKWULAK.js.map +1 -0
  188. package/dist/chunk-VOSWUO3K.js +100 -0
  189. package/dist/chunk-VOSWUO3K.js.map +1 -0
  190. package/dist/{chunk-TUHBYJXL.js → chunk-VQ4AMTGZ.js} +1 -1
  191. package/dist/{chunk-3BCULS4U.js → chunk-VQNRICAQ.js} +145 -507
  192. package/dist/chunk-VQNRICAQ.js.map +1 -0
  193. package/dist/{chunk-H2YSH3DG.js → chunk-WKAXBXVA.js} +2 -2
  194. package/dist/{chunk-HRHO3ZNG.js → chunk-WKJFIMVN.js} +2 -2
  195. package/dist/{chunk-SXIMQLGV.js → chunk-WVGXCBOC.js} +2 -2
  196. package/dist/{chunk-CRML27CO.js → chunk-X5YYSAZX.js} +4 -4
  197. package/dist/{chunk-FZEEWOI2.js → chunk-XJJYSX6F.js} +2 -2
  198. package/dist/{chunk-U7EW2W4W.js → chunk-XKNHFDTT.js} +26 -6
  199. package/dist/chunk-XKNHFDTT.js.map +1 -0
  200. package/dist/{chunk-UG6VXIOK.js → chunk-XSTNGNJP.js} +2 -2
  201. package/dist/{chunk-YDPAE2RD.js → chunk-YFLLGRXO.js} +2 -2
  202. package/dist/{chunk-LPNCR4QK.js → chunk-YXFCALVT.js} +12 -12
  203. package/dist/{chunk-Q4WONDMJ.js → chunk-YYGZJPOK.js} +2 -2
  204. package/dist/{chunk-GTO56JY5.js → chunk-ZJPM7GZ3.js} +2 -2
  205. package/dist/{chunk-LOXHYCVS.js → chunk-ZW4VXELZ.js} +2 -2
  206. package/dist/{cli-O3F-ht3i.d.ts → cli-BEkm2MEf.d.ts} +5 -5
  207. package/dist/cli.d.ts +13 -14
  208. package/dist/cli.js +90 -85
  209. package/dist/coding/export-okf-codegraph.d.ts +56 -0
  210. package/dist/coding/export-okf-codegraph.js +526 -0
  211. package/dist/coding/export-okf-codegraph.js.map +1 -0
  212. package/dist/coding/pre-action-gate.d.ts +1 -2
  213. package/dist/compounding/engine.d.ts +2 -3
  214. package/dist/compounding/engine.js +24 -24
  215. package/dist/compounding/preference-consolidator.d.ts +1 -2
  216. package/dist/compression-optimizer.d.ts +1 -2
  217. package/dist/config.d.ts +1 -2
  218. package/dist/config.js +11 -11
  219. package/dist/connectors/codex-materialize-runner.d.ts +1 -2
  220. package/dist/connectors/codex-materialize-runner.js +23 -23
  221. package/dist/connectors/codex-materialize.d.ts +1 -2
  222. package/dist/connectors/index.d.ts +1 -2
  223. package/dist/connectors/index.js +23 -23
  224. package/dist/consolidation-provenance-check.d.ts +2 -3
  225. package/dist/consolidation-provenance-check.js +4 -4
  226. package/dist/consolidation-undo.d.ts +2 -3
  227. package/dist/consolidation-undo.js +3 -3
  228. package/dist/contradiction/index.d.ts +3 -4
  229. package/dist/contradiction/index.js +9 -9
  230. package/dist/{contradiction-scan-AKUWPX5N.js → contradiction-scan-NOYMFG66.js} +3 -3
  231. package/dist/converge-config.d.ts +1 -2
  232. package/dist/convergence-refresh.d.ts +2 -3
  233. package/dist/convergence-refresh.js +25 -25
  234. package/dist/conversation-index/backend.d.ts +1 -2
  235. package/dist/conversation-index/backend.js +2 -2
  236. package/dist/conversation-index/chunker.d.ts +1 -2
  237. package/dist/conversation-index/faiss-adapter.d.ts +1 -2
  238. package/dist/conversation-index/indexer.d.ts +1 -2
  239. package/dist/conversation-index/search.d.ts +1 -2
  240. package/dist/corpus-watermark.d.ts +1 -2
  241. package/dist/corpus-watermark.js +25 -25
  242. package/dist/cross-lingual-recall.d.ts +1 -2
  243. package/dist/day-summary.d.ts +1 -2
  244. package/dist/delinearize.d.ts +1 -2
  245. package/dist/dependency-propagation-config.d.ts +1 -2
  246. package/dist/{dependency-propagation-delivery-CL6RWXTA.d.ts → dependency-propagation-delivery-BCpeo14F.d.ts} +1 -1
  247. package/dist/direct-answer-wiring.d.ts +1 -2
  248. package/dist/direct-answer.d.ts +1 -2
  249. package/dist/embedding-fallback.d.ts +1 -2
  250. package/dist/enrichment/index.d.ts +1 -2
  251. package/dist/entity-origin-fields.d.ts +1 -2
  252. package/dist/entity-retrieval.d.ts +2 -3
  253. package/dist/entity-retrieval.js +23 -23
  254. package/dist/entity-schema.d.ts +1 -2
  255. package/dist/episodic-context.d.ts +1 -2
  256. package/dist/eval-trajectory-contracts.d.ts +1 -2
  257. package/dist/eval-trajectory-store.d.ts +1 -2
  258. package/dist/eval-trajectory.d.ts +1 -2
  259. package/dist/explicit-capture.d.ts +9 -10
  260. package/dist/explicit-capture.js +11 -11
  261. package/dist/external-wiki-access.d.ts +11 -12
  262. package/dist/external-wiki-access.js +50 -47
  263. package/dist/external-wiki-collection-registration.d.ts +1 -2
  264. package/dist/external-wiki-collection.d.ts +1 -2
  265. package/dist/external-wiki-mcp-tools.d.ts +11 -12
  266. package/dist/extraction-error-classification.d.ts +1 -2
  267. package/dist/extraction-faithfulness.d.ts +1 -2
  268. package/dist/extraction-faithfulness.js +2 -2
  269. package/dist/extraction-judge-telemetry.d.ts +1 -2
  270. package/dist/extraction-judge-training.d.ts +1 -2
  271. package/dist/extraction-judge.d.ts +1 -2
  272. package/dist/extraction-judge.js +2 -2
  273. package/dist/extraction-liveness.d.ts +1 -2
  274. package/dist/extraction-normalization.d.ts +1 -2
  275. package/dist/extraction-prompt.d.ts +1 -2
  276. package/dist/extraction-source-grounding-rules.d.ts +1 -2
  277. package/dist/extraction-source-grounding.d.ts +1 -2
  278. package/dist/extraction.d.ts +1 -2
  279. package/dist/extraction.js +32 -29
  280. package/dist/fallback-llm.d.ts +7 -2
  281. package/dist/fallback-llm.js +1 -1
  282. package/dist/{first-start-migration-4NETATFF.js → first-start-migration-KHIMCBIC.js} +3 -3
  283. package/dist/graph-dashboard-diff.d.ts +1 -2
  284. package/dist/graph-dashboard-key.d.ts +1 -2
  285. package/dist/graph-dashboard-parser.d.ts +1 -2
  286. package/dist/graph-edge-reinforcement.d.ts +1 -2
  287. package/dist/graph-path-reconstruction.d.ts +1 -2
  288. package/dist/graph-path-scoring.d.ts +1 -2
  289. package/dist/graph-snapshot.d.ts +1 -2
  290. package/dist/graph.d.ts +1 -2
  291. package/dist/harmonic-retrieval.js +1 -1
  292. package/dist/importance.d.ts +1 -2
  293. package/dist/importers/index.d.ts +1 -2
  294. package/dist/in-flight-reads.d.ts +1 -2
  295. package/dist/{index-C7Xep6S9.d.ts → index-D_pyMUaP.d.ts} +2 -2
  296. package/dist/index.d.ts +929 -700
  297. package/dist/index.js +167 -132
  298. package/dist/intent.d.ts +1 -2
  299. package/dist/lcm/engine.d.ts +1 -2
  300. package/dist/lcm/index.d.ts +1 -2
  301. package/dist/lcm/tools.d.ts +1 -2
  302. package/dist/lifecycle.d.ts +1 -2
  303. package/dist/live-connectors-runner.d.ts +1 -2
  304. package/dist/local-llm.d.ts +1 -2
  305. package/dist/local-model-endpoint.d.ts +1 -2
  306. package/dist/location/index.d.ts +315 -6
  307. package/dist/location/index.js +151 -19
  308. package/dist/maintenance/memory-governance.d.ts +1 -2
  309. package/dist/maintenance/memory-governance.js +23 -23
  310. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -3
  311. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +23 -23
  312. package/dist/maintenance/rebuild-memory-projection.d.ts +2 -3
  313. package/dist/maintenance/rebuild-memory-projection.js +24 -24
  314. package/dist/{maintenance-CJ-xqFp0.d.ts → maintenance-DDUX9d6D.d.ts} +3 -3
  315. package/dist/mcp-memory-inspector-app.d.ts +11 -12
  316. package/dist/mcp-read-only-tools.js +1 -1
  317. package/dist/memory-action-policy.d.ts +1 -2
  318. package/dist/memory-cache.d.ts +1 -2
  319. package/dist/memory-controller.d.ts +1 -2
  320. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -2
  321. package/dist/memory-projection-mutations.js +3 -3
  322. package/dist/memory-projection-store.d.ts +1 -2
  323. package/dist/memory-projection-store.js +1 -1
  324. package/dist/memory-provenance.d.ts +1 -2
  325. package/dist/memory-snapshot.d.ts +1 -2
  326. package/dist/memory-subject-cli.d.ts +11 -12
  327. package/dist/memory-subject.d.ts +11 -12
  328. package/dist/memory-subject.js +4 -4
  329. package/dist/memory-worth-outcomes.d.ts +2 -3
  330. package/dist/models-json.d.ts +1 -2
  331. package/dist/namespaces/migrate.d.ts +3 -4
  332. package/dist/namespaces/migrate.js +24 -24
  333. package/dist/namespaces/principal.d.ts +1 -2
  334. package/dist/namespaces/search.d.ts +1 -2
  335. package/dist/namespaces/search.js +5 -5
  336. package/dist/namespaces/storage.d.ts +3 -4
  337. package/dist/namespaces/storage.js +23 -23
  338. package/dist/native-knowledge.d.ts +1 -2
  339. package/dist/offline-sync-file-io.js +3 -3
  340. package/dist/offline-sync-impression-drain.d.ts +1 -2
  341. package/dist/offline-sync-impression-drain.js +9 -9
  342. package/dist/offline-sync.js +4 -4
  343. package/dist/operator-doctor-corpus.d.ts +1 -2
  344. package/dist/operator-doctor-corpus.js +26 -26
  345. package/dist/operator-doctor-replica.d.ts +1 -2
  346. package/dist/operator-toolkit.d.ts +3 -4
  347. package/dist/operator-toolkit.js +42 -42
  348. package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -3
  349. package/dist/orchestration/maintenance.d.ts +4 -5
  350. package/dist/orchestration/maintenance.js +37 -36
  351. package/dist/{orchestrator-BsntWxLy.d.ts → orchestrator-3F4jihCo.d.ts} +8 -8
  352. package/dist/orchestrator.d.ts +9 -10
  353. package/dist/orchestrator.js +111 -106
  354. package/dist/page-versioning.js +3 -3
  355. package/dist/patterns-cli.d.ts +1 -2
  356. package/dist/{pipeline-CVoysPm2.d.ts → pipeline-CB1dj6Uh.d.ts} +1 -1
  357. package/dist/policy-runtime.d.ts +1 -2
  358. package/dist/proactive-contention.d.ts +1 -2
  359. package/dist/provenance.d.ts +1 -2
  360. package/dist/{public-http-CuOxlTC2.d.ts → public-http-34-JIAGQ.d.ts} +1 -1
  361. package/dist/{purge-GB7PZHT2.js → purge-OP6BEDFY.js} +2 -2
  362. package/dist/{qmd-DWMAGA5l.d.ts → qmd-edLLZXc5.d.ts} +1 -1
  363. package/dist/qmd-preflight.d.ts +2 -3
  364. package/dist/qmd-recall-cache.d.ts +1 -2
  365. package/dist/qmd.d.ts +2 -3
  366. package/dist/recall-concurrency-config.d.ts +1 -2
  367. package/dist/recall-disclosure-escalation.d.ts +1 -2
  368. package/dist/recall-explain-renderer.d.ts +1 -2
  369. package/dist/recall-memory-map.d.ts +1 -2
  370. package/dist/recall-planner-llm.d.ts +1 -2
  371. package/dist/recall-planner-llm.js +1 -1
  372. package/dist/recall-state.d.ts +1 -2
  373. package/dist/recall-tag-filter.d.ts +1 -2
  374. package/dist/recall-timings.d.ts +1 -2
  375. package/dist/recall-xray-cli.d.ts +1 -2
  376. package/dist/recall-xray-renderer.d.ts +1 -2
  377. package/dist/recall-xray.d.ts +1 -2
  378. package/dist/reconcile/cursor.d.ts +1 -2
  379. package/dist/reconcile/manifest.d.ts +1 -2
  380. package/dist/reconcile/manifest.js +4 -4
  381. package/dist/reconcile/plan.d.ts +1 -2
  382. package/dist/replay/normalizers/chatgpt.d.ts +1 -2
  383. package/dist/replay/normalizers/claude.d.ts +1 -2
  384. package/dist/replay/normalizers/openclaw.d.ts +1 -2
  385. package/dist/replay/normalizers/shared.d.ts +1 -2
  386. package/dist/replay/runner.d.ts +1 -2
  387. package/dist/replay/types.d.ts +1 -2
  388. package/dist/replica-divergence.d.ts +1 -2
  389. package/dist/replica-peers-config.d.ts +1 -2
  390. package/dist/{resolution-XWBPKYFB.js → resolution-4DLI3IOR.js} +10 -10
  391. package/dist/resolve-auth-token.d.ts +1 -2
  392. package/dist/resume-bundles.js +12 -12
  393. package/dist/retrieval-agents.d.ts +2 -3
  394. package/dist/retrieval-tiers.d.ts +1 -2
  395. package/dist/routing/engine.d.ts +1 -2
  396. package/dist/routing/store.d.ts +1 -2
  397. package/dist/salvage-envelope.d.ts +1 -2
  398. package/dist/salvage-envelope.js +6 -6
  399. package/dist/schemas.d.ts +639 -174
  400. package/dist/schemas.js +3 -1
  401. package/dist/{scope-profiles-CPWkW_dI.d.ts → scope-profiles-BF2lu81V.d.ts} +1 -1
  402. package/dist/search/document-scanner.js +1 -1
  403. package/dist/search/embed-helper.d.ts +1 -2
  404. package/dist/search/factory.d.ts +1 -2
  405. package/dist/search/factory.js +4 -4
  406. package/dist/search/index.d.ts +1 -2
  407. package/dist/search/index.js +4 -4
  408. package/dist/search/lancedb-backend.d.ts +1 -2
  409. package/dist/search/lancedb-backend.js +1 -1
  410. package/dist/search/meilisearch-backend.d.ts +1 -2
  411. package/dist/search/meilisearch-backend.js +1 -1
  412. package/dist/search/noop-backend.d.ts +1 -2
  413. package/dist/search/orama-backend.d.ts +1 -2
  414. package/dist/search/orama-backend.js +1 -1
  415. package/dist/search/port.d.ts +1 -2
  416. package/dist/search/remote-backend.d.ts +1 -2
  417. package/dist/secure-store/index.js +3 -3
  418. package/dist/{semantic-consolidation-CNFVBXFc.d.ts → semantic-consolidation-5OuWXBRt.d.ts} +1 -1
  419. package/dist/semantic-consolidation.d.ts +2 -3
  420. package/dist/semantic-consolidation.js +24 -24
  421. package/dist/semantic-rule-promotion.js +23 -23
  422. package/dist/semantic-rule-verifier.d.ts +1 -2
  423. package/dist/semantic-rule-verifier.js +23 -23
  424. package/dist/{service-Bb-JIdQ0.d.ts → service-CrqEhLXD.d.ts} +2 -2
  425. package/dist/session-observer-bands.d.ts +1 -2
  426. package/dist/session-observer-state.d.ts +1 -2
  427. package/dist/shared-context/manager.d.ts +7 -8
  428. package/dist/signal.d.ts +1 -2
  429. package/dist/source-agent-qualifier.d.ts +1 -2
  430. package/dist/source-agent-qualifier.js +30 -27
  431. package/dist/standup/build.d.ts +16 -0
  432. package/dist/standup/build.js +17 -0
  433. package/dist/standup/build.js.map +1 -0
  434. package/dist/{storage-CukrlNKk.d.ts → storage-BQn-xnxm.d.ts} +1 -1
  435. package/dist/storage.d.ts +2 -3
  436. package/dist/storage.js +22 -22
  437. package/dist/subject-config.d.ts +1 -2
  438. package/dist/subject-config.js +5 -5
  439. package/dist/summarizer.d.ts +1 -2
  440. package/dist/summarizer.js +2 -2
  441. package/dist/summary-snapshot.d.ts +1 -2
  442. package/dist/support-passport/index.d.ts +16 -17
  443. package/dist/support-passport/index.js +52 -49
  444. package/dist/temporal-supersession.d.ts +2 -3
  445. package/dist/temporal-timeline-recall.d.ts +1 -2
  446. package/dist/temporal-validity.d.ts +1 -2
  447. package/dist/threading.d.ts +1 -2
  448. package/dist/tier-migration.d.ts +2 -3
  449. package/dist/tier-routing.d.ts +1 -2
  450. package/dist/tier-routing.js +2 -2
  451. package/dist/{tier-stats-4B5IJ3NE.js → tier-stats-2TOW3QNL.js} +3 -3
  452. package/dist/topics.d.ts +1 -2
  453. package/dist/transcript.d.ts +1 -2
  454. package/dist/transfer/capsule-export.js +2 -2
  455. package/dist/transfer/capsule-import.js +5 -5
  456. package/dist/transfer/export-okf.d.ts +39 -0
  457. package/dist/transfer/export-okf.js +112 -0
  458. package/dist/transfer/export-okf.js.map +1 -0
  459. package/dist/transfer/types.d.ts +78 -78
  460. package/dist/trust-score-stage.d.ts +1 -2
  461. package/dist/trust-score.d.ts +1 -2
  462. package/dist/{types-djxQlxJ7.d.ts → types-BRpcNjHZ.d.ts} +117 -2
  463. package/dist/types.d.ts +1 -2
  464. package/dist/utility-runtime.d.ts +1 -2
  465. package/dist/verified-recall.js +23 -23
  466. package/dist/who-knows-cli.d.ts +11 -12
  467. package/dist/who-knows-cli.js +24 -24
  468. package/dist/who-knows.d.ts +11 -12
  469. package/dist/who-knows.js +23 -23
  470. package/dist/write-envelope.d.ts +1 -2
  471. package/dist/write-envelope.js +5 -5
  472. package/package.json +34 -3
  473. package/src/access-admin-ops-surface.ts +6 -1
  474. package/src/access-boundary.ts +1 -0
  475. package/src/access-http.ts +3 -1
  476. package/src/access-mcp-output-schemas.ts +1 -0
  477. package/src/access-mcp.ts +3 -3
  478. package/src/access-operations.ts +1 -0
  479. package/src/access-service-offline-file-content.test.ts +63 -0
  480. package/src/access-surface-catalog.ts +2 -0
  481. package/src/activity/config.test.ts +1 -0
  482. package/src/activity/config.ts +21 -1
  483. package/src/activity/index.ts +1 -0
  484. package/src/activity/timeline/build.ts +279 -0
  485. package/src/activity/timeline/categories.ts +111 -0
  486. package/src/activity/timeline/classify.ts +110 -0
  487. package/src/activity/timeline/corrections.ts +145 -0
  488. package/src/activity/timeline/index.ts +6 -0
  489. package/src/activity/timeline/timeline.test.ts +277 -0
  490. package/src/activity/timeline/types.ts +106 -0
  491. package/src/activity/types.ts +6 -0
  492. package/src/cli/okf-commands.ts +45 -0
  493. package/src/cli.ts +2 -2
  494. package/src/coding/export-okf-codegraph.test.ts +381 -0
  495. package/src/coding/export-okf-codegraph.ts +565 -0
  496. package/src/config.test.ts +1 -0
  497. package/src/extraction-prompt-safety.test.ts +14 -2
  498. package/src/extraction.ts +21 -1
  499. package/src/fallback-llm.test.ts +134 -0
  500. package/src/fallback-llm.ts +77 -5
  501. package/src/location/access-operations.ts +17 -8
  502. package/src/location/backfill.ts +137 -0
  503. package/src/location/config.test.ts +3 -0
  504. package/src/location/config.ts +46 -2
  505. package/src/location/http-glue.ts +1 -1
  506. package/src/location/index.ts +3 -0
  507. package/src/location/intervals.ts +1 -0
  508. package/src/location/matching.test.ts +65 -0
  509. package/src/location/matching.ts +354 -0
  510. package/src/location/mcp-tools.ts +2 -1
  511. package/src/location/surfaces.test.ts +15 -2
  512. package/src/location/surfaces.ts +95 -18
  513. package/src/location/tagging.test.ts +119 -0
  514. package/src/location/tagging.ts +277 -0
  515. package/src/location/types.ts +23 -1
  516. package/src/mcp-read-only-tools.ts +1 -0
  517. package/src/memory-projection-store.ts +3 -1
  518. package/src/okf/cli.ts +18 -5
  519. package/src/okf/config.ts +5 -0
  520. package/src/okf/index-files.test.ts +60 -0
  521. package/src/okf/index-files.ts +114 -0
  522. package/src/okf/render.ts +133 -0
  523. package/src/okf/type-mapping.test.ts +3 -0
  524. package/src/okf/type-mapping.ts +2 -0
  525. package/src/orchestration/extraction-run.ts +2 -1
  526. package/src/orchestration/generic-recall-paths.ts +4 -3
  527. package/src/schemas.ts +17 -1
  528. package/src/standup/access-operations.ts +14 -0
  529. package/src/standup/build.test.ts +34 -0
  530. package/src/standup/build.ts +115 -0
  531. package/src/standup/http-glue.ts +15 -0
  532. package/src/standup/mcp-tools.ts +16 -0
  533. package/src/support-passport/card-projection.ts +1 -0
  534. package/src/support-passport/card-service-commit-forwarding.test.ts +1 -0
  535. package/src/support-passport/card-service.test.ts +75 -1
  536. package/src/support-passport/card-service.ts +6 -3
  537. package/src/support-passport/card-state.ts +5 -1
  538. package/src/support-passport/offline-sync-guard.ts +14 -1
  539. package/src/transfer/export-okf.test.ts +164 -0
  540. package/src/transfer/export-okf.ts +286 -0
  541. package/dist/chunk-2LWQSV6A.js.map +0 -1
  542. package/dist/chunk-3BCULS4U.js.map +0 -1
  543. package/dist/chunk-7BDZTALN.js.map +0 -1
  544. package/dist/chunk-7PHI6GUI.js.map +0 -1
  545. package/dist/chunk-AX7UXCHJ.js.map +0 -1
  546. package/dist/chunk-DEACDKE3.js.map +0 -1
  547. package/dist/chunk-FP7YTTVO.js.map +0 -1
  548. package/dist/chunk-JYSN42VN.js.map +0 -1
  549. package/dist/chunk-KZIF6XHX.js.map +0 -1
  550. package/dist/chunk-LKYIOCWL.js.map +0 -1
  551. package/dist/chunk-OXRRJXPR.js.map +0 -1
  552. package/dist/chunk-U7EW2W4W.js.map +0 -1
  553. package/dist/chunk-UW5NPZJ2.js.map +0 -1
  554. package/dist/chunk-XAB6STPO.js.map +0 -1
  555. package/dist/chunk-XNWXSGHS.js.map +0 -1
  556. package/dist/types-CM86alG1.d.ts +0 -89
  557. /package/dist/{auto-sync-2YPITIWN.js.map → auto-sync-Q6Q2FVSC.js.map} +0 -0
  558. /package/dist/{capsule-merge-SGIVB3WA.js.map → capsule-merge-SEHERWWP.js.map} +0 -0
  559. /package/dist/{chunk-LEPOP46W.js.map → chunk-227UFSEQ.js.map} +0 -0
  560. /package/dist/{chunk-NPFUNWNX.js.map → chunk-23CVL7HS.js.map} +0 -0
  561. /package/dist/{chunk-PO7NXBG2.js.map → chunk-2GF27PGH.js.map} +0 -0
  562. /package/dist/{chunk-MY2BC6UE.js.map → chunk-2LBAFHOQ.js.map} +0 -0
  563. /package/dist/{chunk-AZMLH5UT.js.map → chunk-33MFRY25.js.map} +0 -0
  564. /package/dist/{chunk-UEBDCMOO.js.map → chunk-3TSU662L.js.map} +0 -0
  565. /package/dist/{chunk-CAMNRAJF.js.map → chunk-4FHRZD5T.js.map} +0 -0
  566. /package/dist/{chunk-S5XOSTYM.js.map → chunk-4STAANV7.js.map} +0 -0
  567. /package/dist/{chunk-4F4AQFWL.js.map → chunk-6CEGSTBD.js.map} +0 -0
  568. /package/dist/{chunk-MDD2RINF.js.map → chunk-6RUHELWR.js.map} +0 -0
  569. /package/dist/{chunk-WNXYT4MK.js.map → chunk-72OIT7KS.js.map} +0 -0
  570. /package/dist/{chunk-KQAFEZQX.js.map → chunk-7LCGFUMB.js.map} +0 -0
  571. /package/dist/{chunk-SNOIKAHM.js.map → chunk-7UTDHQZ5.js.map} +0 -0
  572. /package/dist/{chunk-5HK3CJAR.js.map → chunk-7XOG75AU.js.map} +0 -0
  573. /package/dist/{chunk-UPFNQJC7.js.map → chunk-CN4VKV3S.js.map} +0 -0
  574. /package/dist/{chunk-PMVPCZJZ.js.map → chunk-CTCGHNWN.js.map} +0 -0
  575. /package/dist/{chunk-EGBDFJ36.js.map → chunk-DD5JFCWM.js.map} +0 -0
  576. /package/dist/{chunk-XBGHAAKR.js.map → chunk-DDX6KIXF.js.map} +0 -0
  577. /package/dist/{chunk-JIYDRBVZ.js.map → chunk-DJORULH3.js.map} +0 -0
  578. /package/dist/{chunk-UENKPWCS.js.map → chunk-DMEHOEC7.js.map} +0 -0
  579. /package/dist/{chunk-7KQB4EBS.js.map → chunk-DUAJKRR2.js.map} +0 -0
  580. /package/dist/{chunk-SEEJOGQX.js.map → chunk-EFQCDJZ2.js.map} +0 -0
  581. /package/dist/{chunk-Q57GOHLF.js.map → chunk-EGALNSZ4.js.map} +0 -0
  582. /package/dist/{chunk-KCT36JAW.js.map → chunk-ESNFSSO4.js.map} +0 -0
  583. /package/dist/{chunk-XQ3HXAQH.js.map → chunk-ET2CNMLD.js.map} +0 -0
  584. /package/dist/{chunk-PU56CXZA.js.map → chunk-EZSCW4EM.js.map} +0 -0
  585. /package/dist/{chunk-HMZKGHMD.js.map → chunk-FESUGFIL.js.map} +0 -0
  586. /package/dist/{chunk-3A2NJP2U.js.map → chunk-FKKGCGYL.js.map} +0 -0
  587. /package/dist/{chunk-BWGCOLEL.js.map → chunk-FTTJRVB7.js.map} +0 -0
  588. /package/dist/{chunk-ODU2CNNX.js.map → chunk-FYWLSFFS.js.map} +0 -0
  589. /package/dist/{chunk-3PKAS6VL.js.map → chunk-GX6FTSYH.js.map} +0 -0
  590. /package/dist/{chunk-76DIF5KT.js.map → chunk-H7VDIF2V.js.map} +0 -0
  591. /package/dist/{chunk-F7XUD3PL.js.map → chunk-HJXA6ZM7.js.map} +0 -0
  592. /package/dist/{chunk-4QEYREAV.js.map → chunk-HNPE66LB.js.map} +0 -0
  593. /package/dist/{chunk-P36Z4JRA.js.map → chunk-I5VB44ZK.js.map} +0 -0
  594. /package/dist/{chunk-EUYWQ7TS.js.map → chunk-IEZ6CGTW.js.map} +0 -0
  595. /package/dist/{chunk-5DHKCO52.js.map → chunk-IVIAHQBR.js.map} +0 -0
  596. /package/dist/{chunk-TFR3HG4K.js.map → chunk-J3OND5QT.js.map} +0 -0
  597. /package/dist/{chunk-5ACCD4L7.js.map → chunk-JRRQ747T.js.map} +0 -0
  598. /package/dist/{chunk-V4IDF3EZ.js.map → chunk-JTWZKNUH.js.map} +0 -0
  599. /package/dist/{chunk-5RWZH6PH.js.map → chunk-L4X4PJYK.js.map} +0 -0
  600. /package/dist/{chunk-UTQUEHC7.js.map → chunk-LUDBXTBJ.js.map} +0 -0
  601. /package/dist/{chunk-LDKPDODJ.js.map → chunk-ME35HVDJ.js.map} +0 -0
  602. /package/dist/{chunk-DPCXDG7G.js.map → chunk-MJRGVXPQ.js.map} +0 -0
  603. /package/dist/{chunk-773TRRGT.js.map → chunk-MJUCDM3C.js.map} +0 -0
  604. /package/dist/{chunk-T6ILXUAH.js.map → chunk-MN5NOOI7.js.map} +0 -0
  605. /package/dist/{chunk-AHPIFKNG.js.map → chunk-N4F7ZSSG.js.map} +0 -0
  606. /package/dist/{chunk-JOZUBF4A.js.map → chunk-NACLNNFQ.js.map} +0 -0
  607. /package/dist/{chunk-LC2BDILZ.js.map → chunk-NBP4EX5N.js.map} +0 -0
  608. /package/dist/{chunk-ZVPVTPGI.js.map → chunk-NNZFPYYX.js.map} +0 -0
  609. /package/dist/{chunk-DA7ITC5Z.js.map → chunk-O57GM3FR.js.map} +0 -0
  610. /package/dist/{chunk-7VZFRUQU.js.map → chunk-O7ERGZDA.js.map} +0 -0
  611. /package/dist/{chunk-3SZD4CYO.js.map → chunk-OAJMQKQR.js.map} +0 -0
  612. /package/dist/{chunk-HSZMX3ZJ.js.map → chunk-ODW5GDFE.js.map} +0 -0
  613. /package/dist/{chunk-J2WC5LF4.js.map → chunk-QBC33MPY.js.map} +0 -0
  614. /package/dist/{chunk-T7XP6IZE.js.map → chunk-QCRJMU5V.js.map} +0 -0
  615. /package/dist/{chunk-OA2O2GJ4.js.map → chunk-RZ3IZIJG.js.map} +0 -0
  616. /package/dist/{chunk-UL4MKZHI.js.map → chunk-SN4JXNLL.js.map} +0 -0
  617. /package/dist/{chunk-CPA5NBHN.js.map → chunk-TNGH4ZYI.js.map} +0 -0
  618. /package/dist/{chunk-F3NVYTTA.js.map → chunk-TNXNECAN.js.map} +0 -0
  619. /package/dist/{chunk-BEC4YBNA.js.map → chunk-TVW4C7PV.js.map} +0 -0
  620. /package/dist/{chunk-UFKPQBXH.js.map → chunk-U62OK7BB.js.map} +0 -0
  621. /package/dist/{chunk-TUHBYJXL.js.map → chunk-VQ4AMTGZ.js.map} +0 -0
  622. /package/dist/{chunk-H2YSH3DG.js.map → chunk-WKAXBXVA.js.map} +0 -0
  623. /package/dist/{chunk-HRHO3ZNG.js.map → chunk-WKJFIMVN.js.map} +0 -0
  624. /package/dist/{chunk-SXIMQLGV.js.map → chunk-WVGXCBOC.js.map} +0 -0
  625. /package/dist/{chunk-CRML27CO.js.map → chunk-X5YYSAZX.js.map} +0 -0
  626. /package/dist/{chunk-FZEEWOI2.js.map → chunk-XJJYSX6F.js.map} +0 -0
  627. /package/dist/{chunk-UG6VXIOK.js.map → chunk-XSTNGNJP.js.map} +0 -0
  628. /package/dist/{chunk-YDPAE2RD.js.map → chunk-YFLLGRXO.js.map} +0 -0
  629. /package/dist/{chunk-LPNCR4QK.js.map → chunk-YXFCALVT.js.map} +0 -0
  630. /package/dist/{chunk-Q4WONDMJ.js.map → chunk-YYGZJPOK.js.map} +0 -0
  631. /package/dist/{chunk-GTO56JY5.js.map → chunk-ZJPM7GZ3.js.map} +0 -0
  632. /package/dist/{chunk-LOXHYCVS.js.map → chunk-ZW4VXELZ.js.map} +0 -0
  633. /package/dist/{contradiction-scan-AKUWPX5N.js.map → contradiction-scan-NOYMFG66.js.map} +0 -0
  634. /package/dist/{first-start-migration-4NETATFF.js.map → first-start-migration-KHIMCBIC.js.map} +0 -0
  635. /package/dist/{purge-GB7PZHT2.js.map → purge-OP6BEDFY.js.map} +0 -0
  636. /package/dist/{resolution-XWBPKYFB.js.map → resolution-4DLI3IOR.js.map} +0 -0
  637. /package/dist/{tier-stats-4B5IJ3NE.js.map → tier-stats-2TOW3QNL.js.map} +0 -0
@@ -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,6 @@
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";
@@ -0,0 +1,277 @@
1
+ import assert from "node:assert/strict";
2
+ import { mkdtempSync, rmSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import path from "node:path";
5
+ import test from "node:test";
6
+
7
+ import { activityDayWindow } from "../digest.js";
8
+ import { parseActivityConfig } from "../config.js";
9
+ import {
10
+ DEFAULT_TIMELINE_CATEGORIES,
11
+ TIMELINE_RESERVED_IDLE,
12
+ TIMELINE_RESERVED_PAUSE,
13
+ TIMELINE_RESERVED_UNKNOWN,
14
+ sortTimelineCategories,
15
+ validateTimelineCategories,
16
+ } from "./categories.js";
17
+ import { classifyTimelineObservation } from "./classify.js";
18
+ import { buildTimelineDay, serializeTimelineDay, TIMELINE_MERGE_GAP_MS } from "./build.js";
19
+ import { applyTimelineCorrections, TimelineCorrectionStore } from "./corrections.js";
20
+ import type { TimelineCategory, TimelineObservation } from "./types.js";
21
+
22
+ function obs(overrides: Partial<TimelineObservation> & { id: number; capturedAtUtc: string }): TimelineObservation {
23
+ return {
24
+ machine: "workstation-a",
25
+ app: "Code",
26
+ windowTitle: "main.ts — editor",
27
+ contentHash: `hash-${overrides.id}`,
28
+ ...overrides,
29
+ };
30
+ }
31
+
32
+ const BASE_INPUT = {
33
+ date: "2026-06-01",
34
+ timezone: "UTC",
35
+ observations: [
36
+ obs({ id: 1, capturedAtUtc: "2026-06-01T09:00:00.000Z" }),
37
+ obs({ id: 2, capturedAtUtc: "2026-06-01T09:01:00.000Z" }),
38
+ obs({ id: 3, capturedAtUtc: "2026-06-01T09:02:00.000Z" }),
39
+ obs({ id: 4, capturedAtUtc: "2026-06-01T09:40:00.000Z" }),
40
+ ],
41
+ };
42
+
43
+ test("synthetic observations replay into byte-stable cards regardless of input order", () => {
44
+ const first = buildTimelineDay(BASE_INPUT);
45
+ const second = buildTimelineDay({ ...BASE_INPUT, observations: [...BASE_INPUT.observations].reverse() });
46
+ assert.equal(serializeTimelineDay(second), serializeTimelineDay(first));
47
+ // "Restart" isolation: a completely fresh call over equal content matches.
48
+ const third = buildTimelineDay(JSON.parse(JSON.stringify(BASE_INPUT)));
49
+ assert.equal(serializeTimelineDay(third), serializeTimelineDay(first));
50
+ assert.ok(first.cards.every((card) => card.id.startsWith("tlc_")));
51
+ });
52
+
53
+ test("adjacent compatible observations merge; key changes and long gaps split cards", () => {
54
+ const day = buildTimelineDay(BASE_INPUT);
55
+ const activity = day.cards.filter((card) => card.kind === "activity");
56
+ assert.equal(activity.length, 2, "2-min gaps merge, a 38-min gap splits");
57
+ assert.deepEqual(activity[0].evidenceIds, [1, 2, 3]);
58
+ // Dwell caps at 15 min past the LAST observation: [09:00, 09:17), [09:40, 09:55).
59
+ assert.equal(activity[0].startUtc, "2026-06-01T09:00:00.000Z");
60
+ assert.equal(activity[0].endUtc, "2026-06-01T09:17:00.000Z");
61
+ assert.equal(activity[1].startUtc, "2026-06-01T09:40:00.000Z");
62
+ assert.equal(activity[1].endUtc, "2026-06-01T09:55:00.000Z");
63
+ // The >15-min remainder is a derived idle card with no evidence.
64
+ const idle = day.cards.filter((card) => card.kind === "idle");
65
+ assert.equal(idle.length, 1);
66
+ assert.equal(idle[0].categoryId, TIMELINE_RESERVED_IDLE);
67
+ assert.deepEqual(idle[0].evidenceIds, []);
68
+ assert.equal(idle[0].startUtc, "2026-06-01T09:17:00.000Z");
69
+ assert.equal(idle[0].endUtc, "2026-06-01T09:40:00.000Z");
70
+
71
+ // Same cadence but a different window title: two cards, contiguous, no idle.
72
+ const keyed = buildTimelineDay({
73
+ ...BASE_INPUT,
74
+ observations: [
75
+ obs({ id: 1, capturedAtUtc: "2026-06-01T09:00:00.000Z" }),
76
+ obs({ id: 2, capturedAtUtc: "2026-06-01T09:01:00.000Z", windowTitle: "other.ts — editor" }),
77
+ ],
78
+ });
79
+ const cards = keyed.cards.filter((card) => card.kind === "activity");
80
+ assert.equal(cards.length, 2);
81
+ assert.equal(cards[0].endUtc, cards[1].startUtc, "dwell stops at the next observation");
82
+ assert.equal(keyed.cards.filter((card) => card.kind === "idle").length, 0);
83
+ assert.equal(TIMELINE_MERGE_GAP_MS, 120_000, "merge gap contract");
84
+ });
85
+
86
+ test("card dwell is clipped at the local day end (midnight)", () => {
87
+ const day = buildTimelineDay({
88
+ date: "2026-06-01",
89
+ timezone: "UTC",
90
+ observations: [obs({ id: 7, capturedAtUtc: "2026-06-01T23:59:00.000Z" })],
91
+ });
92
+ const card = day.cards[0];
93
+ assert.equal(card.startUtc, "2026-06-01T23:59:00.000Z");
94
+ assert.equal(card.endUtc, "2026-06-02T00:00:00.000Z", "15-min dwell must not cross midnight");
95
+ assert.equal(card.dayKey, "2026-06-01");
96
+ });
97
+
98
+ test("DST transition days bucket observations through the shifted window", () => {
99
+ // America/New_York springs forward 2026-03-08: the local day is 23 hours.
100
+ const window = activityDayWindow("2026-03-08", "America/New_York");
101
+ assert.equal(Date.parse(window.endUtc) - Date.parse(window.startUtc), 23 * 3_600_000);
102
+ const day = buildTimelineDay({
103
+ date: "2026-03-08",
104
+ timezone: "America/New_York",
105
+ observations: [
106
+ obs({ id: 11, capturedAtUtc: "2026-03-08T06:30:00.000Z" }),
107
+ obs({ id: 12, capturedAtUtc: "2026-03-08T06:31:00.000Z" }),
108
+ ],
109
+ });
110
+ assert.equal(day.cards.length, 1);
111
+ assert.equal(day.cards[0].dayKey, "2026-03-08");
112
+ assert.equal(day.startUtc, window.startUtc);
113
+ // Fall-back day is 25 hours.
114
+ const fallWindow = activityDayWindow("2026-11-01", "America/New_York");
115
+ assert.equal(Date.parse(fallWindow.endUtc) - Date.parse(fallWindow.startUtc), 25 * 3_600_000);
116
+ });
117
+ test("user pause closes cards, is emitted as its own kind, and wins over idle", () => {
118
+ const day = buildTimelineDay({
119
+ ...BASE_INPUT,
120
+ observations: [
121
+ obs({ id: 1, capturedAtUtc: "2026-06-01T10:00:00.000Z" }),
122
+ obs({ id: 2, capturedAtUtc: "2026-06-01T10:01:30.000Z" }),
123
+ obs({ id: 3, capturedAtUtc: "2026-06-01T11:00:00.000Z" }),
124
+ ],
125
+ pauses: [{ startUtc: "2026-06-01T10:30:00.000Z", endUtc: "2026-06-01T11:00:00.000Z", reason: "lunch" }],
126
+ });
127
+ const pause = day.cards.filter((card) => card.kind === "pause");
128
+ assert.equal(pause.length, 1);
129
+ assert.equal(pause[0].categoryId, TIMELINE_RESERVED_PAUSE);
130
+ assert.deepEqual(pause[0].evidenceIds, []);
131
+ assert.ok(pause[0].summary.includes("lunch"));
132
+ const before = day.cards.find((card) => card.kind === "activity" && card.evidenceIds.includes(1));
133
+ assert.equal(before?.endUtc, "2026-06-01T10:16:30.000Z", "dwell (15m from last obs) ends before the pause");
134
+ // Dwell stops short of the pause, so the 13.5-min remainder is one idle
135
+ // card; the pause wins over idle covering the same minutes.
136
+ const idle = day.cards.filter((card) => card.kind === "idle");
137
+ assert.equal(idle.length, 1);
138
+ assert.equal(idle[0].startUtc, "2026-06-01T10:16:30.000Z");
139
+ assert.equal(idle[0].endUtc, "2026-06-01T10:30:00.000Z");
140
+ // No idle overlaps the pause interval itself.
141
+ assert.ok(idle.every((card) => card.endUtc <= pause[0].startUtc || card.startUtc >= pause[0].endUtc));
142
+ // Overlapping pauses union into one interval.
143
+ const unioned = buildTimelineDay({
144
+ date: "2026-06-01",
145
+ timezone: "UTC",
146
+ pauses: [
147
+ { startUtc: "2026-06-01T10:00:00.000Z", endUtc: "2026-06-01T10:30:00.000Z" },
148
+ { startUtc: "2026-06-01T10:20:00.000Z", endUtc: "2026-06-01T11:00:00.000Z" },
149
+ ],
150
+ observations: [],
151
+ });
152
+ assert.equal(unioned.cards.length, 1);
153
+ assert.equal(unioned.cards[0].endUtc, "2026-06-01T11:00:00.000Z");
154
+ // A pause between two compatible observations still closes the card.
155
+ const split = buildTimelineDay({
156
+ date: "2026-06-01",
157
+ timezone: "UTC",
158
+ observations: [
159
+ obs({ id: 1, capturedAtUtc: "2026-06-01T09:00:00.000Z" }),
160
+ obs({ id: 2, capturedAtUtc: "2026-06-01T09:00:30.000Z" }),
161
+ ],
162
+ pauses: [{ startUtc: "2026-06-01T09:00:10.000Z", endUtc: "2026-06-01T09:00:20.000Z" }],
163
+ });
164
+ assert.equal(split.cards.filter((card) => card.kind === "activity").length, 2);
165
+ });
166
+
167
+ test("overlapping multi-machine tracks never merge across machines", () => {
168
+ const day = buildTimelineDay({
169
+ ...BASE_INPUT,
170
+ observations: [
171
+ obs({ id: 1, machine: "ws-a", capturedAtUtc: "2026-06-01T09:00:00.000Z", app: "Chrome", windowTitle: "Docs" }),
172
+ obs({ id: 2, machine: "ws-b", capturedAtUtc: "2026-06-01T09:00:30.000Z", app: "Chrome", windowTitle: "Docs" }),
173
+ obs({ id: 3, machine: "ws-a", capturedAtUtc: "2026-06-01T09:01:00.000Z", app: "Chrome", windowTitle: "Docs" }),
174
+ ],
175
+ });
176
+ const activity = day.cards.filter((card) => card.kind === "activity");
177
+ assert.equal(activity.length, 2);
178
+ assert.deepEqual(new Set(activity.map((card) => card.machine)), new Set(["ws-a", "ws-b"]));
179
+ // Global order is start-time first with a stable machine tie-break.
180
+ assert.ok(activity[0].startUtc <= activity[1].startUtc);
181
+ assert.equal(activity.find((card) => card.machine === "ws-a")?.evidenceIds.length, 2);
182
+ });
183
+
184
+ test("unclassified activity stays visible in system.unknown; domains outrank app names", () => {
185
+ const unknown = classifyTimelineObservation({ app: "MysteryTool", windowTitle: "untitled" }, DEFAULT_TIMELINE_CATEGORIES);
186
+ assert.deepEqual(unknown, { categoryId: TIMELINE_RESERVED_UNKNOWN, confidence: 0 });
187
+ const day = buildTimelineDay({
188
+ date: "2026-06-01",
189
+ timezone: "UTC",
190
+ observations: [obs({ id: 1, capturedAtUtc: "2026-06-01T09:00:00.000Z", app: "MysteryTool", windowTitle: "untitled" })],
191
+ });
192
+ assert.equal(day.cards[0].categoryId, TIMELINE_RESERVED_UNKNOWN);
193
+ assert.equal(day.cards[0].confidence, 0);
194
+ // A browser on github.com is development (domain signal) even though the
195
+ // app rule alone would say browsing.
196
+ const classified = classifyTimelineObservation(
197
+ { app: "Chrome", windowTitle: "feat: timeline", browserUrl: "https://github.com/org/repo" },
198
+ DEFAULT_TIMELINE_CATEGORIES,
199
+ );
200
+ assert.equal(classified.categoryId, "development");
201
+ assert.equal(classified.confidence, 0.85);
202
+ });
203
+
204
+ test("categories validate reserved/system rules and sort with equal-order tie-breaks", () => {
205
+ assert.throws(
206
+ () => validateTimelineCategories([{ id: "development", name: "x", color: "#3b82f6", description: "d", order: 1 }]),
207
+ /system\.unknown/,
208
+ );
209
+ assert.throws(
210
+ () =>
211
+ validateTimelineCategories([
212
+ ...DEFAULT_TIMELINE_CATEGORIES,
213
+ { id: "development", name: "dup", color: "#000000", description: "d", order: 5 },
214
+ ]),
215
+ /unique/,
216
+ );
217
+ assert.throws(
218
+ () => validateTimelineCategories(DEFAULT_TIMELINE_CATEGORIES.map((c) => (c.id === "development" ? { ...c, color: "blue" } : c))),
219
+ /#RRGGBB/,
220
+ );
221
+ assert.throws(
222
+ () => validateTimelineCategories(DEFAULT_TIMELINE_CATEGORIES.map((c) => (c.id === "development" ? { ...c, system: true } : c))),
223
+ /only reserved categories/,
224
+ );
225
+ const equalOrder: TimelineCategory[] = [
226
+ { id: "beta", name: "B", color: "#000001", description: "d", order: 50 },
227
+ { id: "alpha", name: "A", color: "#000002", description: "d", order: 50 },
228
+ ...DEFAULT_TIMELINE_CATEGORIES,
229
+ ];
230
+ validateTimelineCategories(equalOrder);
231
+ const sorted = sortTimelineCategories(equalOrder);
232
+ assert.ok(sorted.findIndex((c) => c.id === "alpha") < sorted.findIndex((c) => c.id === "beta"), "equal order tie-breaks by id");
233
+ });
234
+
235
+ test("manual corrections survive a rebuild and reset reverts the card", () => {
236
+ const memoryDir = mkdtempSync(path.join(tmpdir(), "remnic-timeline-test-"));
237
+ try {
238
+ const store = TimelineCorrectionStore.open(memoryDir);
239
+ const day = buildTimelineDay(BASE_INPUT);
240
+ const target = day.cards[0];
241
+ store.upsert({ cardId: target.id, categoryId: "communication", title: "Morning standup", editedAtUtc: "2026-06-01T12:00:00.000Z" });
242
+ assert.throws(() => store.upsert({ cardId: target.id, categoryId: "nope", editedAtUtc: "2026-06-01T12:00:00.000Z" }), /unknown category/);
243
+
244
+ // "Rebuild" — same evidence, fresh build call, corrections reapplied.
245
+ const rebuiltDay = buildTimelineDay(BASE_INPUT);
246
+ const rebuilt = applyTimelineCorrections(rebuiltDay.cards, store.list());
247
+ const corrected = rebuilt.find((card) => card.id === target.id);
248
+ assert.equal(corrected?.title, "Morning standup");
249
+ assert.equal(corrected?.categoryId, "communication");
250
+ assert.equal(corrected?.confidence, 1);
251
+ assert.equal(corrected?.manualEdit?.editedAtUtc, "2026-06-01T12:00:00.000Z");
252
+ const untouched = rebuilt.find((card) => card.id !== target.id);
253
+ assert.deepEqual(untouched, rebuiltDay.cards.find((card) => card.id === untouched?.id));
254
+
255
+ // Explicit reset restores the derived card byte-for-byte.
256
+ assert.equal(store.reset(target.id), true);
257
+ assert.equal(store.reset(target.id), false);
258
+ const afterReset = applyTimelineCorrections(buildTimelineDay(BASE_INPUT).cards, store.list());
259
+ assert.deepEqual(afterReset.find((card) => card.id === target.id), target);
260
+
261
+ // Corrections persist across close/reopen (process restart).
262
+ store.close();
263
+ const reopened = TimelineCorrectionStore.open(memoryDir);
264
+ assert.equal(reopened.list().length, 0);
265
+ reopened.close();
266
+ } finally {
267
+ rmSync(memoryDir, { recursive: true, force: true });
268
+ }
269
+ });
270
+
271
+ test("activity.timeline config gate defaults off and parses explicitly", () => {
272
+ assert.equal(parseActivityConfig(undefined).timeline.enabled, false);
273
+ assert.equal(parseActivityConfig({ timeline: { enabled: true } }).timeline.enabled, true);
274
+ assert.equal(parseActivityConfig({ timeline: { enabled: "false" } }).timeline.enabled, false);
275
+ assert.throws(() => parseActivityConfig({ timeline: "on" }), /activity\.timeline must be an object/);
276
+ assert.throws(() => parseActivityConfig({ timeline: { enabled: "maybe" } }), /activity\.timeline\.enabled must be a boolean/);
277
+ });
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Timeline-card layer over the #1899 activity store (issue #2049).
3
+ *
4
+ * A card is a deterministic, replayable *derived view*: it references snapshot
5
+ * evidence by store row id and content identity, never copying or re-storing
6
+ * it. All intervals are half-open [start, end) UTC; day bucketing reuses the
7
+ * DST-aware `activityDayWindow` from the digest layer, so timeline days and
8
+ * digests always agree on day bounds.
9
+ */
10
+
11
+ /** Reference to one stored observation (subset of ActivitySnapshot; no text). */
12
+ export interface TimelineObservation {
13
+ /** Store row id of the referenced snapshot. */
14
+ id: number;
15
+ machine: string;
16
+ /** UTC ISO-8601 capture instant. */
17
+ capturedAtUtc: string;
18
+ app: string;
19
+ windowTitle: string;
20
+ /** Browser tab URL, when the frontmost window is a known browser. */
21
+ browserUrl?: string;
22
+ /** Content hash of the referenced snapshot (identity, not re-stored text). */
23
+ contentHash: string;
24
+ }
25
+
26
+ /** User-declared pause, half-open [startUtc, endUtc) in UTC. Not idle. */
27
+ export interface TimelinePause {
28
+ startUtc: string;
29
+ endUtc: string;
30
+ /** Free-form reason, kept verbatim on the derived pause card. */
31
+ reason?: string;
32
+ }
33
+
34
+ /** One category definition in the registry. */
35
+ export interface TimelineCategory {
36
+ /** Stable ID (`system.*` is the reserved namespace). */
37
+ id: string;
38
+ name: string;
39
+ /** Hex color, `#RRGGBB`. */
40
+ color: string;
41
+ description: string;
42
+ /** Presentation order; equal orders tie-break by id. */
43
+ order: number;
44
+ /** Reserved system category (idle / pause / unknown). */
45
+ system?: boolean;
46
+ /** Marks the reserved idle category. */
47
+ idle?: boolean;
48
+ }
49
+
50
+ export type TimelineCardKind = "activity" | "idle" | "pause";
51
+
52
+ /** Provenance stamped on a card when a manual correction was applied. */
53
+ export interface TimelineManualEdit {
54
+ categoryId?: string;
55
+ title?: string;
56
+ editedAtUtc: string;
57
+ }
58
+
59
+ /** A persisted manual correction; keyed by stable card id, survives rebuilds. */
60
+ export interface TimelineCorrection {
61
+ cardId: string;
62
+ categoryId?: string;
63
+ title?: string;
64
+ editedAtUtc: string;
65
+ }
66
+
67
+ /** Stable first/last evidence identity keys bracketing a card's sources. */
68
+ export interface TimelineEvidenceRange {
69
+ firstKey: string;
70
+ lastKey: string;
71
+ }
72
+
73
+ export interface TimelineCard {
74
+ /** Stable content-derived id (never array position or wall-clock). */
75
+ id: string;
76
+ kind: TimelineCardKind;
77
+ title: string;
78
+ summary: string;
79
+ categoryId: string;
80
+ /** Classification confidence; manual corrections set it to 1. */
81
+ confidence: number;
82
+ /** Half-open [startUtc, endUtc) UTC bounds. */
83
+ startUtc: string;
84
+ endUtc: string;
85
+ /** Local day key (YYYY-MM-DD) this card belongs to. */
86
+ dayKey: string;
87
+ timezone: string;
88
+ /** Track the card was built on; null for machine-less pause cards. */
89
+ machine: string | null;
90
+ /** Store row ids of the source snapshots (empty for idle/pause). */
91
+ evidenceIds: number[];
92
+ /** First/last evidence identity keys (null for idle/pause). */
93
+ evidenceRange: TimelineEvidenceRange | null;
94
+ /** Present only when a manual correction was applied. */
95
+ manualEdit?: TimelineManualEdit;
96
+ }
97
+
98
+ /** One replayable local day of cards. */
99
+ export interface TimelineDay {
100
+ formatVersion: number;
101
+ date: string;
102
+ timezone: string;
103
+ startUtc: string;
104
+ endUtc: string;
105
+ cards: TimelineCard[];
106
+ }
@@ -96,6 +96,11 @@ export interface ActivitySourceConfig {
96
96
  token?: string;
97
97
  }
98
98
 
99
+ /** Opt-in timeline-card derivation settings (issue #2049). Default off. */
100
+ export interface ActivityTimelineConfig {
101
+ enabled: boolean;
102
+ }
103
+
99
104
  /** Opt-in activity synchronization + trust-gated extraction settings. */
100
105
  export interface ActivityConfig {
101
106
  enabled: boolean;
@@ -114,4 +119,5 @@ export interface ActivityConfig {
114
119
  minImportance: ImportanceLevel;
115
120
  /** `0` means no count cap. */
116
121
  maxMemoriesPerDay: number;
122
+ timeline: ActivityTimelineConfig;
117
123
  }