@remnic/core 9.3.690 → 9.3.692

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 (294) hide show
  1. package/dist/access-boundary.d.ts +7 -6
  2. package/dist/access-boundary.js +21 -21
  3. package/dist/access-cli.js +49 -47
  4. package/dist/access-cli.js.map +1 -1
  5. package/dist/access-http.d.ts +7 -6
  6. package/dist/access-http.js +26 -26
  7. package/dist/access-mcp.d.ts +7 -6
  8. package/dist/access-mcp.js +23 -23
  9. package/dist/access-operations.d.ts +7 -6
  10. package/dist/access-operations.js +22 -22
  11. package/dist/{access-service-Dujr3MTm.d.ts → access-service-DvApf9LZ.d.ts} +2 -2
  12. package/dist/access-service.d.ts +7 -6
  13. package/dist/access-service.js +20 -20
  14. package/dist/access-surface-catalog.d.ts +7 -6
  15. package/dist/action-confidence.d.ts +1 -1
  16. package/dist/active-memory-bridge.d.ts +1 -1
  17. package/dist/active-recall.d.ts +1 -1
  18. package/dist/active-recall.js +1 -1
  19. package/dist/adapters/index.js +4 -4
  20. package/dist/adapters/registry.js +2 -2
  21. package/dist/{auto-sync-NUQWSFQD.js → auto-sync-RWXT6P5M.js} +5 -5
  22. package/dist/behavior-learner.d.ts +1 -1
  23. package/dist/behavior-signals.d.ts +1 -1
  24. package/dist/bootstrap.d.ts +6 -5
  25. package/dist/briefing.d.ts +1 -1
  26. package/dist/briefing.js +5 -5
  27. package/dist/buffer-surprise-report.d.ts +1 -1
  28. package/dist/buffer.d.ts +1 -1
  29. package/dist/calibration.d.ts +1 -1
  30. package/dist/calibration.js +2 -2
  31. package/dist/capabilities.d.ts +1 -1
  32. package/dist/{catalog-CKPtJ114.d.ts → catalog-BEWLjdOr.d.ts} +1 -1
  33. package/dist/causal-behavior.d.ts +1 -1
  34. package/dist/causal-consolidation.d.ts +1 -1
  35. package/dist/causal-consolidation.js +8 -8
  36. package/dist/{chunk-GTDH3IUH.js → chunk-2D27ODNX.js} +2 -2
  37. package/dist/{chunk-46URPRE6.js → chunk-2EN5WZQB.js} +2 -2
  38. package/dist/{chunk-3K37VPM3.js → chunk-3BRA3N5A.js} +2 -2
  39. package/dist/{chunk-RTFAZOIR.js → chunk-3VVH6ZQW.js} +2 -2
  40. package/dist/{chunk-ZU7N3S6V.js → chunk-4IQNAOP3.js} +6 -142
  41. package/dist/chunk-4IQNAOP3.js.map +1 -0
  42. package/dist/{chunk-FIVDN2SM.js → chunk-4RGWCRIJ.js} +4 -4
  43. package/dist/{chunk-AGJH5ISO.js → chunk-5KBNNUXS.js} +2 -2
  44. package/dist/{chunk-X7RLU5CR.js → chunk-66HROLW5.js} +2 -2
  45. package/dist/chunk-6C2BMUZA.js +444 -0
  46. package/dist/chunk-6C2BMUZA.js.map +1 -0
  47. package/dist/{chunk-TYF3D4MS.js → chunk-6ZNIUGXB.js} +11 -11
  48. package/dist/{chunk-UPIBE2DK.js → chunk-ADUAF5EV.js} +2 -2
  49. package/dist/{chunk-LLONI6PY.js → chunk-AFWEUTMS.js} +2 -2
  50. package/dist/{chunk-ZUDM75KG.js → chunk-DCWIQFNA.js} +4 -4
  51. package/dist/{chunk-OMKUJTVJ.js → chunk-DO7MDZMU.js} +4 -4
  52. package/dist/{chunk-NGFEWFNK.js → chunk-DQHZA7Y3.js} +1 -1
  53. package/dist/chunk-DQHZA7Y3.js.map +1 -0
  54. package/dist/{chunk-LXIEXSHU.js → chunk-E6BOD3UJ.js} +2 -2
  55. package/dist/{chunk-OBXTMFZQ.js → chunk-ECZPWSB5.js} +2 -2
  56. package/dist/{chunk-CWE74HRG.js → chunk-FM7KLRKN.js} +3 -3
  57. package/dist/{chunk-BFVPIKDY.js → chunk-GCOSQBQ2.js} +3 -3
  58. package/dist/chunk-HXNMDPHN.js +149 -0
  59. package/dist/chunk-HXNMDPHN.js.map +1 -0
  60. package/dist/{chunk-MDYG7VI7.js → chunk-IREVVFTM.js} +10 -1
  61. package/dist/{chunk-MDYG7VI7.js.map → chunk-IREVVFTM.js.map} +1 -1
  62. package/dist/{chunk-RKNJBZ55.js → chunk-JBPKEARU.js} +4 -4
  63. package/dist/{chunk-CP2NZQLT.js → chunk-KYH53EFD.js} +6 -6
  64. package/dist/{chunk-LQ6JI4VH.js → chunk-LD53WPMU.js} +4 -4
  65. package/dist/{chunk-SB6CQTKP.js → chunk-MCV2DD6F.js} +2 -2
  66. package/dist/{chunk-3FC6LW6T.js → chunk-MRFVMSTR.js} +2 -2
  67. package/dist/{chunk-WDXCNJSF.js → chunk-MXZWKOOR.js} +2 -2
  68. package/dist/{chunk-NSVXK7M5.js → chunk-NEILAC3H.js} +3 -3
  69. package/dist/{chunk-RGNEARXW.js → chunk-NUZ3N445.js} +7 -7
  70. package/dist/{chunk-WROKD3XC.js → chunk-O4ZIV62T.js} +35 -35
  71. package/dist/{chunk-PHZKALOE.js → chunk-QFG23CRE.js} +2 -2
  72. package/dist/{chunk-A4HH2EWA.js → chunk-QVG4LAQO.js} +2 -2
  73. package/dist/{chunk-54PVJDO5.js → chunk-SAC5V6JT.js} +2 -2
  74. package/dist/{chunk-XKUKJIOY.js → chunk-SEK4XIDN.js} +6 -6
  75. package/dist/{chunk-5CEJH5ZN.js → chunk-TAPSNIMA.js} +4 -4
  76. package/dist/{chunk-2N6UNJSX.js → chunk-U2OBZSGG.js} +2 -2
  77. package/dist/{chunk-BKAMHZYR.js → chunk-UOCLRM74.js} +2 -2
  78. package/dist/{chunk-A7UZR6RA.js → chunk-UTUYAPLY.js} +14 -1
  79. package/dist/chunk-UTUYAPLY.js.map +1 -0
  80. package/dist/{chunk-Z7KILAOU.js → chunk-V56S3A23.js} +19 -19
  81. package/dist/{chunk-CUNTLEJP.js → chunk-VFVG4NS2.js} +30 -9
  82. package/dist/chunk-VFVG4NS2.js.map +1 -0
  83. package/dist/{chunk-UD5OKH4J.js → chunk-W4ELOUNX.js} +2 -2
  84. package/dist/{chunk-CE6CBRCV.js → chunk-W4MICQIZ.js} +89 -407
  85. package/dist/chunk-W4MICQIZ.js.map +1 -0
  86. package/dist/{chunk-GR77Z2BM.js → chunk-WIKNVFBS.js} +2 -2
  87. package/dist/{chunk-WRFKZEO6.js → chunk-YQGHW5ML.js} +4 -4
  88. package/dist/{chunk-67MMWC74.js → chunk-ZLXGFAML.js} +2 -2
  89. package/dist/{cli-BkDp6WNi.d.ts → cli-BjsY9Le7.d.ts} +3 -3
  90. package/dist/cli.d.ts +8 -7
  91. package/dist/cli.js +45 -44
  92. package/dist/compounding/engine.d.ts +1 -1
  93. package/dist/compounding/engine.js +5 -5
  94. package/dist/compounding/preference-consolidator.d.ts +1 -1
  95. package/dist/compression-optimizer.d.ts +1 -1
  96. package/dist/config.d.ts +1 -1
  97. package/dist/config.js +1 -1
  98. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  99. package/dist/connectors/codex-materialize-runner.js +5 -5
  100. package/dist/connectors/codex-materialize.d.ts +1 -1
  101. package/dist/connectors/index.d.ts +1 -1
  102. package/dist/connectors/index.js +5 -5
  103. package/dist/consolidation-provenance-check.d.ts +1 -1
  104. package/dist/consolidation-undo.d.ts +1 -1
  105. package/dist/contradiction/index.d.ts +1 -1
  106. package/dist/conversation-index/backend.d.ts +1 -1
  107. package/dist/conversation-index/backend.js +2 -2
  108. package/dist/conversation-index/chunker.d.ts +1 -1
  109. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  110. package/dist/conversation-index/indexer.d.ts +1 -1
  111. package/dist/conversation-index/search.d.ts +1 -1
  112. package/dist/day-summary.d.ts +1 -1
  113. package/dist/delinearize.d.ts +1 -1
  114. package/dist/direct-answer-wiring.d.ts +1 -1
  115. package/dist/direct-answer.d.ts +1 -1
  116. package/dist/embedding-fallback.d.ts +1 -1
  117. package/dist/enrichment/index.d.ts +1 -1
  118. package/dist/entity-retrieval.d.ts +1 -1
  119. package/dist/entity-retrieval.js +5 -5
  120. package/dist/entity-schema.d.ts +1 -1
  121. package/dist/event-time.d.ts +35 -0
  122. package/dist/event-time.js +325 -0
  123. package/dist/event-time.js.map +1 -0
  124. package/dist/explicit-capture.d.ts +6 -5
  125. package/dist/extraction-judge-telemetry.d.ts +1 -1
  126. package/dist/extraction-judge-training.d.ts +1 -1
  127. package/dist/extraction-judge.d.ts +1 -1
  128. package/dist/extraction-judge.js +3 -3
  129. package/dist/extraction.d.ts +1 -1
  130. package/dist/extraction.js +3 -3
  131. package/dist/fallback-llm.d.ts +1 -1
  132. package/dist/fallback-llm.js +2 -2
  133. package/dist/identity-continuity.d.ts +1 -1
  134. package/dist/importance.d.ts +1 -1
  135. package/dist/index.d.ts +11 -10
  136. package/dist/index.js +77 -75
  137. package/dist/index.js.map +1 -1
  138. package/dist/intent.d.ts +1 -1
  139. package/dist/lcm/engine.d.ts +1 -1
  140. package/dist/lcm/index.d.ts +1 -1
  141. package/dist/lcm/tools.d.ts +1 -1
  142. package/dist/lifecycle.d.ts +1 -1
  143. package/dist/live-connectors-runner.d.ts +1 -1
  144. package/dist/local-llm.d.ts +1 -1
  145. package/dist/maintenance/memory-governance.d.ts +1 -1
  146. package/dist/maintenance/memory-governance.js +5 -5
  147. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +5 -5
  148. package/dist/maintenance/rebuild-memory-projection.js +6 -6
  149. package/dist/mcp-memory-inspector-app.d.ts +7 -6
  150. package/dist/memory-action-policy.d.ts +1 -1
  151. package/dist/memory-cache.d.ts +1 -1
  152. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  153. package/dist/memory-projection-store.d.ts +1 -1
  154. package/dist/memory-provenance.d.ts +1 -1
  155. package/dist/memory-worth-outcomes.d.ts +1 -1
  156. package/dist/models-json.d.ts +1 -1
  157. package/dist/namespaces/migrate.d.ts +2 -2
  158. package/dist/namespaces/migrate.js +15 -15
  159. package/dist/namespaces/principal.d.ts +1 -1
  160. package/dist/namespaces/search.d.ts +1 -1
  161. package/dist/namespaces/search.js +9 -9
  162. package/dist/namespaces/storage.d.ts +2 -2
  163. package/dist/namespaces/storage.js +5 -5
  164. package/dist/native-knowledge.d.ts +1 -1
  165. package/dist/operator-toolkit.d.ts +1 -1
  166. package/dist/operator-toolkit.js +20 -19
  167. package/dist/orchestration/maintenance.d.ts +112 -0
  168. package/dist/orchestration/maintenance.js +39 -0
  169. package/dist/orchestration/maintenance.js.map +1 -0
  170. package/dist/{orchestrator-B7ixmUkP.d.ts → orchestrator-CNJCYjZ1.d.ts} +12 -36
  171. package/dist/orchestrator.d.ts +5 -4
  172. package/dist/orchestrator.js +42 -40
  173. package/dist/patterns-cli.d.ts +1 -1
  174. package/dist/policy-runtime.d.ts +1 -1
  175. package/dist/provenance.d.ts +1 -1
  176. package/dist/qmd-recall-cache.d.ts +1 -1
  177. package/dist/qmd.d.ts +1 -1
  178. package/dist/recall-disclosure-escalation.d.ts +1 -1
  179. package/dist/recall-explain-renderer.d.ts +1 -1
  180. package/dist/recall-explain-renderer.js +3 -3
  181. package/dist/recall-planner-llm.d.ts +1 -1
  182. package/dist/recall-planner-llm.js +2 -2
  183. package/dist/recall-state.d.ts +1 -1
  184. package/dist/recall-tag-filter.d.ts +1 -1
  185. package/dist/recall-xray-cli.d.ts +1 -1
  186. package/dist/recall-xray-cli.js +4 -4
  187. package/dist/recall-xray-renderer.d.ts +1 -1
  188. package/dist/recall-xray-renderer.js +3 -3
  189. package/dist/recall-xray.d.ts +1 -1
  190. package/dist/recall-xray.js +2 -2
  191. package/dist/resolve-auth-token.d.ts +1 -1
  192. package/dist/resume-bundles.js +2 -2
  193. package/dist/retrieval-agents.d.ts +1 -1
  194. package/dist/retrieval-tiers.d.ts +1 -1
  195. package/dist/routing/engine.d.ts +1 -1
  196. package/dist/routing/store.d.ts +1 -1
  197. package/dist/search/embed-helper.d.ts +1 -1
  198. package/dist/search/factory.d.ts +1 -1
  199. package/dist/search/factory.js +8 -8
  200. package/dist/search/index.d.ts +1 -1
  201. package/dist/search/index.js +13 -13
  202. package/dist/search/lancedb-backend.d.ts +1 -1
  203. package/dist/search/lancedb-backend.js +2 -2
  204. package/dist/search/meilisearch-backend.d.ts +1 -1
  205. package/dist/search/meilisearch-backend.js +2 -2
  206. package/dist/search/noop-backend.d.ts +1 -1
  207. package/dist/search/orama-backend.d.ts +1 -1
  208. package/dist/search/orama-backend.js +2 -2
  209. package/dist/search/port.d.ts +1 -1
  210. package/dist/search/remote-backend.d.ts +1 -1
  211. package/dist/{semantic-consolidation-CWch5uM7.d.ts → semantic-consolidation-D5U0Mrdb.d.ts} +1 -1
  212. package/dist/semantic-consolidation.d.ts +2 -2
  213. package/dist/semantic-consolidation.js +6 -6
  214. package/dist/semantic-rule-promotion.js +5 -5
  215. package/dist/semantic-rule-verifier.d.ts +1 -1
  216. package/dist/semantic-rule-verifier.js +5 -5
  217. package/dist/session-observer-bands.d.ts +1 -1
  218. package/dist/session-observer-state.d.ts +1 -1
  219. package/dist/shared-context/manager.d.ts +1 -1
  220. package/dist/signal.d.ts +1 -1
  221. package/dist/storage.d.ts +3 -1
  222. package/dist/storage.js +4 -4
  223. package/dist/summarizer.d.ts +1 -1
  224. package/dist/summarizer.js +3 -3
  225. package/dist/summary-snapshot.d.ts +1 -1
  226. package/dist/temporal-supersession.d.ts +1 -1
  227. package/dist/temporal-supersession.js +2 -2
  228. package/dist/temporal-validity.d.ts +22 -2
  229. package/dist/temporal-validity.js +3 -1
  230. package/dist/threading.d.ts +1 -1
  231. package/dist/tier-migration.d.ts +1 -1
  232. package/dist/tier-routing.d.ts +1 -1
  233. package/dist/topics.d.ts +1 -1
  234. package/dist/transcript.d.ts +1 -1
  235. package/dist/{types-Dm5xxVrr.d.ts → types-2NoBoRBM.d.ts} +38 -0
  236. package/dist/types.d.ts +1 -1
  237. package/dist/types.js +1 -1
  238. package/dist/utility-runtime.d.ts +1 -1
  239. package/dist/verified-recall.js +5 -5
  240. package/package.json +12 -2
  241. package/src/bitemporal-frontmatter.test.ts +177 -0
  242. package/src/config.ts +13 -0
  243. package/src/event-time.test.ts +514 -0
  244. package/src/event-time.ts +548 -0
  245. package/src/orchestration/maintenance.test.ts +738 -0
  246. package/src/orchestration/maintenance.ts +557 -0
  247. package/src/orchestrator-flush.test.ts +0 -599
  248. package/src/orchestrator.ts +60 -420
  249. package/src/storage.ts +34 -0
  250. package/src/temporal-validity.ts +34 -0
  251. package/src/types.ts +38 -0
  252. package/dist/chunk-A7UZR6RA.js.map +0 -1
  253. package/dist/chunk-CE6CBRCV.js.map +0 -1
  254. package/dist/chunk-CUNTLEJP.js.map +0 -1
  255. package/dist/chunk-NGFEWFNK.js.map +0 -1
  256. package/dist/chunk-ZU7N3S6V.js.map +0 -1
  257. /package/dist/{auto-sync-NUQWSFQD.js.map → auto-sync-RWXT6P5M.js.map} +0 -0
  258. /package/dist/{chunk-GTDH3IUH.js.map → chunk-2D27ODNX.js.map} +0 -0
  259. /package/dist/{chunk-46URPRE6.js.map → chunk-2EN5WZQB.js.map} +0 -0
  260. /package/dist/{chunk-3K37VPM3.js.map → chunk-3BRA3N5A.js.map} +0 -0
  261. /package/dist/{chunk-RTFAZOIR.js.map → chunk-3VVH6ZQW.js.map} +0 -0
  262. /package/dist/{chunk-FIVDN2SM.js.map → chunk-4RGWCRIJ.js.map} +0 -0
  263. /package/dist/{chunk-AGJH5ISO.js.map → chunk-5KBNNUXS.js.map} +0 -0
  264. /package/dist/{chunk-X7RLU5CR.js.map → chunk-66HROLW5.js.map} +0 -0
  265. /package/dist/{chunk-TYF3D4MS.js.map → chunk-6ZNIUGXB.js.map} +0 -0
  266. /package/dist/{chunk-UPIBE2DK.js.map → chunk-ADUAF5EV.js.map} +0 -0
  267. /package/dist/{chunk-LLONI6PY.js.map → chunk-AFWEUTMS.js.map} +0 -0
  268. /package/dist/{chunk-ZUDM75KG.js.map → chunk-DCWIQFNA.js.map} +0 -0
  269. /package/dist/{chunk-OMKUJTVJ.js.map → chunk-DO7MDZMU.js.map} +0 -0
  270. /package/dist/{chunk-LXIEXSHU.js.map → chunk-E6BOD3UJ.js.map} +0 -0
  271. /package/dist/{chunk-OBXTMFZQ.js.map → chunk-ECZPWSB5.js.map} +0 -0
  272. /package/dist/{chunk-CWE74HRG.js.map → chunk-FM7KLRKN.js.map} +0 -0
  273. /package/dist/{chunk-BFVPIKDY.js.map → chunk-GCOSQBQ2.js.map} +0 -0
  274. /package/dist/{chunk-RKNJBZ55.js.map → chunk-JBPKEARU.js.map} +0 -0
  275. /package/dist/{chunk-CP2NZQLT.js.map → chunk-KYH53EFD.js.map} +0 -0
  276. /package/dist/{chunk-LQ6JI4VH.js.map → chunk-LD53WPMU.js.map} +0 -0
  277. /package/dist/{chunk-SB6CQTKP.js.map → chunk-MCV2DD6F.js.map} +0 -0
  278. /package/dist/{chunk-3FC6LW6T.js.map → chunk-MRFVMSTR.js.map} +0 -0
  279. /package/dist/{chunk-WDXCNJSF.js.map → chunk-MXZWKOOR.js.map} +0 -0
  280. /package/dist/{chunk-NSVXK7M5.js.map → chunk-NEILAC3H.js.map} +0 -0
  281. /package/dist/{chunk-RGNEARXW.js.map → chunk-NUZ3N445.js.map} +0 -0
  282. /package/dist/{chunk-WROKD3XC.js.map → chunk-O4ZIV62T.js.map} +0 -0
  283. /package/dist/{chunk-PHZKALOE.js.map → chunk-QFG23CRE.js.map} +0 -0
  284. /package/dist/{chunk-A4HH2EWA.js.map → chunk-QVG4LAQO.js.map} +0 -0
  285. /package/dist/{chunk-54PVJDO5.js.map → chunk-SAC5V6JT.js.map} +0 -0
  286. /package/dist/{chunk-XKUKJIOY.js.map → chunk-SEK4XIDN.js.map} +0 -0
  287. /package/dist/{chunk-5CEJH5ZN.js.map → chunk-TAPSNIMA.js.map} +0 -0
  288. /package/dist/{chunk-2N6UNJSX.js.map → chunk-U2OBZSGG.js.map} +0 -0
  289. /package/dist/{chunk-BKAMHZYR.js.map → chunk-UOCLRM74.js.map} +0 -0
  290. /package/dist/{chunk-Z7KILAOU.js.map → chunk-V56S3A23.js.map} +0 -0
  291. /package/dist/{chunk-UD5OKH4J.js.map → chunk-W4ELOUNX.js.map} +0 -0
  292. /package/dist/{chunk-GR77Z2BM.js.map → chunk-WIKNVFBS.js.map} +0 -0
  293. /package/dist/{chunk-WRFKZEO6.js.map → chunk-YQGHW5ML.js.map} +0 -0
  294. /package/dist/{chunk-67MMWC74.js.map → chunk-ZLXGFAML.js.map} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remnic/core",
3
- "version": "9.3.690",
3
+ "version": "9.3.692",
4
4
  "description": "Framework-agnostic Remnic memory engine — orchestrator, storage, extraction, search, trust zones",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1646,6 +1646,16 @@
1646
1646
  "remnic-source": "./src/orchestrator.ts",
1647
1647
  "import": "./dist/orchestrator.js"
1648
1648
  },
1649
+ "./orchestration/maintenance": {
1650
+ "types": "./dist/orchestration/maintenance.d.ts",
1651
+ "remnic-source": "./src/orchestration/maintenance.ts",
1652
+ "import": "./dist/orchestration/maintenance.js"
1653
+ },
1654
+ "./orchestration/maintenance.js": {
1655
+ "types": "./dist/orchestration/maintenance.d.ts",
1656
+ "remnic-source": "./src/orchestration/maintenance.ts",
1657
+ "import": "./dist/orchestration/maintenance.js"
1658
+ },
1649
1659
  "./page-versioning": {
1650
1660
  "types": "./dist/page-versioning.d.ts",
1651
1661
  "remnic-source": "./src/page-versioning.ts",
@@ -2931,7 +2941,7 @@
2931
2941
  "core"
2932
2942
  ],
2933
2943
  "peerDependencies": {
2934
- "@remnic/coding-graph": "^9.3.690"
2944
+ "@remnic/coding-graph": "^9.3.692"
2935
2945
  },
2936
2946
  "peerDependenciesMeta": {
2937
2947
  "@remnic/coding-graph": {
@@ -0,0 +1,177 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ import { mkdtemp, rm } from "node:fs/promises";
6
+
7
+ import { StorageManager } from "./storage.js";
8
+ import { isValidityExpiredNow } from "./temporal-validity.js";
9
+
10
+ /**
11
+ * Issue #1578 PR 1 — bi-temporal validity frontmatter round-trip + injection
12
+ * filter unit tests.
13
+ *
14
+ * These tests pin the on-disk contract added by #1578 (`observedAt`,
15
+ * `eventTimeSource`) AND prove the pre-existing temporal/lifecycle fields
16
+ * (`created`, `updated`, `source`, `valid_at`, `invalid_at`, `forgottenAt`)
17
+ * round-trip unchanged alongside them — i.e. the parser was not corrupted by
18
+ * the additive change. Every test goes through the public StorageManager API
19
+ * (`writeMemory` + `writeMemoryFrontmatter`, both of which route through the
20
+ * `serializeFrontmatter` chokepoint) so the serialize → parse round trip is
21
+ * exercised end to end.
22
+ *
23
+ * The injection filter (`isValidityExpiredNow`) is a pure function, so it is
24
+ * unit-tested directly with minimal frontmatter fragments.
25
+ */
26
+
27
+ const OBSERVED = "2026-06-20T14:02:11.000Z";
28
+ const VALID_FROM = "2026-03-01T00:00:00.000Z";
29
+ const VALID_UNTIL = "2026-06-15T00:00:00.000Z";
30
+
31
+ test("round-trip: observedAt + eventTimeSource + valid_at survive write → readAllMemories", async () => {
32
+ const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-bitemporal-rt-"));
33
+ try {
34
+ const storage = new StorageManager(dir);
35
+ await storage.ensureDirectories();
36
+
37
+ const id = await storage.writeMemory("fact", "We moved offices in March.", {
38
+ observedAt: OBSERVED,
39
+ eventTimeSource: "extracted",
40
+ validAt: VALID_FROM,
41
+ });
42
+
43
+ const memories = await storage.readAllMemories();
44
+ const written = memories.find((m) => m.frontmatter.id === id);
45
+ assert.ok(written, "fact must be discoverable after write");
46
+ assert.equal(written!.frontmatter.observedAt, OBSERVED);
47
+ assert.equal(written!.frontmatter.eventTimeSource, "extracted");
48
+ assert.equal(written!.frontmatter.valid_at, VALID_FROM);
49
+ // The auto-set baseline fields must remain present and well-formed.
50
+ assert.ok(typeof written!.frontmatter.created === "string" && written!.frontmatter.created!.length > 0);
51
+ assert.ok(typeof written!.frontmatter.updated === "string" && written!.frontmatter.updated!.length > 0);
52
+ assert.equal(written!.frontmatter.source, "extraction");
53
+ } finally {
54
+ await rm(dir, { recursive: true, force: true });
55
+ }
56
+ });
57
+
58
+ test("round-trip: invalid_at + forgottenAt coexist with observedAt/eventTimeSource (parser not corrupted)", async () => {
59
+ // Exercises the full serialize→parse round trip through the
60
+ // writeMemoryFrontmatter chokepoint for the fields writeMemory does not
61
+ // accept as options (invalid_at, forgottenAt). This is the direct
62
+ // regression guard for the "frontmatter parser corruption" risk: every
63
+ // pre-existing field must survive alongside the new bi-temporal fields,
64
+ // with no field dropped or duplicated.
65
+ const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-bitemporal-coexist-"));
66
+ try {
67
+ const storage = new StorageManager(dir);
68
+ await storage.ensureDirectories();
69
+
70
+ const id = await storage.writeMemory("fact", "Old stack was Node 18.", {
71
+ observedAt: OBSERVED,
72
+ eventTimeSource: "assumed",
73
+ validAt: VALID_FROM,
74
+ });
75
+
76
+ const before = await storage.readAllMemories();
77
+ const memory = before.find((m) => m.frontmatter.id === id);
78
+ assert.ok(memory);
79
+
80
+ const ok = await storage.writeMemoryFrontmatter(memory!, {
81
+ invalid_at: VALID_UNTIL,
82
+ forgottenAt: "2026-07-01T00:00:00.000Z",
83
+ });
84
+ assert.equal(ok, true);
85
+
86
+ const after = await storage.readAllMemories();
87
+ const patched = after.find((m) => m.frontmatter.id === id);
88
+ assert.ok(patched, "patched fact must be readable");
89
+ const fm = patched!.frontmatter;
90
+ // New bi-temporal fields.
91
+ assert.equal(fm.observedAt, OBSERVED);
92
+ assert.equal(fm.eventTimeSource, "assumed");
93
+ // Pre-existing temporal/lifecycle fields — all present, correct values.
94
+ assert.equal(fm.valid_at, VALID_FROM);
95
+ assert.equal(fm.invalid_at, VALID_UNTIL);
96
+ assert.equal(fm.forgottenAt, "2026-07-01T00:00:00.000Z");
97
+ // Baseline identity fields untouched by the patch.
98
+ assert.ok(typeof fm.created === "string" && fm.created!.length > 0);
99
+ assert.ok(typeof fm.source === "string" && fm.source!.length > 0);
100
+ } finally {
101
+ await rm(dir, { recursive: true, force: true });
102
+ }
103
+ });
104
+
105
+ test("legacy memory without bi-temporal fields reads cleanly — observedAt/eventTimeSource undefined", async () => {
106
+ const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-bitemporal-legacy-"));
107
+ try {
108
+ const storage = new StorageManager(dir);
109
+ await storage.ensureDirectories();
110
+
111
+ const id = await storage.writeMemory("fact", "Legacy fact pre-dating #1578.");
112
+
113
+ const memories = await storage.readAllMemories();
114
+ const written = memories.find((m) => m.frontmatter.id === id);
115
+ assert.ok(written);
116
+ assert.equal(written!.frontmatter.observedAt, undefined);
117
+ assert.equal(written!.frontmatter.eventTimeSource, undefined);
118
+ } finally {
119
+ await rm(dir, { recursive: true, force: true });
120
+ }
121
+ });
122
+
123
+ test("garbage observedAt is rejected on write — corrupt timestamps cannot leak to disk", async () => {
124
+ const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-bitemporal-reject-"));
125
+ try {
126
+ const storage = new StorageManager(dir);
127
+ await storage.ensureDirectories();
128
+
129
+ await assert.rejects(
130
+ () => storage.writeMemory("fact", "Bad observedAt.", { observedAt: "not-a-timestamp" }),
131
+ /observedAt must be a valid ISO timestamp/,
132
+ );
133
+ } finally {
134
+ await rm(dir, { recursive: true, force: true });
135
+ }
136
+ });
137
+
138
+ test("isValidityExpiredNow: absent invalid_at → never expired (still valid)", () => {
139
+ assert.equal(isValidityExpiredNow({ invalid_at: undefined }, Date.now()), false);
140
+ assert.equal(isValidityExpiredNow({ invalid_at: "" }, Date.now()), false);
141
+ });
142
+
143
+ test("isValidityExpiredNow: invalid_at in the past → expired (interval ended)", () => {
144
+ const now = Date.parse("2026-06-20T00:00:00.000Z");
145
+ assert.equal(
146
+ isValidityExpiredNow({ invalid_at: "2026-06-15T00:00:00.000Z" }, now),
147
+ true,
148
+ );
149
+ });
150
+
151
+ test("isValidityExpiredNow: invalid_at in the future → not expired (still within window)", () => {
152
+ const now = Date.parse("2026-06-20T00:00:00.000Z");
153
+ assert.equal(
154
+ isValidityExpiredNow({ invalid_at: "2026-12-31T00:00:00.000Z" }, now),
155
+ false,
156
+ );
157
+ });
158
+
159
+ test("isValidityExpiredNow: exclusive end — invalid_at == now is EXPIRED ([from, until) ended)", () => {
160
+ const boundary = Date.parse("2026-06-15T00:00:00.000Z");
161
+ // At the exact exclusive boundary the interval has ended.
162
+ assert.equal(
163
+ isValidityExpiredNow({ invalid_at: "2026-06-15T00:00:00.000Z" }, boundary),
164
+ true,
165
+ );
166
+ });
167
+
168
+ test("isValidityExpiredNow: status-orthogonal — considers invalid_at only, ignores status", () => {
169
+ // The filter must be status-orthogonal (issue pitfall matrix): an `active`
170
+ // memory can be validity-expired. isValidityExpiredNow only receives the
171
+ // invalid_at field, so status never enters the decision.
172
+ const now = Date.parse("2026-06-20T00:00:00.000Z");
173
+ assert.equal(
174
+ isValidityExpiredNow({ invalid_at: "2026-06-15T00:00:00.000Z" }, now),
175
+ true,
176
+ );
177
+ });
package/src/config.ts CHANGED
@@ -2084,6 +2084,19 @@ export function parseConfig(
2084
2084
  temporalSupersessionEnabled: cfg.temporalSupersessionEnabled !== false, // On by default
2085
2085
  temporalSupersessionIncludeInRecall:
2086
2086
  cfg.temporalSupersessionIncludeInRecall === true, // Off by default
2087
+ // Bi-temporal validity (issue #1578). Default `false` so recall behaves
2088
+ // byte-identically to pre-#1578 until an operator opts in. Uses coerceBool
2089
+ // (same as recallDirectAnswerEnabled below) so CLI string "true" works.
2090
+ //
2091
+ // CURRENT scope (this PR): the recall injection filter (expired-validity
2092
+ // facts leave default injection but stay findable by explicit search and
2093
+ // as_of queries) + the observedAt/eventTimeSource storage fields. The
2094
+ // extraction prompt → resolveEventTime write-time wiring lands in a
2095
+ // follow-on PR; until then, enabling the gate exercises the filter and
2096
+ // storage round-trip but new extractions are not yet event-time-resolved
2097
+ // (docs kept honest — review: wire resolver before exposing the gate).
2098
+ temporalBiTemporal: coerceBool(cfg.temporalBiTemporal) ?? false,
2099
+ temporalExpiredInInjection: coerceBool(cfg.temporalExpiredInInjection) ?? false,
2087
2100
  // Direct-answer retrieval tier (issue #518). Default off so the
2088
2101
  // recall path keeps least-privileged behavior unless operators
2089
2102
  // explicitly opt in.