@remnic/core 9.3.705 → 9.3.706

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 (259) hide show
  1. package/dist/access-boundary.d.ts +5 -5
  2. package/dist/access-boundary.js +10 -10
  3. package/dist/access-cli.js +26 -25
  4. package/dist/access-cli.js.map +1 -1
  5. package/dist/access-http.d.ts +5 -5
  6. package/dist/access-http.js +14 -14
  7. package/dist/access-mcp.d.ts +5 -5
  8. package/dist/access-mcp.js +13 -13
  9. package/dist/access-operations-batch.js +11 -11
  10. package/dist/access-operations.d.ts +5 -5
  11. package/dist/access-operations.js +12 -12
  12. package/dist/{access-service-C8hc8N2i.d.ts → access-service-j1c1gptF.d.ts} +3 -3
  13. package/dist/access-service.d.ts +5 -5
  14. package/dist/access-service.js +9 -9
  15. package/dist/access-surface-catalog.d.ts +5 -5
  16. package/dist/action-confidence.d.ts +1 -1
  17. package/dist/active-memory-bridge.d.ts +1 -1
  18. package/dist/active-recall.d.ts +1 -1
  19. package/dist/behavior-learner.d.ts +1 -1
  20. package/dist/behavior-signals.d.ts +1 -1
  21. package/dist/bootstrap.d.ts +4 -4
  22. package/dist/briefing.d.ts +1 -1
  23. package/dist/briefing.js +5 -5
  24. package/dist/buffer-surprise-report.d.ts +1 -1
  25. package/dist/buffer.d.ts +1 -1
  26. package/dist/calibration.d.ts +1 -1
  27. package/dist/capabilities.d.ts +1 -1
  28. package/dist/{catalog-CAeU0e1C.d.ts → catalog-CKxilpzS.d.ts} +1 -1
  29. package/dist/causal-behavior.d.ts +1 -1
  30. package/dist/causal-consolidation.d.ts +1 -1
  31. package/dist/causal-consolidation.js +6 -6
  32. package/dist/{chunk-JZCKDTAS.js → chunk-24FGNOQS.js} +3 -3
  33. package/dist/{chunk-C2EHWNP2.js → chunk-2VQYHHWB.js} +9 -3
  34. package/dist/chunk-2VQYHHWB.js.map +1 -0
  35. package/dist/{chunk-47LPHBIP.js → chunk-3PTOZJOI.js} +2 -2
  36. package/dist/{chunk-2SYPOX45.js → chunk-4DZATVK5.js} +3 -3
  37. package/dist/{chunk-S5APSA3U.js → chunk-4E2QCH46.js} +2 -2
  38. package/dist/{chunk-KKK7YTYN.js → chunk-5GSUBCZM.js} +6 -2
  39. package/dist/chunk-5GSUBCZM.js.map +1 -0
  40. package/dist/{chunk-5DTWZ66X.js → chunk-66TSLESZ.js} +2 -2
  41. package/dist/{chunk-IREVVFTM.js → chunk-6CIAGZ6X.js} +9 -1
  42. package/dist/chunk-6CIAGZ6X.js.map +1 -0
  43. package/dist/{chunk-Y4PMATX2.js → chunk-6HPJMR5I.js} +2 -2
  44. package/dist/{chunk-M5MWSG4S.js → chunk-BGAHTI4C.js} +5 -5
  45. package/dist/{chunk-OM6ETLLH.js → chunk-C63MK3WL.js} +2 -2
  46. package/dist/{chunk-GT4VBKM4.js → chunk-EJDAXR7O.js} +5 -5
  47. package/dist/{chunk-ULVM34NP.js → chunk-ESMY4RJ4.js} +2 -2
  48. package/dist/{chunk-MNH2OODZ.js → chunk-GKI6LX5L.js} +2 -2
  49. package/dist/{chunk-KZMMAVR2.js → chunk-HIV5E57C.js} +2 -2
  50. package/dist/{chunk-SFOAQQDJ.js → chunk-IONFO7UK.js} +3 -3
  51. package/dist/{chunk-BMKGG7GC.js → chunk-IVCQW4C4.js} +2 -2
  52. package/dist/chunk-M7R5R6OJ.js +355 -0
  53. package/dist/chunk-M7R5R6OJ.js.map +1 -0
  54. package/dist/{chunk-IX3UQT4H.js → chunk-MLLTU5FX.js} +1 -1
  55. package/dist/chunk-MLLTU5FX.js.map +1 -0
  56. package/dist/{chunk-NFGJBEPT.js → chunk-MRX6ZXHZ.js} +2 -2
  57. package/dist/{chunk-GI3MTYDU.js → chunk-N75N5SNX.js} +3 -3
  58. package/dist/{chunk-BKBSE3BU.js → chunk-NM6TSEGQ.js} +2 -2
  59. package/dist/{chunk-S3WYRPSA.js → chunk-PDJQVAGM.js} +68 -31
  60. package/dist/chunk-PDJQVAGM.js.map +1 -0
  61. package/dist/{chunk-SY6WG6DB.js → chunk-RH2OSRQY.js} +2 -2
  62. package/dist/{chunk-YTMDF6S7.js → chunk-SPETAWFE.js} +2 -2
  63. package/dist/{chunk-JHAYR2JY.js → chunk-STYMKPFT.js} +7 -7
  64. package/dist/{chunk-OMNTQPZO.js → chunk-TKZ3AL5V.js} +2 -2
  65. package/dist/{chunk-IFR23TC5.js → chunk-VYZNWH4J.js} +37 -6
  66. package/dist/chunk-VYZNWH4J.js.map +1 -0
  67. package/dist/{chunk-KFU2SKDD.js → chunk-W2S3Z5MT.js} +2 -2
  68. package/dist/{chunk-6GJ2WQRK.js → chunk-W2WQ4LE7.js} +2 -2
  69. package/dist/{chunk-7ARKLLCV.js → chunk-WDH3KUZU.js} +2 -2
  70. package/dist/{chunk-7L54YZUI.js → chunk-WQADZ3ZY.js} +17 -17
  71. package/dist/{chunk-HEHPVBWA.js → chunk-WSWYIKXX.js} +4 -4
  72. package/dist/{chunk-WN4GHSDH.js → chunk-XKMDDM7P.js} +2 -2
  73. package/dist/{chunk-LY4FJLPT.js → chunk-Y6YHAGQP.js} +2 -2
  74. package/dist/{cli-ChE0XlJY.d.ts → cli-CbT-pyM4.d.ts} +3 -3
  75. package/dist/cli.d.ts +6 -6
  76. package/dist/cli.js +26 -26
  77. package/dist/compounding/engine.d.ts +1 -1
  78. package/dist/compounding/engine.js +5 -5
  79. package/dist/compounding/preference-consolidator.d.ts +1 -1
  80. package/dist/compression-optimizer.d.ts +1 -1
  81. package/dist/config.d.ts +1 -1
  82. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  83. package/dist/connectors/codex-materialize-runner.js +5 -5
  84. package/dist/connectors/codex-materialize.d.ts +1 -1
  85. package/dist/connectors/index.d.ts +1 -1
  86. package/dist/connectors/index.js +5 -5
  87. package/dist/consolidation-provenance-check.d.ts +1 -1
  88. package/dist/consolidation-undo.d.ts +1 -1
  89. package/dist/contradiction/index.d.ts +1 -1
  90. package/dist/conversation-index/backend.d.ts +1 -1
  91. package/dist/conversation-index/chunker.d.ts +1 -1
  92. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  93. package/dist/conversation-index/indexer.d.ts +1 -1
  94. package/dist/conversation-index/search.d.ts +1 -1
  95. package/dist/day-summary.d.ts +1 -1
  96. package/dist/delinearize.d.ts +1 -1
  97. package/dist/direct-answer-wiring.d.ts +1 -1
  98. package/dist/direct-answer.d.ts +1 -1
  99. package/dist/embedding-fallback.d.ts +1 -1
  100. package/dist/enrichment/index.d.ts +1 -1
  101. package/dist/entity-retrieval.d.ts +1 -1
  102. package/dist/entity-retrieval.js +5 -5
  103. package/dist/entity-schema.d.ts +1 -1
  104. package/dist/event-time.d.ts +35 -1
  105. package/dist/event-time.js +6 -320
  106. package/dist/event-time.js.map +1 -1
  107. package/dist/explicit-capture.d.ts +4 -4
  108. package/dist/extraction-faithfulness.d.ts +1 -1
  109. package/dist/extraction-judge-telemetry.d.ts +1 -1
  110. package/dist/extraction-judge-training.d.ts +1 -1
  111. package/dist/extraction-judge.d.ts +1 -1
  112. package/dist/extraction.d.ts +10 -1
  113. package/dist/extraction.js +2 -2
  114. package/dist/fallback-llm.d.ts +1 -1
  115. package/dist/{forget-6SOIPUMQ.js → forget-U66KPDPY.js} +3 -3
  116. package/dist/identity-continuity.d.ts +1 -1
  117. package/dist/importance.d.ts +1 -1
  118. package/dist/index.d.ts +9 -9
  119. package/dist/index.js +35 -34
  120. package/dist/index.js.map +1 -1
  121. package/dist/intent.d.ts +1 -1
  122. package/dist/lcm/engine.d.ts +1 -1
  123. package/dist/lcm/index.d.ts +1 -1
  124. package/dist/lcm/tools.d.ts +1 -1
  125. package/dist/lifecycle.d.ts +1 -1
  126. package/dist/live-connectors-runner.d.ts +1 -1
  127. package/dist/local-llm.d.ts +1 -1
  128. package/dist/maintenance/memory-governance.d.ts +1 -1
  129. package/dist/maintenance/memory-governance.js +5 -5
  130. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +5 -5
  131. package/dist/maintenance/rebuild-memory-projection.js +6 -6
  132. package/dist/mcp-memory-inspector-app.d.ts +5 -5
  133. package/dist/memory-action-policy.d.ts +1 -1
  134. package/dist/memory-cache.d.ts +1 -1
  135. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  136. package/dist/memory-projection-store.d.ts +1 -1
  137. package/dist/memory-provenance.d.ts +1 -1
  138. package/dist/memory-worth-outcomes.d.ts +1 -1
  139. package/dist/models-json.d.ts +1 -1
  140. package/dist/namespaces/migrate.d.ts +2 -2
  141. package/dist/namespaces/migrate.js +6 -6
  142. package/dist/namespaces/principal.d.ts +1 -1
  143. package/dist/namespaces/search.d.ts +1 -1
  144. package/dist/namespaces/storage.d.ts +2 -2
  145. package/dist/namespaces/storage.js +5 -5
  146. package/dist/native-knowledge.d.ts +1 -1
  147. package/dist/operator-toolkit.d.ts +1 -1
  148. package/dist/operator-toolkit.js +10 -10
  149. package/dist/orchestration/maintenance.d.ts +2 -2
  150. package/dist/orchestration/maintenance.js +7 -7
  151. package/dist/{orchestrator-m_PnhyHj.d.ts → orchestrator-D4ovYV3x.d.ts} +3 -3
  152. package/dist/orchestrator.d.ts +4 -4
  153. package/dist/orchestrator.js +20 -19
  154. package/dist/patterns-cli.d.ts +1 -1
  155. package/dist/policy-runtime.d.ts +1 -1
  156. package/dist/provenance.d.ts +1 -1
  157. package/dist/qmd-recall-cache.d.ts +1 -1
  158. package/dist/qmd.d.ts +1 -1
  159. package/dist/recall-disclosure-escalation.d.ts +1 -1
  160. package/dist/recall-explain-renderer.d.ts +1 -1
  161. package/dist/recall-explain-renderer.js +3 -3
  162. package/dist/recall-planner-llm.d.ts +1 -1
  163. package/dist/recall-state.d.ts +1 -1
  164. package/dist/recall-tag-filter.d.ts +1 -1
  165. package/dist/recall-xray-cli.d.ts +1 -1
  166. package/dist/recall-xray-cli.js +4 -4
  167. package/dist/recall-xray-renderer.d.ts +1 -1
  168. package/dist/recall-xray-renderer.js +3 -3
  169. package/dist/recall-xray.d.ts +1 -1
  170. package/dist/recall-xray.js +2 -2
  171. package/dist/resolve-auth-token.d.ts +1 -1
  172. package/dist/retrieval-agents.d.ts +1 -1
  173. package/dist/retrieval-tiers.d.ts +1 -1
  174. package/dist/routing/engine.d.ts +1 -1
  175. package/dist/routing/store.d.ts +1 -1
  176. package/dist/schemas.d.ts +38 -0
  177. package/dist/schemas.js +1 -1
  178. package/dist/search/embed-helper.d.ts +1 -1
  179. package/dist/search/factory.d.ts +1 -1
  180. package/dist/search/index.d.ts +1 -1
  181. package/dist/search/lancedb-backend.d.ts +1 -1
  182. package/dist/search/meilisearch-backend.d.ts +1 -1
  183. package/dist/search/noop-backend.d.ts +1 -1
  184. package/dist/search/orama-backend.d.ts +1 -1
  185. package/dist/search/port.d.ts +1 -1
  186. package/dist/search/remote-backend.d.ts +1 -1
  187. package/dist/{semantic-consolidation-DVBbq6Wr.d.ts → semantic-consolidation-DyMUCsfN.d.ts} +1 -1
  188. package/dist/semantic-consolidation.d.ts +2 -2
  189. package/dist/semantic-consolidation.js +6 -6
  190. package/dist/semantic-rule-promotion.js +5 -5
  191. package/dist/semantic-rule-verifier.d.ts +1 -1
  192. package/dist/semantic-rule-verifier.js +5 -5
  193. package/dist/session-observer-bands.d.ts +1 -1
  194. package/dist/session-observer-state.d.ts +1 -1
  195. package/dist/shared-context/manager.d.ts +1 -1
  196. package/dist/signal.d.ts +1 -1
  197. package/dist/storage.d.ts +5 -1
  198. package/dist/storage.js +4 -4
  199. package/dist/summarizer.d.ts +1 -1
  200. package/dist/summary-snapshot.d.ts +1 -1
  201. package/dist/temporal-supersession.d.ts +1 -1
  202. package/dist/temporal-supersession.js +2 -2
  203. package/dist/temporal-validity.d.ts +2 -2
  204. package/dist/temporal-validity.js +1 -1
  205. package/dist/threading.d.ts +1 -1
  206. package/dist/tier-migration.d.ts +1 -1
  207. package/dist/tier-routing.d.ts +1 -1
  208. package/dist/topics.d.ts +1 -1
  209. package/dist/transcript.d.ts +1 -1
  210. package/dist/{types-CJrvHJjx.d.ts → types-Couvz-L3.d.ts} +12 -2
  211. package/dist/types.d.ts +1 -1
  212. package/dist/types.js +1 -1
  213. package/dist/utility-runtime.d.ts +1 -1
  214. package/dist/verified-recall.js +5 -5
  215. package/package.json +2 -2
  216. package/src/event-time.ts +73 -0
  217. package/src/extraction-eventtime-wiring.test.ts +269 -0
  218. package/src/extraction.ts +50 -3
  219. package/src/orchestrator.ts +71 -17
  220. package/src/schemas.ts +12 -0
  221. package/src/storage.ts +13 -2
  222. package/src/temporal-validity.test.ts +33 -0
  223. package/src/temporal-validity.ts +24 -1
  224. package/src/types.ts +12 -2
  225. package/dist/chunk-C2EHWNP2.js.map +0 -1
  226. package/dist/chunk-IFR23TC5.js.map +0 -1
  227. package/dist/chunk-IREVVFTM.js.map +0 -1
  228. package/dist/chunk-IX3UQT4H.js.map +0 -1
  229. package/dist/chunk-KKK7YTYN.js.map +0 -1
  230. package/dist/chunk-S3WYRPSA.js.map +0 -1
  231. /package/dist/{chunk-JZCKDTAS.js.map → chunk-24FGNOQS.js.map} +0 -0
  232. /package/dist/{chunk-47LPHBIP.js.map → chunk-3PTOZJOI.js.map} +0 -0
  233. /package/dist/{chunk-2SYPOX45.js.map → chunk-4DZATVK5.js.map} +0 -0
  234. /package/dist/{chunk-S5APSA3U.js.map → chunk-4E2QCH46.js.map} +0 -0
  235. /package/dist/{chunk-5DTWZ66X.js.map → chunk-66TSLESZ.js.map} +0 -0
  236. /package/dist/{chunk-Y4PMATX2.js.map → chunk-6HPJMR5I.js.map} +0 -0
  237. /package/dist/{chunk-M5MWSG4S.js.map → chunk-BGAHTI4C.js.map} +0 -0
  238. /package/dist/{chunk-OM6ETLLH.js.map → chunk-C63MK3WL.js.map} +0 -0
  239. /package/dist/{chunk-GT4VBKM4.js.map → chunk-EJDAXR7O.js.map} +0 -0
  240. /package/dist/{chunk-ULVM34NP.js.map → chunk-ESMY4RJ4.js.map} +0 -0
  241. /package/dist/{chunk-MNH2OODZ.js.map → chunk-GKI6LX5L.js.map} +0 -0
  242. /package/dist/{chunk-KZMMAVR2.js.map → chunk-HIV5E57C.js.map} +0 -0
  243. /package/dist/{chunk-SFOAQQDJ.js.map → chunk-IONFO7UK.js.map} +0 -0
  244. /package/dist/{chunk-BMKGG7GC.js.map → chunk-IVCQW4C4.js.map} +0 -0
  245. /package/dist/{chunk-NFGJBEPT.js.map → chunk-MRX6ZXHZ.js.map} +0 -0
  246. /package/dist/{chunk-GI3MTYDU.js.map → chunk-N75N5SNX.js.map} +0 -0
  247. /package/dist/{chunk-BKBSE3BU.js.map → chunk-NM6TSEGQ.js.map} +0 -0
  248. /package/dist/{chunk-SY6WG6DB.js.map → chunk-RH2OSRQY.js.map} +0 -0
  249. /package/dist/{chunk-YTMDF6S7.js.map → chunk-SPETAWFE.js.map} +0 -0
  250. /package/dist/{chunk-JHAYR2JY.js.map → chunk-STYMKPFT.js.map} +0 -0
  251. /package/dist/{chunk-OMNTQPZO.js.map → chunk-TKZ3AL5V.js.map} +0 -0
  252. /package/dist/{chunk-KFU2SKDD.js.map → chunk-W2S3Z5MT.js.map} +0 -0
  253. /package/dist/{chunk-6GJ2WQRK.js.map → chunk-W2WQ4LE7.js.map} +0 -0
  254. /package/dist/{chunk-7ARKLLCV.js.map → chunk-WDH3KUZU.js.map} +0 -0
  255. /package/dist/{chunk-7L54YZUI.js.map → chunk-WQADZ3ZY.js.map} +0 -0
  256. /package/dist/{chunk-HEHPVBWA.js.map → chunk-WSWYIKXX.js.map} +0 -0
  257. /package/dist/{chunk-WN4GHSDH.js.map → chunk-XKMDDM7P.js.map} +0 -0
  258. /package/dist/{chunk-LY4FJLPT.js.map → chunk-Y6YHAGQP.js.map} +0 -0
  259. /package/dist/{forget-6SOIPUMQ.js.map → forget-U66KPDPY.js.map} +0 -0
@@ -1,4 +1,4 @@
1
- import { g as MemoryFile, P as PluginConfig } from './types-CJrvHJjx.js';
1
+ import { g as MemoryFile, P as PluginConfig } from './types-Couvz-L3.js';
2
2
  import { TrustZoneName } from './trust-zones.js';
3
3
  import { T as Taxonomy } from './types-DJhqDJUV.js';
4
4
  import { DirectAnswerResult } from './direct-answer.js';
@@ -1,5 +1,5 @@
1
1
  import { TrustZoneName } from './trust-zones.js';
2
- import { g as MemoryFile } from './types-CJrvHJjx.js';
2
+ import { g as MemoryFile } from './types-Couvz-L3.js';
3
3
  import './types-gb_SNtjR.js';
4
4
  import './message-parts/index.js';
5
5
 
@@ -1,4 +1,4 @@
1
- import { P as PluginConfig } from './types-CJrvHJjx.js';
1
+ import { P as PluginConfig } from './types-Couvz-L3.js';
2
2
  import './types-gb_SNtjR.js';
3
3
  import './message-parts/index.js';
4
4
 
@@ -1,4 +1,4 @@
1
- import { M as MemoryCategory, y as ImportanceLevel } from '../types-CJrvHJjx.js';
1
+ import { M as MemoryCategory, y as ImportanceLevel } from '../types-Couvz-L3.js';
2
2
  import { LoggerBackend } from '../logger.js';
3
3
  import '../types-gb_SNtjR.js';
4
4
  import '../message-parts/index.js';
@@ -1,5 +1,5 @@
1
1
  import { StorageManager } from './storage.js';
2
- import { P as PluginConfig, T as TranscriptEntry } from './types-CJrvHJjx.js';
2
+ import { P as PluginConfig, T as TranscriptEntry } from './types-Couvz-L3.js';
3
3
  import './page-versioning.js';
4
4
  import './consolidation-operator.js';
5
5
  import './memory-projection-store.js';
@@ -3,19 +3,19 @@ import {
3
3
  entityIndexVersion,
4
4
  entityRecentTranscriptLookbackHours,
5
5
  readRecentEntityTranscriptEntries
6
- } from "./chunk-KZMMAVR2.js";
6
+ } from "./chunk-HIV5E57C.js";
7
7
  import "./chunk-ZCWIH4LH.js";
8
- import "./chunk-C2EHWNP2.js";
8
+ import "./chunk-2VQYHHWB.js";
9
9
  import "./chunk-M7XQSUBB.js";
10
10
  import "./chunk-3JJWNZTT.js";
11
11
  import "./chunk-5UZXUTVO.js";
12
12
  import "./chunk-5GPPACXK.js";
13
- import "./chunk-OMNTQPZO.js";
14
- import "./chunk-IREVVFTM.js";
13
+ import "./chunk-TKZ3AL5V.js";
14
+ import "./chunk-6CIAGZ6X.js";
15
15
  import "./chunk-SVOZFLIQ.js";
16
16
  import "./chunk-LTJAMRGI.js";
17
17
  import "./chunk-J6A3CX5N.js";
18
- import "./chunk-IX3UQT4H.js";
18
+ import "./chunk-MLLTU5FX.js";
19
19
  import "./chunk-RULE4VG5.js";
20
20
  import "./chunk-SCU65EZI.js";
21
21
  import "./chunk-MB5RSUW6.js";
@@ -1,4 +1,4 @@
1
- import { Z as EntitySchemaDefinition, _ as EntitySchemaSectionDefinition, $ as EntityStructuredSection } from './types-CJrvHJjx.js';
1
+ import { Z as EntitySchemaDefinition, _ as EntitySchemaSectionDefinition, $ as EntityStructuredSection } from './types-Couvz-L3.js';
2
2
  import './types-gb_SNtjR.js';
3
3
  import './message-parts/index.js';
4
4
 
@@ -31,5 +31,39 @@ interface ResolvedEventTime {
31
31
  * @param anchorIso the source turn's ISO timestamp — the resolution anchor
32
32
  */
33
33
  declare function resolveEventTime(expression: string | undefined | null, anchorIso: string): ResolvedEventTime;
34
+ /**
35
+ * Resolved bi-temporal fields for a single extracted fact (issue #1578 PR2).
36
+ *
37
+ * - `validFrom` / `validUntil` — the event-time `[from, until)` interval.
38
+ * When `eventTimeSource === "assumed"`, `validFrom` is copied from
39
+ * `observedAt` (the ingestion anchor) so every bi-temporal-on fact carries
40
+ * at least a start bound.
41
+ * - `observedAt` — always the ingestion anchor (the source turn timestamp).
42
+ * - `eventTimeSource` — `"extracted"` when the expression resolved to a real
43
+ * event-time interval; `"assumed"` when the expression was absent or
44
+ * unresolvable.
45
+ *
46
+ * This is the single write-time helper every extraction entry path calls
47
+ * (rule 39). It is pure: (expression, anchor) in, interval out. Resolution
48
+ * never touches `Date.now()` — replay/import of old transcripts resolves
49
+ * against the old anchor.
50
+ */
51
+ interface FactEventTime {
52
+ validFrom?: string;
53
+ validUntil?: string;
54
+ observedAt: string;
55
+ eventTimeSource: "extracted" | "assumed";
56
+ }
57
+ /**
58
+ * Resolve a single fact's event-time expression against the ingestion anchor.
59
+ *
60
+ * Returns the bi-temporal interval to persist alongside the fact. When the
61
+ * expression is absent, empty, or unresolvable, falls back to
62
+ * `eventTimeSource: "assumed"` with `validFrom = observedAt` — per the
63
+ * #1578 frontmatter contract. When the expression resolves but only pins one
64
+ * bound ("since 2024" → validFrom only; "until 2025-06" → validUntil only),
65
+ * only the resolved bound is returned.
66
+ */
67
+ declare function resolveFactEventTime(expression: string | undefined | null, anchorIso: string): FactEventTime;
34
68
 
35
- export { type ResolvedEventTime, resolveEventTime };
69
+ export { type FactEventTime, type ResolvedEventTime, resolveEventTime, resolveFactEventTime };
@@ -1,325 +1,11 @@
1
1
  import {
2
- parseFlexibleIsoTimestamp
3
- } from "./chunk-P7FMDTKL.js";
2
+ resolveEventTime,
3
+ resolveFactEventTime
4
+ } from "./chunk-M7R5R6OJ.js";
5
+ import "./chunk-P7FMDTKL.js";
4
6
  import "./chunk-PZ5AY32C.js";
5
-
6
- // src/event-time.ts
7
- var UNITS = ["day", "week", "month", "quarter", "year"];
8
- function isRelativeUnit(unit) {
9
- return UNITS.includes(unit);
10
- }
11
- function toIsoUtc(ms) {
12
- if (ms === null || !Number.isFinite(ms)) return void 0;
13
- return new Date(ms).toISOString();
14
- }
15
- function startOfDayUtc(ms) {
16
- const d = new Date(ms);
17
- d.setUTCHours(0, 0, 0, 0);
18
- return d.getTime();
19
- }
20
- function startOfNextDayUtc(ms) {
21
- const d = new Date(startOfDayUtc(ms));
22
- d.setUTCDate(d.getUTCDate() + 1);
23
- return d.getTime();
24
- }
25
- var SEASON_TO_MONTH = {
26
- winter: 12,
27
- // Dec–Feb anchor Dec (Northern Hemisphere convention)
28
- spring: 3,
29
- summer: 6,
30
- fall: 9,
31
- autumn: 9
32
- };
33
- var MONTH_NAMES = {
34
- january: 1,
35
- february: 2,
36
- march: 3,
37
- april: 4,
38
- may: 5,
39
- june: 6,
40
- july: 7,
41
- august: 8,
42
- september: 9,
43
- october: 10,
44
- november: 11,
45
- december: 12,
46
- jan: 1,
47
- feb: 2,
48
- mar: 3,
49
- apr: 4,
50
- jun: 6,
51
- jul: 7,
52
- aug: 8,
53
- sep: 9,
54
- sept: 9,
55
- oct: 10,
56
- nov: 11,
57
- dec: 12
58
- };
59
- var QUARTER_START_MONTH = {
60
- 1: 1,
61
- 2: 4,
62
- 3: 7,
63
- 4: 10
64
- };
65
- function monthIndex(token) {
66
- const idx = MONTH_NAMES[token.toLowerCase()];
67
- return typeof idx === "number" ? idx : void 0;
68
- }
69
- function buildDateMs(year, month1, day) {
70
- if (!Number.isInteger(year) || !Number.isInteger(month1) || month1 < 1 || month1 > 12 || !Number.isInteger(day) || day < 1 || day > daysInMonth(year, month1)) {
71
- return null;
72
- }
73
- return Date.UTC(year, month1 - 1, day, 0, 0, 0, 0);
74
- }
75
- function daysInMonth(year, month1) {
76
- return new Date(Date.UTC(year, month1, 0)).getUTCDate();
77
- }
78
- function shiftUnit(anchorMs, unit, count) {
79
- const d = new Date(anchorMs);
80
- switch (unit) {
81
- case "day":
82
- d.setUTCDate(d.getUTCDate() + count);
83
- return startOfDayUtc(d.getTime());
84
- case "week":
85
- d.setUTCDate(d.getUTCDate() + count * 7);
86
- return startOfDayUtc(d.getTime());
87
- case "month":
88
- d.setUTCMonth(d.getUTCMonth() + count, 1);
89
- return startOfDayUtc(d.getTime());
90
- case "quarter":
91
- d.setUTCMonth(d.getUTCMonth() + count * 3, 1);
92
- return startOfDayUtc(d.getTime());
93
- case "year":
94
- d.setUTCFullYear(d.getUTCFullYear() + count, 0, 1);
95
- return startOfDayUtc(d.getTime());
96
- }
97
- }
98
- function resolveMonthYear(anchorMs, monthToken, direction) {
99
- const lower = monthToken.toLowerCase();
100
- const targetMonth = monthIndex(lower);
101
- if (typeof targetMonth === "number") {
102
- const d = new Date(anchorMs);
103
- let year = d.getUTCFullYear();
104
- let m = targetMonth;
105
- if (direction === -1 && m >= d.getUTCMonth() + 1) year -= 1;
106
- else if (direction === 1 && m <= d.getUTCMonth() + 1) year += 1;
107
- return buildDateMs(year, m, 1);
108
- }
109
- return null;
110
- }
111
- function resolveExplicitMonthYear(token) {
112
- const m = token.trim().toLowerCase().match(/^([a-z]+)\s+(\d{4})$/);
113
- if (!m) return null;
114
- const year = parseInt(m[2], 10);
115
- if (!Number.isInteger(year)) return null;
116
- const monthIdx = monthIndex(m[1]);
117
- const baseMonth = typeof monthIdx === "number" ? monthIdx : SEASON_TO_MONTH[m[1]];
118
- if (typeof baseMonth !== "number") return null;
119
- return buildDateMs(year, baseMonth, 1);
120
- }
121
- function resolveBareYear(token) {
122
- const m = token.trim().match(/^(\d{4})$/);
123
- if (!m) return null;
124
- return buildDateMs(Number(m[1]), 1, 1);
125
- }
126
- function isInSeason(baseMonth, anchorMonth) {
127
- for (let i = 0; i < 3; i++) {
128
- if ((baseMonth - 1 + i) % 12 + 1 === anchorMonth) return true;
129
- }
130
- return false;
131
- }
132
- function resolveSeasonYear(anchorMs, seasonToken, direction) {
133
- const baseMonth = SEASON_TO_MONTH[seasonToken.toLowerCase()];
134
- if (typeof baseMonth !== "number") return null;
135
- const d = new Date(anchorMs);
136
- let year = d.getUTCFullYear();
137
- const anchorMonth = d.getUTCMonth() + 1;
138
- if (direction === -1) {
139
- if (baseMonth > anchorMonth || isInSeason(baseMonth, anchorMonth)) year -= 1;
140
- if (baseMonth === 12 && anchorMonth <= 2) year -= 1;
141
- } else if (direction === 1) {
142
- if (baseMonth === 12 && anchorMonth <= 2) {
143
- } else if (baseMonth < anchorMonth || isInSeason(baseMonth, anchorMonth)) {
144
- year += 1;
145
- }
146
- } else if (direction === 0 && baseMonth === 12 && anchorMonth <= 2) {
147
- year -= 1;
148
- }
149
- return buildDateMs(year, baseMonth, 1);
150
- }
151
- function resolveQuarter(anchorMs, qNumber, direction) {
152
- const startMonth = QUARTER_START_MONTH[qNumber];
153
- if (typeof startMonth !== "number") return null;
154
- const d = new Date(anchorMs);
155
- let year = d.getUTCFullYear();
156
- const anchorMonth = d.getUTCMonth() + 1;
157
- const anchorQ = Math.floor((anchorMonth - 1) / 3) + 1;
158
- if (direction === -1 && (startMonth >= anchorMonth || anchorQ === qNumber))
159
- year -= 1;
160
- else if (direction === 1 && (startMonth <= anchorMonth || anchorQ === qNumber))
161
- year += 1;
162
- return buildDateMs(year, startMonth, 1);
163
- }
164
- function resolveAbsolute(raw) {
165
- const trimmed = raw.trim();
166
- const ms = parseFlexibleIsoTimestamp(trimmed);
167
- if (ms === null) return null;
168
- if (!/[Tt]/.test(trimmed)) return startOfDayUtc(ms);
169
- return ms;
170
- }
171
- function resolveEventTime(expression, anchorIso) {
172
- const fallback = { ok: false };
173
- if (typeof expression !== "string") return fallback;
174
- const expr = expression.trim();
175
- if (expr.length === 0) return fallback;
176
- const anchorMs = parseFlexibleIsoTimestamp(anchorIso);
177
- if (anchorMs === null || !Number.isFinite(anchorMs)) return fallback;
178
- const lower = expr.toLowerCase();
179
- const sinceMatch = lower.match(/^since\s+(.+)$/);
180
- if (sinceMatch) {
181
- const inner = sinceMatch[1].trim();
182
- let fromMs = resolveRelativePeriod(anchorMs, inner) ?? resolveExplicitMonthYear(inner) ?? resolveBareYear(inner) ?? resolveAbsolute(inner);
183
- if (fromMs !== null && fromMs > anchorMs && !/\d{4}/.test(inner)) {
184
- const nd = new Date(fromMs);
185
- nd.setUTCFullYear(nd.getUTCFullYear() - 1);
186
- fromMs = nd.getTime();
187
- }
188
- const fromIso = toIsoUtc(fromMs);
189
- if (!fromIso) return fallback;
190
- return { validFrom: fromIso, ok: true };
191
- }
192
- const untilMatch = lower.match(/^(?:until|through|till|ending)\s+(.+)$/);
193
- if (untilMatch) {
194
- const inner = untilMatch[1].trim();
195
- const untilMs = resolveEndBound(anchorMs, inner);
196
- const untilIso = toIsoUtc(untilMs);
197
- if (!untilIso) return fallback;
198
- return { validUntil: untilIso, ok: true };
199
- }
200
- if (lower === "today") {
201
- const fromIso = toIsoUtc(startOfDayUtc(anchorMs));
202
- return fromIso ? { validFrom: fromIso, ok: true } : fallback;
203
- }
204
- if (lower === "yesterday") {
205
- const fromIso = toIsoUtc(shiftUnit(anchorMs, "day", -1));
206
- return fromIso ? { validFrom: fromIso, ok: true } : fallback;
207
- }
208
- if (lower === "tomorrow") {
209
- const fromIso = toIsoUtc(shiftUnit(anchorMs, "day", 1));
210
- return fromIso ? { validFrom: fromIso, ok: true } : fallback;
211
- }
212
- const relMatch = lower.match(/^(last|this|next)\s+(.+)$/);
213
- if (relMatch) {
214
- const direction = relMatch[1] === "last" ? -1 : relMatch[1] === "next" ? 1 : 0;
215
- const period = relMatch[2].trim();
216
- const ms = resolveRelativePeriod(anchorMs, period, direction);
217
- const fromIso = toIsoUtc(ms);
218
- return fromIso ? { validFrom: fromIso, ok: true } : fallback;
219
- }
220
- const explicitMs = resolveExplicitMonthYear(lower) ?? resolveBareYear(lower);
221
- if (explicitMs !== null) {
222
- const fromIso = toIsoUtc(explicitMs);
223
- if (fromIso) return { validFrom: fromIso, ok: true };
224
- }
225
- const absMs = resolveAbsolute(expr);
226
- if (absMs !== null) {
227
- const fromIso = toIsoUtc(absMs);
228
- return fromIso ? { validFrom: fromIso, ok: true } : fallback;
229
- }
230
- return fallback;
231
- }
232
- function resolveRelativePeriod(anchorMs, period, direction = 0) {
233
- const lower = period.trim().toLowerCase();
234
- const qTok = lower.match(/^q(?:uarter)?\s?([1-4])$/);
235
- if (qTok) {
236
- return resolveQuarter(anchorMs, Number(qTok[1]), direction);
237
- }
238
- if (lower === "quarter") {
239
- const d = new Date(anchorMs);
240
- let q = Math.floor(d.getUTCMonth() / 3) + 1;
241
- let year = d.getUTCFullYear();
242
- if (direction === -1) {
243
- q -= 1;
244
- if (q < 1) {
245
- q = 4;
246
- year -= 1;
247
- }
248
- } else if (direction === 1) {
249
- q += 1;
250
- if (q > 4) {
251
- q = 1;
252
- year += 1;
253
- }
254
- }
255
- return buildDateMs(year, QUARTER_START_MONTH[q], 1);
256
- }
257
- if (isRelativeUnit(lower)) {
258
- return shiftUnit(anchorMs, lower, direction);
259
- }
260
- const monthMs = resolveMonthYear(anchorMs, lower, direction);
261
- if (monthMs !== null) return monthMs;
262
- const seasonMs = resolveSeasonYear(anchorMs, lower, direction);
263
- if (seasonMs !== null) return seasonMs;
264
- return null;
265
- }
266
- function resolveEndBound(anchorMs, period) {
267
- const trimmed = period.trim().replace(/^end\s+of\s+/i, "").trim();
268
- if (/^\d{4}$/.test(trimmed)) {
269
- return buildDateMs(Number(trimmed) + 1, 1, 1);
270
- }
271
- const absMs = resolveAbsolute(trimmed);
272
- if (absMs !== null) {
273
- if (!/[Tt]/.test(trimmed)) return startOfNextDayUtc(absMs);
274
- return absMs;
275
- }
276
- const explicitMs = resolveExplicitMonthYear(trimmed);
277
- if (explicitMs !== null) {
278
- const nd = new Date(explicitMs);
279
- const firstWord = trimmed.toLowerCase().split(/\s+/)[0];
280
- const monthAdvance = firstWord in SEASON_TO_MONTH ? 3 : 1;
281
- nd.setUTCMonth(nd.getUTCMonth() + monthAdvance);
282
- return startOfDayUtc(nd.getTime());
283
- }
284
- const lower = trimmed.toLowerCase();
285
- const monthIdx = monthIndex(lower);
286
- if (typeof monthIdx === "number") {
287
- const d = new Date(anchorMs);
288
- const startMs = buildDateMs(d.getUTCFullYear(), monthIdx, 1);
289
- if (startMs === null) return null;
290
- const nd = new Date(startMs);
291
- nd.setUTCMonth(nd.getUTCMonth() + 1);
292
- let endMs = startOfDayUtc(nd.getTime());
293
- if (endMs > anchorMs && d.getUTCMonth() + 1 !== monthIdx) {
294
- nd.setUTCFullYear(nd.getUTCFullYear() - 1);
295
- endMs = startOfDayUtc(nd.getTime());
296
- }
297
- return endMs;
298
- }
299
- const seasonMonth = SEASON_TO_MONTH[lower];
300
- if (typeof seasonMonth === "number") {
301
- const d = new Date(anchorMs);
302
- const anchorMonth = d.getUTCMonth() + 1;
303
- let year = d.getUTCFullYear();
304
- if (seasonMonth === 12 && anchorMonth <= 2) year -= 1;
305
- const startMs = buildDateMs(year, seasonMonth, 1);
306
- if (startMs === null) return null;
307
- const nd = new Date(startMs);
308
- nd.setUTCMonth(nd.getUTCMonth() + 3);
309
- let endMs = startOfDayUtc(nd.getTime());
310
- if (endMs > anchorMs && !isInSeason(seasonMonth, anchorMonth)) {
311
- nd.setUTCFullYear(nd.getUTCFullYear() - 1);
312
- endMs = startOfDayUtc(nd.getTime());
313
- }
314
- return endMs;
315
- }
316
- if (lower === "year") {
317
- const d = new Date(anchorMs);
318
- return buildDateMs(d.getUTCFullYear() + 1, 1, 1);
319
- }
320
- return null;
321
- }
322
7
  export {
323
- resolveEventTime
8
+ resolveEventTime,
9
+ resolveFactEventTime
324
10
  };
325
11
  //# sourceMappingURL=event-time.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 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 // 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"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,5 +1,5 @@
1
- import { O as Orchestrator } from './orchestrator-m_PnhyHj.js';
2
- import { M as MemoryCategory, P as PluginConfig } from './types-CJrvHJjx.js';
1
+ import { O as Orchestrator } from './orchestrator-D4ovYV3x.js';
2
+ import { M as MemoryCategory, P as PluginConfig } from './types-Couvz-L3.js';
3
3
  import './briefing.js';
4
4
  import './storage.js';
5
5
  import './page-versioning.js';
@@ -21,7 +21,7 @@ import './session-integrity.js';
21
21
  import './summarizer.js';
22
22
  import './orchestration/maintenance.js';
23
23
  import './namespaces/search.js';
24
- import './catalog-CAeU0e1C.js';
24
+ import './catalog-CKxilpzS.js';
25
25
  import './live-connectors-runner.js';
26
26
  import './framework-CNDn2164.js';
27
27
  import './relevance.js';
@@ -43,7 +43,7 @@ import './lcm/archive.js';
43
43
  import './lcm/summarizer.js';
44
44
  import './lcm/dag.js';
45
45
  import './lcm/queue.js';
46
- import './semantic-consolidation-DVBbq6Wr.js';
46
+ import './semantic-consolidation-DyMUCsfN.js';
47
47
  import './connectors/codex-materialize.js';
48
48
  import './logger.js';
49
49
  import './conversation-index/backend.js';
@@ -1,4 +1,4 @@
1
- import { F as FaithfulnessFrontmatter, P as PluginConfig, k as MemoryFrontmatter } from './types-CJrvHJjx.js';
1
+ import { F as FaithfulnessFrontmatter, P as PluginConfig, k as MemoryFrontmatter } from './types-Couvz-L3.js';
2
2
  import { LocalLlmClient } from './local-llm.js';
3
3
  import { FallbackLlmClient } from './fallback-llm.js';
4
4
  import './types-gb_SNtjR.js';
@@ -1,5 +1,5 @@
1
1
  import { JudgeVerdictKind } from './extraction-judge.js';
2
- import './types-CJrvHJjx.js';
2
+ import './types-Couvz-L3.js';
3
3
  import './types-gb_SNtjR.js';
4
4
  import './message-parts/index.js';
5
5
  import './local-llm.js';
@@ -1,5 +1,5 @@
1
1
  import { JudgeVerdictKind } from './extraction-judge.js';
2
- import './types-CJrvHJjx.js';
2
+ import './types-Couvz-L3.js';
3
3
  import './types-gb_SNtjR.js';
4
4
  import './message-parts/index.js';
5
5
  import './local-llm.js';
@@ -1,4 +1,4 @@
1
- import { y as ImportanceLevel, P as PluginConfig } from './types-CJrvHJjx.js';
1
+ import { y as ImportanceLevel, P as PluginConfig } from './types-Couvz-L3.js';
2
2
  import { LocalLlmClient } from './local-llm.js';
3
3
  import { FallbackLlmClient } from './fallback-llm.js';
4
4
  import './types-gb_SNtjR.js';
@@ -1,6 +1,6 @@
1
1
  import { LocalLlmClient } from './local-llm.js';
2
2
  import { ContradictionVerificationResult, SuggestedLinks, MemorySummaryResult } from './schemas.js';
3
- import { P as PluginConfig, G as GatewayConfig, u as BufferTurn, a0 as ExtractionResult, g as MemoryFile, a1 as ConsolidationResult, a2 as DaySummaryResult } from './types-CJrvHJjx.js';
3
+ import { P as PluginConfig, G as GatewayConfig, u as BufferTurn, a0 as ExtractionResult, g as MemoryFile, a1 as ConsolidationResult, a2 as DaySummaryResult } from './types-Couvz-L3.js';
4
4
  import { ModelRegistry } from './model-registry.js';
5
5
  import { ProfilingCollector } from './profiling.js';
6
6
  import './types-gb_SNtjR.js';
@@ -83,6 +83,15 @@ declare class ExtractionEngine {
83
83
  * Local LLMs sometimes hit token limits mid-JSON. This tries to salvage valid facts.
84
84
  */
85
85
  private extractPartialFacts;
86
+ /**
87
+ * Bi-temporal event-time extraction instruction (#1578 PR2). Emitted on
88
+ * every extraction entry path when `temporal.biTemporal` is on so the LLM
89
+ * emits an optional per-fact `eventTime` expression. The expression is
90
+ * resolved against the source turn timestamp at write time — never
91
+ * wall-clock — so replay/import of old transcripts anchors correctly.
92
+ * Returns an empty string when the gate is off (byte-identical prompt).
93
+ */
94
+ private eventTimePromptInstruction;
86
95
  /**
87
96
  * Build extraction instructions shared between local and cloud LLM.
88
97
  */
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  ExtractionEngine
3
- } from "./chunk-IFR23TC5.js";
3
+ } from "./chunk-VYZNWH4J.js";
4
4
  import "./chunk-4RA3C3EV.js";
5
- import "./chunk-KKK7YTYN.js";
5
+ import "./chunk-5GSUBCZM.js";
6
6
  import "./chunk-54V4BZWP.js";
7
7
  import "./chunk-PWFWCGOO.js";
8
8
  import "./chunk-24D66MMN.js";
@@ -1,4 +1,4 @@
1
- import { G as GatewayConfig, f as AgentPersonaModelConfig, P as PluginConfig } from './types-CJrvHJjx.js';
1
+ import { G as GatewayConfig, f as AgentPersonaModelConfig, P as PluginConfig } from './types-Couvz-L3.js';
2
2
  import { GetRuntimeAuthForModelFn, ResolveApiKeyFn } from './resolve-provider-secret.js';
3
3
  import './types-gb_SNtjR.js';
4
4
  import './message-parts/index.js';
@@ -3,8 +3,8 @@ import {
3
3
  } from "./chunk-3JJWNZTT.js";
4
4
  import {
5
5
  supersessionKeysForFact
6
- } from "./chunk-OMNTQPZO.js";
7
- import "./chunk-IREVVFTM.js";
6
+ } from "./chunk-TKZ3AL5V.js";
7
+ import "./chunk-6CIAGZ6X.js";
8
8
  import "./chunk-LTJAMRGI.js";
9
9
  import "./chunk-NU3CSQ4H.js";
10
10
  import "./chunk-PZ5AY32C.js";
@@ -97,4 +97,4 @@ export {
97
97
  ForgetMemoryNotFoundError,
98
98
  forgetMemory
99
99
  };
100
- //# sourceMappingURL=forget-6SOIPUMQ.js.map
100
+ //# sourceMappingURL=forget-U66KPDPY.js.map
@@ -1,4 +1,4 @@
1
- import { a3 as ContinuityIncidentRecord, a4 as ContinuityIncidentCloseInput, a5 as ContinuityIncidentOpenInput, a6 as ContinuityImprovementLoop, a7 as ContinuityLoopReviewInput, a8 as ContinuityLoopUpsertInput } from './types-CJrvHJjx.js';
1
+ import { a3 as ContinuityIncidentRecord, a4 as ContinuityIncidentCloseInput, a5 as ContinuityIncidentOpenInput, a6 as ContinuityImprovementLoop, a7 as ContinuityLoopReviewInput, a8 as ContinuityLoopUpsertInput } from './types-Couvz-L3.js';
2
2
  import './types-gb_SNtjR.js';
3
3
  import './message-parts/index.js';
4
4
 
@@ -1,4 +1,4 @@
1
- import { y as ImportanceLevel, g as MemoryFile, a9 as ImportanceScore, M as MemoryCategory } from './types-CJrvHJjx.js';
1
+ import { y as ImportanceLevel, g as MemoryFile, a9 as ImportanceScore, M as MemoryCategory } from './types-Couvz-L3.js';
2
2
  import './types-gb_SNtjR.js';
3
3
  import './message-parts/index.js';
4
4