@remnic/core 9.63.3 → 9.63.5

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 (437) hide show
  1. package/dist/access-admin-ops-surface.d.ts +11 -11
  2. package/dist/access-admin-ops-surface.js +23 -23
  3. package/dist/access-authorization-probe.d.ts +11 -11
  4. package/dist/access-authorization-probe.js +24 -24
  5. package/dist/access-boundary.d.ts +11 -11
  6. package/dist/access-boundary.js +23 -23
  7. package/dist/access-cli.js +55 -54
  8. package/dist/access-cli.js.map +1 -1
  9. package/dist/access-coding-context-resolution.d.ts +1 -1
  10. package/dist/access-extraction-force-flush.d.ts +11 -11
  11. package/dist/access-extraction-force-flush.js +23 -23
  12. package/dist/access-health-types.d.ts +1 -1
  13. package/dist/access-http-lcm-compaction.d.ts +11 -11
  14. package/dist/access-http-lifecycle-flush.d.ts +11 -11
  15. package/dist/access-http-offline-stream.d.ts +11 -11
  16. package/dist/access-http-query.d.ts +13 -1
  17. package/dist/access-http-query.js +27 -24
  18. package/dist/access-http.d.ts +12 -12
  19. package/dist/access-http.js +34 -33
  20. package/dist/access-identity-continuity-surface.d.ts +9 -9
  21. package/dist/access-identity-continuity-surface.js +23 -23
  22. package/dist/access-lcm-surface.d.ts +11 -11
  23. package/dist/access-lcm-surface.js +23 -23
  24. package/dist/access-mcp.d.ts +11 -11
  25. package/dist/access-mcp.js +28 -28
  26. package/dist/access-memory-search-fanout.d.ts +2 -2
  27. package/dist/{access-namespace-preflight-yO4LMGFH.d.ts → access-namespace-preflight-DB0zXFek.d.ts} +1 -1
  28. package/dist/access-namespace-preflight.d.ts +3 -3
  29. package/dist/access-namespace-preflight.js +23 -23
  30. package/dist/access-observe-write-surface.d.ts +11 -11
  31. package/dist/access-observe-write-surface.js +23 -23
  32. package/dist/access-offline-manifest.d.ts +9 -9
  33. package/dist/access-offline-manifest.js +3 -3
  34. package/dist/access-operations-batch.js +24 -24
  35. package/dist/access-operations.d.ts +14 -14
  36. package/dist/access-operations.js +27 -27
  37. package/dist/access-recall-concurrency.d.ts +11 -11
  38. package/dist/access-recall-concurrency.js +23 -23
  39. package/dist/access-recall-response.d.ts +11 -11
  40. package/dist/access-recall-response.js +23 -23
  41. package/dist/access-recall-surface.d.ts +11 -11
  42. package/dist/access-recall-surface.js +23 -23
  43. package/dist/access-schema.d.ts +88 -88
  44. package/dist/{access-service-M4LgO141.d.ts → access-service-cKQrte9Z.d.ts} +71 -77
  45. package/dist/access-service-helpers.d.ts +11 -11
  46. package/dist/access-service.d.ts +11 -11
  47. package/dist/access-service.js +23 -23
  48. package/dist/access-surface-catalog.d.ts +11 -11
  49. package/dist/access-surface-catalog.js +25 -25
  50. package/dist/access-wearables-meetings-surface.d.ts +3 -3
  51. package/dist/action-confidence.d.ts +1 -1
  52. package/dist/active-memory-bridge.d.ts +1 -1
  53. package/dist/active-recall.d.ts +1 -1
  54. package/dist/ambient-provenance.d.ts +1 -1
  55. package/dist/artifact-search.d.ts +1 -1
  56. package/dist/behavior-learner.d.ts +1 -1
  57. package/dist/behavior-signals.d.ts +1 -1
  58. package/dist/bootstrap.d.ts +9 -9
  59. package/dist/briefing-window.d.ts +2 -2
  60. package/dist/briefing.d.ts +2 -2
  61. package/dist/briefing.js +11 -11
  62. package/dist/buffer-surprise-report.d.ts +1 -1
  63. package/dist/buffer-turn-helpers.d.ts +1 -1
  64. package/dist/buffer.d.ts +2 -2
  65. package/dist/buffer.js +4 -4
  66. package/dist/bulk-import/index.d.ts +3 -3
  67. package/dist/calibration.d.ts +1 -1
  68. package/dist/capabilities.d.ts +1 -1
  69. package/dist/{capsule-merge-HCJJMLPS.js → capsule-merge-SGIVB3WA.js} +5 -5
  70. package/dist/{catalog-CyYTf_ok.d.ts → catalog-CCzmf8IH.d.ts} +3 -11
  71. package/dist/causal-behavior.d.ts +1 -1
  72. package/dist/causal-consolidation.d.ts +1 -1
  73. package/dist/causal-consolidation.js +12 -12
  74. package/dist/causal-trajectory-graph.d.ts +1 -1
  75. package/dist/{chunk-XFCQIQQU.js → chunk-2UM6WHME.js} +3 -3
  76. package/dist/{chunk-6F2UMP4H.js → chunk-3Z5TGRFA.js} +8 -8
  77. package/dist/{chunk-JJX5XEIG.js → chunk-77QZW2D6.js} +4 -4
  78. package/dist/{chunk-X4MGNVOO.js → chunk-7AF243WZ.js} +1 -1
  79. package/dist/{chunk-2ASAS3CQ.js → chunk-7KQB4EBS.js} +2 -2
  80. package/dist/{chunk-3LJ2L3T3.js → chunk-7LF2OHIJ.js} +2 -2
  81. package/dist/{chunk-VAMQU4W7.js → chunk-AYVCKGA6.js} +2 -2
  82. package/dist/{chunk-GTRGH4ZT.js → chunk-BB2LH5JM.js} +2 -2
  83. package/dist/{chunk-XMMESCPD.js → chunk-C64XATK7.js} +17 -27
  84. package/dist/chunk-C64XATK7.js.map +1 -0
  85. package/dist/{chunk-6UZR7KEK.js → chunk-CUDSA46O.js} +8 -2
  86. package/dist/chunk-CUDSA46O.js.map +1 -0
  87. package/dist/{chunk-PADG72LJ.js → chunk-DXDAQZ2K.js} +2 -2
  88. package/dist/{chunk-EJQXDKYK.js → chunk-DYZR3Z6D.js} +3 -3
  89. package/dist/{chunk-VN7IIQGS.js → chunk-E4KMY4KR.js} +2 -2
  90. package/dist/{chunk-ZQKXRKMR.js → chunk-EFKZT6AY.js} +2 -2
  91. package/dist/{chunk-DNRTKO2U.js → chunk-EJY3HJMT.js} +2 -2
  92. package/dist/{chunk-RYGJGXL6.js → chunk-ERPBRXVZ.js} +2 -2
  93. package/dist/{chunk-5UFQCU6M.js → chunk-F6JYBVL6.js} +27 -57
  94. package/dist/{chunk-5UFQCU6M.js.map → chunk-F6JYBVL6.js.map} +1 -1
  95. package/dist/{chunk-JWPG65LH.js → chunk-FHKXVTM5.js} +38 -39
  96. package/dist/chunk-FHKXVTM5.js.map +1 -0
  97. package/dist/{chunk-RPKJHYVE.js → chunk-FPEZ74F7.js} +2 -2
  98. package/dist/{chunk-Z334TJRB.js → chunk-GF7RQWXC.js} +2 -2
  99. package/dist/{chunk-6D7PZKCJ.js → chunk-GG4DN63W.js} +2 -2
  100. package/dist/{chunk-IM56VPKO.js → chunk-GTD4Q62X.js} +2 -6
  101. package/dist/{chunk-A73QHOZP.js → chunk-I5FLIB2J.js} +2 -2
  102. package/dist/{chunk-JJ7JW62R.js → chunk-IVXVLDNT.js} +12 -22
  103. package/dist/chunk-IVXVLDNT.js.map +1 -0
  104. package/dist/{chunk-NRFU5MVH.js → chunk-JOEJG4SD.js} +47 -1
  105. package/dist/chunk-JOEJG4SD.js.map +1 -0
  106. package/dist/{chunk-EJLTNPRY.js → chunk-KHCUVYCY.js} +3 -3
  107. package/dist/{chunk-QSIQVC32.js → chunk-KYTRF64R.js} +2 -2
  108. package/dist/{chunk-R74NCKEY.js → chunk-LX4TNSAE.js} +4 -4
  109. package/dist/{chunk-H6ZXNH5I.js → chunk-MUJ4QFUQ.js} +3 -3
  110. package/dist/{chunk-4NMVX5U7.js → chunk-NA56NSKL.js} +2 -2
  111. package/dist/{chunk-MR5HWQHS.js → chunk-NKB43PGI.js} +2 -2
  112. package/dist/{chunk-DLQQU4EG.js → chunk-NS5ETDYD.js} +2 -2
  113. package/dist/{chunk-44KHFMCM.js → chunk-OETHJBAL.js} +76 -53
  114. package/dist/{chunk-44KHFMCM.js.map → chunk-OETHJBAL.js.map} +1 -1
  115. package/dist/{chunk-KWN6NOHQ.js → chunk-PB4WVYGC.js} +2 -2
  116. package/dist/{chunk-Q35XGIEM.js → chunk-PBRCYYO7.js} +2 -2
  117. package/dist/{chunk-QYN5PXDZ.js → chunk-PMVPCZJZ.js} +4 -4
  118. package/dist/{chunk-AJSZ2EK6.js → chunk-QI5RDDEL.js} +3 -3
  119. package/dist/{chunk-I6OQCT3Y.js → chunk-QRWMS6SI.js} +2 -2
  120. package/dist/{chunk-ITYAXU4S.js → chunk-R6UMNP5C.js} +3 -3
  121. package/dist/{chunk-5W62VEFH.js → chunk-RWMSMTQP.js} +2 -2
  122. package/dist/{chunk-FKJVEW6O.js → chunk-SYVGVK4S.js} +2 -2
  123. package/dist/{chunk-TRPX6F2G.js → chunk-TSTI6A3A.js} +10 -13
  124. package/dist/chunk-TSTI6A3A.js.map +1 -0
  125. package/dist/{chunk-XZPSBGHA.js → chunk-UCLMKNHA.js} +2 -2
  126. package/dist/{chunk-ZMSZVISA.js → chunk-UFKPQBXH.js} +3 -3
  127. package/dist/{chunk-B2OOJCUX.js → chunk-UGHCZS6K.js} +2 -2
  128. package/dist/chunk-V3KIRICY.js +727 -0
  129. package/dist/chunk-V3KIRICY.js.map +1 -0
  130. package/dist/{chunk-6ZYQ36IB.js → chunk-VPHSMJ2E.js} +15 -2
  131. package/dist/chunk-VPHSMJ2E.js.map +1 -0
  132. package/dist/{chunk-E2GYBTSP.js → chunk-VYEPACWY.js} +2 -2
  133. package/dist/{chunk-5W5N7XJZ.js → chunk-X7LEDA74.js} +20 -753
  134. package/dist/chunk-X7LEDA74.js.map +1 -0
  135. package/dist/{chunk-KMAP7SNQ.js → chunk-XCB6QDL6.js} +2 -2
  136. package/dist/{chunk-WDUG2CH3.js → chunk-YEQCMA5L.js} +2 -2
  137. package/dist/{chunk-LZCSOUJ7.js → chunk-YFCEBB5P.js} +2 -2
  138. package/dist/{chunk-IKXUG6KC.js → chunk-YXMHUBN2.js} +2 -2
  139. package/dist/{chunk-GFNS3BHV.js → chunk-ZUPKNWRZ.js} +3 -3
  140. package/dist/{chunk-GSTIBXBW.js → chunk-ZVPVTPGI.js} +2 -2
  141. package/dist/{cli-Bw9z-KqX.d.ts → cli-BFBDYV0D.d.ts} +5 -5
  142. package/dist/cli.d.ts +13 -13
  143. package/dist/cli.js +45 -44
  144. package/dist/coding/pre-action-gate.d.ts +1 -1
  145. package/dist/compounding/engine.d.ts +2 -2
  146. package/dist/compounding/engine.js +11 -11
  147. package/dist/compounding/preference-consolidator.d.ts +1 -1
  148. package/dist/compression-optimizer.d.ts +1 -1
  149. package/dist/config.d.ts +1 -1
  150. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  151. package/dist/connectors/codex-materialize-runner.js +11 -11
  152. package/dist/connectors/codex-materialize.d.ts +1 -1
  153. package/dist/connectors/index.d.ts +1 -1
  154. package/dist/connectors/index.js +11 -11
  155. package/dist/consolidation-provenance-check.d.ts +2 -2
  156. package/dist/consolidation-provenance-check.js +5 -5
  157. package/dist/consolidation-undo.d.ts +2 -2
  158. package/dist/consolidation-undo.js +4 -4
  159. package/dist/contradiction/index.d.ts +2 -2
  160. package/dist/converge-config.d.ts +1 -1
  161. package/dist/convergence-refresh.d.ts +2 -2
  162. package/dist/convergence-refresh.js +13 -13
  163. package/dist/conversation-index/backend.d.ts +1 -1
  164. package/dist/conversation-index/chunker.d.ts +1 -1
  165. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  166. package/dist/conversation-index/indexer.d.ts +1 -1
  167. package/dist/conversation-index/search.d.ts +1 -1
  168. package/dist/corpus-watermark.d.ts +1 -1
  169. package/dist/corpus-watermark.js +13 -13
  170. package/dist/day-summary.d.ts +1 -1
  171. package/dist/delinearize.d.ts +1 -1
  172. package/dist/dependency-propagation-config.d.ts +1 -1
  173. package/dist/{dependency-propagation-delivery-BxhvAppj.d.ts → dependency-propagation-delivery-DiY5T63p.d.ts} +1 -1
  174. package/dist/direct-answer-wiring.d.ts +1 -1
  175. package/dist/direct-answer.d.ts +1 -1
  176. package/dist/embedding-fallback.d.ts +1 -1
  177. package/dist/enrichment/index.d.ts +1 -1
  178. package/dist/entity-origin-fields.d.ts +1 -1
  179. package/dist/entity-retrieval.d.ts +2 -2
  180. package/dist/entity-retrieval.js +11 -11
  181. package/dist/entity-schema.d.ts +1 -1
  182. package/dist/episodic-context.d.ts +1 -1
  183. package/dist/explicit-capture.d.ts +9 -9
  184. package/dist/explicit-capture.js +5 -5
  185. package/dist/external-wiki-access.d.ts +11 -11
  186. package/dist/external-wiki-access.js +24 -24
  187. package/dist/external-wiki-collection-registration.d.ts +1 -1
  188. package/dist/external-wiki-collection.d.ts +1 -1
  189. package/dist/external-wiki-mcp-tools.d.ts +11 -11
  190. package/dist/extraction-error-classification.d.ts +1 -1
  191. package/dist/extraction-faithfulness.d.ts +1 -1
  192. package/dist/extraction-judge-telemetry.d.ts +1 -1
  193. package/dist/extraction-judge-training.d.ts +1 -1
  194. package/dist/extraction-judge.d.ts +1 -1
  195. package/dist/extraction-liveness.d.ts +1 -1
  196. package/dist/extraction-normalization.d.ts +1 -1
  197. package/dist/extraction-prompt.d.ts +1 -1
  198. package/dist/extraction-source-grounding-rules.d.ts +1 -1
  199. package/dist/extraction-source-grounding.d.ts +1 -1
  200. package/dist/extraction.d.ts +1 -1
  201. package/dist/extraction.js +14 -14
  202. package/dist/fallback-llm.d.ts +1 -1
  203. package/dist/graph-dashboard-diff.d.ts +1 -1
  204. package/dist/graph-dashboard-key.d.ts +1 -1
  205. package/dist/graph-dashboard-parser.d.ts +1 -1
  206. package/dist/graph-edge-reinforcement.d.ts +1 -1
  207. package/dist/graph-path-reconstruction.d.ts +1 -1
  208. package/dist/graph-path-scoring.d.ts +1 -1
  209. package/dist/graph-snapshot.d.ts +1 -1
  210. package/dist/graph.d.ts +1 -1
  211. package/dist/harmonic-retrieval.js +1 -1
  212. package/dist/importance.d.ts +1 -1
  213. package/dist/importers/index.d.ts +1 -1
  214. package/dist/in-flight-reads.d.ts +1 -1
  215. package/dist/index.d.ts +697 -697
  216. package/dist/index.js +57 -56
  217. package/dist/intent.d.ts +1 -1
  218. package/dist/lcm/engine.d.ts +1 -1
  219. package/dist/lcm/index.d.ts +1 -1
  220. package/dist/lcm/tools.d.ts +1 -1
  221. package/dist/lifecycle.d.ts +1 -1
  222. package/dist/live-connectors-runner.d.ts +1 -1
  223. package/dist/local-llm.d.ts +1 -1
  224. package/dist/local-model-endpoint.d.ts +1 -1
  225. package/dist/maintenance/memory-governance.d.ts +1 -1
  226. package/dist/maintenance/memory-governance.js +11 -11
  227. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
  228. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +11 -11
  229. package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
  230. package/dist/maintenance/rebuild-memory-projection.js +12 -12
  231. package/dist/{maintenance-uJb74j64.d.ts → maintenance-CaqA4z7V.d.ts} +3 -3
  232. package/dist/mcp-memory-inspector-app.d.ts +11 -11
  233. package/dist/memory-action-policy.d.ts +1 -1
  234. package/dist/memory-cache.d.ts +1 -1
  235. package/dist/memory-cache.js +1 -1
  236. package/dist/memory-corpus-version.js +2 -2
  237. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  238. package/dist/memory-projection-store.d.ts +1 -1
  239. package/dist/memory-provenance.d.ts +1 -1
  240. package/dist/memory-snapshot.d.ts +1 -1
  241. package/dist/memory-worth-outcomes.d.ts +2 -2
  242. package/dist/models-json.d.ts +1 -1
  243. package/dist/namespaces/migrate.d.ts +3 -3
  244. package/dist/namespaces/migrate.js +12 -12
  245. package/dist/namespaces/principal.d.ts +1 -1
  246. package/dist/namespaces/search.d.ts +1 -1
  247. package/dist/namespaces/search.js +4 -4
  248. package/dist/namespaces/storage.d.ts +3 -3
  249. package/dist/namespaces/storage.js +11 -11
  250. package/dist/native-knowledge.d.ts +1 -1
  251. package/dist/offline-sync-impression-drain.d.ts +1 -1
  252. package/dist/operator-doctor-corpus.d.ts +1 -1
  253. package/dist/operator-doctor-corpus.js +14 -14
  254. package/dist/operator-doctor-replica.d.ts +1 -1
  255. package/dist/operator-toolkit.d.ts +3 -3
  256. package/dist/operator-toolkit.js +20 -19
  257. package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
  258. package/dist/orchestration/maintenance.d.ts +4 -4
  259. package/dist/orchestration/maintenance.js +17 -16
  260. package/dist/{orchestrator-CFi-5JSR.d.ts → orchestrator-CSc9GfQv.d.ts} +8 -8
  261. package/dist/orchestrator.d.ts +9 -9
  262. package/dist/orchestrator.js +55 -54
  263. package/dist/page-versioning.js +4 -4
  264. package/dist/patterns-cli.d.ts +1 -1
  265. package/dist/{pipeline-BdF3ferY.d.ts → pipeline-X606GdRJ.d.ts} +1 -1
  266. package/dist/policy-runtime.d.ts +1 -1
  267. package/dist/proactive-contention.d.ts +1 -1
  268. package/dist/provenance.d.ts +1 -1
  269. package/dist/{public-http-DK-QwaBu.d.ts → public-http-8PcrDIYi.d.ts} +1 -1
  270. package/dist/{qmd-CBSxevyb.d.ts → qmd-DCKeR-GX.d.ts} +1 -1
  271. package/dist/qmd-preflight.d.ts +2 -2
  272. package/dist/qmd-recall-cache.d.ts +1 -1
  273. package/dist/qmd.d.ts +2 -2
  274. package/dist/qmd.js +2 -2
  275. package/dist/recall-concurrency-config.d.ts +1 -1
  276. package/dist/recall-disclosure-escalation.d.ts +1 -1
  277. package/dist/recall-explain-renderer.d.ts +1 -1
  278. package/dist/recall-memory-map.d.ts +1 -1
  279. package/dist/recall-planner-llm.d.ts +1 -1
  280. package/dist/recall-state.d.ts +1 -1
  281. package/dist/recall-tag-filter.d.ts +1 -1
  282. package/dist/recall-timings.d.ts +1 -1
  283. package/dist/recall-xray-cli.d.ts +1 -1
  284. package/dist/recall-xray-renderer.d.ts +1 -1
  285. package/dist/recall-xray.d.ts +1 -1
  286. package/dist/reconcile/cursor.d.ts +1 -1
  287. package/dist/reconcile/manifest.d.ts +1 -1
  288. package/dist/reconcile/manifest.js +2 -2
  289. package/dist/reconcile/plan.d.ts +1 -1
  290. package/dist/replay/normalizers/chatgpt.d.ts +1 -1
  291. package/dist/replay/normalizers/claude.d.ts +1 -1
  292. package/dist/replay/normalizers/openclaw.d.ts +1 -1
  293. package/dist/replay/normalizers/shared.d.ts +1 -1
  294. package/dist/replay/runner.d.ts +1 -1
  295. package/dist/replay/types.d.ts +1 -1
  296. package/dist/replica-divergence.d.ts +1 -1
  297. package/dist/replica-peers-config.d.ts +1 -1
  298. package/dist/resolve-auth-token.d.ts +1 -1
  299. package/dist/retrieval-agents.d.ts +2 -2
  300. package/dist/retrieval-tiers.d.ts +1 -1
  301. package/dist/routing/engine.d.ts +1 -1
  302. package/dist/routing/store.d.ts +1 -1
  303. package/dist/salvage-envelope.d.ts +1 -1
  304. package/dist/schemas.d.ts +108 -108
  305. package/dist/{scope-profiles-CeMv7pP0.d.ts → scope-profiles-_Y_RHCeE.d.ts} +1 -1
  306. package/dist/search/embed-helper.d.ts +1 -1
  307. package/dist/search/factory.d.ts +1 -1
  308. package/dist/search/factory.js +3 -3
  309. package/dist/search/index.d.ts +1 -1
  310. package/dist/search/index.js +3 -3
  311. package/dist/search/lancedb-backend.d.ts +1 -1
  312. package/dist/search/meilisearch-backend.d.ts +1 -1
  313. package/dist/search/noop-backend.d.ts +1 -1
  314. package/dist/search/orama-backend.d.ts +1 -1
  315. package/dist/search/port.d.ts +1 -1
  316. package/dist/search/remote-backend.d.ts +1 -1
  317. package/dist/{semantic-consolidation-B-85brYj.d.ts → semantic-consolidation-DT2VSrU0.d.ts} +1 -1
  318. package/dist/semantic-consolidation.d.ts +2 -2
  319. package/dist/semantic-consolidation.js +12 -12
  320. package/dist/semantic-rule-promotion.js +11 -11
  321. package/dist/semantic-rule-verifier.d.ts +1 -1
  322. package/dist/semantic-rule-verifier.js +11 -11
  323. package/dist/{service-CoO0HA2E.d.ts → service-BMo-gwDE.d.ts} +3 -3
  324. package/dist/session-observer-bands.d.ts +1 -1
  325. package/dist/session-observer-state.d.ts +1 -1
  326. package/dist/shared-context/manager.d.ts +9 -9
  327. package/dist/signal.d.ts +1 -1
  328. package/dist/source-agent-qualifier.d.ts +1 -1
  329. package/dist/source-agent-qualifier.js +13 -13
  330. package/dist/{storage-BVAVitkO.d.ts → storage-CGzJGUUu.d.ts} +49 -24
  331. package/dist/storage.d.ts +2 -2
  332. package/dist/storage.js +10 -10
  333. package/dist/summarizer.d.ts +1 -1
  334. package/dist/summary-snapshot.d.ts +1 -1
  335. package/dist/support-passport/index.d.ts +14 -14
  336. package/dist/support-passport/index.js +26 -26
  337. package/dist/temporal-supersession.d.ts +2 -2
  338. package/dist/temporal-timeline-recall.d.ts +1 -1
  339. package/dist/temporal-validity.d.ts +1 -1
  340. package/dist/threading.d.ts +1 -1
  341. package/dist/tier-migration.d.ts +2 -2
  342. package/dist/tier-routing.d.ts +1 -1
  343. package/dist/topics.d.ts +1 -1
  344. package/dist/transcript.d.ts +1 -1
  345. package/dist/transfer/capsule-import.js +5 -5
  346. package/dist/transfer/types.d.ts +66 -66
  347. package/dist/trust-score-stage.d.ts +1 -1
  348. package/dist/trust-score.d.ts +1 -1
  349. package/dist/{types-DWHOxlZP.d.ts → types-CBEAYU76.d.ts} +112 -128
  350. package/dist/types.d.ts +1 -1
  351. package/dist/utility-runtime.d.ts +1 -1
  352. package/dist/verified-recall.js +11 -11
  353. package/dist/write-envelope.d.ts +1 -1
  354. package/package.json +2 -2
  355. package/src/access-http-query.ts +12 -0
  356. package/src/access-http.test.ts +32 -0
  357. package/src/access-http.ts +3 -7
  358. package/src/admin/admin-surfaces.test.ts +5 -10
  359. package/src/admin/admin-surfaces.ts +0 -16
  360. package/src/binary-lifecycle/pipeline.test.ts +1 -1
  361. package/src/binary-lifecycle/pipeline.ts +23 -9
  362. package/src/buffer.ts +6 -0
  363. package/src/chat/chat-cli.test.ts +53 -0
  364. package/src/chat/chat-cli.ts +22 -58
  365. package/src/dedup/index.test.ts +65 -1
  366. package/src/dedup/index.ts +24 -2
  367. package/src/maintenance/namespace-planner.ts +0 -2
  368. package/src/meetings/build.test.ts +20 -4
  369. package/src/meetings/build.ts +2 -2
  370. package/src/meetings/day-source.test.ts +3 -1
  371. package/src/meetings/day-source.ts +1 -12
  372. package/src/meetings/fuse.test.ts +64 -15
  373. package/src/meetings/fuse.ts +18 -12
  374. package/src/meetings/types.ts +4 -19
  375. package/src/memory-cache-derived.test.ts +90 -0
  376. package/src/memory-cache.ts +40 -42
  377. package/src/namespaces/catalog.test.ts +53 -8
  378. package/src/namespaces/catalog.ts +5 -37
  379. package/src/orchestration/turn-ingestion-snapshot.test.ts +167 -0
  380. package/src/orchestration/turn-ingestion.ts +2 -1
  381. package/src/storage/content-hash-index.ts +54 -0
  382. package/src/storage-contract/content-hash.test.ts +59 -1
  383. package/src/storage-fact-hash-index-defer.test.ts +9 -9
  384. package/src/storage.ts +39 -40
  385. package/dist/chunk-5W5N7XJZ.js.map +0 -1
  386. package/dist/chunk-6UZR7KEK.js.map +0 -1
  387. package/dist/chunk-6ZYQ36IB.js.map +0 -1
  388. package/dist/chunk-JJ7JW62R.js.map +0 -1
  389. package/dist/chunk-JWPG65LH.js.map +0 -1
  390. package/dist/chunk-NRFU5MVH.js.map +0 -1
  391. package/dist/chunk-TRPX6F2G.js.map +0 -1
  392. package/dist/chunk-XMMESCPD.js.map +0 -1
  393. /package/dist/{capsule-merge-HCJJMLPS.js.map → capsule-merge-SGIVB3WA.js.map} +0 -0
  394. /package/dist/{chunk-XFCQIQQU.js.map → chunk-2UM6WHME.js.map} +0 -0
  395. /package/dist/{chunk-6F2UMP4H.js.map → chunk-3Z5TGRFA.js.map} +0 -0
  396. /package/dist/{chunk-JJX5XEIG.js.map → chunk-77QZW2D6.js.map} +0 -0
  397. /package/dist/{chunk-X4MGNVOO.js.map → chunk-7AF243WZ.js.map} +0 -0
  398. /package/dist/{chunk-2ASAS3CQ.js.map → chunk-7KQB4EBS.js.map} +0 -0
  399. /package/dist/{chunk-3LJ2L3T3.js.map → chunk-7LF2OHIJ.js.map} +0 -0
  400. /package/dist/{chunk-VAMQU4W7.js.map → chunk-AYVCKGA6.js.map} +0 -0
  401. /package/dist/{chunk-GTRGH4ZT.js.map → chunk-BB2LH5JM.js.map} +0 -0
  402. /package/dist/{chunk-PADG72LJ.js.map → chunk-DXDAQZ2K.js.map} +0 -0
  403. /package/dist/{chunk-EJQXDKYK.js.map → chunk-DYZR3Z6D.js.map} +0 -0
  404. /package/dist/{chunk-VN7IIQGS.js.map → chunk-E4KMY4KR.js.map} +0 -0
  405. /package/dist/{chunk-ZQKXRKMR.js.map → chunk-EFKZT6AY.js.map} +0 -0
  406. /package/dist/{chunk-DNRTKO2U.js.map → chunk-EJY3HJMT.js.map} +0 -0
  407. /package/dist/{chunk-RYGJGXL6.js.map → chunk-ERPBRXVZ.js.map} +0 -0
  408. /package/dist/{chunk-RPKJHYVE.js.map → chunk-FPEZ74F7.js.map} +0 -0
  409. /package/dist/{chunk-Z334TJRB.js.map → chunk-GF7RQWXC.js.map} +0 -0
  410. /package/dist/{chunk-6D7PZKCJ.js.map → chunk-GG4DN63W.js.map} +0 -0
  411. /package/dist/{chunk-IM56VPKO.js.map → chunk-GTD4Q62X.js.map} +0 -0
  412. /package/dist/{chunk-A73QHOZP.js.map → chunk-I5FLIB2J.js.map} +0 -0
  413. /package/dist/{chunk-EJLTNPRY.js.map → chunk-KHCUVYCY.js.map} +0 -0
  414. /package/dist/{chunk-QSIQVC32.js.map → chunk-KYTRF64R.js.map} +0 -0
  415. /package/dist/{chunk-R74NCKEY.js.map → chunk-LX4TNSAE.js.map} +0 -0
  416. /package/dist/{chunk-H6ZXNH5I.js.map → chunk-MUJ4QFUQ.js.map} +0 -0
  417. /package/dist/{chunk-4NMVX5U7.js.map → chunk-NA56NSKL.js.map} +0 -0
  418. /package/dist/{chunk-MR5HWQHS.js.map → chunk-NKB43PGI.js.map} +0 -0
  419. /package/dist/{chunk-DLQQU4EG.js.map → chunk-NS5ETDYD.js.map} +0 -0
  420. /package/dist/{chunk-KWN6NOHQ.js.map → chunk-PB4WVYGC.js.map} +0 -0
  421. /package/dist/{chunk-Q35XGIEM.js.map → chunk-PBRCYYO7.js.map} +0 -0
  422. /package/dist/{chunk-QYN5PXDZ.js.map → chunk-PMVPCZJZ.js.map} +0 -0
  423. /package/dist/{chunk-AJSZ2EK6.js.map → chunk-QI5RDDEL.js.map} +0 -0
  424. /package/dist/{chunk-I6OQCT3Y.js.map → chunk-QRWMS6SI.js.map} +0 -0
  425. /package/dist/{chunk-ITYAXU4S.js.map → chunk-R6UMNP5C.js.map} +0 -0
  426. /package/dist/{chunk-5W62VEFH.js.map → chunk-RWMSMTQP.js.map} +0 -0
  427. /package/dist/{chunk-FKJVEW6O.js.map → chunk-SYVGVK4S.js.map} +0 -0
  428. /package/dist/{chunk-XZPSBGHA.js.map → chunk-UCLMKNHA.js.map} +0 -0
  429. /package/dist/{chunk-ZMSZVISA.js.map → chunk-UFKPQBXH.js.map} +0 -0
  430. /package/dist/{chunk-B2OOJCUX.js.map → chunk-UGHCZS6K.js.map} +0 -0
  431. /package/dist/{chunk-E2GYBTSP.js.map → chunk-VYEPACWY.js.map} +0 -0
  432. /package/dist/{chunk-KMAP7SNQ.js.map → chunk-XCB6QDL6.js.map} +0 -0
  433. /package/dist/{chunk-WDUG2CH3.js.map → chunk-YEQCMA5L.js.map} +0 -0
  434. /package/dist/{chunk-LZCSOUJ7.js.map → chunk-YFCEBB5P.js.map} +0 -0
  435. /package/dist/{chunk-IKXUG6KC.js.map → chunk-YXMHUBN2.js.map} +0 -0
  436. /package/dist/{chunk-GFNS3BHV.js.map → chunk-ZUPKNWRZ.js.map} +0 -0
  437. /package/dist/{chunk-GSTIBXBW.js.map → chunk-ZVPVTPGI.js.map} +0 -0
@@ -294,11 +294,25 @@ async function stageRedirect(
294
294
  }
295
295
 
296
296
  if (asset.redirectedAt === undefined) {
297
- if (!dryRun) {
298
- asset.status = "mirrored";
297
+ let remoteSeen = false;
298
+ for (const mdPath of mdFiles) {
299
+ try {
300
+ const content = await readMarkdownFile(mdPath);
301
+ if (content.includes(asset.mirroredPath)) {
302
+ remoteSeen = true;
303
+ break;
304
+ }
305
+ } catch {
306
+ // Verify already succeeded; a later read error is not a local ref.
307
+ }
308
+ }
309
+ if (!remoteSeen) {
310
+ if (!dryRun) {
311
+ asset.status = "mirrored";
312
+ }
313
+ log.info(`[binary-lifecycle] preserved mirrored asset without redirected marker: ${asset.originalPath}${dryRun ? " [dry-run]" : ""}`);
314
+ continue;
299
315
  }
300
- log.info(`[binary-lifecycle] preserved mirrored asset without redirected marker: ${asset.originalPath}${dryRun ? " [dry-run]" : ""}`);
301
- continue;
302
316
  }
303
317
 
304
318
  if (!Number.isFinite(new Date(asset.mirroredAt).getTime())) {
@@ -400,9 +414,6 @@ async function stageRedirect(
400
414
  continue;
401
415
  }
402
416
 
403
- const redirectedAt = new Date().toISOString();
404
- asset.redirectedAt = redirectedAt;
405
-
406
417
  const verifyResult = await countRemainingLocalReferences(
407
418
  memoryDir,
408
419
  asset,
@@ -411,7 +422,10 @@ async function stageRedirect(
411
422
  readMarkdownFile,
412
423
  );
413
424
  if (verifyResult.errors.length > 0 || verifyResult.remaining > 0) {
414
- asset.status = "error";
425
+ asset.status = "error";
426
+ // Failed verify must not read as a completed redirect (#2471); this also
427
+ // clears stale stamps written by manifests from before that fix.
428
+ delete asset.redirectedAt;
415
429
  for (const msg of verifyResult.errors) {
416
430
  log.error(`[binary-lifecycle] ${msg}`);
417
431
  errors.push(msg);
@@ -424,7 +438,7 @@ async function stageRedirect(
424
438
  continue;
425
439
  }
426
440
  asset.status = "redirected";
427
- asset.redirectedAt = redirectedAt;
441
+ asset.redirectedAt = new Date().toISOString();
428
442
  redirected++;
429
443
  log.info(`[binary-lifecycle] redirected: ${asset.originalPath}`);
430
444
  }
package/src/buffer.ts CHANGED
@@ -619,6 +619,12 @@ export class SmartBuffer {
619
619
  log.debug(
620
620
  `buffer[${bufferKey}]: ${mutation.turnCountInWindow} turns, signal=${mutation.signalLevel}, decision=${decision}`,
621
621
  );
622
+ if (decision !== "keep_buffering" && extractionTurns === undefined) {
623
+ extractionTurns = [
624
+ ...mutation.retainedTurnsSnapshot,
625
+ ...mutation.activeTurnsSnapshot,
626
+ ];
627
+ }
622
628
  return extractionTurns ? { decision, extractionTurns } : { decision };
623
629
  }
624
630
 
@@ -15,6 +15,12 @@ import { withTempDir as managedWithTempDir } from "../testing/tmp-dir.js";
15
15
  import type { EngramAccessService } from "../access-service.js";
16
16
  import { parseConfig } from "../config.js";
17
17
  import { runChatCli } from "./chat-cli.js";
18
+ import { processChatMessage } from "./chat-factory.js";
19
+ import {
20
+ createChatSession,
21
+ loadChatSession,
22
+ markPendingPlan,
23
+ } from "./chat-session.js";
18
24
  import { DEFAULT_CHAT_CONFIG } from "./chat-config.js";
19
25
 
20
26
  /** Capture stdout.write for the duration of `fn`. */
@@ -137,3 +143,50 @@ test("CLI: resumes an existing session by id", async () => {
137
143
  assert.ok(second.includes("[session:"), "resumed run should also print a session id");
138
144
  });
139
145
  });
146
+
147
+ test("CLI --once: pending plan is visible on reload the same way as HTTP (issue #2479)", async () => {
148
+ await withTempDir(async (memoryDir) => {
149
+ const service = makeService({
150
+ memoryDir,
151
+ configRef: parseConfig({ memoryDir, chat: { ...DEFAULT_CHAT_CONFIG, enabled: true } }),
152
+ });
153
+
154
+ // CLI side: first turn mints the session.
155
+ const first = await captureStdout(() =>
156
+ runChatCli({ service, config: service.configRef!.chat, memoryDir, once: true, input: "hello" }),
157
+ );
158
+ const sessionId = /\[session: ([^\]]+)\]/.exec(first)![1]!;
159
+ // Pending plan minted by an earlier correction-preview turn.
160
+ await markPendingPlan(memoryDir, sessionId, "plan-cli-2479");
161
+ await captureStdout(() =>
162
+ runChatCli({ service, config: service.configRef!.chat, memoryDir, once: true, input: "anything else?", sessionId }),
163
+ );
164
+ const viaCli = await loadChatSession(memoryDir, sessionId);
165
+ // HTTP side: identical scenario through the shared processor.
166
+ const httpSession = await createChatSession(memoryDir, {});
167
+ await processChatMessage({
168
+ service,
169
+ config: service.configRef!.chat,
170
+ memoryDir,
171
+ message: "hello",
172
+ chatSessionId: httpSession.id,
173
+ });
174
+ await markPendingPlan(memoryDir, httpSession.id, "plan-http-2479");
175
+ await processChatMessage({
176
+ service,
177
+ config: service.configRef!.chat,
178
+ memoryDir,
179
+ message: "anything else?",
180
+ chatSessionId: httpSession.id,
181
+ });
182
+ const viaHttp = await loadChatSession(memoryDir, httpSession.id);
183
+
184
+ assert.equal(viaCli?.pendingPlanId, "plan-cli-2479", "CLI turn must leave the pending plan visible on reload");
185
+ assert.equal(viaHttp?.pendingPlanId, "plan-http-2479", "HTTP turn must leave the pending plan visible on reload");
186
+ // Transcript shape parity: both surfaces append the same role sequence.
187
+ assert.deepEqual(
188
+ viaCli!.transcript.map((e) => e.role),
189
+ viaHttp!.transcript.map((e) => e.role),
190
+ );
191
+ });
192
+ });
@@ -6,28 +6,25 @@
6
6
  * and `--once` / non-TTY mode for scripting/tests
7
7
  * (`echo "question" | remnic chat --once`).
8
8
  *
9
+ * Every turn routes through the shared `processChatMessage` factory
10
+ * (issue #2479) so session lifecycle, transcript persistence, and
11
+ * pending-plan/promotion markers behave identically to the HTTP/MCP
12
+ * surfaces.
13
+ *
9
14
  * This module is imported by cli.ts with a single thin registration line —
10
15
  * the god-file ratchet (#1520) tracks cli.ts LOC.
11
16
  */
12
17
 
13
- import readline from "node:readline";
14
18
  import { createInterface } from "node:readline";
15
- import { randomUUID } from "node:crypto";
16
19
 
17
20
  import type { EngramAccessService } from "../access-service.js";
18
- import type { PluginConfig } from "../types.js";
19
- import type { ChatConfig } from "./chat-types.js";
20
- import type { ChatTurnResult } from "./chat-types.js";
21
- import { ChatEngine } from "./chat-engine.js";
22
- import { createProductionChatLlmAdapter } from "./chat-llm.js";
23
- import { createChatExecutor } from "./chat-executor.js";
21
+ import type { ChatConfig, ChatTurnResult } from "./chat-types.js";
22
+ import { processChatMessage } from "./chat-factory.js";
24
23
  import {
25
24
  createChatSession,
26
25
  loadChatSession,
27
- appendTranscriptEntry,
28
26
  sessionBelongsToPrincipal,
29
27
  } from "./chat-session.js";
30
- import { isConfirmationMessage } from "./chat-engine.js";
31
28
 
32
29
  /**
33
30
  * Read all of stdin to a UTF-8 string (non-TTY / scripting mode).
@@ -78,16 +75,10 @@ export async function runChatCli(opts: ChatCliOptions): Promise<void> {
78
75
  return;
79
76
  }
80
77
 
81
- const adapter = createProductionChatLlmAdapter(llm as {
82
- chatCompletion(
83
- messages: Array<{ role: string; content: string }>,
84
- options?: { model?: string; signal?: AbortSignal },
85
- ): Promise<{ content: string } | null>;
86
- });
87
-
88
- // Load or create session FIRST so the executor inherits the session's
89
- // stored namespace/sessionKey scope — a resumed session created via MCP
90
- // must not lose its scope binding (codex review, Thread 19).
78
+ // Resolve the session up front so the banner and --once output print a
79
+ // stable session id. Each turn then routes through processChatMessage,
80
+ // which reloads the session from disk — persisted state markers
81
+ // (pending plan/promotion) stay authoritative across turns.
91
82
  let session;
92
83
  if (opts.sessionId) {
93
84
  session = await loadChatSession(opts.memoryDir, opts.sessionId);
@@ -107,21 +98,15 @@ export async function runChatCli(opts: ChatCliOptions): Promise<void> {
107
98
  });
108
99
  }
109
100
 
110
- const executor = createChatExecutor({
111
- service: opts.service,
112
- principal: opts.principal,
113
- ...(session.namespace ? { namespace: session.namespace } : {}),
114
- ...(session.sessionKey ? { sessionKey: session.sessionKey } : {}),
115
- });
116
-
117
- const engine = new ChatEngine({
118
- llm: adapter,
119
- executor,
120
- maxToolCallsPerTurn: config.maxToolCallsPerTurn,
121
- ...(config.model ? { model: config.model } : {}),
122
- correctionAvailable: false,
123
- scopeInspectAvailable: false,
124
- });
101
+ const processTurn = (message: string): Promise<ChatTurnResult> =>
102
+ processChatMessage({
103
+ service: opts.service,
104
+ config,
105
+ memoryDir: opts.memoryDir,
106
+ message,
107
+ chatSessionId: session.id,
108
+ principal: opts.principal,
109
+ });
125
110
 
126
111
  // ── Non-TTY / --once mode ───────────────────────────────────────────
127
112
  if (opts.once) {
@@ -131,17 +116,7 @@ export async function runChatCli(opts: ChatCliOptions): Promise<void> {
131
116
  process.stdout.write("[error] No input provided.\n");
132
117
  return;
133
118
  }
134
- const userEntry = await appendTranscriptEntry(opts.memoryDir, session.id, {
135
- role: "user",
136
- content: message,
137
- });
138
- session.transcript.push(userEntry);
139
- const result = await engine.processMessage(message, session);
140
- const assistantEntry = await appendTranscriptEntry(opts.memoryDir, session.id, {
141
- role: "assistant",
142
- content: result.reply,
143
- });
144
- session.transcript.push(assistantEntry);
119
+ const result = await processTurn(message);
145
120
  process.stdout.write(result.reply + "\n");
146
121
  process.stdout.write(`[session: ${session.id}]\n`);
147
122
  return;
@@ -173,18 +148,7 @@ export async function runChatCli(opts: ChatCliOptions): Promise<void> {
173
148
  // Serialize turns: a second line waits for the first to finish so
174
149
  // transcript updates and engine state don't race on the same session.
175
150
  inFlight = inFlight.then(async () => {
176
- const userEntry = await appendTranscriptEntry(opts.memoryDir, session!.id, {
177
- role: "user",
178
- content: message,
179
- });
180
- session!.transcript.push(userEntry);
181
-
182
- const result = await engine.processMessage(message, session!);
183
- const assistantEntry = await appendTranscriptEntry(opts.memoryDir, session!.id, {
184
- role: "assistant",
185
- content: result.reply,
186
- });
187
- session!.transcript.push(assistantEntry);
151
+ const result = await processTurn(message);
188
152
 
189
153
  console.log(`\nassistant> ${result.reply}\n`);
190
154
  if (result.pendingPlan) {
@@ -4,7 +4,7 @@ import { tmpdir } from "node:os";
4
4
  import path from "node:path";
5
5
  import test from "node:test";
6
6
 
7
- import { findContradictions, findDuplicates } from "./index.js";
7
+ import { NEGATION_WORDS, findContradictions, findDuplicates } from "./index.js";
8
8
 
9
9
  test("findContradictions detects can versus cannot statements", async () => {
10
10
  const memoryDir = await mkdtemp(path.join(tmpdir(), "remnic-dedup-contradiction-"));
@@ -149,3 +149,67 @@ test("dedup scans reject symlinked category directories outside memoryDir", asyn
149
149
  await rm(outsideDir, { recursive: true, force: true });
150
150
  }
151
151
  });
152
+
153
+ test("strip-negation pattern is derived from NEGATION_WORDS", async () => {
154
+ NEGATION_WORDS.add("seldom");
155
+ const memoryDir = await mkdtemp(path.join(tmpdir(), "remnic-dedup-negation-"));
156
+
157
+ try {
158
+ const factsDir = path.join(memoryDir, "facts");
159
+ await mkdir(factsDir);
160
+ await writeFile(
161
+ path.join(factsDir, "plain.md"),
162
+ ["---", "id: mem-plain", "category: fact", "---", "The user enjoys morning runs."].join("\n"),
163
+ "utf8"
164
+ );
165
+ await writeFile(
166
+ path.join(factsDir, "seldom.md"),
167
+ ["---", "id: mem-seldom", "category: fact", "---", "The user seldom enjoys morning runs."].join("\n"),
168
+ "utf8"
169
+ );
170
+
171
+ const result = findContradictions({ memoryDir, categories: ["facts"] });
172
+
173
+ // "high" requires the stripped texts to match exactly, which only happens
174
+ // when the strip pattern honors the word the test added to the set.
175
+ assert.equal(result.contradictions.length, 1);
176
+ assert.equal(result.contradictions[0]?.severity, "high");
177
+ assert.equal(result.contradictions[0]?.reason, "Negated version of similar content");
178
+ } finally {
179
+ NEGATION_WORDS.delete("seldom");
180
+ await rm(memoryDir, { recursive: true, force: true });
181
+ }
182
+ });
183
+
184
+ test("strip-negation cache rebuilds on same-size vocabulary swap", async () => {
185
+ const memoryDir = await mkdtemp(path.join(tmpdir(), "remnic-dedup-negation-swap-"));
186
+
187
+ try {
188
+ const factsDir = path.join(memoryDir, "facts");
189
+ await mkdir(factsDir);
190
+ await writeFile(
191
+ path.join(factsDir, "plain.md"),
192
+ ["---", "id: mem-swap-plain", "category: fact", "---", "The user enjoys morning runs."].join("\n"),
193
+ "utf8"
194
+ );
195
+ await writeFile(
196
+ path.join(factsDir, "rarely.md"),
197
+ ["---", "id: mem-swap-rarely", "category: fact", "---", "The user rarely enjoys morning runs."].join("\n"),
198
+ "utf8"
199
+ );
200
+
201
+ // Warm the pattern cache with the current vocabulary (no "rarely" yet).
202
+ assert.equal(findContradictions({ memoryDir, categories: ["facts"] }).contradictions.length, 0);
203
+
204
+ // Same-size swap: the size-keyed cache would keep serving the stale pattern.
205
+ NEGATION_WORDS.delete("never");
206
+ NEGATION_WORDS.add("rarely");
207
+ const result = findContradictions({ memoryDir, categories: ["facts"] });
208
+ assert.equal(result.contradictions.length, 1);
209
+ assert.equal(result.contradictions[0]?.severity, "high");
210
+ } finally {
211
+ NEGATION_WORDS.delete("rarely");
212
+ NEGATION_WORDS.add("never");
213
+ await rm(memoryDir, { recursive: true, force: true });
214
+ }
215
+ });
@@ -245,7 +245,7 @@ function tokenizeForSimilarity(text: string): Set<string> {
245
245
 
246
246
  // ── Contradiction detection ──────────────────────────────────────────────────
247
247
 
248
- const NEGATION_WORDS = new Set([
248
+ export const NEGATION_WORDS = new Set([
249
249
  "not",
250
250
  "don't",
251
251
  "doesn't",
@@ -317,9 +317,31 @@ function containsNegation(text: string): boolean {
317
317
  return words.some((w) => NEGATION_WORDS.has(w));
318
318
  }
319
319
 
320
+ function escapeRegExp(value: string): string {
321
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
322
+ }
323
+
324
+ // Single vocabulary source: the strip pattern is derived from NEGATION_WORDS,
325
+ // never hand-maintained. Keyed on the alternation content so any vocabulary
326
+ // change (not just a size change) rebuilds the pattern.
327
+ let stripNegationPattern: RegExp | null = null;
328
+ let stripNegationPatternSource: string | null = null;
329
+
330
+ function stripNegationRegex(): RegExp {
331
+ const alternation = [...NEGATION_WORDS]
332
+ .sort((a, b) => b.length - a.length)
333
+ .map(escapeRegExp)
334
+ .join("|");
335
+ if (stripNegationPattern === null || stripNegationPatternSource !== alternation) {
336
+ stripNegationPattern = new RegExp(`\\b(?:${alternation})\\b`, "gi");
337
+ stripNegationPatternSource = alternation;
338
+ }
339
+ return stripNegationPattern;
340
+ }
341
+
320
342
  function stripNegation(text: string): string {
321
343
  return text
322
- .replace(/\b(not|don't|doesn't|isn't|aren't|won't|can't|cannot|never|no|none|neither|nor|nothing|nowhere)\b/gi, "")
344
+ .replace(stripNegationRegex(), "")
323
345
  .replace(/\s+/g, " ")
324
346
  .trim();
325
347
  }
@@ -177,8 +177,6 @@ function candidatePriority(candidate: NamespaceMaintenanceCandidate): number {
177
177
  if (candidate.source === "configured") return 2;
178
178
  if (candidate.kind === "team-project") return 3;
179
179
  if (candidate.kind === "project") return 4;
180
- if (candidate.kind === "self") return 5;
181
- if (candidate.kind === "legacy") return 6;
182
180
  if (candidate.kind === "branch") return 8;
183
181
  return 7;
184
182
  }
@@ -5,12 +5,12 @@ import { MeetingsBuilder, type MeetingDayData, type MeetingsDayBuildSummary, typ
5
5
  import { DEFAULT_MEETINGS_CONFIG } from "./config.js";
6
6
  import { MeetingRecordStore, type MeetingRecordFileIo } from "./store.js";
7
7
  import type {
8
- MeetingActivitySnapshot,
9
8
  MeetingsConfig,
10
9
  MeetingAppSpan,
11
10
  MeetingAudioWindow,
12
11
  MeetingRecord,
13
12
  } from "./types.js";
13
+ import type { ActivitySnapshot } from "../activity/types.js";
14
14
  import type { FusionConversationInput, FusionSegmentInput } from "../wearables/fusion/types.js";
15
15
  import type { MeetingMemoryGenerator, MeetingMemoryOutcome } from "./memory-generator.js";
16
16
 
@@ -174,9 +174,25 @@ test("degradation — audio only yields a record with no screen-context section"
174
174
  });
175
175
 
176
176
  test("full — app+audio with activity fuses transcript and screen context", async () => {
177
- const activity: MeetingActivitySnapshot[] = [
178
- { tsUtc: "2026-03-10T14:05:00.000Z", app: "Preview", title: "Q3-roadmap.pdf" },
179
- { tsUtc: "2026-03-10T14:30:00.000Z", app: "Zoom", text: "meeting chat" },
177
+ const activity: ActivitySnapshot[] = [
178
+ {
179
+ machine: "workstation",
180
+ capturedAtUtc: "2026-03-10T14:05:00.000Z",
181
+ app: "Preview",
182
+ windowTitle: "Q3-roadmap.pdf",
183
+ text: "",
184
+ textSource: "ax",
185
+ contentHash: "snap-1",
186
+ },
187
+ {
188
+ machine: "workstation",
189
+ capturedAtUtc: "2026-03-10T14:30:00.000Z",
190
+ app: "Zoom",
191
+ windowTitle: "",
192
+ text: "meeting chat",
193
+ textSource: "ax",
194
+ contentHash: "snap-2",
195
+ },
180
196
  ];
181
197
  const { builder: b, store } = builder(
182
198
  {
@@ -22,10 +22,10 @@ import type {
22
22
  MeetingMemoryOutcome,
23
23
  MeetingsDayFactGenResult,
24
24
  } from "./memory-generator.js";
25
+ import type { ActivitySnapshot } from "../activity/types.js";
25
26
  import type { FusionConversationInput } from "../wearables/fusion/types.js";
26
27
  import type {
27
28
  DetectedMeeting,
28
- MeetingActivitySnapshot,
29
29
  MeetingRecord,
30
30
  MeetingsConfig,
31
31
  MeetingsDetectionInput,
@@ -38,7 +38,7 @@ export interface MeetingDayData {
38
38
  /** Fusion conversation inputs across all wearable sources for the day. */
39
39
  conversations: FusionConversationInput[];
40
40
  /** Screen-activity snapshots for the day. */
41
- activity?: MeetingActivitySnapshot[];
41
+ activity?: ActivitySnapshot[];
42
42
  }
43
43
 
44
44
  /** Supplies a day's signals. Backed by fixtures in tests; by the activity +
@@ -127,7 +127,9 @@ test("loadDayData assembles detection + activity for the requested day, keyed to
127
127
  assert.equal(data.detection.appSpans[0]?.app, "Zoom");
128
128
  assert.deepEqual(data.detection.audioWindows, [], "no wearable transcripts → no audio windows");
129
129
  assert.equal(data.activity?.length, 2);
130
- assert.equal(data.activity?.[0]?.title, "Standup");
130
+ // Activity is the raw ActivitySnapshot list now — no rename mapper in between.
131
+ assert.equal(data.activity?.[0]?.windowTitle, "Standup");
132
+ assert.equal(data.activity?.[0]?.capturedAtUtc, "2026-03-10T14:00:00.000Z");
131
133
  assert.equal(data.conversations.length, 0);
132
134
  });
133
135
 
@@ -28,7 +28,6 @@ import type { FusionConversationInput, FusionSegmentInput } from "../wearables/f
28
28
  import type { MeetingDayData, MeetingsDaySource } from "./build.js";
29
29
  import { MeetingsInputError } from "./errors.js";
30
30
  import type {
31
- MeetingActivitySnapshot,
32
31
  MeetingAppSpan,
33
32
  MeetingAudioWindow,
34
33
  MeetingsConfig,
@@ -97,15 +96,6 @@ export function storageWearableDayReader(store: WearableDayTranscriptStore): Mee
97
96
  };
98
97
  }
99
98
 
100
- /** Map an activity snapshot to the redaction-safe screen snapshot fusion sees. */
101
- function toMeetingActivitySnapshot(snapshot: ActivitySnapshot): MeetingActivitySnapshot {
102
- const out: MeetingActivitySnapshot = { tsUtc: snapshot.capturedAtUtc, app: snapshot.app };
103
- if (snapshot.windowTitle.length > 0) out.title = snapshot.windowTitle;
104
- if (snapshot.browserUrl !== undefined && snapshot.browserUrl.length > 0) out.url = snapshot.browserUrl;
105
- if (snapshot.text.length > 0) out.text = snapshot.text;
106
- return out;
107
- }
108
-
109
99
  /**
110
100
  * Fallback dwell for a lone trailing meeting-app tick on a machine that
111
101
  * captured no other snapshot to estimate a cadence from. Five minutes keeps
@@ -341,12 +331,11 @@ export class ActivityWearablesMeetingsDaySource implements MeetingsDaySource {
341
331
  const snapshots = this.deps.activity
342
332
  ? await this.deps.activity.listSnapshotsForDay(null, startUtc, endUtc)
343
333
  : [];
344
- const activity = snapshots.map(toMeetingActivitySnapshot);
345
334
  const appSpans = deriveAppSpans(snapshots, this.deps.config.appPatterns);
346
335
  const bodies = await this.deps.wearables.readDayBodies(date);
347
336
  const tzBySource = new Map(bodies.map((b) => [b.source, b.timezone ?? ""] as const));
348
337
  const conversations = shiftFusionInputsToUtc(reconstructFusionInputs(date, bodies), tzBySource);
349
338
  const audioWindows = buildAudioWindows(conversations);
350
- return { detection: { date, appSpans, audioWindows }, conversations, activity };
339
+ return { detection: { date, appSpans, audioWindows }, conversations, activity: snapshots };
351
340
  }
352
341
  }
@@ -1,13 +1,12 @@
1
1
  import assert from "node:assert/strict";
2
+ import { readFileSync } from "node:fs";
3
+ import { join } from "node:path";
2
4
  import { test } from "node:test";
3
5
 
4
6
  import { DEFAULT_MEETINGS_CONFIG } from "./config.js";
5
7
  import { fuseMeeting } from "./fuse.js";
6
- import type {
7
- DetectedMeeting,
8
- MeetingActivitySnapshot,
9
- MeetingsConfig,
10
- } from "./types.js";
8
+ import type { ActivitySnapshot } from "../activity/types.js";
9
+ import type { DetectedMeeting, MeetingsConfig } from "./types.js";
11
10
  import type { FusionConversationInput, FusionSegmentInput } from "../wearables/fusion/types.js";
12
11
 
13
12
  const DATE = "2026-03-10";
@@ -51,8 +50,17 @@ function conv(
51
50
  return { source, conversationId: id, startIso, endIso, segments };
52
51
  }
53
52
 
54
- function snap(overrides: Partial<MeetingActivitySnapshot> & { tsUtc: string; app: string }): MeetingActivitySnapshot {
55
- return { ...overrides };
53
+ function snap(
54
+ overrides: Partial<ActivitySnapshot> & { capturedAtUtc: string; app: string },
55
+ ): ActivitySnapshot {
56
+ return {
57
+ machine: "workstation",
58
+ windowTitle: "",
59
+ text: "",
60
+ textSource: "ax",
61
+ contentHash: "snap-hash",
62
+ ...overrides,
63
+ };
56
64
  }
57
65
 
58
66
  test("fusion prefers the higher-trust source in overlap regions and records corroboratedBy without duplicating text", () => {
@@ -97,10 +105,10 @@ test("screen context includes a >=20s dwell and omits a 5s alt-tab; meeting-app
97
105
  ]),
98
106
  ],
99
107
  activity: [
100
- snap({ tsUtc: "2026-03-10T14:05:00.000Z", app: "Preview", title: "Q3-roadmap.pdf", text: "Q3 roadmap draft" }),
101
- snap({ tsUtc: "2026-03-10T14:05:25.000Z", app: "Notes", title: "scratch" }), // Preview dwell 25s → include; Notes starts
102
- snap({ tsUtc: "2026-03-10T14:05:30.000Z", app: "Preview", title: "Q3-roadmap.pdf" }), // Notes dwell 5s → exclude
103
- snap({ tsUtc: "2026-03-10T14:10:00.000Z", app: "Zoom", text: "Jane: agenda item one" }), // meeting-app → excerpt
108
+ snap({ capturedAtUtc: "2026-03-10T14:05:00.000Z", app: "Preview", windowTitle: "Q3-roadmap.pdf", text: "Q3 roadmap draft" }),
109
+ snap({ capturedAtUtc: "2026-03-10T14:05:25.000Z", app: "Notes", windowTitle: "scratch" }), // Preview dwell 25s → include; Notes starts
110
+ snap({ capturedAtUtc: "2026-03-10T14:05:30.000Z", app: "Preview", windowTitle: "Q3-roadmap.pdf" }), // Notes dwell 5s → exclude
111
+ snap({ capturedAtUtc: "2026-03-10T14:10:00.000Z", app: "Zoom", text: "Jane: agenda item one" }), // meeting-app → excerpt
104
112
  ],
105
113
  },
106
114
  config(),
@@ -122,9 +130,9 @@ test("context excerpts respect maxContextChars", () => {
122
130
  meeting: meeting(),
123
131
  conversations: [],
124
132
  activity: [
125
- snap({ tsUtc: "2026-03-10T14:01:00.000Z", app: "Zoom", text: "aaaa" }),
126
- snap({ tsUtc: "2026-03-10T14:02:00.000Z", app: "Zoom", text: "bbbb" }),
127
- snap({ tsUtc: "2026-03-10T14:03:00.000Z", app: "Zoom", text: "cccc" }),
133
+ snap({ capturedAtUtc: "2026-03-10T14:01:00.000Z", app: "Zoom", text: "aaaa" }),
134
+ snap({ capturedAtUtc: "2026-03-10T14:02:00.000Z", app: "Zoom", text: "bbbb" }),
135
+ snap({ capturedAtUtc: "2026-03-10T14:03:00.000Z", app: "Zoom", text: "cccc" }),
128
136
  ],
129
137
  },
130
138
  config({ maxContextChars: 8 }),
@@ -199,10 +207,51 @@ test("a lone trailing other-app snapshot is not inflated to the meeting end", ()
199
207
  ],
200
208
  // A single Notes snapshot 1 min before the window end. With no later
201
209
  // snapshot, the trailing run must NOT count dwell up to the meeting end.
202
- activity: [snap({ tsUtc: "2026-03-10T14:29:00.000Z", app: "Notes", title: "scratch" })],
210
+ activity: [snap({ capturedAtUtc: "2026-03-10T14:29:00.000Z", app: "Notes", windowTitle: "scratch" })],
203
211
  },
204
212
  config(),
205
213
  );
206
214
  assert.equal(fused.snapshotCount, 1);
207
215
  assert.deepEqual(fused.screenContext, [], "a lone trailing snapshot has zero observed dwell");
208
216
  });
217
+
218
+ test("fusion reads ActivitySnapshot fields — capturedAtUtc, browserUrl runs, windowTitle fallback", () => {
219
+ const fused = fuseMeeting(
220
+ {
221
+ meeting: meeting(),
222
+ conversations: [],
223
+ activity: [
224
+ snap({ capturedAtUtc: "2026-03-10T14:05:00.000Z", app: "Chrome", browserUrl: "https://github.com/org/repo/pull/1" }),
225
+ snap({ capturedAtUtc: "2026-03-10T14:06:00.000Z", app: "Chrome", browserUrl: "https://github.com/org/repo/pull/1" }),
226
+ // Different URL on the same app → a separate dwell run.
227
+ snap({ capturedAtUtc: "2026-03-10T14:06:30.000Z", app: "Chrome", browserUrl: "https://example.com/doc" }),
228
+ snap({ capturedAtUtc: "2026-03-10T14:07:00.000Z", app: "Chrome", browserUrl: "https://example.com/doc" }),
229
+ // Empty browserUrl falls back to the window title for key and label.
230
+ snap({ capturedAtUtc: "2026-03-10T14:07:30.000Z", app: "Chrome", windowTitle: "Spec v2" }),
231
+ snap({ capturedAtUtc: "2026-03-10T14:08:00.000Z", app: "Chrome", windowTitle: "Spec v2" }),
232
+ ],
233
+ },
234
+ config(),
235
+ );
236
+ assert.equal(fused.snapshotCount, 6);
237
+ assert.deepEqual(
238
+ fused.screenContext.map((e) => e.label),
239
+ [
240
+ "Chrome: github.com/org/repo/pull/1",
241
+ "Chrome: example.com/doc",
242
+ "Chrome: Spec v2",
243
+ ],
244
+ );
245
+ // Run dwell ends at the next different-key snapshot (90s, 60s) or, for the
246
+ // trailing run, at its own last snapshot (30s).
247
+ assert.deepEqual(fused.screenContext.map((e) => e.dwellSeconds), [90, 60, 30]);
248
+ });
249
+
250
+ test("MeetingActivitySnapshot and its rename mapper are gone", () => {
251
+ const here = import.meta.dirname;
252
+ for (const file of ["types.ts", "fuse.ts", "day-source.ts", "build.ts"]) {
253
+ const src = readFileSync(join(here, file), "utf8");
254
+ assert.ok(!src.includes("MeetingActivitySnapshot"), `${file} must not reference MeetingActivitySnapshot`);
255
+ assert.ok(!src.includes("toMeetingActivitySnapshot"), `${file} must not reference toMeetingActivitySnapshot`);
256
+ }
257
+ });