@remnic/core 9.66.0 → 9.66.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (482) hide show
  1. package/dist/access-admin-ops-surface.d.ts +11 -11
  2. package/dist/access-admin-ops-surface.js +22 -22
  3. package/dist/access-authorization-probe.d.ts +11 -11
  4. package/dist/access-authorization-probe.js +23 -23
  5. package/dist/access-boundary.d.ts +11 -11
  6. package/dist/access-boundary.js +22 -22
  7. package/dist/access-cli.js +86 -84
  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 +22 -22
  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 +2 -2
  17. package/dist/access-http-query.js +24 -24
  18. package/dist/access-http.d.ts +12 -12
  19. package/dist/access-http.js +39 -39
  20. package/dist/access-identity-continuity-surface.d.ts +9 -9
  21. package/dist/access-identity-continuity-surface.js +22 -22
  22. package/dist/access-lcm-surface.d.ts +11 -11
  23. package/dist/access-lcm-surface.js +22 -22
  24. package/dist/access-mcp.d.ts +11 -11
  25. package/dist/access-mcp.js +29 -29
  26. package/dist/access-memory-search-fanout.d.ts +2 -2
  27. package/dist/{access-namespace-preflight-CLWUoMyW.d.ts → access-namespace-preflight-50VIkPhB.d.ts} +1 -1
  28. package/dist/access-namespace-preflight.d.ts +3 -3
  29. package/dist/access-namespace-preflight.js +22 -22
  30. package/dist/access-observe-write-surface.d.ts +11 -11
  31. package/dist/access-observe-write-surface.js +22 -22
  32. package/dist/access-offline-manifest.d.ts +9 -9
  33. package/dist/access-operations-batch.js +24 -24
  34. package/dist/access-operations.d.ts +16 -16
  35. package/dist/access-operations.js +28 -28
  36. package/dist/access-recall-concurrency.d.ts +11 -11
  37. package/dist/access-recall-concurrency.js +22 -22
  38. package/dist/access-recall-response.d.ts +11 -11
  39. package/dist/access-recall-response.js +22 -22
  40. package/dist/access-recall-surface.d.ts +11 -11
  41. package/dist/access-recall-surface.js +22 -22
  42. package/dist/access-schema.d.ts +89 -89
  43. package/dist/access-schema.js +3 -3
  44. package/dist/{access-service-CEUE1Isj.d.ts → access-service-C2tV2-uL.d.ts} +65 -65
  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 +22 -22
  48. package/dist/access-surface-catalog.d.ts +11 -11
  49. package/dist/access-surface-catalog.js +24 -24
  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/active-recall.js +2 -2
  55. package/dist/adapters/index.js +7 -7
  56. package/dist/adapters/registry.js +3 -3
  57. package/dist/ambient-provenance.d.ts +1 -1
  58. package/dist/artifact-search.d.ts +1 -1
  59. package/dist/behavior-learner.d.ts +1 -1
  60. package/dist/behavior-signals.d.ts +1 -1
  61. package/dist/bootstrap.d.ts +9 -9
  62. package/dist/briefing-window.d.ts +2 -2
  63. package/dist/briefing.d.ts +2 -2
  64. package/dist/briefing.js +9 -9
  65. package/dist/buffer-surprise-report.d.ts +1 -1
  66. package/dist/buffer-turn-helpers.d.ts +1 -1
  67. package/dist/buffer.d.ts +2 -2
  68. package/dist/bulk-import/index.d.ts +3 -3
  69. package/dist/calibration.d.ts +1 -1
  70. package/dist/capabilities.d.ts +1 -1
  71. package/dist/{catalog-D1HgugTA.d.ts → catalog-C2jA-gLm.d.ts} +1 -1
  72. package/dist/causal-behavior.d.ts +1 -1
  73. package/dist/causal-consolidation.d.ts +1 -1
  74. package/dist/causal-consolidation.js +10 -10
  75. package/dist/causal-trajectory-graph.d.ts +1 -1
  76. package/dist/{chunk-J3OND5QT.js → chunk-2FA7U5XY.js} +2 -2
  77. package/dist/{chunk-GEJKYA7D.js → chunk-2ITZ74A6.js} +9 -9
  78. package/dist/{chunk-2LBAFHOQ.js → chunk-2X6BGKQL.js} +8 -8
  79. package/dist/{chunk-KODXCHXJ.js → chunk-46XR5FNZ.js} +39 -3
  80. package/dist/chunk-46XR5FNZ.js.map +1 -0
  81. package/dist/{chunk-4STAANV7.js → chunk-4XLTUR6R.js} +3 -3
  82. package/dist/{chunk-FTTJRVB7.js → chunk-65JOGLIS.js} +2 -2
  83. package/dist/{chunk-FESUGFIL.js → chunk-7UOXCCCI.js} +2 -2
  84. package/dist/{chunk-PEBH5DCK.js → chunk-AF5H7TKI.js} +100 -18
  85. package/dist/chunk-AF5H7TKI.js.map +1 -0
  86. package/dist/{chunk-6CEGSTBD.js → chunk-B4AOWRYF.js} +4 -4
  87. package/dist/{chunk-FYWLSFFS.js → chunk-C5IUOBCN.js} +2 -2
  88. package/dist/{chunk-FKKGCGYL.js → chunk-CHGG74CY.js} +2 -2
  89. package/dist/{chunk-H7VDIF2V.js → chunk-CX4OLNIH.js} +2 -2
  90. package/dist/{chunk-Z3YEGSR4.js → chunk-D3UXGE5D.js} +10 -10
  91. package/dist/{chunk-7XOG75AU.js → chunk-D6Q5EPOV.js} +2 -2
  92. package/dist/{chunk-MJRGVXPQ.js → chunk-EH65UV2Z.js} +2 -2
  93. package/dist/{chunk-VQ4AMTGZ.js → chunk-EWKVYCFP.js} +1 -1
  94. package/dist/{chunk-23CVL7HS.js → chunk-FFUMTH27.js} +2 -2
  95. package/dist/{chunk-GX6FTSYH.js → chunk-GAJK3DQ5.js} +2 -2
  96. package/dist/{chunk-O57GM3FR.js → chunk-GBEOUCBB.js} +2 -2
  97. package/dist/{chunk-DMEHOEC7.js → chunk-H2IRSXZN.js} +3 -3
  98. package/dist/{chunk-CFVTRUR3.js → chunk-H6RSANGQ.js} +2 -2
  99. package/dist/chunk-HVAEXYPL.js +98 -0
  100. package/dist/chunk-HVAEXYPL.js.map +1 -0
  101. package/dist/{chunk-OAJMQKQR.js → chunk-IGZCAHFL.js} +2 -2
  102. package/dist/{chunk-CN4VKV3S.js → chunk-INUBU6I5.js} +2 -2
  103. package/dist/{chunk-CTCGHNWN.js → chunk-J2R275FN.js} +4 -4
  104. package/dist/{chunk-2QSZNTDO.js → chunk-JBPKEARU.js} +7 -7
  105. package/dist/{chunk-VQNRICAQ.js → chunk-JKTV3JNX.js} +3 -3
  106. package/dist/{chunk-33MFRY25.js → chunk-KI64TTBL.js} +2 -2
  107. package/dist/{chunk-VCKWULAK.js → chunk-KJXCD7VR.js} +5 -5
  108. package/dist/{chunk-7LCGFUMB.js → chunk-KQAFEZQX.js} +4 -4
  109. package/dist/{chunk-GSKINLAK.js → chunk-LJABGXC4.js} +3 -3
  110. package/dist/{chunk-NPIBN2VL.js → chunk-LK4TOYPU.js} +2 -2
  111. package/dist/{chunk-EZSCW4EM.js → chunk-LYUUA6QB.js} +2 -2
  112. package/dist/{chunk-I5VB44ZK.js → chunk-M5ERTI4I.js} +2 -2
  113. package/dist/{chunk-IHGMRDEE.js → chunk-MUEGIKKY.js} +227 -144
  114. package/dist/chunk-MUEGIKKY.js.map +1 -0
  115. package/dist/{chunk-QCRJMU5V.js → chunk-NFP4KPTA.js} +2 -2
  116. package/dist/{chunk-YXFCALVT.js → chunk-NSTNGMSS.js} +8 -8
  117. package/dist/{chunk-L4X4PJYK.js → chunk-NUF7VSEX.js} +2 -2
  118. package/dist/{chunk-IVIAHQBR.js → chunk-OJUEUQDJ.js} +2 -2
  119. package/dist/{chunk-ZW4VXELZ.js → chunk-OMX6TKXH.js} +2 -2
  120. package/dist/{chunk-EFQCDJZ2.js → chunk-QBNE55VA.js} +2 -2
  121. package/dist/{chunk-6QDXA26G.js → chunk-RPIS5FQ7.js} +47 -47
  122. package/dist/{chunk-HJXA6ZM7.js → chunk-S4CDUXQY.js} +2 -2
  123. package/dist/{chunk-72OIT7KS.js → chunk-S4Z2OBTX.js} +3 -3
  124. package/dist/{chunk-4FHRZD5T.js → chunk-SZMYGDSM.js} +2 -2
  125. package/dist/{chunk-MAH64N55.js → chunk-TBCDF556.js} +4 -4
  126. package/dist/{chunk-56IV4J5W.js → chunk-TCF4MU7L.js} +443 -58
  127. package/dist/chunk-TCF4MU7L.js.map +1 -0
  128. package/dist/{chunk-K66OY4EI.js → chunk-TCQRIIIN.js} +2 -2
  129. package/dist/{chunk-KXIXO76C.js → chunk-U65VJSCJ.js} +14 -14
  130. package/dist/{chunk-HNPE66LB.js → chunk-U6NGKS32.js} +7 -7
  131. package/dist/{chunk-WKJFIMVN.js → chunk-UW4RYPWC.js} +2 -2
  132. package/dist/{chunk-MN5NOOI7.js → chunk-VG4SSPAW.js} +2 -2
  133. package/dist/chunk-WFCWP4XU.js +17 -0
  134. package/dist/chunk-WFCWP4XU.js.map +1 -0
  135. package/dist/{chunk-UNUMFURP.js → chunk-X5PIDJ3L.js} +3 -3
  136. package/dist/{chunk-RZ3IZIJG.js → chunk-XOHYGIWF.js} +2 -2
  137. package/dist/{chunk-MINHJ55X.js → chunk-XXW32OL7.js} +1 -1
  138. package/dist/{chunk-MINHJ55X.js.map → chunk-XXW32OL7.js.map} +1 -1
  139. package/dist/{chunk-6RUHELWR.js → chunk-YWPLOJ7T.js} +2 -2
  140. package/dist/{chunk-ZJPM7GZ3.js → chunk-ZPS724LT.js} +2 -2
  141. package/dist/{chunk-7UTDHQZ5.js → chunk-ZZZWEDF4.js} +2 -2
  142. package/dist/{cli-BEkm2MEf.d.ts → cli-CsfFMe6n.d.ts} +5 -5
  143. package/dist/cli.d.ts +13 -13
  144. package/dist/cli.js +63 -63
  145. package/dist/coding/export-okf-codegraph.d.ts +1 -1
  146. package/dist/coding/export-okf-codegraph.js +9 -9
  147. package/dist/coding/pre-action-gate.d.ts +1 -1
  148. package/dist/compounding/engine.d.ts +2 -2
  149. package/dist/compounding/engine.js +9 -9
  150. package/dist/compounding/preference-consolidator.d.ts +1 -1
  151. package/dist/compression-optimizer.d.ts +1 -1
  152. package/dist/config.d.ts +1 -1
  153. package/dist/config.js +2 -2
  154. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  155. package/dist/connectors/codex-materialize-runner.js +9 -9
  156. package/dist/connectors/codex-materialize.d.ts +1 -1
  157. package/dist/connectors/index.d.ts +1 -1
  158. package/dist/connectors/index.js +9 -9
  159. package/dist/consolidation-provenance-check.d.ts +2 -2
  160. package/dist/consolidation-undo.d.ts +2 -2
  161. package/dist/contradiction/index.d.ts +3 -3
  162. package/dist/converge-config.d.ts +1 -1
  163. package/dist/convergence-refresh.d.ts +2 -2
  164. package/dist/convergence-refresh.js +11 -11
  165. package/dist/conversation-index/backend.d.ts +1 -1
  166. package/dist/conversation-index/chunker.d.ts +1 -1
  167. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  168. package/dist/conversation-index/indexer.d.ts +1 -1
  169. package/dist/conversation-index/search.d.ts +1 -1
  170. package/dist/corpus-watermark.d.ts +1 -1
  171. package/dist/corpus-watermark.js +11 -11
  172. package/dist/cross-lingual-recall.d.ts +1 -1
  173. package/dist/day-summary.d.ts +1 -1
  174. package/dist/delinearize.d.ts +1 -1
  175. package/dist/dependency-propagation-config.d.ts +1 -1
  176. package/dist/{dependency-propagation-delivery-BCpeo14F.d.ts → dependency-propagation-delivery-D4WMbOwA.d.ts} +1 -1
  177. package/dist/direct-answer-wiring.d.ts +1 -1
  178. package/dist/direct-answer.d.ts +1 -1
  179. package/dist/embedding-fallback.d.ts +1 -1
  180. package/dist/enrichment/index.d.ts +1 -1
  181. package/dist/entity-origin-fields.d.ts +1 -1
  182. package/dist/entity-retrieval.d.ts +2 -2
  183. package/dist/entity-retrieval.js +9 -9
  184. package/dist/entity-schema.d.ts +1 -1
  185. package/dist/episodic-context.d.ts +1 -1
  186. package/dist/eval-trajectory-contracts.d.ts +1 -1
  187. package/dist/eval-trajectory-store.d.ts +1 -1
  188. package/dist/eval-trajectory.d.ts +1 -1
  189. package/dist/explicit-capture.d.ts +9 -9
  190. package/dist/external-wiki-access.d.ts +11 -11
  191. package/dist/external-wiki-access.js +23 -23
  192. package/dist/external-wiki-collection-registration.d.ts +1 -1
  193. package/dist/external-wiki-collection.d.ts +1 -1
  194. package/dist/external-wiki-mcp-tools.d.ts +11 -11
  195. package/dist/extraction-error-classification.d.ts +1 -1
  196. package/dist/extraction-faithfulness.d.ts +1 -1
  197. package/dist/extraction-judge-telemetry.d.ts +1 -1
  198. package/dist/extraction-judge-training.d.ts +1 -1
  199. package/dist/extraction-judge.d.ts +1 -1
  200. package/dist/extraction-liveness.d.ts +1 -1
  201. package/dist/extraction-normalization.d.ts +1 -1
  202. package/dist/extraction-prompt.d.ts +1 -1
  203. package/dist/extraction-source-grounding-rules.d.ts +1 -1
  204. package/dist/extraction-source-grounding.d.ts +1 -1
  205. package/dist/extraction.d.ts +1 -1
  206. package/dist/extraction.js +9 -9
  207. package/dist/fallback-llm.d.ts +1 -1
  208. package/dist/graph-dashboard-diff.d.ts +1 -1
  209. package/dist/graph-dashboard-key.d.ts +1 -1
  210. package/dist/graph-dashboard-parser.d.ts +1 -1
  211. package/dist/graph-edge-reinforcement.d.ts +1 -1
  212. package/dist/graph-path-reconstruction.d.ts +1 -1
  213. package/dist/graph-path-scoring.d.ts +1 -1
  214. package/dist/graph-snapshot.d.ts +1 -1
  215. package/dist/graph.d.ts +1 -1
  216. package/dist/harmonic-retrieval.js +1 -1
  217. package/dist/importance.d.ts +1 -1
  218. package/dist/importers/index.d.ts +1 -1
  219. package/dist/in-flight-reads.d.ts +1 -1
  220. package/dist/{index-D_pyMUaP.d.ts → index-DuJnzwHv.d.ts} +2 -2
  221. package/dist/index.d.ts +807 -698
  222. package/dist/index.js +130 -102
  223. package/dist/intent.d.ts +1 -1
  224. package/dist/lcm/engine.d.ts +1 -1
  225. package/dist/lcm/engine.js +4 -4
  226. package/dist/lcm/index.d.ts +1 -1
  227. package/dist/lcm/index.js +10 -10
  228. package/dist/lcm/tools.d.ts +1 -1
  229. package/dist/lifecycle.d.ts +1 -1
  230. package/dist/live-connectors-runner.d.ts +1 -1
  231. package/dist/local-llm.d.ts +1 -1
  232. package/dist/local-model-endpoint.d.ts +1 -1
  233. package/dist/location/index.d.ts +3 -3
  234. package/dist/location/index.js +11 -11
  235. package/dist/maintenance/memory-governance.d.ts +1 -1
  236. package/dist/maintenance/memory-governance.js +9 -9
  237. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
  238. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +9 -9
  239. package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
  240. package/dist/maintenance/rebuild-memory-projection.js +10 -10
  241. package/dist/{maintenance-DDUX9d6D.d.ts → maintenance-BBeaeYRR.d.ts} +3 -3
  242. package/dist/mcp-memory-inspector-app.d.ts +11 -11
  243. package/dist/memory-action-policy.d.ts +1 -1
  244. package/dist/memory-cache.d.ts +1 -1
  245. package/dist/memory-controller.d.ts +1 -1
  246. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  247. package/dist/memory-projection-store.d.ts +1 -1
  248. package/dist/memory-provenance.d.ts +1 -1
  249. package/dist/memory-snapshot.d.ts +1 -1
  250. package/dist/memory-subject-cli.d.ts +11 -11
  251. package/dist/memory-subject.d.ts +11 -11
  252. package/dist/memory-worth-outcomes.d.ts +2 -2
  253. package/dist/models-json.d.ts +1 -1
  254. package/dist/namespaces/migrate.d.ts +3 -3
  255. package/dist/namespaces/migrate.js +10 -10
  256. package/dist/namespaces/principal.d.ts +1 -1
  257. package/dist/namespaces/search.d.ts +1 -1
  258. package/dist/namespaces/search.js +5 -5
  259. package/dist/namespaces/storage.d.ts +3 -3
  260. package/dist/namespaces/storage.js +9 -9
  261. package/dist/native-knowledge.d.ts +1 -1
  262. package/dist/offline-sync-impression-drain.d.ts +1 -1
  263. package/dist/operator-doctor-corpus.d.ts +1 -1
  264. package/dist/operator-doctor-corpus.js +12 -12
  265. package/dist/operator-doctor-replica.d.ts +1 -1
  266. package/dist/operator-toolkit.d.ts +3 -3
  267. package/dist/operator-toolkit.js +19 -19
  268. package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
  269. package/dist/orchestration/maintenance.d.ts +4 -4
  270. package/dist/orchestration/maintenance.js +18 -18
  271. package/dist/{orchestrator-3F4jihCo.d.ts → orchestrator-CaqnwNwM.d.ts} +8 -8
  272. package/dist/orchestrator.d.ts +9 -9
  273. package/dist/orchestrator.js +86 -84
  274. package/dist/patterns-cli.d.ts +1 -1
  275. package/dist/{pipeline-CB1dj6Uh.d.ts → pipeline-CrxVjlJr.d.ts} +1 -1
  276. package/dist/policy-runtime.d.ts +1 -1
  277. package/dist/proactive-contention.d.ts +1 -1
  278. package/dist/provenance.d.ts +1 -1
  279. package/dist/{public-http-34-JIAGQ.d.ts → public-http-Cwvl4QZr.d.ts} +1 -1
  280. package/dist/{qmd-edLLZXc5.d.ts → qmd-BZgbJm0g.d.ts} +1 -1
  281. package/dist/qmd-preflight.d.ts +2 -2
  282. package/dist/qmd-recall-cache.d.ts +1 -1
  283. package/dist/qmd.d.ts +2 -2
  284. package/dist/recall-concurrency-config.d.ts +1 -1
  285. package/dist/recall-deep.d.ts +37 -0
  286. package/dist/recall-deep.js +81 -0
  287. package/dist/recall-deep.js.map +1 -0
  288. package/dist/recall-disclosure-escalation.d.ts +1 -1
  289. package/dist/recall-explain-renderer.d.ts +1 -1
  290. package/dist/recall-explain-renderer.js +3 -3
  291. package/dist/recall-memory-map.d.ts +1 -1
  292. package/dist/recall-navigate.d.ts +70 -0
  293. package/dist/recall-navigate.js +51 -0
  294. package/dist/recall-navigate.js.map +1 -0
  295. package/dist/recall-planner-llm.d.ts +1 -1
  296. package/dist/recall-state-view-wire.d.ts +14 -0
  297. package/dist/recall-state-view-wire.js +11 -0
  298. package/dist/recall-state-view-wire.js.map +1 -0
  299. package/dist/recall-state-view.d.ts +25 -0
  300. package/dist/recall-state-view.js +22 -0
  301. package/dist/recall-state-view.js.map +1 -0
  302. package/dist/recall-state.d.ts +1 -1
  303. package/dist/recall-tag-filter.d.ts +1 -1
  304. package/dist/recall-timings.d.ts +1 -1
  305. package/dist/recall-xray-cli.d.ts +1 -1
  306. package/dist/recall-xray-cli.js +4 -4
  307. package/dist/recall-xray-renderer.d.ts +1 -1
  308. package/dist/recall-xray-renderer.js +3 -3
  309. package/dist/recall-xray.d.ts +1 -1
  310. package/dist/recall-xray.js +2 -2
  311. package/dist/reconcile/cursor.d.ts +1 -1
  312. package/dist/reconcile/manifest.d.ts +1 -1
  313. package/dist/reconcile/plan.d.ts +1 -1
  314. package/dist/replay/normalizers/chatgpt.d.ts +1 -1
  315. package/dist/replay/normalizers/claude.d.ts +1 -1
  316. package/dist/replay/normalizers/openclaw.d.ts +1 -1
  317. package/dist/replay/normalizers/shared.d.ts +1 -1
  318. package/dist/replay/runner.d.ts +1 -1
  319. package/dist/replay/types.d.ts +1 -1
  320. package/dist/replica-divergence.d.ts +1 -1
  321. package/dist/replica-peers-config.d.ts +1 -1
  322. package/dist/resolve-auth-token.d.ts +1 -1
  323. package/dist/resume-bundles.js +3 -3
  324. package/dist/retrieval-agents.d.ts +2 -2
  325. package/dist/retrieval-tiers.d.ts +1 -1
  326. package/dist/routing/engine.d.ts +1 -1
  327. package/dist/routing/store.d.ts +1 -1
  328. package/dist/salvage-envelope.d.ts +1 -1
  329. package/dist/schemas.d.ts +152 -152
  330. package/dist/{scope-profiles-BF2lu81V.d.ts → scope-profiles-DFaojvoP.d.ts} +1 -1
  331. package/dist/search/embed-helper.d.ts +1 -1
  332. package/dist/search/factory.d.ts +1 -1
  333. package/dist/search/factory.js +4 -4
  334. package/dist/search/index.d.ts +1 -1
  335. package/dist/search/index.js +10 -10
  336. package/dist/search/lancedb-backend.d.ts +1 -1
  337. package/dist/search/meilisearch-backend.d.ts +1 -1
  338. package/dist/search/noop-backend.d.ts +1 -1
  339. package/dist/search/orama-backend.d.ts +1 -1
  340. package/dist/search/port.d.ts +1 -1
  341. package/dist/search/remote-backend.d.ts +1 -1
  342. package/dist/{semantic-consolidation-5OuWXBRt.d.ts → semantic-consolidation-BiX68wZA.d.ts} +1 -1
  343. package/dist/semantic-consolidation.d.ts +2 -2
  344. package/dist/semantic-consolidation.js +10 -10
  345. package/dist/semantic-rule-promotion.js +9 -9
  346. package/dist/semantic-rule-verifier.d.ts +1 -1
  347. package/dist/semantic-rule-verifier.js +9 -9
  348. package/dist/{service-CrqEhLXD.d.ts → service-D5h2zZ0M.d.ts} +2 -2
  349. package/dist/session-observer-bands.d.ts +1 -1
  350. package/dist/session-observer-state.d.ts +1 -1
  351. package/dist/shared-context/manager.d.ts +7 -7
  352. package/dist/signal.d.ts +1 -1
  353. package/dist/source-agent-qualifier.d.ts +1 -1
  354. package/dist/source-agent-qualifier.js +9 -9
  355. package/dist/{storage-BQn-xnxm.d.ts → storage-CtsaojWD.d.ts} +1 -1
  356. package/dist/storage.d.ts +2 -2
  357. package/dist/storage.js +8 -8
  358. package/dist/subject-config.d.ts +1 -1
  359. package/dist/summarizer.d.ts +1 -1
  360. package/dist/summary-snapshot.d.ts +1 -1
  361. package/dist/support-passport/index.d.ts +14 -14
  362. package/dist/support-passport/index.js +25 -25
  363. package/dist/temporal-supersession.d.ts +2 -2
  364. package/dist/temporal-timeline-recall.d.ts +1 -1
  365. package/dist/temporal-validity.d.ts +1 -1
  366. package/dist/threading.d.ts +1 -1
  367. package/dist/tier-migration.d.ts +2 -2
  368. package/dist/tier-routing.d.ts +1 -1
  369. package/dist/topics.d.ts +1 -1
  370. package/dist/transcript.d.ts +1 -1
  371. package/dist/transfer/capsule-export.js +2 -2
  372. package/dist/transfer/capsule-import.js +2 -2
  373. package/dist/transfer/export-okf.d.ts +1 -1
  374. package/dist/transfer/export-okf.js +10 -10
  375. package/dist/transfer/types.d.ts +78 -78
  376. package/dist/trust-score-stage.d.ts +1 -1
  377. package/dist/trust-score.d.ts +1 -1
  378. package/dist/{types-BRpcNjHZ.d.ts → types-CIpfYz1I.d.ts} +16 -11
  379. package/dist/types.d.ts +1 -1
  380. package/dist/types.js +1 -1
  381. package/dist/utility-runtime.d.ts +1 -1
  382. package/dist/verified-recall.js +9 -9
  383. package/dist/who-knows-cli.d.ts +11 -11
  384. package/dist/who-knows-cli.js +10 -10
  385. package/dist/who-knows.d.ts +11 -11
  386. package/dist/who-knows.js +9 -9
  387. package/dist/write-envelope.d.ts +1 -1
  388. package/package.json +2 -2
  389. package/src/activity/config.test.ts +1 -1
  390. package/src/activity/config.ts +48 -3
  391. package/src/activity/index.ts +2 -0
  392. package/src/activity/journal.test.ts +97 -0
  393. package/src/activity/journal.ts +113 -0
  394. package/src/activity/privacy.test.ts +53 -0
  395. package/src/activity/privacy.ts +80 -0
  396. package/src/activity/timeline/index.ts +2 -0
  397. package/src/activity/timeline/journal-recap.test.ts +113 -0
  398. package/src/activity/timeline/journal-recap.ts +130 -0
  399. package/src/activity/timeline/query.test.ts +198 -0
  400. package/src/activity/timeline/query.ts +313 -0
  401. package/src/activity/timeline/weekly.test.ts +215 -0
  402. package/src/activity/timeline/weekly.ts +234 -0
  403. package/src/activity/types.ts +14 -0
  404. package/src/activity/vault-publish.test.ts +166 -0
  405. package/src/activity/vault-publish.ts +101 -0
  406. package/src/config.test.ts +1 -1
  407. package/src/config.ts +2 -22
  408. package/src/dedup/merge-on-write.test.ts +91 -0
  409. package/src/dedup/merge-on-write.ts +75 -0
  410. package/src/dedup/novelty-gate.test.ts +143 -0
  411. package/src/dedup/novelty-gate.ts +163 -0
  412. package/src/location/recall-exclusion.test.ts +1 -0
  413. package/src/orchestration/extraction-persist.ts +22 -23
  414. package/src/orchestration/generic-recall-paths.ts +11 -0
  415. package/src/orchestration/recall-entry.ts +8 -3
  416. package/src/recall-deep.test.ts +72 -0
  417. package/src/recall-deep.ts +113 -0
  418. package/src/recall-navigate.test.ts +84 -0
  419. package/src/recall-navigate.ts +100 -0
  420. package/src/recall-state-view-wire.test.ts +35 -0
  421. package/src/recall-state-view-wire.ts +28 -0
  422. package/src/recall-state-view.test.ts +131 -0
  423. package/src/recall-state-view.ts +138 -0
  424. package/src/shared-context/governance.test.ts +53 -0
  425. package/src/shared-context/governance.ts +86 -0
  426. package/src/types.ts +3 -10
  427. package/dist/chunk-56IV4J5W.js.map +0 -1
  428. package/dist/chunk-IHGMRDEE.js.map +0 -1
  429. package/dist/chunk-KODXCHXJ.js.map +0 -1
  430. package/dist/chunk-PEBH5DCK.js.map +0 -1
  431. /package/dist/{chunk-J3OND5QT.js.map → chunk-2FA7U5XY.js.map} +0 -0
  432. /package/dist/{chunk-GEJKYA7D.js.map → chunk-2ITZ74A6.js.map} +0 -0
  433. /package/dist/{chunk-2LBAFHOQ.js.map → chunk-2X6BGKQL.js.map} +0 -0
  434. /package/dist/{chunk-4STAANV7.js.map → chunk-4XLTUR6R.js.map} +0 -0
  435. /package/dist/{chunk-FTTJRVB7.js.map → chunk-65JOGLIS.js.map} +0 -0
  436. /package/dist/{chunk-FESUGFIL.js.map → chunk-7UOXCCCI.js.map} +0 -0
  437. /package/dist/{chunk-6CEGSTBD.js.map → chunk-B4AOWRYF.js.map} +0 -0
  438. /package/dist/{chunk-FYWLSFFS.js.map → chunk-C5IUOBCN.js.map} +0 -0
  439. /package/dist/{chunk-FKKGCGYL.js.map → chunk-CHGG74CY.js.map} +0 -0
  440. /package/dist/{chunk-H7VDIF2V.js.map → chunk-CX4OLNIH.js.map} +0 -0
  441. /package/dist/{chunk-Z3YEGSR4.js.map → chunk-D3UXGE5D.js.map} +0 -0
  442. /package/dist/{chunk-7XOG75AU.js.map → chunk-D6Q5EPOV.js.map} +0 -0
  443. /package/dist/{chunk-MJRGVXPQ.js.map → chunk-EH65UV2Z.js.map} +0 -0
  444. /package/dist/{chunk-VQ4AMTGZ.js.map → chunk-EWKVYCFP.js.map} +0 -0
  445. /package/dist/{chunk-23CVL7HS.js.map → chunk-FFUMTH27.js.map} +0 -0
  446. /package/dist/{chunk-GX6FTSYH.js.map → chunk-GAJK3DQ5.js.map} +0 -0
  447. /package/dist/{chunk-O57GM3FR.js.map → chunk-GBEOUCBB.js.map} +0 -0
  448. /package/dist/{chunk-DMEHOEC7.js.map → chunk-H2IRSXZN.js.map} +0 -0
  449. /package/dist/{chunk-CFVTRUR3.js.map → chunk-H6RSANGQ.js.map} +0 -0
  450. /package/dist/{chunk-OAJMQKQR.js.map → chunk-IGZCAHFL.js.map} +0 -0
  451. /package/dist/{chunk-CN4VKV3S.js.map → chunk-INUBU6I5.js.map} +0 -0
  452. /package/dist/{chunk-CTCGHNWN.js.map → chunk-J2R275FN.js.map} +0 -0
  453. /package/dist/{chunk-2QSZNTDO.js.map → chunk-JBPKEARU.js.map} +0 -0
  454. /package/dist/{chunk-VQNRICAQ.js.map → chunk-JKTV3JNX.js.map} +0 -0
  455. /package/dist/{chunk-33MFRY25.js.map → chunk-KI64TTBL.js.map} +0 -0
  456. /package/dist/{chunk-VCKWULAK.js.map → chunk-KJXCD7VR.js.map} +0 -0
  457. /package/dist/{chunk-7LCGFUMB.js.map → chunk-KQAFEZQX.js.map} +0 -0
  458. /package/dist/{chunk-GSKINLAK.js.map → chunk-LJABGXC4.js.map} +0 -0
  459. /package/dist/{chunk-NPIBN2VL.js.map → chunk-LK4TOYPU.js.map} +0 -0
  460. /package/dist/{chunk-EZSCW4EM.js.map → chunk-LYUUA6QB.js.map} +0 -0
  461. /package/dist/{chunk-I5VB44ZK.js.map → chunk-M5ERTI4I.js.map} +0 -0
  462. /package/dist/{chunk-QCRJMU5V.js.map → chunk-NFP4KPTA.js.map} +0 -0
  463. /package/dist/{chunk-YXFCALVT.js.map → chunk-NSTNGMSS.js.map} +0 -0
  464. /package/dist/{chunk-L4X4PJYK.js.map → chunk-NUF7VSEX.js.map} +0 -0
  465. /package/dist/{chunk-IVIAHQBR.js.map → chunk-OJUEUQDJ.js.map} +0 -0
  466. /package/dist/{chunk-ZW4VXELZ.js.map → chunk-OMX6TKXH.js.map} +0 -0
  467. /package/dist/{chunk-EFQCDJZ2.js.map → chunk-QBNE55VA.js.map} +0 -0
  468. /package/dist/{chunk-6QDXA26G.js.map → chunk-RPIS5FQ7.js.map} +0 -0
  469. /package/dist/{chunk-HJXA6ZM7.js.map → chunk-S4CDUXQY.js.map} +0 -0
  470. /package/dist/{chunk-72OIT7KS.js.map → chunk-S4Z2OBTX.js.map} +0 -0
  471. /package/dist/{chunk-4FHRZD5T.js.map → chunk-SZMYGDSM.js.map} +0 -0
  472. /package/dist/{chunk-MAH64N55.js.map → chunk-TBCDF556.js.map} +0 -0
  473. /package/dist/{chunk-K66OY4EI.js.map → chunk-TCQRIIIN.js.map} +0 -0
  474. /package/dist/{chunk-KXIXO76C.js.map → chunk-U65VJSCJ.js.map} +0 -0
  475. /package/dist/{chunk-HNPE66LB.js.map → chunk-U6NGKS32.js.map} +0 -0
  476. /package/dist/{chunk-WKJFIMVN.js.map → chunk-UW4RYPWC.js.map} +0 -0
  477. /package/dist/{chunk-MN5NOOI7.js.map → chunk-VG4SSPAW.js.map} +0 -0
  478. /package/dist/{chunk-UNUMFURP.js.map → chunk-X5PIDJ3L.js.map} +0 -0
  479. /package/dist/{chunk-RZ3IZIJG.js.map → chunk-XOHYGIWF.js.map} +0 -0
  480. /package/dist/{chunk-6RUHELWR.js.map → chunk-YWPLOJ7T.js.map} +0 -0
  481. /package/dist/{chunk-ZJPM7GZ3.js.map → chunk-ZPS724LT.js.map} +0 -0
  482. /package/dist/{chunk-7UTDHQZ5.js.map → chunk-ZZZWEDF4.js.map} +0 -0
@@ -0,0 +1,234 @@
1
+ /**
2
+ * Deterministic weekly time/activity summary over timeline cards (issue #2052).
3
+ *
4
+ * Pure: cards + week bounds + category registry in, snapshot out. Half-open
5
+ * UTC [weekStart, weekEnd). Previous-period comparison is omitted in this
6
+ * slice and marked unavailable, never a silent zero. Later surfaces
7
+ * (CLI/MCP/HTTP/UI) consume this shape; they are not built here.
8
+ */
9
+ import { parseFlexibleIsoTimestamp } from "../../utils/iso-timestamp.js";
10
+ import { activityDayWindow, assertValidTimezone } from "../digest.js";
11
+ import type { TimelineCard, TimelineCardKind, TimelineCategory } from "./types.js";
12
+
13
+ export const WEEKLY_ACTIVITY_FORMAT_VERSION = 1;
14
+
15
+ export interface WeeklyActivityOptions {
16
+ timezone: string;
17
+ weekStartUtc: string;
18
+ weekEndUtc: string;
19
+ categories: readonly TimelineCategory[];
20
+ }
21
+
22
+ export interface WeeklyCategoryTotal {
23
+ categoryId: string;
24
+ durationMs: number;
25
+ }
26
+
27
+ export interface WeeklyKindTotals {
28
+ activeMs: number;
29
+ idleMs: number;
30
+ pauseMs: number;
31
+ gapMs: number;
32
+ unclassifiedMs: number;
33
+ }
34
+
35
+ export interface WeeklyDayTotal extends WeeklyKindTotals {
36
+ date: string;
37
+ startUtc: string;
38
+ endUtc: string;
39
+ categories: WeeklyCategoryTotal[];
40
+ }
41
+
42
+ /** First slice never computes a prior week; the field is present so callers cannot treat absence as zero. */
43
+ export interface WeeklyPreviousPeriodUnavailable {
44
+ available: false;
45
+ }
46
+
47
+ export interface WeeklyActivitySummary extends WeeklyKindTotals {
48
+ formatVersion: number;
49
+ timezone: string;
50
+ weekStartUtc: string;
51
+ weekEndUtc: string;
52
+ categories: WeeklyCategoryTotal[];
53
+ days: WeeklyDayTotal[];
54
+ previousPeriod: WeeklyPreviousPeriodUnavailable;
55
+ }
56
+
57
+ interface Acc extends WeeklyKindTotals {
58
+ byCategory: Map<string, number>;
59
+ intervals: Array<[number, number]>;
60
+ }
61
+
62
+ function parseBound(value: string, label: string): number {
63
+ const ms = parseFlexibleIsoTimestamp(value);
64
+ if (ms === null) {
65
+ throw new RangeError(`${label} is not a valid ISO timestamp`);
66
+ }
67
+ return ms;
68
+ }
69
+
70
+ function clip(start: number, end: number, winStart: number, winEnd: number): [number, number] | null {
71
+ const clippedStart = Math.max(start, winStart);
72
+ const clippedEnd = Math.min(end, winEnd);
73
+ return clippedEnd > clippedStart ? [clippedStart, clippedEnd] : null;
74
+ }
75
+
76
+ function unionDuration(intervals: readonly (readonly [number, number])[]): number {
77
+ const sorted = [...intervals].sort((a, b) => a[0] - b[0] || a[1] - b[1]);
78
+ let total = 0;
79
+ let curStart = Number.NaN;
80
+ let curEnd = Number.NaN;
81
+ for (const [start, end] of sorted) {
82
+ if (!Number.isFinite(curStart)) {
83
+ curStart = start;
84
+ curEnd = end;
85
+ continue;
86
+ }
87
+ if (start <= curEnd) {
88
+ curEnd = Math.max(curEnd, end);
89
+ continue;
90
+ }
91
+ total += curEnd - curStart;
92
+ curStart = start;
93
+ curEnd = end;
94
+ }
95
+ if (Number.isFinite(curStart)) total += curEnd - curStart;
96
+ return total;
97
+ }
98
+
99
+ function localDateOf(ms: number, timezone: string): string {
100
+ const parts = new Intl.DateTimeFormat("en-CA", {
101
+ timeZone: timezone,
102
+ year: "numeric",
103
+ month: "2-digit",
104
+ day: "2-digit",
105
+ }).formatToParts(new Date(ms));
106
+ const get = (type: string): string => parts.find((part) => part.type === type)?.value ?? "";
107
+ return `${get("year")}-${get("month")}-${get("day")}`;
108
+ }
109
+
110
+ function shiftIsoDate(date: string, days: number): string {
111
+ const parsed = new Date(`${date}T00:00:00Z`);
112
+ parsed.setUTCDate(parsed.getUTCDate() + days);
113
+ return parsed.toISOString().slice(0, 10);
114
+ }
115
+
116
+ function daysOverlappingWeek(
117
+ weekStartMs: number,
118
+ weekEndMs: number,
119
+ timezone: string,
120
+ ): Array<{ date: string; startMs: number; endMs: number }> {
121
+ if (weekEndMs <= weekStartMs) return [];
122
+ let date = localDateOf(weekStartMs, timezone);
123
+ let window = activityDayWindow(date, timezone);
124
+ if (Date.parse(window.startUtc) > weekStartMs) {
125
+ date = shiftIsoDate(date, -1);
126
+ window = activityDayWindow(date, timezone);
127
+ }
128
+ const days: Array<{ date: string; startMs: number; endMs: number }> = [];
129
+ while (Date.parse(window.startUtc) < weekEndMs) {
130
+ const startMs = Math.max(Date.parse(window.startUtc), weekStartMs);
131
+ const endMs = Math.min(Date.parse(window.endUtc), weekEndMs);
132
+ if (endMs > startMs) days.push({ date, startMs, endMs });
133
+ date = shiftIsoDate(date, 1);
134
+ window = activityDayWindow(date, timezone);
135
+ }
136
+ return days;
137
+ }
138
+
139
+ function emptyAcc(categoryIds: readonly string[]): Acc {
140
+ return {
141
+ activeMs: 0,
142
+ idleMs: 0,
143
+ pauseMs: 0,
144
+ gapMs: 0,
145
+ unclassifiedMs: 0,
146
+ byCategory: new Map(categoryIds.map((id) => [id, 0])),
147
+ intervals: [],
148
+ };
149
+ }
150
+
151
+ function addClipped(acc: Acc, kind: TimelineCardKind, categoryId: string, known: ReadonlySet<string>, start: number, end: number): void {
152
+ const duration = end - start;
153
+ acc.intervals.push([start, end]);
154
+ if (kind === "idle") acc.idleMs += duration;
155
+ else if (kind === "pause") acc.pauseMs += duration;
156
+ else acc.activeMs += duration;
157
+ if (known.has(categoryId)) {
158
+ acc.byCategory.set(categoryId, (acc.byCategory.get(categoryId) ?? 0) + duration);
159
+ } else {
160
+ acc.unclassifiedMs += duration;
161
+ }
162
+ }
163
+
164
+ function sortCategoryTotals(byCategory: Map<string, number>): WeeklyCategoryTotal[] {
165
+ return [...byCategory.entries()]
166
+ .map(([categoryId, durationMs]) => ({ categoryId, durationMs }))
167
+ .sort((a, b) => b.durationMs - a.durationMs || (a.categoryId < b.categoryId ? -1 : a.categoryId > b.categoryId ? 1 : 0));
168
+ }
169
+
170
+ function finish(acc: Acc, windowMs: number): WeeklyKindTotals & { categories: WeeklyCategoryTotal[] } {
171
+ const covered = unionDuration(acc.intervals);
172
+ return {
173
+ activeMs: acc.activeMs,
174
+ idleMs: acc.idleMs,
175
+ pauseMs: acc.pauseMs,
176
+ gapMs: Math.max(0, windowMs - covered),
177
+ unclassifiedMs: acc.unclassifiedMs,
178
+ categories: sortCategoryTotals(acc.byCategory),
179
+ };
180
+ }
181
+
182
+ /** Build a time/activity summary for one half-open week. Pure. */
183
+ export function buildWeeklyActivitySummary(
184
+ cards: readonly TimelineCard[],
185
+ options: WeeklyActivityOptions,
186
+ ): WeeklyActivitySummary {
187
+ assertValidTimezone(options.timezone);
188
+ const weekStartMs = parseBound(options.weekStartUtc, "weekStartUtc");
189
+ const weekEndMs = parseBound(options.weekEndUtc, "weekEndUtc");
190
+ if (weekStartMs > weekEndMs) {
191
+ throw new RangeError("reversed range: weekStartUtc must be <= weekEndUtc");
192
+ }
193
+
194
+ const categoryIds = options.categories.map((category) => category.id);
195
+ const known = new Set(categoryIds);
196
+ const week = emptyAcc(categoryIds);
197
+ const dayWindows = daysOverlappingWeek(weekStartMs, weekEndMs, options.timezone);
198
+ const dayAccs = dayWindows.map(() => emptyAcc(categoryIds));
199
+
200
+ for (const card of cards) {
201
+ const start = Date.parse(card.startUtc);
202
+ const end = Date.parse(card.endUtc);
203
+ if (!Number.isFinite(start) || !Number.isFinite(end) || end <= start) continue;
204
+ const weekClip = clip(start, end, weekStartMs, weekEndMs);
205
+ if (!weekClip) continue;
206
+ addClipped(week, card.kind, card.categoryId, known, weekClip[0], weekClip[1]);
207
+ for (let i = 0; i < dayWindows.length; i++) {
208
+ const day = dayWindows[i];
209
+ const dayClip = clip(start, end, day.startMs, day.endMs);
210
+ if (dayClip) addClipped(dayAccs[i], card.kind, card.categoryId, known, dayClip[0], dayClip[1]);
211
+ }
212
+ }
213
+
214
+ const weekTotals = finish(week, weekEndMs - weekStartMs);
215
+ const days: WeeklyDayTotal[] = dayWindows.map((day, i) => {
216
+ const totals = finish(dayAccs[i], day.endMs - day.startMs);
217
+ return {
218
+ date: day.date,
219
+ startUtc: new Date(day.startMs).toISOString(),
220
+ endUtc: new Date(day.endMs).toISOString(),
221
+ ...totals,
222
+ };
223
+ });
224
+
225
+ return {
226
+ formatVersion: WEEKLY_ACTIVITY_FORMAT_VERSION,
227
+ timezone: options.timezone,
228
+ weekStartUtc: new Date(weekStartMs).toISOString(),
229
+ weekEndUtc: new Date(weekEndMs).toISOString(),
230
+ ...weekTotals,
231
+ days,
232
+ previousPeriod: { available: false },
233
+ };
234
+ }
@@ -96,9 +96,23 @@ export interface ActivitySourceConfig {
96
96
  token?: string;
97
97
  }
98
98
 
99
+ /** Opt-in daily journal settings (issue #1984). Default off. */
100
+ export interface ActivityTimelineJournalConfig {
101
+ enabled: boolean;
102
+ }
103
+
104
+ /** Opt-in timeline Q&A range/search settings (issue #1983 PR1). Default off. */
105
+ export interface ActivityTimelineQaConfig {
106
+ enabled: boolean;
107
+ /** Inclusive max half-open range length in 24h days. Integer 1..366. */
108
+ maxRangeDays: number;
109
+ }
110
+
99
111
  /** Opt-in timeline-card derivation settings (issue #2049). Default off. */
100
112
  export interface ActivityTimelineConfig {
101
113
  enabled: boolean;
114
+ journal: ActivityTimelineJournalConfig;
115
+ qa: ActivityTimelineQaConfig;
102
116
  }
103
117
 
104
118
  /** Opt-in activity synchronization + trust-gated extraction settings. */
@@ -0,0 +1,166 @@
1
+ import assert from "node:assert/strict";
2
+ import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import path from "node:path";
5
+ import test from "node:test";
6
+
7
+ import { applyManagedRegion, publishVaultRegion } from "./vault-publish.js";
8
+
9
+ const START = "<!-- remnic:timeline:start -->";
10
+ const END = "<!-- remnic:timeline:end -->";
11
+
12
+ function withVault(fn: (vaultPath: string) => void): void {
13
+ const vaultPath = mkdtempSync(path.join(tmpdir(), "remnic-vault-"));
14
+ try {
15
+ fn(vaultPath);
16
+ } finally {
17
+ rmSync(vaultPath, { recursive: true, force: true });
18
+ }
19
+ }
20
+
21
+ test("applyManagedRegion replaces only the marked region", () => {
22
+ const fileText = [
23
+ "---",
24
+ "title: daily",
25
+ "---",
26
+ "",
27
+ "human notes",
28
+ START,
29
+ "old cards",
30
+ END,
31
+ "more human",
32
+ "",
33
+ ].join("\n");
34
+ const result = applyManagedRegion(fileText, {
35
+ strategy: "markers",
36
+ name: "timeline",
37
+ content: "new cards",
38
+ });
39
+ assert.equal(result.ok, true);
40
+ if (!result.ok) return;
41
+ assert.equal(
42
+ result.text,
43
+ [
44
+ "---",
45
+ "title: daily",
46
+ "---",
47
+ "",
48
+ "human notes",
49
+ START,
50
+ "new cards",
51
+ END,
52
+ "more human",
53
+ "",
54
+ ].join("\n"),
55
+ );
56
+ });
57
+
58
+ test("applyManagedRegion is a no-op when markers are missing", () => {
59
+ const fileText = "no managed region here\n";
60
+ const result = applyManagedRegion(fileText, {
61
+ strategy: "markers",
62
+ name: "timeline",
63
+ content: "new cards",
64
+ });
65
+ assert.deepEqual(result, { ok: false, reason: "no_marker", text: fileText });
66
+ });
67
+
68
+ test("applyManagedRegion preserves CRLF outside and inside the owned region", () => {
69
+ const fileText = [
70
+ "---",
71
+ "title: daily",
72
+ "---",
73
+ "",
74
+ "human notes",
75
+ START,
76
+ "old cards",
77
+ END,
78
+ "more human",
79
+ "",
80
+ ].join("\r\n");
81
+ const result = applyManagedRegion(fileText, {
82
+ strategy: "markers",
83
+ name: "timeline",
84
+ content: "new cards\nline two",
85
+ });
86
+ assert.equal(result.ok, true);
87
+ if (!result.ok) return;
88
+ assert.equal(
89
+ result.text,
90
+ [
91
+ "---",
92
+ "title: daily",
93
+ "---",
94
+ "",
95
+ "human notes",
96
+ START,
97
+ "new cards",
98
+ "line two",
99
+ END,
100
+ "more human",
101
+ "",
102
+ ].join("\r\n"),
103
+ );
104
+ assert.equal(result.text.includes("\n") && !result.text.includes("\r\n"), false);
105
+ });
106
+
107
+ test("applyManagedRegion keeps every outside byte identical", () => {
108
+ const prefix = "---\nkeep: me\n---\n\n- [ ] task\n```dataview\nLIST\n```\n";
109
+ const suffix = "\n<!-- other-agent:start -->\nleave this\n<!-- other-agent:end -->\n trailing \n";
110
+ const fileText = `${prefix}${START}\nold\n${END}${suffix}`;
111
+ const startAt = fileText.indexOf(START);
112
+ const endAt = fileText.indexOf(END);
113
+ const before = Buffer.from(fileText.slice(0, startAt + START.length), "utf8");
114
+ const after = Buffer.from(fileText.slice(endAt), "utf8");
115
+ const result = applyManagedRegion(fileText, {
116
+ strategy: "markers",
117
+ name: "timeline",
118
+ content: "replacement",
119
+ });
120
+ assert.equal(result.ok, true);
121
+ if (!result.ok) return;
122
+ const nextStart = result.text.indexOf(START);
123
+ const nextEnd = result.text.indexOf(END);
124
+ assert.deepEqual(Buffer.from(result.text.slice(0, nextStart + START.length), "utf8"), before);
125
+ assert.deepEqual(Buffer.from(result.text.slice(nextEnd), "utf8"), after);
126
+ });
127
+
128
+ test("publishVaultRegion updates an existing note and skips an unchanged rewrite", () => {
129
+ withVault((vaultPath) => {
130
+ const relativeFile = "Daily Notes/2026-08-17.md";
131
+ const dest = path.join(vaultPath, relativeFile);
132
+ mkdirSync(path.dirname(dest), { recursive: true });
133
+ writeFileSync(dest, `intro\n${START}\nold\n${END}\noutro\n`);
134
+ const first = publishVaultRegion({
135
+ vaultPath,
136
+ relativeFile,
137
+ name: "timeline",
138
+ content: "new cards",
139
+ });
140
+ assert.deepEqual(first, { ok: true, status: "updated" });
141
+ assert.equal(readFileSync(dest, "utf8"), `intro\n${START}\nnew cards\n${END}\noutro\n`);
142
+ const mtime = statSync(dest).mtimeMs;
143
+ const second = publishVaultRegion({
144
+ vaultPath,
145
+ relativeFile,
146
+ name: "timeline",
147
+ content: "new cards",
148
+ });
149
+ assert.deepEqual(second, { ok: true, status: "unchanged" });
150
+ assert.equal(statSync(dest).mtimeMs, mtime);
151
+ });
152
+ });
153
+
154
+ test("publishVaultRegion never creates a missing file", () => {
155
+ withVault((vaultPath) => {
156
+ const relativeFile = "missing.md";
157
+ const result = publishVaultRegion({
158
+ vaultPath,
159
+ relativeFile,
160
+ name: "timeline",
161
+ content: "new cards",
162
+ });
163
+ assert.deepEqual(result, { ok: false, reason: "missing_file" });
164
+ assert.equal(existsSync(path.join(vaultPath, relativeFile)), false);
165
+ });
166
+ });
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Managed-region vault publisher (issue #1985 first slice).
3
+ *
4
+ * Replaces only the bytes between `<!-- remnic:<name>:start -->` and
5
+ * `<!-- remnic:<name>:end -->`. Missing markers leave the file unchanged.
6
+ * `activity.timeline.vault.enabled` stays default-false until a later parse
7
+ * slice; this module does not read config.
8
+ */
9
+ import { createHash, randomBytes } from "node:crypto";
10
+ import { readFileSync, renameSync, statSync, unlinkSync, writeFileSync } from "node:fs";
11
+ import path from "node:path";
12
+
13
+ import { expandTildePath } from "../utils/path.js";
14
+
15
+ export type ApplyManagedRegionResult =
16
+ | { ok: true; text: string }
17
+ | { ok: false; reason: "no_marker"; text: string };
18
+
19
+ export type PublishVaultRegionResult =
20
+ | { ok: true; status: "updated" | "unchanged" }
21
+ | { ok: false; reason: "no_marker" | "missing_file" | "not_directory" };
22
+
23
+ export function applyManagedRegion(
24
+ fileText: string,
25
+ opts: { strategy: "markers"; name: string; content: string },
26
+ ): ApplyManagedRegionResult {
27
+ const startMarker = `<!-- remnic:${opts.name}:start -->`;
28
+ const endMarker = `<!-- remnic:${opts.name}:end -->`;
29
+ const startIdx = fileText.indexOf(startMarker);
30
+ if (startIdx === -1) return { ok: false, reason: "no_marker", text: fileText };
31
+ const endIdx = fileText.indexOf(endMarker, startIdx + startMarker.length);
32
+ if (endIdx === -1) return { ok: false, reason: "no_marker", text: fileText };
33
+
34
+ const eol = fileText.includes("\r\n") ? "\r\n" : "\n";
35
+ let body = opts.content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
36
+ if (eol === "\r\n") body = body.replace(/\n/g, "\r\n");
37
+ if (body.endsWith(eol)) body = body.slice(0, -eol.length);
38
+
39
+ return {
40
+ ok: true,
41
+ text: `${fileText.slice(0, startIdx + startMarker.length)}${eol}${body}${eol}${fileText.slice(endIdx)}`,
42
+ };
43
+ }
44
+
45
+ export function publishVaultRegion(input: {
46
+ vaultPath: string;
47
+ relativeFile: string;
48
+ name: string;
49
+ content: string;
50
+ }): PublishVaultRegionResult {
51
+ const vault = expandTildePath(input.vaultPath);
52
+ try {
53
+ if (!statSync(vault).isDirectory()) return { ok: false, reason: "not_directory" };
54
+ } catch {
55
+ return { ok: false, reason: "not_directory" };
56
+ }
57
+
58
+ if (input.relativeFile.length === 0 || path.isAbsolute(input.relativeFile)) {
59
+ return { ok: false, reason: "missing_file" };
60
+ }
61
+ const root = path.resolve(vault);
62
+ const dest = path.resolve(root, input.relativeFile);
63
+ const rel = path.relative(root, dest);
64
+ if (rel.length === 0 || rel.startsWith("..") || path.isAbsolute(rel)) {
65
+ return { ok: false, reason: "missing_file" };
66
+ }
67
+
68
+ let existing: string;
69
+ try {
70
+ if (!statSync(dest).isFile()) return { ok: false, reason: "missing_file" };
71
+ existing = readFileSync(dest, "utf8");
72
+ } catch (err) {
73
+ if ((err as NodeJS.ErrnoException).code === "ENOENT") return { ok: false, reason: "missing_file" };
74
+ throw err;
75
+ }
76
+
77
+ const applied = applyManagedRegion(existing, {
78
+ strategy: "markers",
79
+ name: input.name,
80
+ content: input.content,
81
+ });
82
+ if (!applied.ok) return { ok: false, reason: applied.reason };
83
+
84
+ const prevHash = createHash("sha256").update(existing, "utf8").digest("hex");
85
+ const nextHash = createHash("sha256").update(applied.text, "utf8").digest("hex");
86
+ if (prevHash === nextHash) return { ok: true, status: "unchanged" };
87
+
88
+ const tmpPath = path.join(path.dirname(dest), `.remnic-vault-${randomBytes(8).toString("hex")}.tmp`);
89
+ writeFileSync(tmpPath, applied.text);
90
+ try {
91
+ renameSync(tmpPath, dest);
92
+ } catch (renameErr) {
93
+ try {
94
+ unlinkSync(tmpPath);
95
+ } catch {
96
+ // temp cleanup is best-effort
97
+ }
98
+ throw renameErr;
99
+ }
100
+ return { ok: true, status: "updated" };
101
+ }
@@ -2569,7 +2569,7 @@ test("parseConfig forwards activity source settings", () => {
2569
2569
  minConfidence: 0.7,
2570
2570
  minImportance: "normal",
2571
2571
  maxMemoriesPerDay: 0,
2572
- timeline: { enabled: false },
2572
+ timeline: { enabled: false, journal: { enabled: false }, qa: { enabled: false, maxRangeDays: 31 } },
2573
2573
  });
2574
2574
  });
2575
2575
 
package/src/config.ts CHANGED
@@ -48,6 +48,7 @@ import { parseSkillProjectionConfig } from "./procedural/skill-projection.js";
48
48
  import { parseDriftDetectionConfig } from "./preferences/drift-config.js";
49
49
  import { parseContradictionLocalizationConfig, parseContradictionScanConfig } from "./contradiction-config.js";
50
50
  import { parseGraphPathScoringConfig } from "./graph-path-scoring-config.js";
51
+ import { parseWritePathDedupConfig } from "./dedup/novelty-gate.js";
51
52
  import { hasLegacyConnectorEntries } from "./connectors/paths.js";
52
53
  import {
53
54
  parseQmdChunkStrategy,
@@ -3190,28 +3191,7 @@ export function parseConfig(
3190
3191
 
3191
3192
  // v6.0 Fact deduplication & archival
3192
3193
  factDeduplicationEnabled: cfg.factDeduplicationEnabled !== false,
3193
- // Issue #373 — write-time semantic similarity guard
3194
- semanticDedupEnabled: cfg.semanticDedupEnabled !== false,
3195
- // Guard against NaN / Infinity — Number.isFinite rejects both and falls
3196
- // back to the documented default so the semantic dedup guard cannot be
3197
- // silently disabled by a malformed config value.
3198
- semanticDedupThreshold:
3199
- typeof cfg.semanticDedupThreshold === "number" &&
3200
- Number.isFinite(cfg.semanticDedupThreshold)
3201
- ? Math.min(1, Math.max(0, cfg.semanticDedupThreshold))
3202
- : 0.92,
3203
- // Zero is a valid "disable candidate lookup" signal and must be preserved.
3204
- // Only negative or non-finite values fall back to the default of 5.
3205
- // Fractional values in (0, 1) floor to 0, which would silently disable
3206
- // semantic dedup despite a clearly non-zero operator intent — clamp to 1.
3207
- semanticDedupCandidates: (() => {
3208
- const raw = cfg.semanticDedupCandidates;
3209
- if (typeof raw !== "number" || !Number.isFinite(raw) || raw < 0) return 5;
3210
- const n = Math.floor(raw);
3211
- // Positive fractional input (e.g. 0.5) should mean "at least 1 candidate",
3212
- // not "disabled". Only explicit 0 is the operator's disable signal.
3213
- return raw > 0 && n === 0 ? 1 : n;
3214
- })(),
3194
+ ...parseWritePathDedupConfig(cfg),
3215
3195
  factArchivalEnabled: cfg.factArchivalEnabled === true,
3216
3196
  factArchivalAgeDays:
3217
3197
  typeof cfg.factArchivalAgeDays === "number" ? cfg.factArchivalAgeDays : 90,
@@ -0,0 +1,91 @@
1
+ import assert from "node:assert/strict";
2
+ import { test } from "node:test";
3
+ import {
4
+ type MergeJudgeVerdict,
5
+ type MergeOnWritePair,
6
+ applyMergeOnWrite,
7
+ judgeMergeDecision,
8
+ shouldConsiderMerge,
9
+ } from "./merge-on-write.js";
10
+
11
+ function pair(overrides: Partial<MergeOnWritePair> = {}): MergeOnWritePair {
12
+ return {
13
+ category: "fact",
14
+ score: 0.85,
15
+ incomingContent: "User prefers dark mode on laptops.",
16
+ existingContent: "User likes dark mode.",
17
+ existingId: "mem-1",
18
+ ...overrides,
19
+ };
20
+ }
21
+
22
+ const mergeJudge = async () => "merge" as const;
23
+
24
+ test("merge-on-write: skip band is not considered", () => {
25
+ assert.equal(shouldConsiderMerge({ score: 0.92 }), false);
26
+ assert.equal(shouldConsiderMerge({ score: 0.99 }), false);
27
+ });
28
+
29
+ test("merge-on-write: merge band is considered", () => {
30
+ assert.equal(shouldConsiderMerge({ score: 0.8 }), true);
31
+ assert.equal(shouldConsiderMerge({ score: 0.85 }), true);
32
+ assert.equal(shouldConsiderMerge({ score: 0.919 }), true);
33
+ });
34
+
35
+ test("merge-on-write: score below mergeMin is not considered", () => {
36
+ assert.equal(shouldConsiderMerge({ score: 0.79 }), false);
37
+ });
38
+
39
+ test("merge-on-write: refused categories always create", async () => {
40
+ for (const category of ["procedure", "reasoning_trace", "moment", "correction"]) {
41
+ const decision = await applyMergeOnWrite({
42
+ enabled: true,
43
+ pair: pair({ category }),
44
+ judge: mergeJudge,
45
+ });
46
+ assert.equal(decision, "create", category);
47
+ }
48
+ });
49
+
50
+ test("merge-on-write: judge throw creates", async () => {
51
+ const viaJudge = await judgeMergeDecision(pair(), async () => {
52
+ throw new Error("timeout");
53
+ });
54
+ assert.equal(viaJudge, "create");
55
+
56
+ const viaApply = await applyMergeOnWrite({
57
+ enabled: true,
58
+ pair: pair(),
59
+ judge: async () => {
60
+ throw new Error("timeout");
61
+ },
62
+ });
63
+ assert.equal(viaApply, "create");
64
+ });
65
+
66
+ test("merge-on-write: uncertain judge creates", async () => {
67
+ const decision = await judgeMergeDecision(pair(), async (): Promise<MergeJudgeVerdict> => "uncertain");
68
+ assert.equal(decision, "create");
69
+ });
70
+
71
+ test("merge-on-write: disabled or mergeMin 0 creates", async () => {
72
+ let called = 0;
73
+ const judge = async () => {
74
+ called += 1;
75
+ return "merge" as const;
76
+ };
77
+
78
+ assert.equal(await applyMergeOnWrite({ pair: pair(), judge }), "create");
79
+ assert.equal(await applyMergeOnWrite({ enabled: false, pair: pair(), judge }), "create");
80
+ assert.equal(await applyMergeOnWrite({ enabled: true, mergeMin: 0, pair: pair(), judge }), "create");
81
+ assert.equal(called, 0);
82
+ });
83
+
84
+ test("merge-on-write: enabled in-band merge applies", async () => {
85
+ const decision = await applyMergeOnWrite({
86
+ enabled: true,
87
+ pair: pair(),
88
+ judge: mergeJudge,
89
+ });
90
+ assert.equal(decision, "merge");
91
+ });