@remnic/core 9.6.18 → 9.6.20

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 (90) hide show
  1. package/dist/access-admin-ops-surface.js +9 -9
  2. package/dist/access-boundary.js +10 -10
  3. package/dist/access-cli.js +37 -36
  4. package/dist/access-cli.js.map +1 -1
  5. package/dist/access-http.js +16 -16
  6. package/dist/access-identity-continuity-surface.js +9 -9
  7. package/dist/access-lcm-surface.js +9 -9
  8. package/dist/access-mcp.js +15 -15
  9. package/dist/access-observe-write-surface.js +9 -9
  10. package/dist/access-operations-batch.js +12 -12
  11. package/dist/access-operations.js +14 -14
  12. package/dist/access-recall-surface.js +9 -9
  13. package/dist/access-schema.js +5 -5
  14. package/dist/access-service.js +9 -9
  15. package/dist/{capsule-crypto-RAARDY3M.js → capsule-crypto-CZJSLEFG.js} +2 -2
  16. package/dist/{chunk-EEIROWEG.js → chunk-2BFLDH5F.js} +2 -2
  17. package/dist/{chunk-UPSAT4PY.js → chunk-2MR3MFQB.js} +2 -2
  18. package/dist/{chunk-LNQUAJNC.js → chunk-437S3G37.js} +1 -1
  19. package/dist/{chunk-JZKR6ZAV.js → chunk-4Q2XWAHZ.js} +2 -2
  20. package/dist/{chunk-HR4NACR7.js → chunk-A2OFRQ5B.js} +5 -5
  21. package/dist/{chunk-D3YEDDCC.js → chunk-ARDRBJHD.js} +4 -4
  22. package/dist/{chunk-U4CWMKN6.js → chunk-B4LPRAWL.js} +2 -2
  23. package/dist/{chunk-L6NW2XSU.js → chunk-D3D677BV.js} +4 -4
  24. package/dist/{chunk-7WSLR2CU.js → chunk-DE6ENYLG.js} +2 -2
  25. package/dist/{chunk-DEG5ULFJ.js → chunk-DQ2CJYUM.js} +2 -2
  26. package/dist/{chunk-KTULX4YO.js → chunk-FLVL4L3L.js} +4 -4
  27. package/dist/{chunk-KJ3QGI63.js → chunk-GXLFDLX2.js} +6 -6
  28. package/dist/{chunk-MGN7VHWQ.js → chunk-HHAA35A3.js} +120 -7
  29. package/dist/chunk-HHAA35A3.js.map +1 -0
  30. package/dist/chunk-I6WYQSX4.js +99 -0
  31. package/dist/chunk-I6WYQSX4.js.map +1 -0
  32. package/dist/{chunk-JCEFF346.js → chunk-KEY3FEMP.js} +18 -18
  33. package/dist/{chunk-PYHOAXTI.js → chunk-LRGSLV7M.js} +4 -4
  34. package/dist/{chunk-CYWCKFCL.js → chunk-M5QKGHCR.js} +5 -5
  35. package/dist/{chunk-RSS3CZV7.js → chunk-MRQN5Q3I.js} +2 -2
  36. package/dist/{chunk-HLN7RROI.js → chunk-SFHI7JBE.js} +4 -4
  37. package/dist/{chunk-5TYS6NTK.js → chunk-XMNVHYI6.js} +84 -35
  38. package/dist/chunk-XMNVHYI6.js.map +1 -0
  39. package/dist/{chunk-ZZYLM6KQ.js → chunk-YDF4HL3W.js} +4 -4
  40. package/dist/cli.js +25 -25
  41. package/dist/contradiction/index.js +4 -4
  42. package/dist/{first-start-migration-VBJQL6OI.js → first-start-migration-4I3VDSYS.js} +4 -4
  43. package/dist/index.js +46 -45
  44. package/dist/lcm/index.js +3 -3
  45. package/dist/namespaces/migrate.js +4 -4
  46. package/dist/namespaces/search.js +3 -3
  47. package/dist/operator-toolkit.js +5 -5
  48. package/dist/orchestrator.js +39 -38
  49. package/dist/retrieval-agents.js +2 -2
  50. package/dist/search/factory.js +2 -2
  51. package/dist/search/index.js +4 -4
  52. package/dist/temporal-index.d.ts +42 -7
  53. package/dist/temporal-index.js +3 -1
  54. package/dist/temporal-timeline-recall.d.ts +24 -0
  55. package/dist/temporal-timeline-recall.js +8 -0
  56. package/dist/temporal-timeline-recall.js.map +1 -0
  57. package/dist/transfer/backup.js +3 -3
  58. package/dist/transfer/capsule-export.js +4 -4
  59. package/dist/transfer/capsule-import.js +3 -3
  60. package/dist/transfer/import-sqlite.js +2 -2
  61. package/package.json +2 -2
  62. package/src/lifecycle/tombstones.test.ts +78 -5
  63. package/src/orchestration/persistence-index.ts +15 -2
  64. package/src/orchestration/recall-internal.ts +77 -35
  65. package/src/temporal-index.test.ts +157 -0
  66. package/src/temporal-index.ts +211 -7
  67. package/src/temporal-timeline-recall.test.ts +70 -0
  68. package/src/temporal-timeline-recall.ts +111 -0
  69. package/dist/chunk-5TYS6NTK.js.map +0 -1
  70. package/dist/chunk-MGN7VHWQ.js.map +0 -1
  71. /package/dist/{capsule-crypto-RAARDY3M.js.map → capsule-crypto-CZJSLEFG.js.map} +0 -0
  72. /package/dist/{chunk-EEIROWEG.js.map → chunk-2BFLDH5F.js.map} +0 -0
  73. /package/dist/{chunk-UPSAT4PY.js.map → chunk-2MR3MFQB.js.map} +0 -0
  74. /package/dist/{chunk-LNQUAJNC.js.map → chunk-437S3G37.js.map} +0 -0
  75. /package/dist/{chunk-JZKR6ZAV.js.map → chunk-4Q2XWAHZ.js.map} +0 -0
  76. /package/dist/{chunk-HR4NACR7.js.map → chunk-A2OFRQ5B.js.map} +0 -0
  77. /package/dist/{chunk-D3YEDDCC.js.map → chunk-ARDRBJHD.js.map} +0 -0
  78. /package/dist/{chunk-U4CWMKN6.js.map → chunk-B4LPRAWL.js.map} +0 -0
  79. /package/dist/{chunk-L6NW2XSU.js.map → chunk-D3D677BV.js.map} +0 -0
  80. /package/dist/{chunk-7WSLR2CU.js.map → chunk-DE6ENYLG.js.map} +0 -0
  81. /package/dist/{chunk-DEG5ULFJ.js.map → chunk-DQ2CJYUM.js.map} +0 -0
  82. /package/dist/{chunk-KTULX4YO.js.map → chunk-FLVL4L3L.js.map} +0 -0
  83. /package/dist/{chunk-KJ3QGI63.js.map → chunk-GXLFDLX2.js.map} +0 -0
  84. /package/dist/{chunk-JCEFF346.js.map → chunk-KEY3FEMP.js.map} +0 -0
  85. /package/dist/{chunk-PYHOAXTI.js.map → chunk-LRGSLV7M.js.map} +0 -0
  86. /package/dist/{chunk-CYWCKFCL.js.map → chunk-M5QKGHCR.js.map} +0 -0
  87. /package/dist/{chunk-RSS3CZV7.js.map → chunk-MRQN5Q3I.js.map} +0 -0
  88. /package/dist/{chunk-HLN7RROI.js.map → chunk-SFHI7JBE.js.map} +0 -0
  89. /package/dist/{chunk-ZZYLM6KQ.js.map → chunk-YDF4HL3W.js.map} +0 -0
  90. /package/dist/{first-start-migration-VBJQL6OI.js.map → first-start-migration-4I3VDSYS.js.map} +0 -0
@@ -43,34 +43,35 @@ import {
43
43
  throwIfRecallAborted,
44
44
  tokenizeRecallQuery,
45
45
  utcDateKeysForLocalDay
46
- } from "./chunk-5TYS6NTK.js";
46
+ } from "./chunk-XMNVHYI6.js";
47
47
  import "./chunk-J3XHPFEU.js";
48
+ import {
49
+ formatCompressionGuidelinesForRecall
50
+ } from "./chunk-BRDJ2HFP.js";
48
51
  import "./chunk-JODHPNLN.js";
49
52
  import "./chunk-I74SUMNI.js";
50
53
  import "./chunk-ILNPU5W5.js";
51
54
  import "./chunk-7HYPN2GC.js";
52
- import {
53
- formatCompressionGuidelinesForRecall
54
- } from "./chunk-BRDJ2HFP.js";
55
55
  import "./chunk-666A3MOW.js";
56
56
  import "./chunk-HHLLAQGZ.js";
57
- import "./chunk-UWK5OXUJ.js";
58
- import "./chunk-KBL3JJR6.js";
59
- import "./chunk-FQ7HAWWC.js";
60
57
  import "./chunk-Y4RKAQZ7.js";
61
58
  import "./chunk-TPDBFYEG.js";
62
59
  import "./chunk-KCYE2MZM.js";
63
60
  import "./chunk-7N2RUBAP.js";
64
61
  import "./chunk-MTR7BZQN.js";
62
+ import "./chunk-UWK5OXUJ.js";
63
+ import "./chunk-RP7YXA67.js";
64
+ import "./chunk-KBL3JJR6.js";
65
+ import "./chunk-FQ7HAWWC.js";
65
66
  import "./chunk-O7BBFJLP.js";
66
67
  import "./chunk-7N4KAIGN.js";
68
+ import "./chunk-B5GBWBCZ.js";
69
+ import "./chunk-UI4FVU6T.js";
67
70
  import "./chunk-VCW74PNH.js";
68
71
  import "./chunk-V5OCT34X.js";
69
72
  import "./chunk-TECVW3JP.js";
70
- import "./chunk-RP7YXA67.js";
71
- import "./chunk-B5GBWBCZ.js";
72
- import "./chunk-UI4FVU6T.js";
73
73
  import "./chunk-LXOM6IQU.js";
74
+ import "./chunk-VOUOLGIP.js";
74
75
  import "./chunk-S75M5ZRK.js";
75
76
  import "./chunk-ECZU5BJH.js";
76
77
  import "./chunk-4OKLXWDZ.js";
@@ -78,8 +79,8 @@ import "./chunk-UHGBNIOS.js";
78
79
  import "./chunk-BCDKBDSY.js";
79
80
  import "./chunk-YN2UN7N3.js";
80
81
  import "./chunk-4SBW47WK.js";
82
+ import "./chunk-I6WYQSX4.js";
81
83
  import "./chunk-4EX5WZ4M.js";
82
- import "./chunk-VOUOLGIP.js";
83
84
  import "./chunk-XZ5I7OZR.js";
84
85
  import "./chunk-3FAMU5TX.js";
85
86
  import "./chunk-FDPZVY6D.js";
@@ -87,8 +88,8 @@ import "./chunk-5IZL4DCV.js";
87
88
  import "./chunk-2IZAGAJR.js";
88
89
  import "./chunk-E3VODCC3.js";
89
90
  import "./chunk-L6W77GWW.js";
90
- import "./chunk-7WSLR2CU.js";
91
- import "./chunk-MGN7VHWQ.js";
91
+ import "./chunk-DE6ENYLG.js";
92
+ import "./chunk-HHAA35A3.js";
92
93
  import "./chunk-X7XN6YU4.js";
93
94
  import "./chunk-YDBIWGNI.js";
94
95
  import "./chunk-JZHHREBL.js";
@@ -125,21 +126,21 @@ import "./chunk-Q6IP2ARR.js";
125
126
  import "./chunk-6HEM6HTQ.js";
126
127
  import "./chunk-O2EL7EGG.js";
127
128
  import "./chunk-FVTLSFWU.js";
128
- import "./chunk-JCEFF346.js";
129
+ import "./chunk-KEY3FEMP.js";
129
130
  import "./chunk-MMACM5G2.js";
130
131
  import "./chunk-54BGIBCR.js";
131
132
  import "./chunk-H4CKS5B2.js";
132
133
  import "./chunk-FXZTL7F7.js";
133
134
  import "./chunk-HDDRVXX4.js";
134
- import "./chunk-PYHOAXTI.js";
135
- import "./chunk-EEIROWEG.js";
136
- import "./chunk-UP6MOYCB.js";
137
- import "./chunk-BV2TIZ4F.js";
138
- import "./chunk-Z734BLO3.js";
135
+ import "./chunk-LRGSLV7M.js";
139
136
  import "./chunk-OZKVVUJB.js";
140
137
  import "./chunk-2DL3OFLD.js";
141
138
  import "./chunk-G4IAEX6D.js";
139
+ import "./chunk-2BFLDH5F.js";
140
+ import "./chunk-UP6MOYCB.js";
142
141
  import "./chunk-765K3SAT.js";
142
+ import "./chunk-BV2TIZ4F.js";
143
+ import "./chunk-Z734BLO3.js";
143
144
  import "./chunk-FGDKJJZS.js";
144
145
  import "./chunk-AJVLDJU6.js";
145
146
  import "./chunk-KQPJLK3X.js";
@@ -148,10 +149,10 @@ import "./chunk-PYIFUBRK.js";
148
149
  import "./chunk-D6RIFG4O.js";
149
150
  import "./chunk-CAZ3Z5M6.js";
150
151
  import "./chunk-KJIJNLXT.js";
152
+ import "./chunk-KJTKLXTH.js";
151
153
  import "./chunk-LZZNTPLR.js";
152
154
  import "./chunk-JCK7V6SN.js";
153
155
  import "./chunk-WMWVO45V.js";
154
- import "./chunk-KJTKLXTH.js";
155
156
  import "./chunk-HSSERO3E.js";
156
157
  import "./chunk-NOUJNHWG.js";
157
158
  import "./chunk-GQL52GQ5.js";
@@ -169,9 +170,9 @@ import "./chunk-GQGDRLDM.js";
169
170
  import "./chunk-SFQ6QNL7.js";
170
171
  import "./chunk-3T74IZB3.js";
171
172
  import "./chunk-33JBK2XP.js";
172
- import "./chunk-U4CWMKN6.js";
173
+ import "./chunk-B4LPRAWL.js";
173
174
  import "./chunk-VHJARF5R.js";
174
- import "./chunk-JZKR6ZAV.js";
175
+ import "./chunk-4Q2XWAHZ.js";
175
176
  import "./chunk-23G3T2Q5.js";
176
177
  import "./chunk-KFY3SGN7.js";
177
178
  import "./chunk-CMTINOFS.js";
@@ -216,7 +217,7 @@ import "./chunk-G6NKALRN.js";
216
217
  import "./chunk-OO42R444.js";
217
218
  import "./chunk-K6MV3TRQ.js";
218
219
  import "./chunk-OADWQ5CR.js";
219
- import "./chunk-HR4NACR7.js";
220
+ import "./chunk-A2OFRQ5B.js";
220
221
  import "./chunk-V7IZKJI3.js";
221
222
  import "./chunk-SEDEKFYQ.js";
222
223
  import "./chunk-RKNJBZ55.js";
@@ -225,26 +226,26 @@ import "./chunk-RSUYKGGZ.js";
225
226
  import "./chunk-42NQ7AVG.js";
226
227
  import "./chunk-TMSXWOBZ.js";
227
228
  import "./chunk-7RXCMVFQ.js";
228
- import "./chunk-L6NW2XSU.js";
229
+ import "./chunk-D3D677BV.js";
229
230
  import "./chunk-IC2TCZJ2.js";
230
231
  import "./chunk-D24OXEPB.js";
231
232
  import "./chunk-5RUE3GHQ.js";
232
- import "./chunk-D3YEDDCC.js";
233
- import "./chunk-UPSAT4PY.js";
234
- import "./chunk-KJ3QGI63.js";
233
+ import "./chunk-ARDRBJHD.js";
234
+ import "./chunk-2MR3MFQB.js";
235
+ import "./chunk-GXLFDLX2.js";
235
236
  import "./chunk-HLTAPHZZ.js";
236
237
  import "./chunk-YF6FMLBT.js";
237
- import "./chunk-KQDNAXOM.js";
238
238
  import "./chunk-PRTA6444.js";
239
+ import "./chunk-KQDNAXOM.js";
239
240
  import "./chunk-35NN3ZFA.js";
240
241
  import "./chunk-FTYDWKO6.js";
241
242
  import "./chunk-T4WDJPEZ.js";
242
- import "./chunk-RSS3CZV7.js";
243
+ import "./chunk-MRQN5Q3I.js";
243
244
  import "./chunk-D7FOKIY5.js";
244
- import "./chunk-ZZYLM6KQ.js";
245
+ import "./chunk-YDF4HL3W.js";
245
246
  import "./chunk-GDASG7NC.js";
246
247
  import "./chunk-GDB4J2H3.js";
247
- import "./chunk-CYWCKFCL.js";
248
+ import "./chunk-M5QKGHCR.js";
248
249
  import "./chunk-64SE4X5G.js";
249
250
  import "./chunk-VQ7B2Q6M.js";
250
251
  import "./chunk-ERA5RSMZ.js";
@@ -261,8 +262,9 @@ import "./chunk-ICP53SKG.js";
261
262
  import "./chunk-AQEJKOKI.js";
262
263
  import "./chunk-6HMYUWXR.js";
263
264
  import "./chunk-BAVVI5GP.js";
264
- import "./chunk-DEG5ULFJ.js";
265
- import "./chunk-HLN7RROI.js";
265
+ import "./chunk-DQ2CJYUM.js";
266
+ import "./chunk-SFHI7JBE.js";
267
+ import "./chunk-CYEPCZN5.js";
266
268
  import "./chunk-7MW3CVLD.js";
267
269
  import "./chunk-ZIDSD6VC.js";
268
270
  import "./chunk-QWGNDWKB.js";
@@ -270,7 +272,6 @@ import "./chunk-N3JDIRBW.js";
270
272
  import "./chunk-UTRJFDP2.js";
271
273
  import "./chunk-6SXVCD7W.js";
272
274
  import "./chunk-CINZGPSJ.js";
273
- import "./chunk-CYEPCZN5.js";
274
275
  import "./chunk-EGGE52UU.js";
275
276
  import "./chunk-O6YI4CVI.js";
276
277
  import "./chunk-JI5AVXYO.js";
@@ -328,13 +329,13 @@ import "./chunk-L2EXJQJP.js";
328
329
  import "./chunk-VFSP73LP.js";
329
330
  import "./chunk-RGMVMVMF.js";
330
331
  import "./chunk-N7RWREIQ.js";
331
- import "./chunk-KTULX4YO.js";
332
- import "./chunk-LNQUAJNC.js";
332
+ import "./chunk-FLVL4L3L.js";
333
+ import "./chunk-WEHSQBFR.js";
334
+ import "./chunk-437S3G37.js";
335
+ import "./chunk-J4EB7DNW.js";
333
336
  import "./chunk-GWTFLF2P.js";
334
337
  import "./chunk-UKJAGEXH.js";
335
338
  import "./chunk-FP2373TW.js";
336
- import "./chunk-WEHSQBFR.js";
337
- import "./chunk-J4EB7DNW.js";
338
339
  import "./chunk-Z2YFLXHU.js";
339
340
  import "./chunk-I4WBNM3M.js";
340
341
  import "./chunk-SOAU2OE2.js";
@@ -7,8 +7,8 @@ import {
7
7
  runDirectAgent,
8
8
  runTemporalAgent,
9
9
  shouldRunAgent
10
- } from "./chunk-7WSLR2CU.js";
11
- import "./chunk-MGN7VHWQ.js";
10
+ } from "./chunk-DE6ENYLG.js";
11
+ import "./chunk-HHAA35A3.js";
12
12
  import "./chunk-37CTGERM.js";
13
13
  import "./chunk-PVGDJXVK.js";
14
14
  import "./chunk-PZ5AY32C.js";
@@ -2,7 +2,8 @@ import {
2
2
  createConversationIndexRuntime,
3
3
  createConversationSearchBackend,
4
4
  createSearchBackend
5
- } from "../chunk-HLN7RROI.js";
5
+ } from "../chunk-SFHI7JBE.js";
6
+ import "../chunk-CYEPCZN5.js";
6
7
  import "../chunk-7MW3CVLD.js";
7
8
  import "../chunk-ZIDSD6VC.js";
8
9
  import "../chunk-QWGNDWKB.js";
@@ -10,7 +11,6 @@ import "../chunk-N3JDIRBW.js";
10
11
  import "../chunk-UTRJFDP2.js";
11
12
  import "../chunk-6SXVCD7W.js";
12
13
  import "../chunk-CINZGPSJ.js";
13
- import "../chunk-CYEPCZN5.js";
14
14
  import "../chunk-JI5AVXYO.js";
15
15
  import "../chunk-TN7THW5U.js";
16
16
  import "../chunk-R5VAVVHP.js";
@@ -2,7 +2,10 @@ import {
2
2
  createConversationIndexRuntime,
3
3
  createConversationSearchBackend,
4
4
  createSearchBackend
5
- } from "../chunk-HLN7RROI.js";
5
+ } from "../chunk-SFHI7JBE.js";
6
+ import {
7
+ NoopSearchBackend
8
+ } from "../chunk-CYEPCZN5.js";
6
9
  import {
7
10
  OramaBackend
8
11
  } from "../chunk-7MW3CVLD.js";
@@ -22,9 +25,6 @@ import {
22
25
  scanMemoryDir
23
26
  } from "../chunk-6SXVCD7W.js";
24
27
  import "../chunk-CINZGPSJ.js";
25
- import {
26
- NoopSearchBackend
27
- } from "../chunk-CYEPCZN5.js";
28
28
  import "../chunk-JI5AVXYO.js";
29
29
  import "../chunk-TN7THW5U.js";
30
30
  import "../chunk-R5VAVVHP.js";
@@ -21,6 +21,35 @@ interface TemporalIndex {
21
21
  lastRebuildAt?: string;
22
22
  /** Map from YYYY-MM-DD → array of memory paths */
23
23
  dates: Record<string, string[]>;
24
+ /**
25
+ * Per-memory event-time rows used to reconstruct one chronology across
26
+ * source sessions. Keyed by path so an update replaces the prior row.
27
+ */
28
+ events: Record<string, TemporalIndexEvent>;
29
+ }
30
+ interface TemporalIndexEvent {
31
+ path: string;
32
+ /** Event/valid time used for chronology. */
33
+ eventAt: string;
34
+ /** Ingest/source-observation time, when known. */
35
+ observedAt?: string;
36
+ /** Source session provenance, when the extractor recorded it. */
37
+ sessionKey?: string;
38
+ /** Exclusive validity end, when the event is bounded. */
39
+ validUntil?: string;
40
+ /** SHA-256 lexical fingerprints for bounded query-aware candidate selection. */
41
+ searchTokenHashes?: string[];
42
+ }
43
+ interface TemporalIndexEntry {
44
+ path: string;
45
+ createdAt: string;
46
+ tags: string[];
47
+ validAt?: string;
48
+ observedAt?: string;
49
+ sessionKey?: string;
50
+ validUntil?: string;
51
+ /** Used only to derive token hashes; raw text is never persisted in the index. */
52
+ searchText?: string;
24
53
  }
25
54
  interface TagIndex {
26
55
  version: number;
@@ -43,7 +72,7 @@ interface TagNode {
43
72
  * @param createdAt ISO timestamp of the memory's creation date
44
73
  * @param tags Array of tag strings from the memory's frontmatter
45
74
  */
46
- declare function indexMemory(memoryDir: string, memoryPath: string, createdAt: string, tags: string[]): void;
75
+ declare function indexMemory(memoryDir: string, memoryPath: string, createdAt: string, tags: string[], temporal?: Omit<Partial<TemporalIndexEntry>, "path" | "createdAt" | "tags">): void;
47
76
  /**
48
77
  * Remove a memory file from both indexes (called on deletion/archival).
49
78
  */
@@ -63,11 +92,7 @@ declare function indexesExist(memoryDir: string): boolean;
63
92
  * Batch-add multiple memories to both indexes in a single read-modify-write cycle.
64
93
  * More efficient than calling indexMemory() per file when adding many at once.
65
94
  */
66
- declare function indexMemoriesBatch(memoryDir: string, entries: Array<{
67
- path: string;
68
- createdAt: string;
69
- tags: string[];
70
- }>): void;
95
+ declare function indexMemoriesBatch(memoryDir: string, entries: TemporalIndexEntry[]): void;
71
96
  /**
72
97
  * Return the set of memory paths whose index date falls in [fromDate, toDate).
73
98
  *
@@ -84,6 +109,16 @@ declare function indexMemoriesBatch(memoryDir: string, entries: Array<{
84
109
  * @returns Set of matching file paths, or null if the index is unavailable.
85
110
  */
86
111
  declare function queryByDateRangeAsync(memoryDir: string, fromDate: string, toDate?: string): Promise<Set<string> | null>;
112
+ /**
113
+ * Return the persisted event-time rows as one deterministic cross-session
114
+ * chronology. Equal event times are ordered by observation time, then path.
115
+ * Returns `null` when the index is missing, corrupt, or from an older schema;
116
+ * callers can then fail open to the pre-index recall path.
117
+ */
118
+ declare function queryTemporalTimelineAsync(memoryDir: string, options?: {
119
+ query?: string;
120
+ limit?: number;
121
+ }): Promise<TemporalIndexEvent[] | null>;
87
122
  /**
88
123
  * Async version of queryByTags — uses non-blocking fs.promises.readFile
89
124
  * to avoid blocking the Node.js event loop.
@@ -136,4 +171,4 @@ declare function recencyWindowBoundsFromPrompt(prompt: string, nowMs?: number):
136
171
  toDate: string;
137
172
  };
138
173
 
139
- export { type TagIndex, type TagNode, type TemporalIndex, clearIndexes, deindexMemory, extractTagsFromPrompt, indexMemoriesBatch, indexMemory, indexesExist, isTemporalQuery, queryByDateRangeAsync, queryByTagsAsync, recencyWindowBoundsFromPrompt, recencyWindowFromPrompt, resolvePromptTagPrefilterAsync };
174
+ export { type TagIndex, type TagNode, type TemporalIndex, type TemporalIndexEntry, type TemporalIndexEvent, clearIndexes, deindexMemory, extractTagsFromPrompt, indexMemoriesBatch, indexMemory, indexesExist, isTemporalQuery, queryByDateRangeAsync, queryByTagsAsync, queryTemporalTimelineAsync, recencyWindowBoundsFromPrompt, recencyWindowFromPrompt, resolvePromptTagPrefilterAsync };
@@ -8,10 +8,11 @@ import {
8
8
  isTemporalQuery,
9
9
  queryByDateRangeAsync,
10
10
  queryByTagsAsync,
11
+ queryTemporalTimelineAsync,
11
12
  recencyWindowBoundsFromPrompt,
12
13
  recencyWindowFromPrompt,
13
14
  resolvePromptTagPrefilterAsync
14
- } from "./chunk-MGN7VHWQ.js";
15
+ } from "./chunk-HHAA35A3.js";
15
16
  import "./chunk-PZ5AY32C.js";
16
17
  export {
17
18
  clearIndexes,
@@ -23,6 +24,7 @@ export {
23
24
  isTemporalQuery,
24
25
  queryByDateRangeAsync,
25
26
  queryByTagsAsync,
27
+ queryTemporalTimelineAsync,
26
28
  recencyWindowBoundsFromPrompt,
27
29
  recencyWindowFromPrompt,
28
30
  resolvePromptTagPrefilterAsync
@@ -0,0 +1,24 @@
1
+ import { M as MemoryFile } from './types-DDUDgd7T.js';
2
+ import './message-parts/index.js';
3
+
4
+ interface TemporalTimelineRecallItem {
5
+ memory: MemoryFile;
6
+ eventAt: string;
7
+ observedAt?: string;
8
+ sessionKey?: string;
9
+ validUntil?: string;
10
+ }
11
+ interface TemporalTimelineRecallOptions {
12
+ items: readonly TemporalTimelineRecallItem[];
13
+ query: string;
14
+ maxChars: number;
15
+ maxItems: number;
16
+ title?: string;
17
+ }
18
+ /**
19
+ * Build a query-focused timeline from ingest-indexed memory primitives.
20
+ * Selection is relevance-first; presentation is always event-time ordered.
21
+ */
22
+ declare function buildTemporalTimelineRecallSection(options: TemporalTimelineRecallOptions): string;
23
+
24
+ export { type TemporalTimelineRecallItem, type TemporalTimelineRecallOptions, buildTemporalTimelineRecallSection };
@@ -0,0 +1,8 @@
1
+ import {
2
+ buildTemporalTimelineRecallSection
3
+ } from "./chunk-I6WYQSX4.js";
4
+ import "./chunk-PZ5AY32C.js";
5
+ export {
6
+ buildTemporalTimelineRecallSection
7
+ };
8
+ //# sourceMappingURL=temporal-timeline-recall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  backupMemoryDir
3
- } from "../chunk-EEIROWEG.js";
3
+ } from "../chunk-2BFLDH5F.js";
4
4
  import "../chunk-765K3SAT.js";
5
- import "../chunk-LNQUAJNC.js";
5
+ import "../chunk-437S3G37.js";
6
+ import "../chunk-J4EB7DNW.js";
6
7
  import "../chunk-GWTFLF2P.js";
7
8
  import "../chunk-UKJAGEXH.js";
8
9
  import "../chunk-FP2373TW.js";
9
- import "../chunk-J4EB7DNW.js";
10
10
  import "../chunk-UI3NYK34.js";
11
11
  import "../chunk-GCGJW34D.js";
12
12
  import "../chunk-A6XUJE5D.js";
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  exportCapsule,
3
3
  isValidCapsuleSince
4
- } from "../chunk-KTULX4YO.js";
5
- import "../chunk-LNQUAJNC.js";
4
+ } from "../chunk-FLVL4L3L.js";
5
+ import "../chunk-WEHSQBFR.js";
6
+ import "../chunk-437S3G37.js";
7
+ import "../chunk-J4EB7DNW.js";
6
8
  import "../chunk-GWTFLF2P.js";
7
9
  import "../chunk-UKJAGEXH.js";
8
10
  import "../chunk-FP2373TW.js";
9
- import "../chunk-WEHSQBFR.js";
10
- import "../chunk-J4EB7DNW.js";
11
11
  import "../chunk-UI3NYK34.js";
12
12
  import "../chunk-GCGJW34D.js";
13
13
  import "../chunk-A6XUJE5D.js";
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  importCapsule
3
- } from "../chunk-CYWCKFCL.js";
3
+ } from "../chunk-M5QKGHCR.js";
4
4
  import "../chunk-VF4XKTX3.js";
5
- import "../chunk-LNQUAJNC.js";
5
+ import "../chunk-WEHSQBFR.js";
6
+ import "../chunk-437S3G37.js";
6
7
  import "../chunk-GWTFLF2P.js";
7
8
  import "../chunk-UKJAGEXH.js";
8
9
  import "../chunk-FP2373TW.js";
9
- import "../chunk-WEHSQBFR.js";
10
10
  import "../chunk-GCGJW34D.js";
11
11
  import "../chunk-A6XUJE5D.js";
12
12
  import "../chunk-VS2IYZRU.js";
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  importSqlite
3
- } from "../chunk-PYHOAXTI.js";
4
- import "../chunk-Z734BLO3.js";
3
+ } from "../chunk-LRGSLV7M.js";
5
4
  import "../chunk-G4IAEX6D.js";
5
+ import "../chunk-Z734BLO3.js";
6
6
  import "../chunk-RL6NEVXT.js";
7
7
  import "../chunk-GCGJW34D.js";
8
8
  import "../chunk-PZ5AY32C.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remnic/core",
3
- "version": "9.6.18",
3
+ "version": "9.6.20",
4
4
  "description": "Framework-agnostic Remnic memory engine — orchestrator, storage, extraction, search, trust zones",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -3000,7 +3000,7 @@
3000
3000
  "core"
3001
3001
  ],
3002
3002
  "peerDependencies": {
3003
- "@remnic/coding-graph": "^9.6.18"
3003
+ "@remnic/coding-graph": "^9.6.20"
3004
3004
  },
3005
3005
  "peerDependenciesMeta": {
3006
3006
  "@remnic/coding-graph": {
@@ -509,6 +509,7 @@ describe("TombstoneStore — cross-process write lock (issue #1639)", () => {
509
509
  // the retired fact silently un-revokes (resurrection).
510
510
  const dir = await mkdtemp(path.join(tmpdir(), "tomb-rebuild-race-"));
511
511
  const filePath = path.join(dir, "tombstones.jsonl");
512
+ const moduleUrl = new URL("./tombstones.ts", import.meta.url).href;
512
513
  const opts = { enabled: true, semanticMatch: false, semanticThreshold: 0.9, hashContent: computeHash, normalizeText: normalizeContent };
513
514
  const io = makeReadMergeWriteIo();
514
515
  // Store A writes tombstone-1, then goes stale (never sees the peer write).
@@ -519,17 +520,87 @@ describe("TombstoneStore — cross-process write lock (issue #1639)", () => {
519
520
  sourceMemoryId: "fact-rebuild-1",
520
521
  rawContent: "The DB is MySQL.",
521
522
  });
522
- // Peer (store B, same file) revokes t1 durably. Store A's in-memory index
523
- // is now stale (it still thinks t1 is active).
524
- const storeB = new TombstoneStore(filePath, "default", opts, io);
525
- await storeB.revoke(t1, "user_correction");
523
+ // A real peer process revokes t1. Its append callback runs only after the
524
+ // peer holds the advisory write lock, so LOCK_HELD is a deterministic
525
+ // handshake: store A starts rebuilding while the peer still owns the
526
+ // lock, then RELEASE lets the peer durably append before A can acquire it.
527
+ const workerSource = [
528
+ "(async () => {",
529
+ "const { TombstoneStore } = await import(process.argv[1]);",
530
+ "const { mkdir, readFile, writeFile } = await import(\"node:fs/promises\");",
531
+ "const { statSync } = await import(\"node:fs\");",
532
+ "const path = await import(\"node:path\");",
533
+ "const { createHash } = await import(\"node:crypto\");",
534
+ "const filePath = path.join(process.argv[2], \"tombstones.jsonl\");",
535
+ "const tombstoneId = process.argv[3];",
536
+ "let release;",
537
+ "const released = new Promise((resolve) => { release = resolve; });",
538
+ "process.stdin.setEncoding(\"utf8\");",
539
+ "process.stdin.once(\"data\", (chunk) => { if (chunk.trim() === \"RELEASE\") release(); });",
540
+ "function hash(c){return createHash(\"sha256\").update(c).digest(\"hex\");}",
541
+ "function normalize(c){return c;}",
542
+ "const io = {",
543
+ " read: (p) => readFile(p, \"utf8\"),",
544
+ " append: async (p, c) => {",
545
+ " await mkdir(path.dirname(p), { recursive: true });",
546
+ " let existing = \"\";",
547
+ " try { existing = await readFile(p, \"utf8\"); } catch (e) { if (e.code !== \"ENOENT\") throw e; }",
548
+ " process.stdout.write(\"LOCK_HELD\\n\");",
549
+ " await released;",
550
+ " await writeFile(p, existing + c, \"utf8\");",
551
+ " },",
552
+ " write: async (p, c) => { await mkdir(path.dirname(p), { recursive: true }); await writeFile(p, c, \"utf8\"); },",
553
+ " stat: (p) => statSync(p),",
554
+ "};",
555
+ "const store = new TombstoneStore(filePath, \"default\", { enabled: true, semanticMatch: false, semanticThreshold: 0.9, hashContent: hash, normalizeText: normalize }, io);",
556
+ "await store.revoke(tombstoneId, \"user_correction\");",
557
+ "process.stdout.write(\"DONE\\n\");",
558
+ "})().catch((error) => { console.error(error); process.exitCode = 1; });",
559
+ ].join("\n");
560
+
561
+ const peer = spawn(
562
+ process.execPath,
563
+ ["--import", "tsx", "-e", workerSource, moduleUrl, dir, t1],
564
+ { stdio: ["pipe", "pipe", "pipe"] },
565
+ );
566
+ let stderr = "";
567
+ let stdout = "";
568
+ let lockHeld = false;
569
+ let resolveLockHeld!: () => void;
570
+ let rejectLockHeld!: (error: Error) => void;
571
+ const peerLockHeld = new Promise<void>((resolve, reject) => {
572
+ resolveLockHeld = resolve;
573
+ rejectLockHeld = reject;
574
+ });
575
+ peer.stdout.setEncoding("utf8");
576
+ peer.stdout.on("data", (chunk) => {
577
+ stdout += chunk;
578
+ if (!lockHeld && stdout.split("\n").includes("LOCK_HELD")) {
579
+ lockHeld = true;
580
+ resolveLockHeld();
581
+ }
582
+ });
583
+ peer.stderr.setEncoding("utf8");
584
+ peer.stderr.on("data", (chunk) => { stderr += chunk; });
585
+ peer.on("error", (error) => rejectLockHeld(error));
586
+ const peerCompleted = new Promise<void>((resolve, reject) => {
587
+ peer.on("close", (code) => {
588
+ if (!lockHeld) {
589
+ rejectLockHeld(new Error(`revocation peer exited before acquiring lock (${code}): ${stderr}`));
590
+ }
591
+ if (code === 0 && stdout.split("\n").includes("DONE")) resolve();
592
+ else reject(new Error(`revocation peer exited ${code}: ${stderr}`));
593
+ });
594
+ });
595
+
596
+ await peerLockHeld;
526
597
  // Store A rebuilds from a retired-memory corpus that reconstructs t1.
527
598
  // Without the under-lock re-read, A computes existingRevocations from its
528
599
  // stale index (empty), overwrites the file with [rebuilt-t1], and the
529
600
  // revocation is LOST — t1 is active again (resurrection). With the fix,
530
601
  // ensureFreshAgainstDisk reloads the revocation under the lock and rebuild
531
602
  // preserves it.
532
- await storeA.rebuild([
603
+ const rebuild = storeA.rebuild([
533
604
  {
534
605
  memoryId: "fact-rebuild-1",
535
606
  rawContent: "The DB is MySQL.",
@@ -538,6 +609,8 @@ describe("TombstoneStore — cross-process write lock (issue #1639)", () => {
538
609
  createdAt: "2026-01-01T00:00:00.000Z",
539
610
  },
540
611
  ]);
612
+ peer.stdin.end("RELEASE\n");
613
+ await Promise.all([rebuild, peerCompleted]);
541
614
  // The rebuilt file must still contain the revocation (the retired fact
542
615
  // stays revoked, not silently un-revoked by the rebuild).
543
616
  const raw = await readFile(filePath, "utf8");
@@ -15,7 +15,7 @@
15
15
  */
16
16
 
17
17
  import path from "node:path";
18
- import { type GraphConstructionCapabilitySet, resolveCapabilities, resolveGraphConstructionCapabilities, resolveIndexingCapabilities, resolveMemoryLifecycleCapabilities, resolveNamespaceCapabilities } from "../capabilities.js";
18
+ import { type GraphConstructionCapabilitySet, resolveCapabilities, resolveGraphConstructionCapabilities, resolveIndexingCapabilities, resolveMemoryLifecycleCapabilities, resolveNamespaceCapabilities, resolveRecallEnhancementCapabilities } from "../capabilities.js";
19
19
  import type { SemanticDedupHit } from "../dedup/semantic.js";
20
20
  import { EmbeddingFallback } from "../embedding-fallback.js";
21
21
  import { GraphIndex } from "../graph.js";
@@ -386,7 +386,8 @@ export class PersistenceIndexCoordinator {
386
386
  // produce an empty temporal index, leaving the temporal agent with no data to work from.
387
387
  if (
388
388
  !resolveIndexingCapabilities(this.deps.config).queryAwareIndexing &&
389
- !caps.parallelRetrieval
389
+ !caps.parallelRetrieval &&
390
+ !resolveRecallEnhancementCapabilities(this.deps.config).eventOrderRecall
390
391
  )
391
392
  return;
392
393
  // Check for missing indexes BEFORE the early-return so first-time enablement
@@ -423,6 +424,11 @@ export class PersistenceIndexCoordinator {
423
424
  path: string;
424
425
  createdAt: string;
425
426
  tags: string[];
427
+ validAt?: string;
428
+ observedAt?: string;
429
+ sessionKey?: string;
430
+ validUntil?: string;
431
+ searchText?: string;
426
432
  }> = [];
427
433
  for (const mem of pool) {
428
434
  if (mem.path && mem.frontmatter?.created) {
@@ -430,6 +436,13 @@ export class PersistenceIndexCoordinator {
430
436
  path: mem.path,
431
437
  createdAt: mem.frontmatter.created,
432
438
  tags: mem.frontmatter.tags ?? [],
439
+ ...(mem.frontmatter.valid_at ? { validAt: mem.frontmatter.valid_at } : {}),
440
+ ...(mem.frontmatter.observedAt ? { observedAt: mem.frontmatter.observedAt } : {}),
441
+ ...(mem.frontmatter.sources?.[0]?.sessionKey
442
+ ? { sessionKey: mem.frontmatter.sources[0].sessionKey }
443
+ : {}),
444
+ ...(mem.frontmatter.invalid_at ? { validUntil: mem.frontmatter.invalid_at } : {}),
445
+ searchText: `${mem.content} ${(mem.frontmatter.tags ?? []).join(" ")} ${mem.frontmatter.entityRef ?? ""}`,
433
446
  });
434
447
  }
435
448
  }