@remnic/core 9.3.722 → 9.3.724

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 (268) hide show
  1. package/dist/access-boundary.d.ts +6 -11
  2. package/dist/access-boundary.js +9 -9
  3. package/dist/access-cli.js +29 -23
  4. package/dist/access-cli.js.map +1 -1
  5. package/dist/access-http.d.ts +5 -5
  6. package/dist/access-http.js +19 -14
  7. package/dist/access-mcp.d.ts +5 -5
  8. package/dist/access-mcp.js +18 -13
  9. package/dist/access-operations-batch.js +16 -10
  10. package/dist/access-operations.d.ts +5 -5
  11. package/dist/access-operations.js +17 -11
  12. package/dist/{access-service-Dj3I-VBS.d.ts → access-service-B2PlPtxh.d.ts} +3 -3
  13. package/dist/access-service.d.ts +5 -5
  14. package/dist/access-service.js +8 -8
  15. package/dist/access-surface-catalog.d.ts +5 -5
  16. package/dist/access-surface-catalog.js +82 -82
  17. package/dist/access-surface-catalog.js.map +1 -1
  18. package/dist/action-confidence.d.ts +1 -1
  19. package/dist/active-memory-bridge.d.ts +1 -1
  20. package/dist/active-recall.d.ts +1 -1
  21. package/dist/behavior-learner.d.ts +1 -1
  22. package/dist/behavior-signals.d.ts +1 -1
  23. package/dist/bootstrap.d.ts +4 -4
  24. package/dist/briefing.d.ts +1 -1
  25. package/dist/briefing.js +3 -3
  26. package/dist/buffer-surprise-report.d.ts +1 -1
  27. package/dist/buffer.d.ts +1 -1
  28. package/dist/calibration.d.ts +1 -1
  29. package/dist/capabilities.d.ts +1 -1
  30. package/dist/{catalog-F-OEVbRQ.d.ts → catalog-CzUb-GyD.d.ts} +1 -1
  31. package/dist/causal-behavior.d.ts +1 -1
  32. package/dist/causal-consolidation.d.ts +1 -1
  33. package/dist/causal-consolidation.js +4 -4
  34. package/dist/causal-trajectory-graph.d.ts +1 -1
  35. package/dist/{chunk-EVPNWN7Z.js → chunk-4R3CGCI5.js} +2 -2
  36. package/dist/{chunk-UO5ZHIIH.js → chunk-4WZ3J7M6.js} +2 -2
  37. package/dist/{chunk-PD42EYQN.js → chunk-5OPYYPJN.js} +2 -2
  38. package/dist/{chunk-EEJMD2L2.js → chunk-6CWGS2LY.js} +2 -2
  39. package/dist/{chunk-7CTNUVHZ.js → chunk-6SQQOJ4U.js} +2 -2
  40. package/dist/{chunk-ILFSEIRT.js → chunk-7AG54AF3.js} +1 -1
  41. package/dist/{chunk-ILFSEIRT.js.map → chunk-7AG54AF3.js.map} +1 -1
  42. package/dist/{chunk-UIXXE6NI.js → chunk-C6BWLYW5.js} +24 -15
  43. package/dist/chunk-C6BWLYW5.js.map +1 -0
  44. package/dist/{chunk-A5XNBK2D.js → chunk-DF3I6JGP.js} +6 -6
  45. package/dist/{chunk-GJSL4WG2.js → chunk-F3XZN24Z.js} +2 -2
  46. package/dist/{chunk-J3JPB7ZI.js → chunk-FACTVMXQ.js} +2 -2
  47. package/dist/{chunk-B7WISIAJ.js → chunk-FN6QP7JQ.js} +154 -1067
  48. package/dist/chunk-FN6QP7JQ.js.map +1 -0
  49. package/dist/{chunk-EBDA5TYA.js → chunk-FXCIOLRB.js} +2 -2
  50. package/dist/{chunk-TXQCG6SE.js → chunk-H7HUQIY7.js} +3 -3
  51. package/dist/{chunk-QD6QP5P6.js → chunk-I2HL5M6T.js} +17 -17
  52. package/dist/{chunk-M7R5R6OJ.js → chunk-IAIPNEHD.js} +20 -2
  53. package/dist/{chunk-M7R5R6OJ.js.map → chunk-IAIPNEHD.js.map} +1 -1
  54. package/dist/{chunk-Z4RU5VPM.js → chunk-J334N6QV.js} +2 -2
  55. package/dist/{chunk-NXRUUDUF.js → chunk-JJJCVCCQ.js} +2 -2
  56. package/dist/{chunk-GDUOCHCD.js → chunk-KGZF2VO3.js} +10 -10
  57. package/dist/{chunk-LA3HZKES.js → chunk-KLFYKC3K.js} +448 -49
  58. package/dist/chunk-KLFYKC3K.js.map +1 -0
  59. package/dist/{chunk-LLUGAZ3B.js → chunk-NT36GU6X.js} +30 -4
  60. package/dist/chunk-NT36GU6X.js.map +1 -0
  61. package/dist/{chunk-OHTOPFRF.js → chunk-SC2YAWRF.js} +2 -2
  62. package/dist/{chunk-YEE5KJQQ.js → chunk-T55EGZSJ.js} +2 -2
  63. package/dist/{chunk-N77ELJ2D.js → chunk-TT5U3UDO.js} +4 -4
  64. package/dist/{chunk-6FAMMBQ3.js → chunk-UBHVAGO7.js} +2 -2
  65. package/dist/chunk-VI5SGGXB.js +420 -0
  66. package/dist/chunk-VI5SGGXB.js.map +1 -0
  67. package/dist/{chunk-EDOQM4E4.js → chunk-WAFDHKES.js} +2 -2
  68. package/dist/{chunk-EXUCUPV2.js → chunk-WM7DNKBD.js} +2 -2
  69. package/dist/{dreams-ledger-3WSCI5V4.js → chunk-YF6FMLBT.js} +5 -6
  70. package/dist/{dreams-ledger-3WSCI5V4.js.map → chunk-YF6FMLBT.js.map} +1 -1
  71. package/dist/{chunk-WQYSDPMA.js → chunk-YQMPUYHE.js} +2 -2
  72. package/dist/{chunk-5O42UKXI.js → chunk-YUYPWJD3.js} +2 -2
  73. package/dist/{chunk-VCLGUIFM.js → chunk-Z3FGC3QE.js} +2 -2
  74. package/dist/{chunk-A7TJZLPK.js → chunk-ZK2L72VN.js} +2 -2
  75. package/dist/{chunk-BXEOHV7K.js → chunk-ZOHMPFOB.js} +3 -3
  76. package/dist/{graph-edge-decay-QPRJQ7DL.js → chunk-ZQNCHPTZ.js} +4 -5
  77. package/dist/{graph-edge-decay-QPRJQ7DL.js.map → chunk-ZQNCHPTZ.js.map} +1 -1
  78. package/dist/{cli-P_GaYcCY.d.ts → cli-IOlDHSBT.d.ts} +3 -3
  79. package/dist/cli.d.ts +6 -6
  80. package/dist/cli.js +31 -26
  81. package/dist/compounding/engine.d.ts +1 -1
  82. package/dist/compounding/engine.js +3 -3
  83. package/dist/compounding/preference-consolidator.d.ts +1 -1
  84. package/dist/compression-optimizer.d.ts +1 -1
  85. package/dist/config.d.ts +1 -1
  86. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  87. package/dist/connectors/codex-materialize-runner.js +3 -3
  88. package/dist/connectors/codex-materialize.d.ts +1 -1
  89. package/dist/connectors/index.d.ts +1 -1
  90. package/dist/connectors/index.js +3 -3
  91. package/dist/consolidation-provenance-check.d.ts +1 -1
  92. package/dist/consolidation-undo.d.ts +1 -1
  93. package/dist/contradiction/index.d.ts +1 -1
  94. package/dist/conversation-index/backend.d.ts +1 -1
  95. package/dist/conversation-index/chunker.d.ts +1 -1
  96. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  97. package/dist/conversation-index/indexer.d.ts +1 -1
  98. package/dist/conversation-index/search.d.ts +1 -1
  99. package/dist/day-summary.d.ts +1 -1
  100. package/dist/delinearize.d.ts +1 -1
  101. package/dist/direct-answer-wiring.d.ts +1 -1
  102. package/dist/direct-answer.d.ts +1 -1
  103. package/dist/dreams-ledger-6UODQOX6.js +22 -0
  104. package/dist/dreams-ledger-6UODQOX6.js.map +1 -0
  105. package/dist/embedding-fallback.d.ts +1 -1
  106. package/dist/enrichment/index.d.ts +1 -1
  107. package/dist/entity-retrieval.d.ts +1 -1
  108. package/dist/entity-retrieval.js +3 -3
  109. package/dist/entity-schema.d.ts +1 -1
  110. package/dist/event-time.d.ts +33 -1
  111. package/dist/event-time.js +3 -1
  112. package/dist/explicit-capture.d.ts +4 -4
  113. package/dist/extraction-faithfulness.d.ts +1 -1
  114. package/dist/extraction-judge-telemetry.d.ts +1 -1
  115. package/dist/extraction-judge-training.d.ts +1 -1
  116. package/dist/extraction-judge.d.ts +1 -1
  117. package/dist/extraction.d.ts +1 -1
  118. package/dist/fallback-llm.d.ts +1 -1
  119. package/dist/graph-dashboard-diff.d.ts +1 -1
  120. package/dist/graph-dashboard-key.d.ts +1 -1
  121. package/dist/graph-dashboard-parser.d.ts +1 -1
  122. package/dist/graph-edge-decay-RXUCJIN4.js +22 -0
  123. package/dist/graph-edge-decay-RXUCJIN4.js.map +1 -0
  124. package/dist/graph-edge-reinforcement.d.ts +1 -1
  125. package/dist/graph-snapshot.d.ts +1 -1
  126. package/dist/graph.d.ts +1 -1
  127. package/dist/identity-continuity.d.ts +1 -1
  128. package/dist/importance.d.ts +1 -1
  129. package/dist/index.d.ts +9 -9
  130. package/dist/index.js +58 -56
  131. package/dist/index.js.map +1 -1
  132. package/dist/intent.d.ts +1 -1
  133. package/dist/lcm/engine.d.ts +1 -1
  134. package/dist/lcm/index.d.ts +1 -1
  135. package/dist/lcm/tools.d.ts +1 -1
  136. package/dist/lifecycle.d.ts +1 -1
  137. package/dist/live-connectors-runner.d.ts +1 -1
  138. package/dist/local-llm.d.ts +1 -1
  139. package/dist/local-model-endpoint.d.ts +1 -1
  140. package/dist/maintenance/memory-governance.d.ts +1 -1
  141. package/dist/maintenance/memory-governance.js +3 -3
  142. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -3
  143. package/dist/maintenance/rebuild-memory-projection.js +4 -4
  144. package/dist/mcp-memory-inspector-app.d.ts +5 -5
  145. package/dist/memory-action-policy.d.ts +1 -1
  146. package/dist/memory-cache.d.ts +1 -1
  147. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  148. package/dist/memory-projection-store.d.ts +1 -1
  149. package/dist/memory-provenance.d.ts +1 -1
  150. package/dist/memory-worth-outcomes.d.ts +1 -1
  151. package/dist/models-json.d.ts +1 -1
  152. package/dist/namespaces/migrate.d.ts +2 -2
  153. package/dist/namespaces/migrate.js +4 -4
  154. package/dist/namespaces/principal.d.ts +1 -1
  155. package/dist/namespaces/search.d.ts +1 -1
  156. package/dist/namespaces/storage.d.ts +2 -2
  157. package/dist/namespaces/storage.js +3 -3
  158. package/dist/native-knowledge.d.ts +1 -1
  159. package/dist/operator-toolkit.d.ts +1 -1
  160. package/dist/operator-toolkit.js +8 -8
  161. package/dist/orchestration/maintenance.d.ts +2 -2
  162. package/dist/orchestration/maintenance.js +5 -5
  163. package/dist/{orchestrator-f5xv19kp.d.ts → orchestrator-C_OMSIMZ.d.ts} +34 -3
  164. package/dist/orchestrator.d.ts +4 -4
  165. package/dist/orchestrator.js +17 -17
  166. package/dist/patterns-cli.d.ts +1 -1
  167. package/dist/policy-runtime.d.ts +1 -1
  168. package/dist/provenance.d.ts +1 -1
  169. package/dist/qmd-recall-cache.d.ts +1 -1
  170. package/dist/qmd.d.ts +1 -1
  171. package/dist/recall-disclosure-escalation.d.ts +1 -1
  172. package/dist/recall-explain-renderer.d.ts +1 -1
  173. package/dist/recall-explain-renderer.js +3 -3
  174. package/dist/recall-planner-llm.d.ts +1 -1
  175. package/dist/recall-state.d.ts +1 -1
  176. package/dist/recall-tag-filter.d.ts +1 -1
  177. package/dist/recall-xray-cli.d.ts +1 -1
  178. package/dist/recall-xray-cli.js +4 -4
  179. package/dist/recall-xray-renderer.d.ts +1 -1
  180. package/dist/recall-xray-renderer.js +3 -3
  181. package/dist/recall-xray.d.ts +1 -1
  182. package/dist/recall-xray.js +2 -2
  183. package/dist/resolve-auth-token.d.ts +1 -1
  184. package/dist/retrieval-agents.d.ts +1 -1
  185. package/dist/retrieval-tiers.d.ts +1 -1
  186. package/dist/routing/engine.d.ts +1 -1
  187. package/dist/routing/store.d.ts +1 -1
  188. package/dist/search/embed-helper.d.ts +1 -1
  189. package/dist/search/factory.d.ts +1 -1
  190. package/dist/search/index.d.ts +1 -1
  191. package/dist/search/lancedb-backend.d.ts +1 -1
  192. package/dist/search/meilisearch-backend.d.ts +1 -1
  193. package/dist/search/noop-backend.d.ts +1 -1
  194. package/dist/search/orama-backend.d.ts +1 -1
  195. package/dist/search/port.d.ts +1 -1
  196. package/dist/search/remote-backend.d.ts +1 -1
  197. package/dist/{semantic-consolidation-BQm1e1Pn.d.ts → semantic-consolidation-B8LiYtvx.d.ts} +1 -1
  198. package/dist/semantic-consolidation.d.ts +2 -2
  199. package/dist/semantic-consolidation.js +4 -4
  200. package/dist/semantic-rule-promotion.js +3 -3
  201. package/dist/semantic-rule-verifier.d.ts +1 -1
  202. package/dist/semantic-rule-verifier.js +3 -3
  203. package/dist/session-observer-bands.d.ts +1 -1
  204. package/dist/session-observer-state.d.ts +1 -1
  205. package/dist/shared-context/manager.d.ts +1 -1
  206. package/dist/signal.d.ts +1 -1
  207. package/dist/storage.d.ts +1 -1
  208. package/dist/storage.js +2 -2
  209. package/dist/summarizer.d.ts +1 -1
  210. package/dist/summary-snapshot.d.ts +1 -1
  211. package/dist/temporal-supersession.d.ts +1 -1
  212. package/dist/temporal-validity.d.ts +1 -1
  213. package/dist/threading.d.ts +1 -1
  214. package/dist/tier-migration.d.ts +1 -1
  215. package/dist/tier-routing.d.ts +1 -1
  216. package/dist/topics.d.ts +1 -1
  217. package/dist/transcript.d.ts +1 -1
  218. package/dist/trust-score-stage.d.ts +1 -1
  219. package/dist/trust-score.d.ts +1 -1
  220. package/dist/{types-DwO1Ot4n.d.ts → types-DmTaqob2.d.ts} +14 -0
  221. package/dist/types.d.ts +1 -1
  222. package/dist/types.js +1 -1
  223. package/dist/utility-runtime.d.ts +1 -1
  224. package/dist/verified-recall.js +3 -3
  225. package/package.json +2 -2
  226. package/src/access-boundary.ts +36 -2
  227. package/src/access-http.ts +17 -8
  228. package/src/access-mcp.ts +149 -1189
  229. package/src/access-operations-batch.ts +227 -1439
  230. package/src/access-surface-catalog.test.ts +4 -15
  231. package/src/access-surface-catalog.ts +82 -82
  232. package/src/bitemporal-dedup-backfill.test.ts +169 -0
  233. package/src/event-time.ts +57 -0
  234. package/src/extraction-eventtime-wiring.test.ts +101 -1
  235. package/src/orchestrator.ts +238 -43
  236. package/src/recall/archive-scoring.ts +526 -0
  237. package/src/types.ts +14 -0
  238. package/dist/chunk-B7WISIAJ.js.map +0 -1
  239. package/dist/chunk-EM2LDXJ2.js +0 -1315
  240. package/dist/chunk-EM2LDXJ2.js.map +0 -1
  241. package/dist/chunk-LA3HZKES.js.map +0 -1
  242. package/dist/chunk-LLUGAZ3B.js.map +0 -1
  243. package/dist/chunk-UIXXE6NI.js.map +0 -1
  244. /package/dist/{chunk-EVPNWN7Z.js.map → chunk-4R3CGCI5.js.map} +0 -0
  245. /package/dist/{chunk-UO5ZHIIH.js.map → chunk-4WZ3J7M6.js.map} +0 -0
  246. /package/dist/{chunk-PD42EYQN.js.map → chunk-5OPYYPJN.js.map} +0 -0
  247. /package/dist/{chunk-EEJMD2L2.js.map → chunk-6CWGS2LY.js.map} +0 -0
  248. /package/dist/{chunk-7CTNUVHZ.js.map → chunk-6SQQOJ4U.js.map} +0 -0
  249. /package/dist/{chunk-A5XNBK2D.js.map → chunk-DF3I6JGP.js.map} +0 -0
  250. /package/dist/{chunk-GJSL4WG2.js.map → chunk-F3XZN24Z.js.map} +0 -0
  251. /package/dist/{chunk-J3JPB7ZI.js.map → chunk-FACTVMXQ.js.map} +0 -0
  252. /package/dist/{chunk-EBDA5TYA.js.map → chunk-FXCIOLRB.js.map} +0 -0
  253. /package/dist/{chunk-TXQCG6SE.js.map → chunk-H7HUQIY7.js.map} +0 -0
  254. /package/dist/{chunk-QD6QP5P6.js.map → chunk-I2HL5M6T.js.map} +0 -0
  255. /package/dist/{chunk-Z4RU5VPM.js.map → chunk-J334N6QV.js.map} +0 -0
  256. /package/dist/{chunk-NXRUUDUF.js.map → chunk-JJJCVCCQ.js.map} +0 -0
  257. /package/dist/{chunk-GDUOCHCD.js.map → chunk-KGZF2VO3.js.map} +0 -0
  258. /package/dist/{chunk-OHTOPFRF.js.map → chunk-SC2YAWRF.js.map} +0 -0
  259. /package/dist/{chunk-YEE5KJQQ.js.map → chunk-T55EGZSJ.js.map} +0 -0
  260. /package/dist/{chunk-N77ELJ2D.js.map → chunk-TT5U3UDO.js.map} +0 -0
  261. /package/dist/{chunk-6FAMMBQ3.js.map → chunk-UBHVAGO7.js.map} +0 -0
  262. /package/dist/{chunk-EDOQM4E4.js.map → chunk-WAFDHKES.js.map} +0 -0
  263. /package/dist/{chunk-EXUCUPV2.js.map → chunk-WM7DNKBD.js.map} +0 -0
  264. /package/dist/{chunk-WQYSDPMA.js.map → chunk-YQMPUYHE.js.map} +0 -0
  265. /package/dist/{chunk-5O42UKXI.js.map → chunk-YUYPWJD3.js.map} +0 -0
  266. /package/dist/{chunk-VCLGUIFM.js.map → chunk-Z3FGC3QE.js.map} +0 -0
  267. /package/dist/{chunk-A7TJZLPK.js.map → chunk-ZK2L72VN.js.map} +0 -0
  268. /package/dist/{chunk-BXEOHV7K.js.map → chunk-ZOHMPFOB.js.map} +0 -0
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-ZBJMUXZH.js";
8
8
  import {
9
9
  StorageManager
10
- } from "./chunk-EVPNWN7Z.js";
10
+ } from "./chunk-4R3CGCI5.js";
11
11
  import {
12
12
  getCachedEpisodeMap,
13
13
  setCachedEpisodeMap
@@ -107,4 +107,4 @@ export {
107
107
  compareVerifiedEpisodeResults,
108
108
  searchVerifiedEpisodes
109
109
  };
110
- //# sourceMappingURL=chunk-EBDA5TYA.js.map
110
+ //# sourceMappingURL=chunk-FXCIOLRB.js.map
@@ -10,10 +10,10 @@ import {
10
10
  import {
11
11
  listMemoryGovernanceRuns,
12
12
  readMemoryGovernanceRunArtifact
13
- } from "./chunk-EDOQM4E4.js";
13
+ } from "./chunk-WAFDHKES.js";
14
14
  import {
15
15
  StorageManager
16
- } from "./chunk-EVPNWN7Z.js";
16
+ } from "./chunk-4R3CGCI5.js";
17
17
  import {
18
18
  MEMORY_LIFECYCLE_EVENT_SORT_ORDER,
19
19
  buildLifecycleEventsForMemory,
@@ -929,4 +929,4 @@ export {
929
929
  verifyMemoryProjection,
930
930
  repairMemoryProjection
931
931
  };
932
- //# sourceMappingURL=chunk-TXQCG6SE.js.map
932
+ //# sourceMappingURL=chunk-H7HUQIY7.js.map
@@ -47,12 +47,12 @@ import {
47
47
  } from "./chunk-D6RIFG4O.js";
48
48
  import {
49
49
  rebuildMemoryLifecycleLedger
50
- } from "./chunk-6FAMMBQ3.js";
50
+ } from "./chunk-UBHVAGO7.js";
51
51
  import {
52
52
  rebuildMemoryProjection,
53
53
  repairMemoryProjection,
54
54
  verifyMemoryProjection
55
- } from "./chunk-TXQCG6SE.js";
55
+ } from "./chunk-H7HUQIY7.js";
56
56
  import {
57
57
  rebuildObservations
58
58
  } from "./chunk-LZZNTPLR.js";
@@ -70,7 +70,7 @@ import {
70
70
  } from "./chunk-GQL52GQ5.js";
71
71
  import {
72
72
  promoteSemanticRuleFromMemory
73
- } from "./chunk-J3JPB7ZI.js";
73
+ } from "./chunk-FACTVMXQ.js";
74
74
  import {
75
75
  resolveAgentAccessAuthToken
76
76
  } from "./chunk-TGQ2NTWH.js";
@@ -81,7 +81,7 @@ import {
81
81
  } from "./chunk-D7EBTQ24.js";
82
82
  import {
83
83
  parseXrayCliOptions
84
- } from "./chunk-BXEOHV7K.js";
84
+ } from "./chunk-ZOHMPFOB.js";
85
85
  import {
86
86
  runBenchmarkRecall,
87
87
  runOperatorConfigReview,
@@ -89,12 +89,12 @@ import {
89
89
  runOperatorInventory,
90
90
  runOperatorRepair,
91
91
  runOperatorSetup
92
- } from "./chunk-A5XNBK2D.js";
92
+ } from "./chunk-DF3I6JGP.js";
93
93
  import {
94
94
  listNamespaces,
95
95
  runNamespaceMigration,
96
96
  verifyNamespaces
97
- } from "./chunk-EEJMD2L2.js";
97
+ } from "./chunk-6CWGS2LY.js";
98
98
  import {
99
99
  collectPatternMemories,
100
100
  explainPatternMemory,
@@ -124,13 +124,13 @@ import {
124
124
  } from "./chunk-TERNBNJB.js";
125
125
  import {
126
126
  searchVerifiedEpisodes
127
- } from "./chunk-EBDA5TYA.js";
127
+ } from "./chunk-FXCIOLRB.js";
128
128
  import {
129
129
  ThreadingManager
130
130
  } from "./chunk-QRDOSYOR.js";
131
131
  import {
132
132
  searchVerifiedSemanticRules
133
- } from "./chunk-YEE5KJQQ.js";
133
+ } from "./chunk-T55EGZSJ.js";
134
134
  import {
135
135
  getWorkProductLedgerStatus,
136
136
  recordWorkProductLedgerEntry,
@@ -145,7 +145,7 @@ import {
145
145
  } from "./chunk-33JBK2XP.js";
146
146
  import {
147
147
  formatNamespaceMaintenanceHealthText
148
- } from "./chunk-PD42EYQN.js";
148
+ } from "./chunk-5OPYYPJN.js";
149
149
  import {
150
150
  analyzeSessionIntegrity,
151
151
  applySessionRepair,
@@ -215,7 +215,7 @@ import {
215
215
  } from "./chunk-OADWQ5CR.js";
216
216
  import {
217
217
  EngramAccessHttpServer
218
- } from "./chunk-UIXXE6NI.js";
218
+ } from "./chunk-C6BWLYW5.js";
219
219
  import {
220
220
  WearablesInputError
221
221
  } from "./chunk-7WV3F5DQ.js";
@@ -228,10 +228,10 @@ import {
228
228
  createProductionChatLlmAdapter,
229
229
  loadChatSession,
230
230
  sessionBelongsToPrincipal
231
- } from "./chunk-B7WISIAJ.js";
231
+ } from "./chunk-FN6QP7JQ.js";
232
232
  import {
233
233
  EngramAccessService
234
- } from "./chunk-GDUOCHCD.js";
234
+ } from "./chunk-KGZF2VO3.js";
235
235
  import {
236
236
  WorkStorage
237
237
  } from "./chunk-GDB4J2H3.js";
@@ -243,13 +243,13 @@ import {
243
243
  parseRecallExplainFormat,
244
244
  renderRecallExplain,
245
245
  renderXray
246
- } from "./chunk-7CTNUVHZ.js";
246
+ } from "./chunk-6SQQOJ4U.js";
247
247
  import {
248
248
  listMemoryGovernanceRuns,
249
249
  readMemoryGovernanceRunArtifact,
250
250
  restoreMemoryGovernanceRun,
251
251
  runMemoryGovernance
252
- } from "./chunk-EDOQM4E4.js";
252
+ } from "./chunk-WAFDHKES.js";
253
253
  import {
254
254
  getTrustZoneStoreStatus,
255
255
  promoteTrustZoneRecord,
@@ -274,7 +274,7 @@ import {
274
274
  import {
275
275
  RECALL_DISCLOSURE_LEVELS,
276
276
  isRecallDisclosure
277
- } from "./chunk-ILFSEIRT.js";
277
+ } from "./chunk-7AG54AF3.js";
278
278
  import {
279
279
  RECALL_FALLBACK_DIRS
280
280
  } from "./chunk-VS2IYZRU.js";
@@ -6825,7 +6825,7 @@ Semantic consolidation complete. clusters=${result.clustersFound}, consolidated=
6825
6825
  console.error(`Invalid --format '${fmt}'. Must be one of: text, json, markdown`);
6826
6826
  process.exit(1);
6827
6827
  }
6828
- const { normalizeDreamsStatusWindowHours } = await import("./dreams-ledger-3WSCI5V4.js");
6828
+ const { normalizeDreamsStatusWindowHours } = await import("./dreams-ledger-6UODQOX6.js");
6829
6829
  let windowHours;
6830
6830
  const rawWindowHours = options.windowHours;
6831
6831
  try {
@@ -7505,4 +7505,4 @@ export {
7505
7505
  listMemoryMarkdownFilePaths,
7506
7506
  registerCli
7507
7507
  };
7508
- //# sourceMappingURL=chunk-QD6QP5P6.js.map
7508
+ //# sourceMappingURL=chunk-I2HL5M6T.js.map
@@ -347,9 +347,27 @@ function resolveFactEventTime(expression, anchorIso) {
347
347
  eventTimeSource: "assumed"
348
348
  };
349
349
  }
350
+ function pickFactEventTimeAnchor(fact, batchAnchor) {
351
+ if (typeof fact.sourceTurnTimestamp === "string" && fact.sourceTurnTimestamp.trim().length > 0) {
352
+ const ms = parseFlexibleIsoTimestamp(fact.sourceTurnTimestamp.trim());
353
+ if (ms !== null) return new Date(ms).toISOString();
354
+ }
355
+ if (fact.sources && fact.sources.length > 0) {
356
+ let earliestMs = null;
357
+ for (const src of fact.sources) {
358
+ if (typeof src.observedAt !== "string") continue;
359
+ const ms = parseFlexibleIsoTimestamp(src.observedAt.trim());
360
+ if (ms === null) continue;
361
+ if (earliestMs === null || ms < earliestMs) earliestMs = ms;
362
+ }
363
+ if (earliestMs !== null) return new Date(earliestMs).toISOString();
364
+ }
365
+ return batchAnchor;
366
+ }
350
367
 
351
368
  export {
352
369
  resolveEventTime,
353
- resolveFactEventTime
370
+ resolveFactEventTime,
371
+ pickFactEventTimeAnchor
354
372
  };
355
- //# sourceMappingURL=chunk-M7R5R6OJ.js.map
373
+ //# sourceMappingURL=chunk-IAIPNEHD.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/event-time.ts"],"sourcesContent":["/**\n * Event-time resolver (issue #1578).\n *\n * Extraction can carry an optional per-fact `eventTime` expression — an ISO\n * date or a relative phrase verbatim from the source turn (\"last March\",\n * \"yesterday\", \"since 2024\"). This module resolves such expressions into a\n * `[validFrom, validUntil)` event-time interval, **anchored to the source\n * turn's timestamp** — never to `Date.now()`.\n *\n * Why anchor (not wall-clock): replay/import of old transcripts must resolve\n * \"yesterday\" against the *old* turn's yesterday, not today. A relative\n * expression is meaningless without its anchor; resolving it against the\n * current time would silently rewrite history (AGENTS.md §39 — byte-identical\n * when the feature is off; rule 35 — half-open intervals; rule 51 — never\n * silently default invalid input).\n *\n * Resolution is **write-time-only**. The on-disk frontmatter stores absolute\n * ISO timestamps strings (`valid_at` / `invalid_at`); readers never call back\n * into this module. Anything unresolvable yields `ok: false` and the caller\n * records `eventTimeSource: \"assumed\"` with `valid_at` copied from the\n * ingestion anchor (`observedAt`).\n *\n * Interval semantics are `[validFrom, validUntil)` — inclusive start,\n * exclusive end (AGENTS.md §23). A date-only expression resolving an *end*\n * bound converts to start-of-next-day so the end date itself is excluded.\n */\nimport { parseFlexibleIsoTimestamp } from \"./utils/iso-timestamp.js\";\n\n/**\n * Resolved event-time interval. All timestamps are UTC ISO strings.\n *\n * - `validFrom` / `validUntil` carry the half-open `[from, until)` event\n * interval. Either may be absent when the expression only pinned one side\n * (\"since 2024\" → validFrom only).\n * - `ok` is false when the expression could not be resolved. The caller then\n * falls back to `eventTimeSource: \"assumed\"`.\n */\nexport interface ResolvedEventTime {\n validFrom?: string;\n validUntil?: string;\n ok: boolean;\n}\n\nconst UNITS = [\"day\", \"week\", \"month\", \"quarter\", \"year\"] as const;\ntype RelativeUnit = (typeof UNITS)[number];\n\nfunction isRelativeUnit(unit: string): unit is RelativeUnit {\n return (UNITS as readonly string[]).includes(unit);\n}\n\n/**\n * Format a `Date` as a UTC ISO string with millisecond precision, matching the\n * canonical frontmatter form. Returns `undefined` when the input is not\n * finite (the resolver treats that as unresolvable rather than emitting\n * `Invalid Date`).\n */\nfunction toIsoUtc(ms: number | null): string | undefined {\n if (ms === null || !Number.isFinite(ms)) return undefined;\n return new Date(ms).toISOString();\n}\n\n/**\n * Compute the start of the day (UTC) for the given ms, used when a date-only\n * expression resolves a *start* bound — the fact holds from midnight UTC.\n */\nfunction startOfDayUtc(ms: number): number {\n const d = new Date(ms);\n d.setUTCHours(0, 0, 0, 0);\n return d.getTime();\n}\n\n/**\n * Compute the start of the *next* day (UTC) for the given ms, used when a\n * date-only expression resolves an *end* bound — the exclusive `validUntil`\n * must land on the following midnight so the end date itself is excluded\n * (AGENTS.md §23: date-only ends convert to start-of-next-day).\n */\nfunction startOfNextDayUtc(ms: number): number {\n const d = new Date(startOfDayUtc(ms));\n d.setUTCDate(d.getUTCDate() + 1);\n return d.getTime();\n}\n\nconst SEASON_TO_MONTH: Record<string, number> = {\n winter: 12, // Dec–Feb anchor Dec (Northern Hemisphere convention)\n spring: 3,\n summer: 6,\n fall: 9,\n autumn: 9,\n};\n\nconst MONTH_NAMES: Record<string, number> = {\n january: 1, february: 2, march: 3, april: 4, may: 5, june: 6,\n july: 7, august: 8, september: 9, october: 10, november: 11, december: 12,\n jan: 1, feb: 2, mar: 3, apr: 4, jun: 6, jul: 7, aug: 8, sep: 9, sept: 9,\n oct: 10, nov: 11, dec: 12,\n};\n\nconst QUARTER_START_MONTH: Record<number, number> = {\n 1: 1, 2: 4, 3: 7, 4: 10,\n};\n\nfunction monthIndex(token: string): number | undefined {\n const idx = MONTH_NAMES[token.toLowerCase()];\n return typeof idx === \"number\" ? idx : undefined;\n}\n\n/**\n * Construct a UTC timestamp from year/month(1-12)/day with overflow validation.\n * Returns `null` when the components do not form a real calendar date (e.g.\n * Feb 30) rather than letting `Date` silently roll over.\n */\nfunction buildDateMs(year: number, month1: number, day: number): number | null {\n if (\n !Number.isInteger(year) ||\n !Number.isInteger(month1) ||\n month1 < 1 ||\n month1 > 12 ||\n !Number.isInteger(day) ||\n day < 1 ||\n day > daysInMonth(year, month1)\n ) {\n return null;\n }\n return Date.UTC(year, month1 - 1, day, 0, 0, 0, 0);\n}\n\nfunction daysInMonth(year: number, month1: number): number {\n return new Date(Date.UTC(year, month1, 0)).getUTCDate();\n}\n\n/**\n * Add `count` units to a UTC ms timestamp, returning the start-of-period for\n * the resulting date. Used by \"last/this/next <unit>\" resolution.\n */\nfunction shiftUnit(anchorMs: number, unit: RelativeUnit, count: number): number {\n const d = new Date(anchorMs);\n switch (unit) {\n case \"day\":\n d.setUTCDate(d.getUTCDate() + count);\n return startOfDayUtc(d.getTime());\n case \"week\":\n d.setUTCDate(d.getUTCDate() + count * 7);\n return startOfDayUtc(d.getTime());\n case \"month\":\n d.setUTCMonth(d.getUTCMonth() + count, 1);\n return startOfDayUtc(d.getTime());\n case \"quarter\":\n d.setUTCMonth(d.getUTCMonth() + count * 3, 1);\n return startOfDayUtc(d.getTime());\n case \"year\":\n d.setUTCFullYear(d.getUTCFullYear() + count, 0, 1);\n return startOfDayUtc(d.getTime());\n }\n}\n\n/**\n * Resolve \"last December\" / \"this March\" / \"next Q2\" against the anchor.\n * `direction` is -1 (last), 0 (this), +1 (next). Returns the start-of-period\n * ms for the referenced month/season/quarter, or `null` if it cannot be\n * placed (e.g. month token not recognized).\n */\nfunction resolveMonthYear(\n anchorMs: number,\n monthToken: string,\n direction: number,\n): number | null {\n const lower = monthToken.toLowerCase();\n const targetMonth = monthIndex(lower);\n if (typeof targetMonth === \"number\") {\n const d = new Date(anchorMs);\n let year = d.getUTCFullYear();\n let m = targetMonth;\n if (direction === -1 && m >= d.getUTCMonth() + 1) year -= 1;\n else if (direction === +1 && m <= d.getUTCMonth() + 1) year += 1;\n return buildDateMs(year, m, 1);\n }\n return null;\n}\n/**\n * Resolve an explicit \"<month|season> <year>\" token (e.g. \"march 2025\",\n * \"dec 2024\", \"spring 2025\") to a start-of-month ms. The explicit year is\n * authoritative — it is never derived from the anchor. Returns null when\n * the token is not in that shape or does not name a real month/season.\n * Shared by the bare phrase path, \"since <month> <year>\", and the end bound\n * so all three resolve identically (review: month-year phrases after since).\n */\nfunction resolveExplicitMonthYear(token: string): number | null {\n const m = token.trim().toLowerCase().match(/^([a-z]+)\\s+(\\d{4})$/);\n if (!m) return null;\n const year = parseInt(m[2], 10);\n if (!Number.isInteger(year)) return null;\n const monthIdx = monthIndex(m[1]);\n const baseMonth = typeof monthIdx === \"number\" ? monthIdx : SEASON_TO_MONTH[m[1]];\n if (typeof baseMonth !== \"number\") return null;\n return buildDateMs(year, baseMonth, 1);\n}\n\n\n/**\n * Resolve a bare four-digit year token (e.g. \"2024\") to January 1 of that\n * year. Used by \"since 2024\" and bare year expressions. Review #1578 r2:\n * previously these fell through to ok:false, stamping the fact at ingestion\n * time instead of the documented year start.\n */\nfunction resolveBareYear(token: string): number | null {\n const m = token.trim().match(/^(\\d{4})$/);\n if (!m) return null;\n return buildDateMs(Number(m[1]), 1, 1);\n}\n\n\n/**\n * Check whether the anchor month falls inside a season's 3-month span.\n * Seasons start at `baseMonth` and span 3 months (e.g. summer = Jun–Aug).\n * Winter (Dec=12) wraps: Dec, Jan, Feb.\n */\nfunction isInSeason(baseMonth: number, anchorMonth: number): boolean {\n for (let i = 0; i < 3; i++) {\n if (((baseMonth - 1 + i) % 12) + 1 === anchorMonth) return true;\n }\n return false;\n}\n\nfunction resolveSeasonYear(\n anchorMs: number,\n seasonToken: string,\n direction: number,\n): number | null {\n const baseMonth = SEASON_TO_MONTH[seasonToken.toLowerCase()];\n if (typeof baseMonth !== \"number\") return null;\n const d = new Date(anchorMs);\n let year = d.getUTCFullYear();\n const anchorMonth = d.getUTCMonth() + 1;\n\n if (direction === -1) {\n // \"last <season>\": go to the previous occurrence.\n // If the season hasn't started yet this year (baseMonth > anchorMonth)\n // or the anchor is currently INSIDE the season, roll back a year.\n if (baseMonth > anchorMonth || isInSeason(baseMonth, anchorMonth)) year -= 1;\n // Winter tail (Jan/Feb): current winter started prev Dec, so \"last\"\n // needs one more year back.\n if (baseMonth === 12 && anchorMonth <= 2) year -= 1;\n } else if (direction === +1) {\n // \"next <season>\": go to the next occurrence.\n // Winter from Jan/Feb: current winter started prev Dec; next is this Dec.\n if (baseMonth === 12 && anchorMonth <= 2) {\n // no year change — next winter is December of the anchor year\n } else if (baseMonth < anchorMonth || isInSeason(baseMonth, anchorMonth)) {\n year += 1;\n }\n } else if (direction === 0 && baseMonth === 12 && anchorMonth <= 2) {\n // \"this winter\" from Jan/Feb: winter started in the previous December.\n year -= 1;\n }\n return buildDateMs(year, baseMonth, 1);\n}\n\nfunction resolveQuarter(\n anchorMs: number,\n qNumber: number,\n direction: number,\n): number | null {\n const startMonth = QUARTER_START_MONTH[qNumber];\n if (typeof startMonth !== \"number\") return null;\n const d = new Date(anchorMs);\n let year = d.getUTCFullYear();\n const anchorMonth = d.getUTCMonth() + 1;\n const anchorQ = Math.floor((anchorMonth - 1) / 3) + 1;\n // Roll back/forward when the target quarter hasn't started yet this year\n // (startMonth past the anchor month) OR when the anchor is currently\n // INSIDE the target quarter (review r2: \"last Q2\" from May returned 2026\n // instead of 2025 because the quarter start month had already passed but\n // the quarter was still ongoing).\n if (direction === -1 && (startMonth >= anchorMonth || anchorQ === qNumber))\n year -= 1;\n else if (direction === +1 && (startMonth <= anchorMonth || anchorQ === qNumber))\n year += 1;\n return buildDateMs(year, startMonth, 1);\n}\n\n/**\n * Resolve an absolute ISO date/datetime to ms. A date-only value yields\n * start-of-day (UTC). Returns `null` when the string is not a well-formed,\n * non-overflowed ISO timestamp.\n */\nfunction resolveAbsolute(raw: string): number | null {\n const trimmed = raw.trim();\n // YYYY-MM (ISO year-month, no day) → first day of that month, UTC\n // (#1578 review r3: the prompt example \"until 2025-06\" must resolve, not\n // fall back to \"assumed\").\n const ym = /^(\\d{4})-(\\d{2})$/.exec(trimmed);\n if (ym) {\n const ms = buildDateMs(Number(ym[1]), Number(ym[2]), 1);\n return ms === null ? null : startOfDayUtc(ms);\n }\n const ms = parseFlexibleIsoTimestamp(trimmed);\n if (ms === null) return null;\n // Date-only inputs (no T) anchor to start-of-day UTC.\n if (!/[Tt]/.test(trimmed)) return startOfDayUtc(ms);\n return ms;\n}\n\n/**\n * Resolve a relative event-time expression against an anchor ISO timestamp.\n *\n * Supported shapes (case-insensitive, trimmed):\n * - absolute ISO date / datetime: `\"2026-03-01\"`, `\"2026-03-01T00:00:00Z\"`\n * - `\"since <date|monthyear>\"` → validFrom only\n * - `\"until <date|monthyear>\"` / `\"through ...\"` / `\"until end of ...\"` → validUntil only\n * - `\"last <month|season|Qn|unit>\"` → validFrom = start of referenced period\n * - `\"this <month|season|Qn|unit>\"` → validFrom = start of current period\n * - `\"next <month|season|Qn|unit>\"` → validFrom = start of referenced period\n * - `\"yesterday\"` / `\"today\"` / `\"tomorrow\"` → validFrom = start of that day\n *\n * Anything else returns `{ ok: false }`. The caller then records\n * `eventTimeSource: \"assumed\"`.\n *\n * @param expression the raw per-fact event-time phrase (may be empty/garbage)\n * @param anchorIso the source turn's ISO timestamp — the resolution anchor\n */\nexport function resolveEventTime(\n expression: string | undefined | null,\n anchorIso: string,\n): ResolvedEventTime {\n const fallback: ResolvedEventTime = { ok: false };\n if (typeof expression !== \"string\") return fallback;\n const expr = expression.trim();\n if (expr.length === 0) return fallback;\n\n const anchorMs = parseFlexibleIsoTimestamp(anchorIso);\n if (anchorMs === null || !Number.isFinite(anchorMs)) return fallback;\n\n const lower = expr.toLowerCase();\n\n // ── \"since <x>\" / \"until <x>\" / \"through <x>\" ──────────────────────────\n const sinceMatch = lower.match(/^since\\s+(.+)$/);\n if (sinceMatch) {\n const inner = sinceMatch[1].trim();\n let fromMs =\n resolveRelativePeriod(anchorMs, inner) ??\n resolveExplicitMonthYear(inner) ??\n resolveBareYear(inner) ??\n resolveAbsolute(inner);\n // \"since <bare month/season>\": if the resolved start is future and the\n // expression carries no explicit 4-digit year, the fact meant the most\n // recent PAST occurrence of that period (codex review r2: \"since March\"\n // from January produced a future validFrom).\n if (\n fromMs !== null &&\n fromMs > anchorMs &&\n !/\\d{4}/.test(inner)\n ) {\n const nd = new Date(fromMs);\n nd.setUTCFullYear(nd.getUTCFullYear() - 1);\n fromMs = nd.getTime();\n }\n const fromIso = toIsoUtc(fromMs);\n if (!fromIso) return fallback;\n return { validFrom: fromIso, ok: true };\n }\n const untilMatch = lower.match(/^(?:until|through|till|ending)\\s+(.+)$/);\n if (untilMatch) {\n const inner = untilMatch[1].trim();\n const untilMs = resolveEndBound(anchorMs, inner);\n const untilIso = toIsoUtc(untilMs);\n if (!untilIso) return fallback;\n return { validUntil: untilIso, ok: true };\n }\n\n // ── \"yesterday\" / \"today\" / \"tomorrow\" ─────────────────────────────────\n if (lower === \"today\") {\n const fromIso = toIsoUtc(startOfDayUtc(anchorMs));\n return fromIso ? { validFrom: fromIso, ok: true } : fallback;\n }\n if (lower === \"yesterday\") {\n const fromIso = toIsoUtc(shiftUnit(anchorMs, \"day\", -1));\n return fromIso ? { validFrom: fromIso, ok: true } : fallback;\n }\n if (lower === \"tomorrow\") {\n const fromIso = toIsoUtc(shiftUnit(anchorMs, \"day\", +1));\n return fromIso ? { validFrom: fromIso, ok: true } : fallback;\n }\n\n // ── \"last/this/next <period>\" ──────────────────────────────────────────\n const relMatch = lower.match(/^(last|this|next)\\s+(.+)$/);\n if (relMatch) {\n const direction = relMatch[1] === \"last\" ? -1 : relMatch[1] === \"next\" ? +1 : 0;\n const period = relMatch[2].trim();\n const ms = resolveRelativePeriod(anchorMs, period, direction);\n const fromIso = toIsoUtc(ms);\n return fromIso ? { validFrom: fromIso, ok: true } : fallback;\n }\n\n // ── bare month+year (\"March 2025\", \"Dec 2024\", \"spring 2025\") or\n // bare four-digit year (\"2024\") ────────────────────────────────────────\n // Explicit year is authoritative (never derived from the anchor). Shares\n // resolveExplicitMonthYear / resolveBareYear with the since/until paths.\n const explicitMs = resolveExplicitMonthYear(lower) ?? resolveBareYear(lower);\n if (explicitMs !== null) {\n const fromIso = toIsoUtc(explicitMs);\n if (fromIso) return { validFrom: fromIso, ok: true };\n }\n\n // ── absolute ISO date / datetime ───────────────────────────────────────\n const absMs = resolveAbsolute(expr);\n if (absMs !== null) {\n const fromIso = toIsoUtc(absMs);\n return fromIso ? { validFrom: fromIso, ok: true } : fallback;\n }\n\n return fallback;\n}\n\n/**\n * Resolve a period token (with optional direction) to a start-of-period ms.\n * Handles month/season names, quarter tokens (`q1`..`q4`), and relative units\n * (`day/week/month/quarter/year`) used by \"last week\", \"this month\", etc.\n */\nfunction resolveRelativePeriod(\n anchorMs: number,\n period: string,\n direction: number = 0,\n): number | null {\n const lower = period.trim().toLowerCase();\n\n // Quarter token: \"q1\", \"Q2\", \"quarter 3\"\n const qTok = lower.match(/^q(?:uarter)?\\s?([1-4])$/);\n if (qTok) {\n return resolveQuarter(anchorMs, Number(qTok[1]), direction);\n }\n if (lower === \"quarter\") {\n // \"last quarter\" / \"next quarter\" move the quarter INDEX (with year\n // wraparound), not just the year — resolveQuarter only nudges the year\n // for an explicit quarter number, so routing \"last quarter\" through it\n // returned the current quarter's start (review: bare last/next quarter).\n const d = new Date(anchorMs);\n let q = Math.floor(d.getUTCMonth() / 3) + 1;\n let year = d.getUTCFullYear();\n if (direction === -1) {\n q -= 1;\n if (q < 1) { q = 4; year -= 1; }\n } else if (direction === +1) {\n q += 1;\n if (q > 4) { q = 1; year += 1; }\n }\n return buildDateMs(year, QUARTER_START_MONTH[q], 1);\n }\n\n // Relative unit: \"week\", \"month\", \"year\", \"day\"\n if (isRelativeUnit(lower)) {\n return shiftUnit(anchorMs, lower, direction);\n }\n\n // Month or season name\n const monthMs = resolveMonthYear(anchorMs, lower, direction);\n if (monthMs !== null) return monthMs;\n const seasonMs = resolveSeasonYear(anchorMs, lower, direction);\n if (seasonMs !== null) return seasonMs;\n\n return null;\n}\n\n/**\n * Resolve an end-bound period to an *exclusive* upper bound ms. Date-only\n * values convert to start-of-next-day (AGENTS.md §23); period names resolve to\n * the start of the *following* period.\n */\nfunction resolveEndBound(anchorMs: number, period: string): number | null {\n // Strip an optional \"end of \" prefix so \"until end of March\" resolves the\n // same as \"until March\". Review #1578 r2: previously the prefix was passed\n // unchanged and resolveEndBound returned null for the full phrase.\n const trimmed = period.trim().replace(/^end\\s+of\\s+/i, \"\").trim();\n\n // Bare four-digit year: exclusive end = January 1 of the FOLLOWING year.\n if (/^\\d{4}$/.test(trimmed)) {\n return buildDateMs(Number(trimmed) + 1, 1, 1);\n }\n\n // YYYY-MM (year-month) end bound: exclusive end = start of the FOLLOWING\n // month, so \"until 2025-06\" spans all of June (#1578 review r3).\n const ymEnd = /^(\\d{4})-(\\d{2})$/.exec(trimmed);\n if (ymEnd) {\n const startMs = buildDateMs(Number(ymEnd[1]), Number(ymEnd[2]), 1);\n if (startMs === null) return null;\n const nd = new Date(startMs);\n nd.setUTCMonth(nd.getUTCMonth() + 1);\n return startOfDayUtc(nd.getTime());\n }\n\n // Absolute date/datetime end bound.\n const absMs = resolveAbsolute(trimmed);\n if (absMs !== null) {\n // Date-only → start of next day (exclusive end). Datetime → use as-is.\n if (!/[Tt]/.test(trimmed)) return startOfNextDayUtc(absMs);\n return absMs;\n }\n // Explicit \"<month|season> <year>\" end bound (e.g. \"until March 2025\",\n // \"through spring 2025\"). The explicit year is authoritative, so the\n // exclusive end = start of the FOLLOWING month (for a single month) or the\n // start of the month AFTER the season ends (for a 3-month season).\n // Review r2: seasons previously advanced only 1 month, cutting off the\n // last 2 months of the season.\n const explicitMs = resolveExplicitMonthYear(trimmed);\n if (explicitMs !== null) {\n const nd = new Date(explicitMs);\n const firstWord = trimmed.toLowerCase().split(/\\s+/)[0];\n const monthAdvance = firstWord in SEASON_TO_MONTH ? 3 : 1;\n nd.setUTCMonth(nd.getUTCMonth() + monthAdvance);\n return startOfDayUtc(nd.getTime());\n }\n\n // Period-name end bound: month → exclusive end at start of the FOLLOWING\n // month. \"until <month>\" is backwards-looking (the fact already stopped\n // being true), so prefer the most recent PAST boundary: build it in the\n // anchor year and roll back a year if that boundary is still future.\n const lower = trimmed.toLowerCase();\n const monthIdx = monthIndex(lower);\n if (typeof monthIdx === \"number\") {\n const d = new Date(anchorMs);\n const startMs = buildDateMs(d.getUTCFullYear(), monthIdx, 1);\n if (startMs === null) return null;\n // Exclusive end = start of the month AFTER the named month.\n const nd = new Date(startMs);\n nd.setUTCMonth(nd.getUTCMonth() + 1);\n let endMs = startOfDayUtc(nd.getTime());\n // Only roll back when the named month boundary is genuinely future\n // relative to the anchor cycle. When the anchor IS in the named month,\n // the end of the current month is the right boundary — do not roll back\n // (cursor review r2: \"until March\" from mid-March returned the prior year).\n if (endMs > anchorMs && d.getUTCMonth() + 1 !== monthIdx) {\n nd.setUTCFullYear(nd.getUTCFullYear() - 1);\n endMs = startOfDayUtc(nd.getTime());\n }\n return endMs;\n }\n // Season end bound: advance by the full 3-month season. Same\n // backwards-looking rollback logic as month names, but do not roll back\n // when the anchor is currently inside the season (codex review r2: bare\n // season end bounds like \"until spring\" / \"through summer\" returned null).\n const seasonMonth = SEASON_TO_MONTH[lower];\n if (typeof seasonMonth === \"number\") {\n const d = new Date(anchorMs);\n const anchorMonth = d.getUTCMonth() + 1;\n let year = d.getUTCFullYear();\n // Winter (Dec) from Jan/Feb: the current winter started in prev Dec,\n // so build the season start from the previous year (codex review r2:\n // bare winter end bounds used the anchor year's December, producing\n // an exclusive end one year too far forward).\n if (seasonMonth === 12 && anchorMonth <= 2) year -= 1;\n const startMs = buildDateMs(year, seasonMonth, 1);\n if (startMs === null) return null;\n const nd = new Date(startMs);\n nd.setUTCMonth(nd.getUTCMonth() + 3);\n let endMs = startOfDayUtc(nd.getTime());\n if (endMs > anchorMs && !isInSeason(seasonMonth, anchorMonth)) {\n nd.setUTCFullYear(nd.getUTCFullYear() - 1);\n endMs = startOfDayUtc(nd.getTime());\n }\n return endMs;\n }\n if (lower === \"year\") {\n const d = new Date(anchorMs);\n return buildDateMs(d.getUTCFullYear() + 1, 1, 1);\n }\n return null;\n}\n\n/**\n * Resolved bi-temporal fields for a single extracted fact (issue #1578 PR2).\n *\n * - `validFrom` / `validUntil` — the event-time `[from, until)` interval.\n * When `eventTimeSource === \"assumed\"`, `validFrom` is copied from\n * `observedAt` (the ingestion anchor) so every bi-temporal-on fact carries\n * at least a start bound.\n * - `observedAt` — always the ingestion anchor (the source turn timestamp).\n * - `eventTimeSource` — `\"extracted\"` when the expression resolved to a real\n * event-time interval; `\"assumed\"` when the expression was absent or\n * unresolvable.\n *\n * This is the single write-time helper every extraction entry path calls\n * (rule 39). It is pure: (expression, anchor) in, interval out. Resolution\n * never touches `Date.now()` — replay/import of old transcripts resolves\n * against the old anchor.\n */\nexport interface FactEventTime {\n validFrom?: string;\n validUntil?: string;\n observedAt: string;\n eventTimeSource: \"extracted\" | \"assumed\";\n}\n\n/**\n * Resolve a single fact's event-time expression against the ingestion anchor.\n *\n * Returns the bi-temporal interval to persist alongside the fact. When the\n * expression is absent, empty, or unresolvable, falls back to\n * `eventTimeSource: \"assumed\"` with `validFrom = observedAt` — per the\n * #1578 frontmatter contract. When the expression resolves but only pins one\n * bound (\"since 2024\" → validFrom only; \"until 2025-06\" → validUntil only),\n * only the resolved bound is returned.\n */\nexport function resolveFactEventTime(\n expression: string | undefined | null,\n anchorIso: string,\n): FactEventTime {\n const resolved = resolveEventTime(expression, anchorIso);\n if (resolved.ok && (resolved.validFrom !== undefined || resolved.validUntil !== undefined)) {\n return {\n ...(resolved.validFrom !== undefined ? { validFrom: resolved.validFrom } : {}),\n ...(resolved.validUntil !== undefined ? { validUntil: resolved.validUntil } : {}),\n observedAt: anchorIso,\n eventTimeSource: \"extracted\",\n };\n }\n return {\n validFrom: anchorIso,\n observedAt: anchorIso,\n eventTimeSource: \"assumed\",\n };\n}\n"],"mappings":"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","names":["ms"]}
1
+ {"version":3,"sources":["../src/event-time.ts"],"sourcesContent":["/**\n * Event-time resolver (issue #1578).\n *\n * Extraction can carry an optional per-fact `eventTime` expression — an ISO\n * date or a relative phrase verbatim from the source turn (\"last March\",\n * \"yesterday\", \"since 2024\"). This module resolves such expressions into a\n * `[validFrom, validUntil)` event-time interval, **anchored to the source\n * turn's timestamp** — never to `Date.now()`.\n *\n * Why anchor (not wall-clock): replay/import of old transcripts must resolve\n * \"yesterday\" against the *old* turn's yesterday, not today. A relative\n * expression is meaningless without its anchor; resolving it against the\n * current time would silently rewrite history (AGENTS.md §39 — byte-identical\n * when the feature is off; rule 35 — half-open intervals; rule 51 — never\n * silently default invalid input).\n *\n * Resolution is **write-time-only**. The on-disk frontmatter stores absolute\n * ISO timestamps strings (`valid_at` / `invalid_at`); readers never call back\n * into this module. Anything unresolvable yields `ok: false` and the caller\n * records `eventTimeSource: \"assumed\"` with `valid_at` copied from the\n * ingestion anchor (`observedAt`).\n *\n * Interval semantics are `[validFrom, validUntil)` — inclusive start,\n * exclusive end (AGENTS.md §23). A date-only expression resolving an *end*\n * bound converts to start-of-next-day so the end date itself is excluded.\n */\nimport { parseFlexibleIsoTimestamp } from \"./utils/iso-timestamp.js\";\n\n/**\n * Resolved event-time interval. All timestamps are UTC ISO strings.\n *\n * - `validFrom` / `validUntil` carry the half-open `[from, until)` event\n * interval. Either may be absent when the expression only pinned one side\n * (\"since 2024\" → validFrom only).\n * - `ok` is false when the expression could not be resolved. The caller then\n * falls back to `eventTimeSource: \"assumed\"`.\n */\nexport interface ResolvedEventTime {\n validFrom?: string;\n validUntil?: string;\n ok: boolean;\n}\n\nconst UNITS = [\"day\", \"week\", \"month\", \"quarter\", \"year\"] as const;\ntype RelativeUnit = (typeof UNITS)[number];\n\nfunction isRelativeUnit(unit: string): unit is RelativeUnit {\n return (UNITS as readonly string[]).includes(unit);\n}\n\n/**\n * Format a `Date` as a UTC ISO string with millisecond precision, matching the\n * canonical frontmatter form. Returns `undefined` when the input is not\n * finite (the resolver treats that as unresolvable rather than emitting\n * `Invalid Date`).\n */\nfunction toIsoUtc(ms: number | null): string | undefined {\n if (ms === null || !Number.isFinite(ms)) return undefined;\n return new Date(ms).toISOString();\n}\n\n/**\n * Compute the start of the day (UTC) for the given ms, used when a date-only\n * expression resolves a *start* bound — the fact holds from midnight UTC.\n */\nfunction startOfDayUtc(ms: number): number {\n const d = new Date(ms);\n d.setUTCHours(0, 0, 0, 0);\n return d.getTime();\n}\n\n/**\n * Compute the start of the *next* day (UTC) for the given ms, used when a\n * date-only expression resolves an *end* bound — the exclusive `validUntil`\n * must land on the following midnight so the end date itself is excluded\n * (AGENTS.md §23: date-only ends convert to start-of-next-day).\n */\nfunction startOfNextDayUtc(ms: number): number {\n const d = new Date(startOfDayUtc(ms));\n d.setUTCDate(d.getUTCDate() + 1);\n return d.getTime();\n}\n\nconst SEASON_TO_MONTH: Record<string, number> = {\n winter: 12, // Dec–Feb anchor Dec (Northern Hemisphere convention)\n spring: 3,\n summer: 6,\n fall: 9,\n autumn: 9,\n};\n\nconst MONTH_NAMES: Record<string, number> = {\n january: 1, february: 2, march: 3, april: 4, may: 5, june: 6,\n july: 7, august: 8, september: 9, october: 10, november: 11, december: 12,\n jan: 1, feb: 2, mar: 3, apr: 4, jun: 6, jul: 7, aug: 8, sep: 9, sept: 9,\n oct: 10, nov: 11, dec: 12,\n};\n\nconst QUARTER_START_MONTH: Record<number, number> = {\n 1: 1, 2: 4, 3: 7, 4: 10,\n};\n\nfunction monthIndex(token: string): number | undefined {\n const idx = MONTH_NAMES[token.toLowerCase()];\n return typeof idx === \"number\" ? idx : undefined;\n}\n\n/**\n * Construct a UTC timestamp from year/month(1-12)/day with overflow validation.\n * Returns `null` when the components do not form a real calendar date (e.g.\n * Feb 30) rather than letting `Date` silently roll over.\n */\nfunction buildDateMs(year: number, month1: number, day: number): number | null {\n if (\n !Number.isInteger(year) ||\n !Number.isInteger(month1) ||\n month1 < 1 ||\n month1 > 12 ||\n !Number.isInteger(day) ||\n day < 1 ||\n day > daysInMonth(year, month1)\n ) {\n return null;\n }\n return Date.UTC(year, month1 - 1, day, 0, 0, 0, 0);\n}\n\nfunction daysInMonth(year: number, month1: number): number {\n return new Date(Date.UTC(year, month1, 0)).getUTCDate();\n}\n\n/**\n * Add `count` units to a UTC ms timestamp, returning the start-of-period for\n * the resulting date. Used by \"last/this/next <unit>\" resolution.\n */\nfunction shiftUnit(anchorMs: number, unit: RelativeUnit, count: number): number {\n const d = new Date(anchorMs);\n switch (unit) {\n case \"day\":\n d.setUTCDate(d.getUTCDate() + count);\n return startOfDayUtc(d.getTime());\n case \"week\":\n d.setUTCDate(d.getUTCDate() + count * 7);\n return startOfDayUtc(d.getTime());\n case \"month\":\n d.setUTCMonth(d.getUTCMonth() + count, 1);\n return startOfDayUtc(d.getTime());\n case \"quarter\":\n d.setUTCMonth(d.getUTCMonth() + count * 3, 1);\n return startOfDayUtc(d.getTime());\n case \"year\":\n d.setUTCFullYear(d.getUTCFullYear() + count, 0, 1);\n return startOfDayUtc(d.getTime());\n }\n}\n\n/**\n * Resolve \"last December\" / \"this March\" / \"next Q2\" against the anchor.\n * `direction` is -1 (last), 0 (this), +1 (next). Returns the start-of-period\n * ms for the referenced month/season/quarter, or `null` if it cannot be\n * placed (e.g. month token not recognized).\n */\nfunction resolveMonthYear(\n anchorMs: number,\n monthToken: string,\n direction: number,\n): number | null {\n const lower = monthToken.toLowerCase();\n const targetMonth = monthIndex(lower);\n if (typeof targetMonth === \"number\") {\n const d = new Date(anchorMs);\n let year = d.getUTCFullYear();\n let m = targetMonth;\n if (direction === -1 && m >= d.getUTCMonth() + 1) year -= 1;\n else if (direction === +1 && m <= d.getUTCMonth() + 1) year += 1;\n return buildDateMs(year, m, 1);\n }\n return null;\n}\n/**\n * Resolve an explicit \"<month|season> <year>\" token (e.g. \"march 2025\",\n * \"dec 2024\", \"spring 2025\") to a start-of-month ms. The explicit year is\n * authoritative — it is never derived from the anchor. Returns null when\n * the token is not in that shape or does not name a real month/season.\n * Shared by the bare phrase path, \"since <month> <year>\", and the end bound\n * so all three resolve identically (review: month-year phrases after since).\n */\nfunction resolveExplicitMonthYear(token: string): number | null {\n const m = token.trim().toLowerCase().match(/^([a-z]+)\\s+(\\d{4})$/);\n if (!m) return null;\n const year = parseInt(m[2], 10);\n if (!Number.isInteger(year)) return null;\n const monthIdx = monthIndex(m[1]);\n const baseMonth = typeof monthIdx === \"number\" ? monthIdx : SEASON_TO_MONTH[m[1]];\n if (typeof baseMonth !== \"number\") return null;\n return buildDateMs(year, baseMonth, 1);\n}\n\n\n/**\n * Resolve a bare four-digit year token (e.g. \"2024\") to January 1 of that\n * year. Used by \"since 2024\" and bare year expressions. Review #1578 r2:\n * previously these fell through to ok:false, stamping the fact at ingestion\n * time instead of the documented year start.\n */\nfunction resolveBareYear(token: string): number | null {\n const m = token.trim().match(/^(\\d{4})$/);\n if (!m) return null;\n return buildDateMs(Number(m[1]), 1, 1);\n}\n\n\n/**\n * Check whether the anchor month falls inside a season's 3-month span.\n * Seasons start at `baseMonth` and span 3 months (e.g. summer = Jun–Aug).\n * Winter (Dec=12) wraps: Dec, Jan, Feb.\n */\nfunction isInSeason(baseMonth: number, anchorMonth: number): boolean {\n for (let i = 0; i < 3; i++) {\n if (((baseMonth - 1 + i) % 12) + 1 === anchorMonth) return true;\n }\n return false;\n}\n\nfunction resolveSeasonYear(\n anchorMs: number,\n seasonToken: string,\n direction: number,\n): number | null {\n const baseMonth = SEASON_TO_MONTH[seasonToken.toLowerCase()];\n if (typeof baseMonth !== \"number\") return null;\n const d = new Date(anchorMs);\n let year = d.getUTCFullYear();\n const anchorMonth = d.getUTCMonth() + 1;\n\n if (direction === -1) {\n // \"last <season>\": go to the previous occurrence.\n // If the season hasn't started yet this year (baseMonth > anchorMonth)\n // or the anchor is currently INSIDE the season, roll back a year.\n if (baseMonth > anchorMonth || isInSeason(baseMonth, anchorMonth)) year -= 1;\n // Winter tail (Jan/Feb): current winter started prev Dec, so \"last\"\n // needs one more year back.\n if (baseMonth === 12 && anchorMonth <= 2) year -= 1;\n } else if (direction === +1) {\n // \"next <season>\": go to the next occurrence.\n // Winter from Jan/Feb: current winter started prev Dec; next is this Dec.\n if (baseMonth === 12 && anchorMonth <= 2) {\n // no year change — next winter is December of the anchor year\n } else if (baseMonth < anchorMonth || isInSeason(baseMonth, anchorMonth)) {\n year += 1;\n }\n } else if (direction === 0 && baseMonth === 12 && anchorMonth <= 2) {\n // \"this winter\" from Jan/Feb: winter started in the previous December.\n year -= 1;\n }\n return buildDateMs(year, baseMonth, 1);\n}\n\nfunction resolveQuarter(\n anchorMs: number,\n qNumber: number,\n direction: number,\n): number | null {\n const startMonth = QUARTER_START_MONTH[qNumber];\n if (typeof startMonth !== \"number\") return null;\n const d = new Date(anchorMs);\n let year = d.getUTCFullYear();\n const anchorMonth = d.getUTCMonth() + 1;\n const anchorQ = Math.floor((anchorMonth - 1) / 3) + 1;\n // Roll back/forward when the target quarter hasn't started yet this year\n // (startMonth past the anchor month) OR when the anchor is currently\n // INSIDE the target quarter (review r2: \"last Q2\" from May returned 2026\n // instead of 2025 because the quarter start month had already passed but\n // the quarter was still ongoing).\n if (direction === -1 && (startMonth >= anchorMonth || anchorQ === qNumber))\n year -= 1;\n else if (direction === +1 && (startMonth <= anchorMonth || anchorQ === qNumber))\n year += 1;\n return buildDateMs(year, startMonth, 1);\n}\n\n/**\n * Resolve an absolute ISO date/datetime to ms. A date-only value yields\n * start-of-day (UTC). Returns `null` when the string is not a well-formed,\n * non-overflowed ISO timestamp.\n */\nfunction resolveAbsolute(raw: string): number | null {\n const trimmed = raw.trim();\n // YYYY-MM (ISO year-month, no day) → first day of that month, UTC\n // (#1578 review r3: the prompt example \"until 2025-06\" must resolve, not\n // fall back to \"assumed\").\n const ym = /^(\\d{4})-(\\d{2})$/.exec(trimmed);\n if (ym) {\n const ms = buildDateMs(Number(ym[1]), Number(ym[2]), 1);\n return ms === null ? null : startOfDayUtc(ms);\n }\n const ms = parseFlexibleIsoTimestamp(trimmed);\n if (ms === null) return null;\n // Date-only inputs (no T) anchor to start-of-day UTC.\n if (!/[Tt]/.test(trimmed)) return startOfDayUtc(ms);\n return ms;\n}\n\n/**\n * Resolve a relative event-time expression against an anchor ISO timestamp.\n *\n * Supported shapes (case-insensitive, trimmed):\n * - absolute ISO date / datetime: `\"2026-03-01\"`, `\"2026-03-01T00:00:00Z\"`\n * - `\"since <date|monthyear>\"` → validFrom only\n * - `\"until <date|monthyear>\"` / `\"through ...\"` / `\"until end of ...\"` → validUntil only\n * - `\"last <month|season|Qn|unit>\"` → validFrom = start of referenced period\n * - `\"this <month|season|Qn|unit>\"` → validFrom = start of current period\n * - `\"next <month|season|Qn|unit>\"` → validFrom = start of referenced period\n * - `\"yesterday\"` / `\"today\"` / `\"tomorrow\"` → validFrom = start of that day\n *\n * Anything else returns `{ ok: false }`. The caller then records\n * `eventTimeSource: \"assumed\"`.\n *\n * @param expression the raw per-fact event-time phrase (may be empty/garbage)\n * @param anchorIso the source turn's ISO timestamp — the resolution anchor\n */\nexport function resolveEventTime(\n expression: string | undefined | null,\n anchorIso: string,\n): ResolvedEventTime {\n const fallback: ResolvedEventTime = { ok: false };\n if (typeof expression !== \"string\") return fallback;\n const expr = expression.trim();\n if (expr.length === 0) return fallback;\n\n const anchorMs = parseFlexibleIsoTimestamp(anchorIso);\n if (anchorMs === null || !Number.isFinite(anchorMs)) return fallback;\n\n const lower = expr.toLowerCase();\n\n // ── \"since <x>\" / \"until <x>\" / \"through <x>\" ──────────────────────────\n const sinceMatch = lower.match(/^since\\s+(.+)$/);\n if (sinceMatch) {\n const inner = sinceMatch[1].trim();\n let fromMs =\n resolveRelativePeriod(anchorMs, inner) ??\n resolveExplicitMonthYear(inner) ??\n resolveBareYear(inner) ??\n resolveAbsolute(inner);\n // \"since <bare month/season>\": if the resolved start is future and the\n // expression carries no explicit 4-digit year, the fact meant the most\n // recent PAST occurrence of that period (codex review r2: \"since March\"\n // from January produced a future validFrom).\n if (\n fromMs !== null &&\n fromMs > anchorMs &&\n !/\\d{4}/.test(inner)\n ) {\n const nd = new Date(fromMs);\n nd.setUTCFullYear(nd.getUTCFullYear() - 1);\n fromMs = nd.getTime();\n }\n const fromIso = toIsoUtc(fromMs);\n if (!fromIso) return fallback;\n return { validFrom: fromIso, ok: true };\n }\n const untilMatch = lower.match(/^(?:until|through|till|ending)\\s+(.+)$/);\n if (untilMatch) {\n const inner = untilMatch[1].trim();\n const untilMs = resolveEndBound(anchorMs, inner);\n const untilIso = toIsoUtc(untilMs);\n if (!untilIso) return fallback;\n return { validUntil: untilIso, ok: true };\n }\n\n // ── \"yesterday\" / \"today\" / \"tomorrow\" ─────────────────────────────────\n if (lower === \"today\") {\n const fromIso = toIsoUtc(startOfDayUtc(anchorMs));\n return fromIso ? { validFrom: fromIso, ok: true } : fallback;\n }\n if (lower === \"yesterday\") {\n const fromIso = toIsoUtc(shiftUnit(anchorMs, \"day\", -1));\n return fromIso ? { validFrom: fromIso, ok: true } : fallback;\n }\n if (lower === \"tomorrow\") {\n const fromIso = toIsoUtc(shiftUnit(anchorMs, \"day\", +1));\n return fromIso ? { validFrom: fromIso, ok: true } : fallback;\n }\n\n // ── \"last/this/next <period>\" ──────────────────────────────────────────\n const relMatch = lower.match(/^(last|this|next)\\s+(.+)$/);\n if (relMatch) {\n const direction = relMatch[1] === \"last\" ? -1 : relMatch[1] === \"next\" ? +1 : 0;\n const period = relMatch[2].trim();\n const ms = resolveRelativePeriod(anchorMs, period, direction);\n const fromIso = toIsoUtc(ms);\n return fromIso ? { validFrom: fromIso, ok: true } : fallback;\n }\n\n // ── bare month+year (\"March 2025\", \"Dec 2024\", \"spring 2025\") or\n // bare four-digit year (\"2024\") ────────────────────────────────────────\n // Explicit year is authoritative (never derived from the anchor). Shares\n // resolveExplicitMonthYear / resolveBareYear with the since/until paths.\n const explicitMs = resolveExplicitMonthYear(lower) ?? resolveBareYear(lower);\n if (explicitMs !== null) {\n const fromIso = toIsoUtc(explicitMs);\n if (fromIso) return { validFrom: fromIso, ok: true };\n }\n\n // ── absolute ISO date / datetime ───────────────────────────────────────\n const absMs = resolveAbsolute(expr);\n if (absMs !== null) {\n const fromIso = toIsoUtc(absMs);\n return fromIso ? { validFrom: fromIso, ok: true } : fallback;\n }\n\n return fallback;\n}\n\n/**\n * Resolve a period token (with optional direction) to a start-of-period ms.\n * Handles month/season names, quarter tokens (`q1`..`q4`), and relative units\n * (`day/week/month/quarter/year`) used by \"last week\", \"this month\", etc.\n */\nfunction resolveRelativePeriod(\n anchorMs: number,\n period: string,\n direction: number = 0,\n): number | null {\n const lower = period.trim().toLowerCase();\n\n // Quarter token: \"q1\", \"Q2\", \"quarter 3\"\n const qTok = lower.match(/^q(?:uarter)?\\s?([1-4])$/);\n if (qTok) {\n return resolveQuarter(anchorMs, Number(qTok[1]), direction);\n }\n if (lower === \"quarter\") {\n // \"last quarter\" / \"next quarter\" move the quarter INDEX (with year\n // wraparound), not just the year — resolveQuarter only nudges the year\n // for an explicit quarter number, so routing \"last quarter\" through it\n // returned the current quarter's start (review: bare last/next quarter).\n const d = new Date(anchorMs);\n let q = Math.floor(d.getUTCMonth() / 3) + 1;\n let year = d.getUTCFullYear();\n if (direction === -1) {\n q -= 1;\n if (q < 1) { q = 4; year -= 1; }\n } else if (direction === +1) {\n q += 1;\n if (q > 4) { q = 1; year += 1; }\n }\n return buildDateMs(year, QUARTER_START_MONTH[q], 1);\n }\n\n // Relative unit: \"week\", \"month\", \"year\", \"day\"\n if (isRelativeUnit(lower)) {\n return shiftUnit(anchorMs, lower, direction);\n }\n\n // Month or season name\n const monthMs = resolveMonthYear(anchorMs, lower, direction);\n if (monthMs !== null) return monthMs;\n const seasonMs = resolveSeasonYear(anchorMs, lower, direction);\n if (seasonMs !== null) return seasonMs;\n\n return null;\n}\n\n/**\n * Resolve an end-bound period to an *exclusive* upper bound ms. Date-only\n * values convert to start-of-next-day (AGENTS.md §23); period names resolve to\n * the start of the *following* period.\n */\nfunction resolveEndBound(anchorMs: number, period: string): number | null {\n // Strip an optional \"end of \" prefix so \"until end of March\" resolves the\n // same as \"until March\". Review #1578 r2: previously the prefix was passed\n // unchanged and resolveEndBound returned null for the full phrase.\n const trimmed = period.trim().replace(/^end\\s+of\\s+/i, \"\").trim();\n\n // Bare four-digit year: exclusive end = January 1 of the FOLLOWING year.\n if (/^\\d{4}$/.test(trimmed)) {\n return buildDateMs(Number(trimmed) + 1, 1, 1);\n }\n\n // YYYY-MM (year-month) end bound: exclusive end = start of the FOLLOWING\n // month, so \"until 2025-06\" spans all of June (#1578 review r3).\n const ymEnd = /^(\\d{4})-(\\d{2})$/.exec(trimmed);\n if (ymEnd) {\n const startMs = buildDateMs(Number(ymEnd[1]), Number(ymEnd[2]), 1);\n if (startMs === null) return null;\n const nd = new Date(startMs);\n nd.setUTCMonth(nd.getUTCMonth() + 1);\n return startOfDayUtc(nd.getTime());\n }\n\n // Absolute date/datetime end bound.\n const absMs = resolveAbsolute(trimmed);\n if (absMs !== null) {\n // Date-only → start of next day (exclusive end). Datetime → use as-is.\n if (!/[Tt]/.test(trimmed)) return startOfNextDayUtc(absMs);\n return absMs;\n }\n // Explicit \"<month|season> <year>\" end bound (e.g. \"until March 2025\",\n // \"through spring 2025\"). The explicit year is authoritative, so the\n // exclusive end = start of the FOLLOWING month (for a single month) or the\n // start of the month AFTER the season ends (for a 3-month season).\n // Review r2: seasons previously advanced only 1 month, cutting off the\n // last 2 months of the season.\n const explicitMs = resolveExplicitMonthYear(trimmed);\n if (explicitMs !== null) {\n const nd = new Date(explicitMs);\n const firstWord = trimmed.toLowerCase().split(/\\s+/)[0];\n const monthAdvance = firstWord in SEASON_TO_MONTH ? 3 : 1;\n nd.setUTCMonth(nd.getUTCMonth() + monthAdvance);\n return startOfDayUtc(nd.getTime());\n }\n\n // Period-name end bound: month → exclusive end at start of the FOLLOWING\n // month. \"until <month>\" is backwards-looking (the fact already stopped\n // being true), so prefer the most recent PAST boundary: build it in the\n // anchor year and roll back a year if that boundary is still future.\n const lower = trimmed.toLowerCase();\n const monthIdx = monthIndex(lower);\n if (typeof monthIdx === \"number\") {\n const d = new Date(anchorMs);\n const startMs = buildDateMs(d.getUTCFullYear(), monthIdx, 1);\n if (startMs === null) return null;\n // Exclusive end = start of the month AFTER the named month.\n const nd = new Date(startMs);\n nd.setUTCMonth(nd.getUTCMonth() + 1);\n let endMs = startOfDayUtc(nd.getTime());\n // Only roll back when the named month boundary is genuinely future\n // relative to the anchor cycle. When the anchor IS in the named month,\n // the end of the current month is the right boundary — do not roll back\n // (cursor review r2: \"until March\" from mid-March returned the prior year).\n if (endMs > anchorMs && d.getUTCMonth() + 1 !== monthIdx) {\n nd.setUTCFullYear(nd.getUTCFullYear() - 1);\n endMs = startOfDayUtc(nd.getTime());\n }\n return endMs;\n }\n // Season end bound: advance by the full 3-month season. Same\n // backwards-looking rollback logic as month names, but do not roll back\n // when the anchor is currently inside the season (codex review r2: bare\n // season end bounds like \"until spring\" / \"through summer\" returned null).\n const seasonMonth = SEASON_TO_MONTH[lower];\n if (typeof seasonMonth === \"number\") {\n const d = new Date(anchorMs);\n const anchorMonth = d.getUTCMonth() + 1;\n let year = d.getUTCFullYear();\n // Winter (Dec) from Jan/Feb: the current winter started in prev Dec,\n // so build the season start from the previous year (codex review r2:\n // bare winter end bounds used the anchor year's December, producing\n // an exclusive end one year too far forward).\n if (seasonMonth === 12 && anchorMonth <= 2) year -= 1;\n const startMs = buildDateMs(year, seasonMonth, 1);\n if (startMs === null) return null;\n const nd = new Date(startMs);\n nd.setUTCMonth(nd.getUTCMonth() + 3);\n let endMs = startOfDayUtc(nd.getTime());\n if (endMs > anchorMs && !isInSeason(seasonMonth, anchorMonth)) {\n nd.setUTCFullYear(nd.getUTCFullYear() - 1);\n endMs = startOfDayUtc(nd.getTime());\n }\n return endMs;\n }\n if (lower === \"year\") {\n const d = new Date(anchorMs);\n return buildDateMs(d.getUTCFullYear() + 1, 1, 1);\n }\n return null;\n}\n\n/**\n * Resolved bi-temporal fields for a single extracted fact (issue #1578 PR2).\n *\n * - `validFrom` / `validUntil` — the event-time `[from, until)` interval.\n * When `eventTimeSource === \"assumed\"`, `validFrom` is copied from\n * `observedAt` (the ingestion anchor) so every bi-temporal-on fact carries\n * at least a start bound.\n * - `observedAt` — always the ingestion anchor (the source turn timestamp).\n * - `eventTimeSource` — `\"extracted\"` when the expression resolved to a real\n * event-time interval; `\"assumed\"` when the expression was absent or\n * unresolvable.\n *\n * This is the single write-time helper every extraction entry path calls\n * (rule 39). It is pure: (expression, anchor) in, interval out. Resolution\n * never touches `Date.now()` — replay/import of old transcripts resolves\n * against the old anchor.\n */\nexport interface FactEventTime {\n validFrom?: string;\n validUntil?: string;\n observedAt: string;\n eventTimeSource: \"extracted\" | \"assumed\";\n}\n\n/**\n * Resolve a single fact's event-time expression against the ingestion anchor.\n *\n * Returns the bi-temporal interval to persist alongside the fact. When the\n * expression is absent, empty, or unresolvable, falls back to\n * `eventTimeSource: \"assumed\"` with `validFrom = observedAt` — per the\n * #1578 frontmatter contract. When the expression resolves but only pins one\n * bound (\"since 2024\" → validFrom only; \"until 2025-06\" → validUntil only),\n * only the resolved bound is returned.\n */\nexport function resolveFactEventTime(\n expression: string | undefined | null,\n anchorIso: string,\n): FactEventTime {\n const resolved = resolveEventTime(expression, anchorIso);\n if (resolved.ok && (resolved.validFrom !== undefined || resolved.validUntil !== undefined)) {\n return {\n ...(resolved.validFrom !== undefined ? { validFrom: resolved.validFrom } : {}),\n ...(resolved.validUntil !== undefined ? { validUntil: resolved.validUntil } : {}),\n observedAt: anchorIso,\n eventTimeSource: \"extracted\",\n };\n }\n return {\n validFrom: anchorIso,\n observedAt: anchorIso,\n eventTimeSource: \"assumed\",\n };\n}\n\n/**\n * Input shape for {@link pickFactEventTimeAnchor} — a structural slice of\n * `ExtractedFact` so the helper stays decoupled from the full type.\n */\nexport interface FactAnchorInput {\n /** Explicit per-fact source-turn timestamp (#1670). */\n sourceTurnTimestamp?: string;\n /** Claim-level provenance spans (#1575), each carrying the turn's `observedAt`. */\n sources?: { observedAt: string }[];\n}\n\n/**\n * Issue #1670 — select the per-fact event-time anchor.\n *\n * Prefers the fact's explicit `sourceTurnTimestamp` (set by extractors that\n * know the exact source turn). Falls back to the earliest provenance span's\n * `observedAt` (the turn where the supporting quote was located). Finally\n * falls back to the batch-wide anchor (latest source turn timestamp) when\n * neither per-fact signal is present — preserving legacy behaviour for\n * extractors that do not emit provenance.\n *\n * The earliest provenance span wins because a fact backed by quotes from\n * multiple turns was *first* uttered at the earliest turn: a relative\n * expression (\"yesterday\") on that fact should resolve against that turn,\n * not a later turn that merely restated the claim.\n *\n * Returns `undefined` only when no signal is usable AND `batchAnchor` is\n * absent — in which case the caller skips bi-temporal resolution entirely\n * (identical to the pre-feature pipeline when biTemporal is off).\n */\nexport function pickFactEventTimeAnchor(\n fact: FactAnchorInput,\n batchAnchor: string | undefined,\n): string | undefined {\n // 1. Explicit per-fact source-turn timestamp (highest priority).\n if (\n typeof fact.sourceTurnTimestamp === \"string\" &&\n fact.sourceTurnTimestamp.trim().length > 0\n ) {\n const ms = parseFlexibleIsoTimestamp(fact.sourceTurnTimestamp.trim());\n if (ms !== null) return new Date(ms).toISOString();\n }\n // 2. Earliest provenance span turn timestamp.\n if (fact.sources && fact.sources.length > 0) {\n let earliestMs: number | null = null;\n for (const src of fact.sources) {\n if (typeof src.observedAt !== \"string\") continue;\n const ms = parseFlexibleIsoTimestamp(src.observedAt.trim());\n if (ms === null) continue;\n if (earliestMs === null || ms < earliestMs) earliestMs = ms;\n }\n if (earliestMs !== null) return new Date(earliestMs).toISOString();\n }\n // 3. Batch-wide anchor (legacy fallback).\n return batchAnchor;\n}\n"],"mappings":"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","names":["ms"]}
@@ -10,7 +10,7 @@ import {
10
10
  import {
11
11
  planNamespaceMaintenance,
12
12
  runNamespaceMaintenanceBatchPlan
13
- } from "./chunk-EXUCUPV2.js";
13
+ } from "./chunk-WM7DNKBD.js";
14
14
  import {
15
15
  resolveHomeDir
16
16
  } from "./chunk-JUC24CTX.js";
@@ -441,4 +441,4 @@ var MaintenanceScheduler = class {
441
441
  export {
442
442
  MaintenanceScheduler
443
443
  };
444
- //# sourceMappingURL=chunk-Z4RU5VPM.js.map
444
+ //# sourceMappingURL=chunk-J334N6QV.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  runPostConsolidationMaterialize
3
- } from "./chunk-A7TJZLPK.js";
3
+ } from "./chunk-ZK2L72VN.js";
4
4
  import {
5
5
  discoverMemoryExtensions,
6
6
  renderExtensionsBlock,
@@ -217,4 +217,4 @@ export {
217
217
  buildExtensionsBlockForConsolidation,
218
218
  materializeAfterSemanticConsolidation
219
219
  };
220
- //# sourceMappingURL=chunk-NXRUUDUF.js.map
220
+ //# sourceMappingURL=chunk-JJJCVCCQ.js.map
@@ -22,7 +22,7 @@ import {
22
22
  } from "./chunk-H7XKCNR6.js";
23
23
  import {
24
24
  toRecallExplainJson
25
- } from "./chunk-7CTNUVHZ.js";
25
+ } from "./chunk-6SQQOJ4U.js";
26
26
  import {
27
27
  buildProposedActions,
28
28
  buildQualityScore,
@@ -30,12 +30,12 @@ import {
30
30
  listMemoryGovernanceRuns,
31
31
  readMemoryGovernanceRunArtifact,
32
32
  runMemoryGovernance
33
- } from "./chunk-EDOQM4E4.js";
33
+ } from "./chunk-WAFDHKES.js";
34
34
  import {
35
35
  clusterByKey,
36
36
  createCorrectionService,
37
37
  isCorrectionFeatureEnabled
38
- } from "./chunk-VCLGUIFM.js";
38
+ } from "./chunk-Z3FGC3QE.js";
39
39
  import {
40
40
  getTrustZoneStoreStatus,
41
41
  isTrustZoneName,
@@ -50,7 +50,7 @@ import {
50
50
  } from "./chunk-FF4KLI5W.js";
51
51
  import {
52
52
  estimateRecallTokens
53
- } from "./chunk-GJSL4WG2.js";
53
+ } from "./chunk-F3XZN24Z.js";
54
54
  import {
55
55
  namespaceCollectionName
56
56
  } from "./chunk-QR67FU5G.js";
@@ -116,17 +116,17 @@ import {
116
116
  buildBriefing,
117
117
  parseBriefingFocus,
118
118
  parseBriefingWindow
119
- } from "./chunk-UO5ZHIIH.js";
119
+ } from "./chunk-4WZ3J7M6.js";
120
120
  import {
121
121
  parseEntityFile
122
- } from "./chunk-EVPNWN7Z.js";
122
+ } from "./chunk-4R3CGCI5.js";
123
123
  import {
124
124
  stripAttributesSuffix
125
125
  } from "./chunk-SVOZFLIQ.js";
126
126
  import {
127
127
  DEFAULT_RECALL_DISCLOSURE,
128
128
  isRecallDisclosure
129
- } from "./chunk-ILFSEIRT.js";
129
+ } from "./chunk-7AG54AF3.js";
130
130
  import {
131
131
  inferMemoryStatus,
132
132
  toMemoryPathRel
@@ -8107,7 +8107,7 @@ ${next}`);
8107
8107
  * Return per-phase Dreams telemetry for the last N hours (default 24).
8108
8108
  */
8109
8109
  async dreamsStatus(options) {
8110
- const { getDreamsStatus, normalizeDreamsStatusWindowHours } = await import("./dreams-ledger-3WSCI5V4.js");
8110
+ const { getDreamsStatus, normalizeDreamsStatusWindowHours } = await import("./dreams-ledger-6UODQOX6.js");
8111
8111
  let windowHours;
8112
8112
  try {
8113
8113
  windowHours = normalizeDreamsStatusWindowHours(options?.windowHours);
@@ -8126,7 +8126,7 @@ ${next}`);
8126
8126
  * respectively, returning the same telemetry shape as a scheduled run.
8127
8127
  */
8128
8128
  async dreamsRun(options) {
8129
- const { runDreamsPhase } = await import("./dreams-ledger-3WSCI5V4.js");
8129
+ const { runDreamsPhase } = await import("./dreams-ledger-6UODQOX6.js");
8130
8130
  const validPhases = ["lightSleep", "rem", "deepSleep"];
8131
8131
  if (!validPhases.includes(options.phase)) {
8132
8132
  throw new EngramAccessInputError(
@@ -8393,4 +8393,4 @@ export {
8393
8393
  shapeMemorySummary,
8394
8394
  EngramAccessService
8395
8395
  };
8396
- //# sourceMappingURL=chunk-GDUOCHCD.js.map
8396
+ //# sourceMappingURL=chunk-KGZF2VO3.js.map