@graphorin/memory 0.5.0

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 (287) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/LICENSE +21 -0
  3. package/README.md +401 -0
  4. package/dist/conflict/index.d.ts +3 -0
  5. package/dist/conflict/index.js +7 -0
  6. package/dist/conflict/locale-packs/en.js +262 -0
  7. package/dist/conflict/locale-packs/en.js.map +1 -0
  8. package/dist/conflict/locale-packs/index.js +4 -0
  9. package/dist/conflict/locale-packs/types.d.ts +103 -0
  10. package/dist/conflict/locale-packs/types.d.ts.map +1 -0
  11. package/dist/conflict/locale-packs/types.js +55 -0
  12. package/dist/conflict/locale-packs/types.js.map +1 -0
  13. package/dist/conflict/pipeline.d.ts +35 -0
  14. package/dist/conflict/pipeline.d.ts.map +1 -0
  15. package/dist/conflict/pipeline.js +257 -0
  16. package/dist/conflict/pipeline.js.map +1 -0
  17. package/dist/conflict/stages/helpers.js +66 -0
  18. package/dist/conflict/stages/helpers.js.map +1 -0
  19. package/dist/conflict/stages/stage1-exact-dedup.js +21 -0
  20. package/dist/conflict/stages/stage1-exact-dedup.js.map +1 -0
  21. package/dist/conflict/stages/stage2-embedding-three-zone.js +37 -0
  22. package/dist/conflict/stages/stage2-embedding-three-zone.js.map +1 -0
  23. package/dist/conflict/stages/stage3-heuristic-regex.js +45 -0
  24. package/dist/conflict/stages/stage3-heuristic-regex.js.map +1 -0
  25. package/dist/conflict/stages/stage4-subject-predicate.js +31 -0
  26. package/dist/conflict/stages/stage4-subject-predicate.js.map +1 -0
  27. package/dist/conflict/stages/stage5-defer-to-deep.js +22 -0
  28. package/dist/conflict/stages/stage5-defer-to-deep.js.map +1 -0
  29. package/dist/conflict/types.d.ts +222 -0
  30. package/dist/conflict/types.d.ts.map +1 -0
  31. package/dist/conflict/types.js +50 -0
  32. package/dist/conflict/types.js.map +1 -0
  33. package/dist/consolidator/budget.d.ts +1 -0
  34. package/dist/consolidator/budget.js +214 -0
  35. package/dist/consolidator/budget.js.map +1 -0
  36. package/dist/consolidator/decay.d.ts +35 -0
  37. package/dist/consolidator/decay.d.ts.map +1 -0
  38. package/dist/consolidator/decay.js +91 -0
  39. package/dist/consolidator/decay.js.map +1 -0
  40. package/dist/consolidator/dlq.js +58 -0
  41. package/dist/consolidator/dlq.js.map +1 -0
  42. package/dist/consolidator/errors.d.ts +54 -0
  43. package/dist/consolidator/errors.d.ts.map +1 -0
  44. package/dist/consolidator/errors.js +67 -0
  45. package/dist/consolidator/errors.js.map +1 -0
  46. package/dist/consolidator/idempotency.d.ts +1 -0
  47. package/dist/consolidator/idempotency.js +22 -0
  48. package/dist/consolidator/idempotency.js.map +1 -0
  49. package/dist/consolidator/index.d.ts +34 -0
  50. package/dist/consolidator/index.d.ts.map +1 -0
  51. package/dist/consolidator/index.js +163 -0
  52. package/dist/consolidator/index.js.map +1 -0
  53. package/dist/consolidator/lock.d.ts +2 -0
  54. package/dist/consolidator/lock.js +89 -0
  55. package/dist/consolidator/lock.js.map +1 -0
  56. package/dist/consolidator/noise-filter.d.ts +2 -0
  57. package/dist/consolidator/noise-filter.js +173 -0
  58. package/dist/consolidator/noise-filter.js.map +1 -0
  59. package/dist/consolidator/phases/deep.d.ts +4 -0
  60. package/dist/consolidator/phases/deep.js +198 -0
  61. package/dist/consolidator/phases/deep.js.map +1 -0
  62. package/dist/consolidator/phases/induce.d.ts +154 -0
  63. package/dist/consolidator/phases/induce.d.ts.map +1 -0
  64. package/dist/consolidator/phases/induce.js +253 -0
  65. package/dist/consolidator/phases/induce.js.map +1 -0
  66. package/dist/consolidator/phases/light.d.ts +4 -0
  67. package/dist/consolidator/phases/light.js +99 -0
  68. package/dist/consolidator/phases/light.js.map +1 -0
  69. package/dist/consolidator/phases/reflect.js +287 -0
  70. package/dist/consolidator/phases/reflect.js.map +1 -0
  71. package/dist/consolidator/phases/standard.d.ts +8 -0
  72. package/dist/consolidator/phases/standard.js +499 -0
  73. package/dist/consolidator/phases/standard.js.map +1 -0
  74. package/dist/consolidator/reconcile.js +192 -0
  75. package/dist/consolidator/reconcile.js.map +1 -0
  76. package/dist/consolidator/runtime.d.ts +62 -0
  77. package/dist/consolidator/runtime.d.ts.map +1 -0
  78. package/dist/consolidator/runtime.js +580 -0
  79. package/dist/consolidator/runtime.js.map +1 -0
  80. package/dist/consolidator/scheduler.d.ts +111 -0
  81. package/dist/consolidator/scheduler.d.ts.map +1 -0
  82. package/dist/consolidator/scheduler.js +71 -0
  83. package/dist/consolidator/scheduler.js.map +1 -0
  84. package/dist/consolidator/triggers.d.ts +40 -0
  85. package/dist/consolidator/triggers.d.ts.map +1 -0
  86. package/dist/consolidator/triggers.js +94 -0
  87. package/dist/consolidator/triggers.js.map +1 -0
  88. package/dist/consolidator/types.d.ts +397 -0
  89. package/dist/consolidator/types.d.ts.map +1 -0
  90. package/dist/consolidator/types.js +117 -0
  91. package/dist/consolidator/types.js.map +1 -0
  92. package/dist/context-engine/annotations.d.ts +118 -0
  93. package/dist/context-engine/annotations.d.ts.map +1 -0
  94. package/dist/context-engine/annotations.js +102 -0
  95. package/dist/context-engine/annotations.js.map +1 -0
  96. package/dist/context-engine/auto-recall.d.ts +52 -0
  97. package/dist/context-engine/auto-recall.d.ts.map +1 -0
  98. package/dist/context-engine/auto-recall.js +41 -0
  99. package/dist/context-engine/auto-recall.js.map +1 -0
  100. package/dist/context-engine/compaction/clear-tool-results.d.ts +55 -0
  101. package/dist/context-engine/compaction/clear-tool-results.d.ts.map +1 -0
  102. package/dist/context-engine/compaction/clear-tool-results.js +97 -0
  103. package/dist/context-engine/compaction/clear-tool-results.js.map +1 -0
  104. package/dist/context-engine/compaction/compactor.d.ts +52 -0
  105. package/dist/context-engine/compaction/compactor.d.ts.map +1 -0
  106. package/dist/context-engine/compaction/compactor.js +196 -0
  107. package/dist/context-engine/compaction/compactor.js.map +1 -0
  108. package/dist/context-engine/compaction/hooks/reanchor-persona-block.d.ts +15 -0
  109. package/dist/context-engine/compaction/hooks/reanchor-persona-block.d.ts.map +1 -0
  110. package/dist/context-engine/compaction/hooks/reanchor-persona-block.js +27 -0
  111. package/dist/context-engine/compaction/hooks/reanchor-persona-block.js.map +1 -0
  112. package/dist/context-engine/compaction/hooks/reanchor-pinned-facts.d.ts +18 -0
  113. package/dist/context-engine/compaction/hooks/reanchor-pinned-facts.d.ts.map +1 -0
  114. package/dist/context-engine/compaction/hooks/reanchor-pinned-facts.js +47 -0
  115. package/dist/context-engine/compaction/hooks/reanchor-pinned-facts.js.map +1 -0
  116. package/dist/context-engine/compaction/hooks/reanchor-project-rules.d.ts +15 -0
  117. package/dist/context-engine/compaction/hooks/reanchor-project-rules.d.ts.map +1 -0
  118. package/dist/context-engine/compaction/hooks/reanchor-project-rules.js +32 -0
  119. package/dist/context-engine/compaction/hooks/reanchor-project-rules.js.map +1 -0
  120. package/dist/context-engine/compaction/hooks/types.d.ts +42 -0
  121. package/dist/context-engine/compaction/hooks/types.d.ts.map +1 -0
  122. package/dist/context-engine/compaction/index.d.ts +9 -0
  123. package/dist/context-engine/compaction/index.js +9 -0
  124. package/dist/context-engine/compaction/templates/summary-9-section.d.ts +84 -0
  125. package/dist/context-engine/compaction/templates/summary-9-section.d.ts.map +1 -0
  126. package/dist/context-engine/compaction/templates/summary-9-section.js +84 -0
  127. package/dist/context-engine/compaction/templates/summary-9-section.js.map +1 -0
  128. package/dist/context-engine/compaction/thresholds.d.ts +68 -0
  129. package/dist/context-engine/compaction/thresholds.d.ts.map +1 -0
  130. package/dist/context-engine/compaction/thresholds.js +63 -0
  131. package/dist/context-engine/compaction/thresholds.js.map +1 -0
  132. package/dist/context-engine/compaction/types.d.ts +202 -0
  133. package/dist/context-engine/compaction/types.d.ts.map +1 -0
  134. package/dist/context-engine/engine.d.ts +258 -0
  135. package/dist/context-engine/engine.d.ts.map +1 -0
  136. package/dist/context-engine/engine.js +424 -0
  137. package/dist/context-engine/engine.js.map +1 -0
  138. package/dist/context-engine/index.d.ts +68 -0
  139. package/dist/context-engine/index.d.ts.map +1 -0
  140. package/dist/context-engine/index.js +24 -0
  141. package/dist/context-engine/locale-packs/en.d.ts +14 -0
  142. package/dist/context-engine/locale-packs/en.d.ts.map +1 -0
  143. package/dist/context-engine/locale-packs/en.js +87 -0
  144. package/dist/context-engine/locale-packs/en.js.map +1 -0
  145. package/dist/context-engine/locale-packs/index.js +4 -0
  146. package/dist/context-engine/locale-packs/resolver.d.ts +41 -0
  147. package/dist/context-engine/locale-packs/resolver.d.ts.map +1 -0
  148. package/dist/context-engine/locale-packs/resolver.js +119 -0
  149. package/dist/context-engine/locale-packs/resolver.js.map +1 -0
  150. package/dist/context-engine/locale-packs/types.d.ts +119 -0
  151. package/dist/context-engine/locale-packs/types.d.ts.map +1 -0
  152. package/dist/context-engine/locale-packs/types.js +24 -0
  153. package/dist/context-engine/locale-packs/types.js.map +1 -0
  154. package/dist/context-engine/metadata.d.ts +40 -0
  155. package/dist/context-engine/metadata.d.ts.map +1 -0
  156. package/dist/context-engine/metadata.js +66 -0
  157. package/dist/context-engine/metadata.js.map +1 -0
  158. package/dist/context-engine/preambles/inbound-en.d.ts +20 -0
  159. package/dist/context-engine/preambles/inbound-en.d.ts.map +1 -0
  160. package/dist/context-engine/preambles/inbound-en.js +23 -0
  161. package/dist/context-engine/preambles/inbound-en.js.map +1 -0
  162. package/dist/context-engine/privacy-filter.d.ts +108 -0
  163. package/dist/context-engine/privacy-filter.d.ts.map +1 -0
  164. package/dist/context-engine/privacy-filter.js +113 -0
  165. package/dist/context-engine/privacy-filter.js.map +1 -0
  166. package/dist/context-engine/templates/base-en.d.ts +19 -0
  167. package/dist/context-engine/templates/base-en.d.ts.map +1 -0
  168. package/dist/context-engine/templates/base-en.js +22 -0
  169. package/dist/context-engine/templates/base-en.js.map +1 -0
  170. package/dist/context-engine/templates/composer.d.ts +55 -0
  171. package/dist/context-engine/templates/composer.d.ts.map +1 -0
  172. package/dist/context-engine/templates/composer.js +51 -0
  173. package/dist/context-engine/templates/composer.js.map +1 -0
  174. package/dist/context-engine/token-budget.d.ts +99 -0
  175. package/dist/context-engine/token-budget.d.ts.map +1 -0
  176. package/dist/context-engine/token-budget.js +211 -0
  177. package/dist/context-engine/token-budget.js.map +1 -0
  178. package/dist/context-engine/token-counter.d.ts +54 -0
  179. package/dist/context-engine/token-counter.d.ts.map +1 -0
  180. package/dist/context-engine/token-counter.js +81 -0
  181. package/dist/context-engine/token-counter.js.map +1 -0
  182. package/dist/errors/index.d.ts +171 -0
  183. package/dist/errors/index.d.ts.map +1 -0
  184. package/dist/errors/index.js +206 -0
  185. package/dist/errors/index.js.map +1 -0
  186. package/dist/facade.d.ts +278 -0
  187. package/dist/facade.d.ts.map +1 -0
  188. package/dist/facade.js +265 -0
  189. package/dist/facade.js.map +1 -0
  190. package/dist/graph/entity-resolver.d.ts +135 -0
  191. package/dist/graph/entity-resolver.d.ts.map +1 -0
  192. package/dist/graph/entity-resolver.js +202 -0
  193. package/dist/graph/entity-resolver.js.map +1 -0
  194. package/dist/graph/index.d.ts +1 -0
  195. package/dist/index.d.ts +103 -0
  196. package/dist/index.d.ts.map +1 -0
  197. package/dist/index.js +95 -0
  198. package/dist/index.js.map +1 -0
  199. package/dist/internal/contextualize.d.ts +14 -0
  200. package/dist/internal/contextualize.d.ts.map +1 -0
  201. package/dist/internal/contextualize.js +110 -0
  202. package/dist/internal/contextualize.js.map +1 -0
  203. package/dist/internal/embedder-binding.js +50 -0
  204. package/dist/internal/embedder-binding.js.map +1 -0
  205. package/dist/internal/id.js +24 -0
  206. package/dist/internal/id.js.map +1 -0
  207. package/dist/internal/injection-heuristics.js +64 -0
  208. package/dist/internal/injection-heuristics.js.map +1 -0
  209. package/dist/internal/spans.js +35 -0
  210. package/dist/internal/spans.js.map +1 -0
  211. package/dist/internal/storage-adapter.d.ts +742 -0
  212. package/dist/internal/storage-adapter.d.ts.map +1 -0
  213. package/dist/migration/embedder-migration.d.ts +124 -0
  214. package/dist/migration/embedder-migration.d.ts.map +1 -0
  215. package/dist/migration/embedder-migration.js +109 -0
  216. package/dist/migration/embedder-migration.js.map +1 -0
  217. package/dist/migration/index.d.ts +2 -0
  218. package/dist/migration/index.js +3 -0
  219. package/dist/search/explain.d.ts +74 -0
  220. package/dist/search/explain.d.ts.map +1 -0
  221. package/dist/search/explain.js +50 -0
  222. package/dist/search/explain.js.map +1 -0
  223. package/dist/search/index.d.ts +6 -0
  224. package/dist/search/index.js +6 -0
  225. package/dist/search/iterative.d.ts +223 -0
  226. package/dist/search/iterative.d.ts.map +1 -0
  227. package/dist/search/iterative.js +330 -0
  228. package/dist/search/iterative.js.map +1 -0
  229. package/dist/search/query-transform.d.ts +112 -0
  230. package/dist/search/query-transform.d.ts.map +1 -0
  231. package/dist/search/query-transform.js +184 -0
  232. package/dist/search/query-transform.js.map +1 -0
  233. package/dist/search/rrf.d.ts +95 -0
  234. package/dist/search/rrf.d.ts.map +1 -0
  235. package/dist/search/rrf.js +166 -0
  236. package/dist/search/rrf.js.map +1 -0
  237. package/dist/search/types.d.ts +50 -0
  238. package/dist/search/types.d.ts.map +1 -0
  239. package/dist/tiers/episodic-memory.d.ts +142 -0
  240. package/dist/tiers/episodic-memory.d.ts.map +1 -0
  241. package/dist/tiers/episodic-memory.js +254 -0
  242. package/dist/tiers/episodic-memory.js.map +1 -0
  243. package/dist/tiers/index.d.ts +8 -0
  244. package/dist/tiers/index.js +9 -0
  245. package/dist/tiers/insight-memory.d.ts +71 -0
  246. package/dist/tiers/insight-memory.d.ts.map +1 -0
  247. package/dist/tiers/insight-memory.js +133 -0
  248. package/dist/tiers/insight-memory.js.map +1 -0
  249. package/dist/tiers/procedural-memory.d.ts +147 -0
  250. package/dist/tiers/procedural-memory.d.ts.map +1 -0
  251. package/dist/tiers/procedural-memory.js +267 -0
  252. package/dist/tiers/procedural-memory.js.map +1 -0
  253. package/dist/tiers/semantic-memory.d.ts +461 -0
  254. package/dist/tiers/semantic-memory.d.ts.map +1 -0
  255. package/dist/tiers/semantic-memory.js +631 -0
  256. package/dist/tiers/semantic-memory.js.map +1 -0
  257. package/dist/tiers/session-memory.d.ts +117 -0
  258. package/dist/tiers/session-memory.d.ts.map +1 -0
  259. package/dist/tiers/session-memory.js +163 -0
  260. package/dist/tiers/session-memory.js.map +1 -0
  261. package/dist/tiers/shared-memory.d.ts +29 -0
  262. package/dist/tiers/shared-memory.d.ts.map +1 -0
  263. package/dist/tiers/shared-memory.js +58 -0
  264. package/dist/tiers/shared-memory.js.map +1 -0
  265. package/dist/tiers/working-memory.d.ts +129 -0
  266. package/dist/tiers/working-memory.d.ts.map +1 -0
  267. package/dist/tiers/working-memory.js +229 -0
  268. package/dist/tiers/working-memory.js.map +1 -0
  269. package/dist/tools/block-tools.d.ts +98 -0
  270. package/dist/tools/block-tools.d.ts.map +1 -0
  271. package/dist/tools/block-tools.js +114 -0
  272. package/dist/tools/block-tools.js.map +1 -0
  273. package/dist/tools/fact-tools.d.ts +294 -0
  274. package/dist/tools/fact-tools.d.ts.map +1 -0
  275. package/dist/tools/fact-tools.js +293 -0
  276. package/dist/tools/fact-tools.js.map +1 -0
  277. package/dist/tools/index.d.ts +35 -0
  278. package/dist/tools/index.d.ts.map +1 -0
  279. package/dist/tools/index.js +36 -0
  280. package/dist/tools/index.js.map +1 -0
  281. package/dist/tools/recall-tools.d.ts +209 -0
  282. package/dist/tools/recall-tools.d.ts.map +1 -0
  283. package/dist/tools/recall-tools.js +170 -0
  284. package/dist/tools/recall-tools.js.map +1 -0
  285. package/dist/tools/types.d.ts +40 -0
  286. package/dist/tools/types.d.ts.map +1 -0
  287. package/package.json +119 -0
@@ -0,0 +1,397 @@
1
+ import { MemoryStoreAdapter } from "../internal/storage-adapter.js";
2
+ import { ContextualRetrievalMode } from "../internal/contextualize.js";
3
+ import { EpisodicMemory } from "../tiers/episodic-memory.js";
4
+ import { SemanticMemory } from "../tiers/semantic-memory.js";
5
+ import { SalienceWeights } from "./decay.js";
6
+ import { Provider, SessionScope, Tracer } from "@graphorin/core";
7
+
8
+ //#region src/consolidator/types.d.ts
9
+
10
+ /**
11
+ * Trigger discriminator. The `'turn:N'` and `'idle:Xm'` variants are
12
+ * the production defaults per DEC-133. `'cron:EXPR'`, `'event:NAME'`
13
+ * and `'budget:N'` are opt-in.
14
+ *
15
+ * @stable
16
+ */
17
+ type ConsolidatorTriggerSpec = `turn:${number}` | `idle:${string}` | `cron:${string}` | `event:${string}` | `budget:${number}`;
18
+ /**
19
+ * Tier preset that selects a consolidator behaviour bundle. The
20
+ * `'free'` preset is the default per DEC-144 / ADR-038 — no LLM call
21
+ * fires until the operator opts in.
22
+ *
23
+ * @stable
24
+ */
25
+ type ConsolidatorTier = 'free' | 'cheap' | 'standard' | 'full' | 'custom';
26
+ /**
27
+ * Triggering reason surfaced through `Consolidator.trigger(...)`.
28
+ *
29
+ * @stable
30
+ */
31
+ interface ConsolidatorTriggerReason {
32
+ readonly kind: 'turn' | 'idle' | 'cron' | 'event' | 'budget' | 'manual';
33
+ readonly value?: string | number;
34
+ }
35
+ /**
36
+ * Hard cost ceilings enforced atomically per UTC day. The default
37
+ * ceiling shape per tier is captured in
38
+ * {@link CONSOLIDATOR_TIER_DEFAULTS}.
39
+ *
40
+ * @stable
41
+ */
42
+ interface ConsolidatorCeilings {
43
+ readonly maxTokensPerDay: number;
44
+ readonly maxCostPerDay: number;
45
+ /**
46
+ * ADVISORY (MCON-8): the per-scope lock serializes runs, so effective
47
+ * concurrency is always 1 per scope regardless of this value. The
48
+ * field is retained for forward compatibility; it enforces nothing
49
+ * today.
50
+ */
51
+ readonly maxConcurrentRuns: number;
52
+ readonly maxRunDurationMs: number;
53
+ /**
54
+ * Minimum quiet period between non-manual runs per scope (MCON-8).
55
+ * After each run the runtime persists `nextEligibleAt = now +
56
+ * cooldownMs`; trigger-driven runs (`turn` / `idle` / `cron` /
57
+ * `event` / `budget`) inside that window defer with reason
58
+ * `'cooldown'`. Manual `fireNow(...)` and DLQ replays bypass it.
59
+ */
60
+ readonly cooldownMs: number;
61
+ }
62
+ /**
63
+ * Behaviour applied by the budget enforcer when a ceiling is hit
64
+ * mid-run. `'pause'` is the conservative default — the consolidator
65
+ * skips subsequent runs until the next budget reset; `'log'` keeps
66
+ * running with a WARN; `'throw'` raises a typed
67
+ * {@link BudgetExceededError}.
68
+ *
69
+ * @stable
70
+ */
71
+ type OnBudgetExceed = 'pause' | 'log' | 'throw';
72
+ /**
73
+ * Phase identifier used by the runtime + audit rows.
74
+ *
75
+ * @stable
76
+ */
77
+ type ConsolidatorPhase = 'light' | 'standard' | 'deep';
78
+ /**
79
+ * Locked-down configuration accepted by `createConsolidator(...)`.
80
+ *
81
+ * @stable
82
+ */
83
+ interface ConsolidatorConfig {
84
+ readonly triggers: ReadonlyArray<ConsolidatorTriggerSpec>;
85
+ readonly tier: ConsolidatorTier;
86
+ readonly phases: ReadonlyArray<ConsolidatorPhase>;
87
+ readonly ceilings: ConsolidatorCeilings;
88
+ readonly onExceed: OnBudgetExceed;
89
+ /**
90
+ * Advisory label for the standard phase's model — recorded on spans /
91
+ * run telemetry only (MCON-7). Routing happens via
92
+ * `CreateConsolidatorOptions.cheapProvider`; this string disables
93
+ * nothing.
94
+ */
95
+ readonly cheapModel: string | null;
96
+ /**
97
+ * Advisory label for the deep phase's model — telemetry only
98
+ * (MCON-7). Routing happens via
99
+ * `CreateConsolidatorOptions.deepProvider`.
100
+ */
101
+ readonly deepModel: string | null;
102
+ readonly budgetResetSemantics: 'utc' | 'local' | 'sliding-24h';
103
+ readonly noiseFilters: ReadonlyArray<'default' | 'minimal' | 'none'>;
104
+ readonly lockWaitMs: number;
105
+ readonly decayTauDays: number;
106
+ readonly decayArchiveThreshold: number;
107
+ /**
108
+ * Capacity-bounded eviction target for the light phase (X-1). When set,
109
+ * each light pass archives the lowest-salience live facts in the LRU
110
+ * decay window down to this many — **cost / staleness control, not an
111
+ * accuracy lever**. `null` (the default at every tier) leaves storage
112
+ * unbounded, so behaviour is identical to pre-X-1. Archiving is a soft,
113
+ * recoverable move; nothing is hard-deleted.
114
+ */
115
+ readonly decayCapacity: number | null;
116
+ /**
117
+ * Weights for the multi-signal salience score (X-1) that orders both
118
+ * threshold archiving and capacity eviction. Defaults to
119
+ * {@link DEFAULT_SALIENCE_WEIGHTS}; with neutral importance, active
120
+ * status, and first-party provenance salience equals plain retention.
121
+ */
122
+ readonly salienceWeights: SalienceWeights;
123
+ readonly maxStandardBatchSize: number;
124
+ readonly maxDeepConflictsPerRun: number;
125
+ readonly dlqMaxRetries: number;
126
+ readonly dlqBaseBackoffMs: number;
127
+ readonly dlqMaxBackoffMs: number;
128
+ /**
129
+ * Auto-form a quarantined episode from each processed standard-phase
130
+ * slice (P1-2). Defaults on at the `standard`+ tiers, off at `free` /
131
+ * `cheap` / `custom`. The episode summary is one budgeted LLM call;
132
+ * when the budget is exhausted (or no episodic tier is wired) the
133
+ * phase degrades to fact-only behaviour.
134
+ */
135
+ readonly formEpisodes: boolean;
136
+ /**
137
+ * Ask the episode-summarization call for an LLM importance score
138
+ * (1–10, normalized to `[0, 1]`) so episodic triple-signal retrieval
139
+ * (recency × relevance × importance) runs on all three signals
140
+ * (P1-2). Importance is always a *soft* signal — it never gates
141
+ * retention. Defaults track {@link formEpisodes}.
142
+ */
143
+ readonly importanceScoring: boolean;
144
+ /**
145
+ * Auto-promotion policy (MCON-2). When `true`, the standard phase admits an
146
+ * injection-clean **extraction** fact as `active` instead of quarantined, so
147
+ * routine distillation surfaces in default recall without a manual
148
+ * `memory review --promote`. Injection-flagged facts always stay quarantined
149
+ * — the security gate is preserved — and episodes / insights / induced
150
+ * procedures are unaffected (they remain quarantined-until-validated).
151
+ * Defaults **off** at every tier: it trades the fail-safe default for
152
+ * convenience and is an explicit operator opt-in.
153
+ */
154
+ readonly autoPromoteExtraction: boolean;
155
+ /**
156
+ * Run the deep-phase reflection pass (P1-1): when accumulated episode
157
+ * importance crosses {@link importanceThreshold}, synthesize
158
+ * higher-order, cited insights over recent memories (Generative
159
+ * Agents). Insights land quarantined + `provenance: 'reflection'` and
160
+ * are ranked below the facts they cite. Defaults **on at the `full`
161
+ * tier only** (off at `free` / `cheap` / `standard` / `custom`) — it
162
+ * is the most LLM-intensive phase. A no-op without an episodic tier
163
+ * or an insight-capable storage adapter.
164
+ */
165
+ readonly reflection: boolean;
166
+ /**
167
+ * Sum of recent episode importance (each in `[0, 1]`) at or above
168
+ * which {@link reflection} fires. Below it the pass makes no LLM
169
+ * call. Defaults to `3`.
170
+ */
171
+ readonly importanceThreshold: number;
172
+ /** Upper bound on salient questions reflection asks per pass. Defaults to `3`. */
173
+ readonly reflectionMaxQuestions: number;
174
+ /**
175
+ * Contextual retrieval for facts written by the standard phase (P1-3).
176
+ * `'late-chunk'` (default at every tier) relies on the offline
177
+ * situating-context prefix the shared {@link SemanticMemory} computes
178
+ * for every write — no extra LLM call. `'llm'` is the opt-in
179
+ * enrichment: the standard phase spends one budgeted cheap-model call
180
+ * per additive write to author a 1–2 sentence situating prefix, then
181
+ * passes it as the write's index text. `'off'` indexes the bare text.
182
+ * The `'llm'` mode is **consolidator-only** by construction — the hot
183
+ * write path never has a provider for contextualization.
184
+ */
185
+ readonly contextualRetrieval: ContextualRetrievalMode;
186
+ }
187
+ /**
188
+ * Per-phase last-run snapshot surfaced inside
189
+ * {@link ConsolidatorStatus.lastRuns}. Each entry carries the
190
+ * timestamp of the most recent **completed** invocation for that
191
+ * phase (`undefined` when the phase has never run).
192
+ *
193
+ * @stable
194
+ */
195
+ interface ConsolidatorLastRuns {
196
+ readonly light?: string;
197
+ readonly standard?: string;
198
+ readonly deep?: string;
199
+ }
200
+ /**
201
+ * Budget snapshot block of {@link ConsolidatorStatus}. Surfaces
202
+ * both the absolute usage and the remaining envelope so consumers
203
+ * (CLI, server health endpoint) can render the operator dashboard
204
+ * without doing the math themselves.
205
+ *
206
+ * @stable
207
+ */
208
+ interface ConsolidatorBudgetSnapshot {
209
+ readonly tokensUsedToday: number;
210
+ readonly costUsedToday: number;
211
+ readonly tokensRemaining: number;
212
+ readonly costRemaining: number;
213
+ readonly resetAt: string;
214
+ }
215
+ /**
216
+ * Status snapshot returned by {@link Consolidator.status}.
217
+ *
218
+ * Public shape: `{ tier, queueDepth, dlqSize, lastRuns,
219
+ * budgetRemaining, deferredRuns }` — extended with a few additional
220
+ * fields the server health endpoint and the
221
+ * `graphorin consolidator status` CLI consume.
222
+ *
223
+ * `queueDepth` is an alias for {@link pendingConflicts} (the size
224
+ * of the deep-phase queue); both fields are populated for backwards
225
+ * compatibility.
226
+ *
227
+ * @stable
228
+ */
229
+ interface ConsolidatorStatus {
230
+ readonly tier: ConsolidatorTier;
231
+ readonly triggers: ReadonlyArray<ConsolidatorTriggerSpec>;
232
+ readonly phases: ReadonlyArray<ConsolidatorPhase>;
233
+ readonly running: boolean;
234
+ readonly paused: boolean;
235
+ /** Most recent completed run timestamp (any phase). */
236
+ readonly lastRunAt?: string;
237
+ /** Phase of the most recent completed run. */
238
+ readonly lastPhase?: ConsolidatorPhase;
239
+ /** Per-phase last-completed timestamps surfaced for CLI / dashboard. */
240
+ readonly lastRuns: ConsolidatorLastRuns;
241
+ /** Spec alias for {@link pendingConflicts}. */
242
+ readonly queueDepth: number;
243
+ readonly pendingConflicts: number;
244
+ readonly dlqSize: number;
245
+ readonly deferredRuns: number;
246
+ readonly emptyExtractions: number;
247
+ readonly budget: ConsolidatorBudgetSnapshot;
248
+ /** Spec alias — surfaces remaining-budget figures at the top level. */
249
+ readonly budgetRemaining: {
250
+ readonly tokens: number;
251
+ readonly costUsd: number;
252
+ };
253
+ }
254
+ /**
255
+ * Outcome surfaced by every phase invocation. Recorded into
256
+ * `consolidator_runs` and emitted on the AISpan.
257
+ *
258
+ * @stable
259
+ */
260
+ interface PhaseOutcome {
261
+ readonly phase: ConsolidatorPhase;
262
+ readonly status: 'completed' | 'failed' | 'deferred' | 'partial';
263
+ readonly factsCreated: number;
264
+ readonly factsUpdated: number;
265
+ readonly conflictsResolved: number;
266
+ /** Episodes auto-formed from the processed slice (P1-2). */
267
+ readonly episodesFormed: number;
268
+ /** Insights synthesized by the deep-phase reflection pass (P1-1). */
269
+ readonly insightsCreated: number;
270
+ readonly noiseFilteredCount: number;
271
+ readonly emptyExtractions: number;
272
+ readonly llmTokensUsed: number;
273
+ readonly llmCostUsd: number | null;
274
+ readonly errorMessage: string | null;
275
+ }
276
+ /**
277
+ * Listener callback subscribed via
278
+ * {@link Consolidator.onPhaseFinished}. Useful for tests + observers.
279
+ *
280
+ * @stable
281
+ */
282
+ type PhaseListener = (outcome: PhaseOutcome & {
283
+ readonly scope: SessionScope;
284
+ readonly trigger: ConsolidatorTriggerReason;
285
+ }) => void;
286
+ /**
287
+ * Options accepted by {@link createConsolidator}.
288
+ *
289
+ * @stable
290
+ */
291
+ interface CreateConsolidatorOptions {
292
+ /**
293
+ * Storage adapter — supplies the consolidator state, runs, DLQ,
294
+ * and per-tier helpers. The default `@graphorin/store-sqlite`
295
+ * adapter exposes everything by construction.
296
+ */
297
+ readonly store: MemoryStoreAdapter;
298
+ /**
299
+ * The {@link SemanticMemory} tier instance from the parent
300
+ * `createMemory(...)` facade. The standard phase routes every
301
+ * extracted fact through `semantic.remember(...)` so the conflict
302
+ * pipeline (Phase 10b) handles dedup / supersede.
303
+ */
304
+ readonly semantic: SemanticMemory;
305
+ /**
306
+ * The {@link EpisodicMemory} tier instance from the parent
307
+ * `createMemory(...)` facade. When supplied (and `formEpisodes` is
308
+ * on) the standard phase auto-forms a quarantined episode per
309
+ * processed slice (P1-2). Omitted ⇒ episode formation is skipped.
310
+ */
311
+ readonly episodic?: EpisodicMemory;
312
+ /**
313
+ * Provider used by the standard + deep phases. Required when the
314
+ * tier enables either phase; ignored when the active phases
315
+ * collapse to `['light']`.
316
+ */
317
+ readonly provider?: Provider | null;
318
+ readonly tracer?: Tracer;
319
+ /** Override the wall clock — used by tests. */
320
+ readonly now?: () => number;
321
+ /** Random source for stable run ids — used by tests. */
322
+ readonly randomId?: () => string;
323
+ readonly triggers?: ReadonlyArray<ConsolidatorTriggerSpec>;
324
+ readonly tier?: ConsolidatorTier;
325
+ readonly phases?: ReadonlyArray<ConsolidatorPhase>;
326
+ readonly ceilings?: Partial<ConsolidatorCeilings>;
327
+ readonly onExceed?: OnBudgetExceed;
328
+ /**
329
+ * Provider routed to the standard phase (extraction / episode /
330
+ * reconcile / situating-context calls) when set (MCON-7). Falls back
331
+ * to `provider`. Pair with `cheapModel` for the telemetry label.
332
+ */
333
+ readonly cheapProvider?: Provider | null;
334
+ /**
335
+ * Provider routed to the deep phase (conflict judge) and the
336
+ * reflection pass when set (MCON-7). Falls back to `provider`.
337
+ */
338
+ readonly deepProvider?: Provider | null;
339
+ readonly cheapModel?: string | null;
340
+ readonly deepModel?: string | null;
341
+ readonly budgetResetSemantics?: 'utc' | 'local' | 'sliding-24h';
342
+ readonly noiseFilters?: ReadonlyArray<'default' | 'minimal' | 'none'>;
343
+ readonly lockWaitMs?: number;
344
+ readonly decayTauDays?: number;
345
+ readonly decayArchiveThreshold?: number;
346
+ /** Override the {@link ConsolidatorConfig.decayCapacity} default (X-1). */
347
+ readonly decayCapacity?: number | null;
348
+ /** Override the {@link ConsolidatorConfig.salienceWeights} default (X-1). */
349
+ readonly salienceWeights?: SalienceWeights;
350
+ readonly maxStandardBatchSize?: number;
351
+ readonly maxDeepConflictsPerRun?: number;
352
+ readonly dlqMaxRetries?: number;
353
+ readonly dlqBaseBackoffMs?: number;
354
+ readonly dlqMaxBackoffMs?: number;
355
+ /** Override the per-tier {@link ConsolidatorConfig.formEpisodes} default (P1-2). */
356
+ readonly formEpisodes?: boolean;
357
+ /** Override the per-tier {@link ConsolidatorConfig.importanceScoring} default (P1-2). */
358
+ readonly importanceScoring?: boolean;
359
+ /**
360
+ * Opt in to auto-promotion of injection-clean extraction facts (MCON-2).
361
+ * Defaults `false`. See {@link ConsolidatorConfig.autoPromoteExtraction}.
362
+ */
363
+ readonly autoPromoteExtraction?: boolean;
364
+ /** Override the per-tier {@link ConsolidatorConfig.reflection} default (P1-1). */
365
+ readonly reflection?: boolean;
366
+ /** Override the {@link ConsolidatorConfig.importanceThreshold} default (P1-1). */
367
+ readonly importanceThreshold?: number;
368
+ /** Override the {@link ConsolidatorConfig.reflectionMaxQuestions} default (P1-1). */
369
+ readonly reflectionMaxQuestions?: number;
370
+ /** Override the per-tier {@link ConsolidatorConfig.contextualRetrieval} default (P1-3). */
371
+ readonly contextualRetrieval?: ContextualRetrievalMode;
372
+ /** Default scope used by event triggers + the manual `fireNow` path. */
373
+ readonly defaultScope?: SessionScope;
374
+ }
375
+ /**
376
+ * Tier preset table. The defaults follow ADR-038 §4 — `'free'`
377
+ * disables every LLM phase and pins zero ceilings, the upper tiers
378
+ * widen the budget envelope progressively.
379
+ *
380
+ * @stable
381
+ */
382
+ declare const CONSOLIDATOR_TIER_DEFAULTS: Readonly<Record<ConsolidatorTier, {
383
+ readonly ceilings: ConsolidatorCeilings;
384
+ readonly phases: ReadonlyArray<ConsolidatorPhase>;
385
+ readonly cheapModel: string | null;
386
+ readonly deepModel: string | null;
387
+ readonly onExceed: OnBudgetExceed;
388
+ readonly formEpisodes: boolean;
389
+ readonly importanceScoring: boolean;
390
+ readonly reflection: boolean;
391
+ readonly importanceThreshold: number;
392
+ readonly reflectionMaxQuestions: number;
393
+ readonly contextualRetrieval: ContextualRetrievalMode;
394
+ }>>;
395
+ //#endregion
396
+ export { CONSOLIDATOR_TIER_DEFAULTS, ConsolidatorBudgetSnapshot, ConsolidatorCeilings, ConsolidatorConfig, ConsolidatorLastRuns, ConsolidatorPhase, ConsolidatorStatus, ConsolidatorTier, ConsolidatorTriggerReason, ConsolidatorTriggerSpec, CreateConsolidatorOptions, OnBudgetExceed, PhaseListener, PhaseOutcome };
397
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/consolidator/types.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;AA8MuD,KAnL3C,uBAAA,GAmL2C,QAAA,MAAA,EAAA,GAAA,QAAA,MAAA,EAAA,GAAA,QAAA,MAAA,EAAA,GAAA,SAAA,MAAA,EAAA,GAAA,UAAA,MAAA,EAAA;AAWvD;AAcA;AAsBA;;;;;AAGmB,KAvNP,gBAAA,GAuNO,MAAA,GAAA,OAAA,GAAA,UAAA,GAAA,MAAA,GAAA,QAAA;;;;;AA6BnB;AAuBY,UApQK,yBAAA,CAoQQ;EACd,SAAA,IAAA,EAAA,MAAA,GAAA,MAAA,GAAA,MAAA,GAAA,OAAA,GAAA,QAAA,GAAA,QAAA;EACS,SAAA,KAAA,CAAA,EAAA,MAAA,GAAA,MAAA;;;AAUpB;;;;;;AAgCoC,UApSnB,oBAAA,CAoSmB;EAAd,SAAA,eAAA,EAAA,MAAA;EACJ,SAAA,aAAA,EAAA,MAAA;EACgB;;;;;;EAaR,SAAA,iBAAA,EAAA,MAAA;EAIA,SAAA,gBAAA,EAAA,MAAA;EAOG;;;;AAkC7B;;;EAKqC,SAAA,UAAA,EAAA,MAAA;;;;;;;;;;;KAvUzB,cAAA;;;;;;KAOA,iBAAA;;;;;;UAOK,kBAAA;qBACI,cAAc;iBAClB;mBACE,cAAc;qBACZ;qBACA;;;;;;;;;;;;;;;yBAeI;;;;;;;;;;;;;;;;;;;4BAmBG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCA+DI;;;;;;;;;;UAWf,oBAAA;;;;;;;;;;;;;UAcA,0BAAA;;;;;;;;;;;;;;;;;;;;;UAsBA,kBAAA;iBACA;qBACI,cAAc;mBAChB,cAAc;;;;;;uBAMV;;qBAEF;;;;;;;mBAOF;;;;;;;;;;;;;UAcF,YAAA;kBACC;;;;;;;;;;;;;;;;;;;;;KAsBN,aAAA,aACD;kBACS;oBACE;;;;;;;UASL,yBAAA;;;;;;kBAMC;;;;;;;qBAOG;;;;;;;sBAOC;;;;;;sBAMA;oBACF;;;;;sBAKE,cAAc;kBAClB;oBACE,cAAc;sBACZ,QAAQ;sBACR;;;;;;2BAMK;;;;;0BAKD;;;;0BAIA;;;;;;;6BAOG;;;;;;;;;;;;;;;;;;;;;;iCAsBI;;0BAEP;;;;;;;;;cAUb,4BAA4B,SACvC,OACE;qBAEqB;mBACF,cAAc;;;qBAGZ;;;;;;gCAMW"}
@@ -0,0 +1,117 @@
1
+ //#region src/consolidator/types.ts
2
+ /**
3
+ * Tier preset table. The defaults follow ADR-038 §4 — `'free'`
4
+ * disables every LLM phase and pins zero ceilings, the upper tiers
5
+ * widen the budget envelope progressively.
6
+ *
7
+ * @stable
8
+ */
9
+ const CONSOLIDATOR_TIER_DEFAULTS = Object.freeze({
10
+ free: {
11
+ ceilings: {
12
+ maxTokensPerDay: 0,
13
+ maxCostPerDay: 0,
14
+ maxConcurrentRuns: 1,
15
+ maxRunDurationMs: 300 * 1e3,
16
+ cooldownMs: 6e4
17
+ },
18
+ phases: ["light"],
19
+ cheapModel: null,
20
+ deepModel: null,
21
+ onExceed: "pause",
22
+ formEpisodes: false,
23
+ importanceScoring: false,
24
+ reflection: false,
25
+ importanceThreshold: 3,
26
+ reflectionMaxQuestions: 3,
27
+ contextualRetrieval: "late-chunk"
28
+ },
29
+ cheap: {
30
+ ceilings: {
31
+ maxTokensPerDay: 5e4,
32
+ maxCostPerDay: .2,
33
+ maxConcurrentRuns: 1,
34
+ maxRunDurationMs: 300 * 1e3,
35
+ cooldownMs: 6e4
36
+ },
37
+ phases: ["light", "standard"],
38
+ cheapModel: null,
39
+ deepModel: null,
40
+ onExceed: "pause",
41
+ formEpisodes: false,
42
+ importanceScoring: false,
43
+ reflection: false,
44
+ importanceThreshold: 3,
45
+ reflectionMaxQuestions: 3,
46
+ contextualRetrieval: "late-chunk"
47
+ },
48
+ standard: {
49
+ ceilings: {
50
+ maxTokensPerDay: 2e5,
51
+ maxCostPerDay: 1,
52
+ maxConcurrentRuns: 1,
53
+ maxRunDurationMs: 600 * 1e3,
54
+ cooldownMs: 3e4
55
+ },
56
+ phases: [
57
+ "light",
58
+ "standard",
59
+ "deep"
60
+ ],
61
+ cheapModel: null,
62
+ deepModel: null,
63
+ onExceed: "log",
64
+ formEpisodes: true,
65
+ importanceScoring: true,
66
+ reflection: false,
67
+ importanceThreshold: 3,
68
+ reflectionMaxQuestions: 3,
69
+ contextualRetrieval: "late-chunk"
70
+ },
71
+ full: {
72
+ ceilings: {
73
+ maxTokensPerDay: 1e6,
74
+ maxCostPerDay: 5,
75
+ maxConcurrentRuns: 2,
76
+ maxRunDurationMs: 900 * 1e3,
77
+ cooldownMs: 1e4
78
+ },
79
+ phases: [
80
+ "light",
81
+ "standard",
82
+ "deep"
83
+ ],
84
+ cheapModel: null,
85
+ deepModel: null,
86
+ onExceed: "log",
87
+ formEpisodes: true,
88
+ importanceScoring: true,
89
+ reflection: true,
90
+ importanceThreshold: 3,
91
+ reflectionMaxQuestions: 3,
92
+ contextualRetrieval: "late-chunk"
93
+ },
94
+ custom: {
95
+ ceilings: {
96
+ maxTokensPerDay: 0,
97
+ maxCostPerDay: 0,
98
+ maxConcurrentRuns: 1,
99
+ maxRunDurationMs: 300 * 1e3,
100
+ cooldownMs: 6e4
101
+ },
102
+ phases: ["light"],
103
+ cheapModel: null,
104
+ deepModel: null,
105
+ onExceed: "pause",
106
+ formEpisodes: false,
107
+ importanceScoring: false,
108
+ reflection: false,
109
+ importanceThreshold: 3,
110
+ reflectionMaxQuestions: 3,
111
+ contextualRetrieval: "late-chunk"
112
+ }
113
+ });
114
+
115
+ //#endregion
116
+ export { CONSOLIDATOR_TIER_DEFAULTS };
117
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","names":["CONSOLIDATOR_TIER_DEFAULTS: Readonly<\n Record<\n ConsolidatorTier,\n {\n readonly ceilings: ConsolidatorCeilings;\n readonly phases: ReadonlyArray<ConsolidatorPhase>;\n readonly cheapModel: string | null;\n readonly deepModel: string | null;\n readonly onExceed: OnBudgetExceed;\n readonly formEpisodes: boolean;\n readonly importanceScoring: boolean;\n readonly reflection: boolean;\n readonly importanceThreshold: number;\n readonly reflectionMaxQuestions: number;\n readonly contextualRetrieval: ContextualRetrievalMode;\n }\n >\n>"],"sources":["../../src/consolidator/types.ts"],"sourcesContent":["/**\n * Public types for the Phase 10c consolidator runtime.\n *\n * The consolidator is the background pipeline that turns raw\n * conversation turns into long-lived facts and episodes. The runtime\n * has three phases (`light` / `standard` / `deep`), an explicit cost\n * envelope, an idempotent cursor, a wait-then-defer lock, and a\n * dead-letter queue for retry-able failures. The binding architecture\n * references are DEC-133 / DEC-134 / ADR-038.\n *\n * @packageDocumentation\n */\n\nimport type { Provider, SessionScope, Tracer } from '@graphorin/core';\nimport type { ContextualRetrievalMode } from '../internal/contextualize.js';\nimport type { MemoryStoreAdapter } from '../internal/storage-adapter.js';\nimport type { EpisodicMemory } from '../tiers/episodic-memory.js';\nimport type { SemanticMemory } from '../tiers/semantic-memory.js';\nimport type { SalienceWeights } from './decay.js';\n\n/**\n * Trigger discriminator. The `'turn:N'` and `'idle:Xm'` variants are\n * the production defaults per DEC-133. `'cron:EXPR'`, `'event:NAME'`\n * and `'budget:N'` are opt-in.\n *\n * @stable\n */\nexport type ConsolidatorTriggerSpec =\n | `turn:${number}`\n | `idle:${string}`\n | `cron:${string}`\n | `event:${string}`\n | `budget:${number}`;\n\n/**\n * Tier preset that selects a consolidator behaviour bundle. The\n * `'free'` preset is the default per DEC-144 / ADR-038 — no LLM call\n * fires until the operator opts in.\n *\n * @stable\n */\nexport type ConsolidatorTier = 'free' | 'cheap' | 'standard' | 'full' | 'custom';\n\n/**\n * Triggering reason surfaced through `Consolidator.trigger(...)`.\n *\n * @stable\n */\nexport interface ConsolidatorTriggerReason {\n readonly kind: 'turn' | 'idle' | 'cron' | 'event' | 'budget' | 'manual';\n readonly value?: string | number;\n}\n\n/**\n * Hard cost ceilings enforced atomically per UTC day. The default\n * ceiling shape per tier is captured in\n * {@link CONSOLIDATOR_TIER_DEFAULTS}.\n *\n * @stable\n */\nexport interface ConsolidatorCeilings {\n readonly maxTokensPerDay: number;\n readonly maxCostPerDay: number;\n /**\n * ADVISORY (MCON-8): the per-scope lock serializes runs, so effective\n * concurrency is always 1 per scope regardless of this value. The\n * field is retained for forward compatibility; it enforces nothing\n * today.\n */\n readonly maxConcurrentRuns: number;\n readonly maxRunDurationMs: number;\n /**\n * Minimum quiet period between non-manual runs per scope (MCON-8).\n * After each run the runtime persists `nextEligibleAt = now +\n * cooldownMs`; trigger-driven runs (`turn` / `idle` / `cron` /\n * `event` / `budget`) inside that window defer with reason\n * `'cooldown'`. Manual `fireNow(...)` and DLQ replays bypass it.\n */\n readonly cooldownMs: number;\n}\n\n/**\n * Behaviour applied by the budget enforcer when a ceiling is hit\n * mid-run. `'pause'` is the conservative default — the consolidator\n * skips subsequent runs until the next budget reset; `'log'` keeps\n * running with a WARN; `'throw'` raises a typed\n * {@link BudgetExceededError}.\n *\n * @stable\n */\nexport type OnBudgetExceed = 'pause' | 'log' | 'throw';\n\n/**\n * Phase identifier used by the runtime + audit rows.\n *\n * @stable\n */\nexport type ConsolidatorPhase = 'light' | 'standard' | 'deep';\n\n/**\n * Locked-down configuration accepted by `createConsolidator(...)`.\n *\n * @stable\n */\nexport interface ConsolidatorConfig {\n readonly triggers: ReadonlyArray<ConsolidatorTriggerSpec>;\n readonly tier: ConsolidatorTier;\n readonly phases: ReadonlyArray<ConsolidatorPhase>;\n readonly ceilings: ConsolidatorCeilings;\n readonly onExceed: OnBudgetExceed;\n /**\n * Advisory label for the standard phase's model — recorded on spans /\n * run telemetry only (MCON-7). Routing happens via\n * `CreateConsolidatorOptions.cheapProvider`; this string disables\n * nothing.\n */\n readonly cheapModel: string | null;\n /**\n * Advisory label for the deep phase's model — telemetry only\n * (MCON-7). Routing happens via\n * `CreateConsolidatorOptions.deepProvider`.\n */\n readonly deepModel: string | null;\n readonly budgetResetSemantics: 'utc' | 'local' | 'sliding-24h';\n readonly noiseFilters: ReadonlyArray<'default' | 'minimal' | 'none'>;\n readonly lockWaitMs: number;\n readonly decayTauDays: number;\n readonly decayArchiveThreshold: number;\n /**\n * Capacity-bounded eviction target for the light phase (X-1). When set,\n * each light pass archives the lowest-salience live facts in the LRU\n * decay window down to this many — **cost / staleness control, not an\n * accuracy lever**. `null` (the default at every tier) leaves storage\n * unbounded, so behaviour is identical to pre-X-1. Archiving is a soft,\n * recoverable move; nothing is hard-deleted.\n */\n readonly decayCapacity: number | null;\n /**\n * Weights for the multi-signal salience score (X-1) that orders both\n * threshold archiving and capacity eviction. Defaults to\n * {@link DEFAULT_SALIENCE_WEIGHTS}; with neutral importance, active\n * status, and first-party provenance salience equals plain retention.\n */\n readonly salienceWeights: SalienceWeights;\n readonly maxStandardBatchSize: number;\n readonly maxDeepConflictsPerRun: number;\n readonly dlqMaxRetries: number;\n readonly dlqBaseBackoffMs: number;\n readonly dlqMaxBackoffMs: number;\n /**\n * Auto-form a quarantined episode from each processed standard-phase\n * slice (P1-2). Defaults on at the `standard`+ tiers, off at `free` /\n * `cheap` / `custom`. The episode summary is one budgeted LLM call;\n * when the budget is exhausted (or no episodic tier is wired) the\n * phase degrades to fact-only behaviour.\n */\n readonly formEpisodes: boolean;\n /**\n * Ask the episode-summarization call for an LLM importance score\n * (1–10, normalized to `[0, 1]`) so episodic triple-signal retrieval\n * (recency × relevance × importance) runs on all three signals\n * (P1-2). Importance is always a *soft* signal — it never gates\n * retention. Defaults track {@link formEpisodes}.\n */\n readonly importanceScoring: boolean;\n /**\n * Auto-promotion policy (MCON-2). When `true`, the standard phase admits an\n * injection-clean **extraction** fact as `active` instead of quarantined, so\n * routine distillation surfaces in default recall without a manual\n * `memory review --promote`. Injection-flagged facts always stay quarantined\n * — the security gate is preserved — and episodes / insights / induced\n * procedures are unaffected (they remain quarantined-until-validated).\n * Defaults **off** at every tier: it trades the fail-safe default for\n * convenience and is an explicit operator opt-in.\n */\n readonly autoPromoteExtraction: boolean;\n /**\n * Run the deep-phase reflection pass (P1-1): when accumulated episode\n * importance crosses {@link importanceThreshold}, synthesize\n * higher-order, cited insights over recent memories (Generative\n * Agents). Insights land quarantined + `provenance: 'reflection'` and\n * are ranked below the facts they cite. Defaults **on at the `full`\n * tier only** (off at `free` / `cheap` / `standard` / `custom`) — it\n * is the most LLM-intensive phase. A no-op without an episodic tier\n * or an insight-capable storage adapter.\n */\n readonly reflection: boolean;\n /**\n * Sum of recent episode importance (each in `[0, 1]`) at or above\n * which {@link reflection} fires. Below it the pass makes no LLM\n * call. Defaults to `3`.\n */\n readonly importanceThreshold: number;\n /** Upper bound on salient questions reflection asks per pass. Defaults to `3`. */\n readonly reflectionMaxQuestions: number;\n /**\n * Contextual retrieval for facts written by the standard phase (P1-3).\n * `'late-chunk'` (default at every tier) relies on the offline\n * situating-context prefix the shared {@link SemanticMemory} computes\n * for every write — no extra LLM call. `'llm'` is the opt-in\n * enrichment: the standard phase spends one budgeted cheap-model call\n * per additive write to author a 1–2 sentence situating prefix, then\n * passes it as the write's index text. `'off'` indexes the bare text.\n * The `'llm'` mode is **consolidator-only** by construction — the hot\n * write path never has a provider for contextualization.\n */\n readonly contextualRetrieval: ContextualRetrievalMode;\n}\n\n/**\n * Per-phase last-run snapshot surfaced inside\n * {@link ConsolidatorStatus.lastRuns}. Each entry carries the\n * timestamp of the most recent **completed** invocation for that\n * phase (`undefined` when the phase has never run).\n *\n * @stable\n */\nexport interface ConsolidatorLastRuns {\n readonly light?: string;\n readonly standard?: string;\n readonly deep?: string;\n}\n\n/**\n * Budget snapshot block of {@link ConsolidatorStatus}. Surfaces\n * both the absolute usage and the remaining envelope so consumers\n * (CLI, server health endpoint) can render the operator dashboard\n * without doing the math themselves.\n *\n * @stable\n */\nexport interface ConsolidatorBudgetSnapshot {\n readonly tokensUsedToday: number;\n readonly costUsedToday: number;\n readonly tokensRemaining: number;\n readonly costRemaining: number;\n readonly resetAt: string;\n}\n\n/**\n * Status snapshot returned by {@link Consolidator.status}.\n *\n * Public shape: `{ tier, queueDepth, dlqSize, lastRuns,\n * budgetRemaining, deferredRuns }` — extended with a few additional\n * fields the server health endpoint and the\n * `graphorin consolidator status` CLI consume.\n *\n * `queueDepth` is an alias for {@link pendingConflicts} (the size\n * of the deep-phase queue); both fields are populated for backwards\n * compatibility.\n *\n * @stable\n */\nexport interface ConsolidatorStatus {\n readonly tier: ConsolidatorTier;\n readonly triggers: ReadonlyArray<ConsolidatorTriggerSpec>;\n readonly phases: ReadonlyArray<ConsolidatorPhase>;\n readonly running: boolean;\n readonly paused: boolean;\n /** Most recent completed run timestamp (any phase). */\n readonly lastRunAt?: string;\n /** Phase of the most recent completed run. */\n readonly lastPhase?: ConsolidatorPhase;\n /** Per-phase last-completed timestamps surfaced for CLI / dashboard. */\n readonly lastRuns: ConsolidatorLastRuns;\n /** Spec alias for {@link pendingConflicts}. */\n readonly queueDepth: number;\n readonly pendingConflicts: number;\n readonly dlqSize: number;\n readonly deferredRuns: number;\n readonly emptyExtractions: number;\n readonly budget: ConsolidatorBudgetSnapshot;\n /** Spec alias — surfaces remaining-budget figures at the top level. */\n readonly budgetRemaining: {\n readonly tokens: number;\n readonly costUsd: number;\n };\n}\n\n/**\n * Outcome surfaced by every phase invocation. Recorded into\n * `consolidator_runs` and emitted on the AISpan.\n *\n * @stable\n */\nexport interface PhaseOutcome {\n readonly phase: ConsolidatorPhase;\n readonly status: 'completed' | 'failed' | 'deferred' | 'partial';\n readonly factsCreated: number;\n readonly factsUpdated: number;\n readonly conflictsResolved: number;\n /** Episodes auto-formed from the processed slice (P1-2). */\n readonly episodesFormed: number;\n /** Insights synthesized by the deep-phase reflection pass (P1-1). */\n readonly insightsCreated: number;\n readonly noiseFilteredCount: number;\n readonly emptyExtractions: number;\n readonly llmTokensUsed: number;\n readonly llmCostUsd: number | null;\n readonly errorMessage: string | null;\n}\n\n/**\n * Listener callback subscribed via\n * {@link Consolidator.onPhaseFinished}. Useful for tests + observers.\n *\n * @stable\n */\nexport type PhaseListener = (\n outcome: PhaseOutcome & {\n readonly scope: SessionScope;\n readonly trigger: ConsolidatorTriggerReason;\n },\n) => void;\n\n/**\n * Options accepted by {@link createConsolidator}.\n *\n * @stable\n */\nexport interface CreateConsolidatorOptions {\n /**\n * Storage adapter — supplies the consolidator state, runs, DLQ,\n * and per-tier helpers. The default `@graphorin/store-sqlite`\n * adapter exposes everything by construction.\n */\n readonly store: MemoryStoreAdapter;\n /**\n * The {@link SemanticMemory} tier instance from the parent\n * `createMemory(...)` facade. The standard phase routes every\n * extracted fact through `semantic.remember(...)` so the conflict\n * pipeline (Phase 10b) handles dedup / supersede.\n */\n readonly semantic: SemanticMemory;\n /**\n * The {@link EpisodicMemory} tier instance from the parent\n * `createMemory(...)` facade. When supplied (and `formEpisodes` is\n * on) the standard phase auto-forms a quarantined episode per\n * processed slice (P1-2). Omitted ⇒ episode formation is skipped.\n */\n readonly episodic?: EpisodicMemory;\n /**\n * Provider used by the standard + deep phases. Required when the\n * tier enables either phase; ignored when the active phases\n * collapse to `['light']`.\n */\n readonly provider?: Provider | null;\n readonly tracer?: Tracer;\n /** Override the wall clock — used by tests. */\n readonly now?: () => number;\n /** Random source for stable run ids — used by tests. */\n readonly randomId?: () => string;\n readonly triggers?: ReadonlyArray<ConsolidatorTriggerSpec>;\n readonly tier?: ConsolidatorTier;\n readonly phases?: ReadonlyArray<ConsolidatorPhase>;\n readonly ceilings?: Partial<ConsolidatorCeilings>;\n readonly onExceed?: OnBudgetExceed;\n /**\n * Provider routed to the standard phase (extraction / episode /\n * reconcile / situating-context calls) when set (MCON-7). Falls back\n * to `provider`. Pair with `cheapModel` for the telemetry label.\n */\n readonly cheapProvider?: Provider | null;\n /**\n * Provider routed to the deep phase (conflict judge) and the\n * reflection pass when set (MCON-7). Falls back to `provider`.\n */\n readonly deepProvider?: Provider | null;\n readonly cheapModel?: string | null;\n readonly deepModel?: string | null;\n readonly budgetResetSemantics?: 'utc' | 'local' | 'sliding-24h';\n readonly noiseFilters?: ReadonlyArray<'default' | 'minimal' | 'none'>;\n readonly lockWaitMs?: number;\n readonly decayTauDays?: number;\n readonly decayArchiveThreshold?: number;\n /** Override the {@link ConsolidatorConfig.decayCapacity} default (X-1). */\n readonly decayCapacity?: number | null;\n /** Override the {@link ConsolidatorConfig.salienceWeights} default (X-1). */\n readonly salienceWeights?: SalienceWeights;\n readonly maxStandardBatchSize?: number;\n readonly maxDeepConflictsPerRun?: number;\n readonly dlqMaxRetries?: number;\n readonly dlqBaseBackoffMs?: number;\n readonly dlqMaxBackoffMs?: number;\n /** Override the per-tier {@link ConsolidatorConfig.formEpisodes} default (P1-2). */\n readonly formEpisodes?: boolean;\n /** Override the per-tier {@link ConsolidatorConfig.importanceScoring} default (P1-2). */\n readonly importanceScoring?: boolean;\n /**\n * Opt in to auto-promotion of injection-clean extraction facts (MCON-2).\n * Defaults `false`. See {@link ConsolidatorConfig.autoPromoteExtraction}.\n */\n readonly autoPromoteExtraction?: boolean;\n /** Override the per-tier {@link ConsolidatorConfig.reflection} default (P1-1). */\n readonly reflection?: boolean;\n /** Override the {@link ConsolidatorConfig.importanceThreshold} default (P1-1). */\n readonly importanceThreshold?: number;\n /** Override the {@link ConsolidatorConfig.reflectionMaxQuestions} default (P1-1). */\n readonly reflectionMaxQuestions?: number;\n /** Override the per-tier {@link ConsolidatorConfig.contextualRetrieval} default (P1-3). */\n readonly contextualRetrieval?: ContextualRetrievalMode;\n /** Default scope used by event triggers + the manual `fireNow` path. */\n readonly defaultScope?: SessionScope;\n}\n\n/**\n * Tier preset table. The defaults follow ADR-038 §4 — `'free'`\n * disables every LLM phase and pins zero ceilings, the upper tiers\n * widen the budget envelope progressively.\n *\n * @stable\n */\nexport const CONSOLIDATOR_TIER_DEFAULTS: Readonly<\n Record<\n ConsolidatorTier,\n {\n readonly ceilings: ConsolidatorCeilings;\n readonly phases: ReadonlyArray<ConsolidatorPhase>;\n readonly cheapModel: string | null;\n readonly deepModel: string | null;\n readonly onExceed: OnBudgetExceed;\n readonly formEpisodes: boolean;\n readonly importanceScoring: boolean;\n readonly reflection: boolean;\n readonly importanceThreshold: number;\n readonly reflectionMaxQuestions: number;\n readonly contextualRetrieval: ContextualRetrievalMode;\n }\n >\n> = Object.freeze({\n free: {\n ceilings: {\n maxTokensPerDay: 0,\n maxCostPerDay: 0,\n maxConcurrentRuns: 1,\n maxRunDurationMs: 5 * 60 * 1000,\n cooldownMs: 60_000,\n },\n phases: ['light'],\n cheapModel: null,\n deepModel: null,\n onExceed: 'pause',\n formEpisodes: false,\n importanceScoring: false,\n reflection: false,\n importanceThreshold: 3,\n reflectionMaxQuestions: 3,\n contextualRetrieval: 'late-chunk',\n },\n cheap: {\n ceilings: {\n maxTokensPerDay: 50_000,\n maxCostPerDay: 0.2,\n maxConcurrentRuns: 1,\n maxRunDurationMs: 5 * 60 * 1000,\n cooldownMs: 60_000,\n },\n phases: ['light', 'standard'],\n cheapModel: null,\n deepModel: null,\n onExceed: 'pause',\n formEpisodes: false,\n importanceScoring: false,\n reflection: false,\n importanceThreshold: 3,\n reflectionMaxQuestions: 3,\n contextualRetrieval: 'late-chunk',\n },\n standard: {\n ceilings: {\n maxTokensPerDay: 200_000,\n maxCostPerDay: 1.0,\n maxConcurrentRuns: 1,\n maxRunDurationMs: 10 * 60 * 1000,\n cooldownMs: 30_000,\n },\n phases: ['light', 'standard', 'deep'],\n cheapModel: null,\n deepModel: null,\n onExceed: 'log',\n formEpisodes: true,\n importanceScoring: true,\n reflection: false,\n importanceThreshold: 3,\n reflectionMaxQuestions: 3,\n contextualRetrieval: 'late-chunk',\n },\n full: {\n ceilings: {\n maxTokensPerDay: 1_000_000,\n maxCostPerDay: 5.0,\n maxConcurrentRuns: 2,\n maxRunDurationMs: 15 * 60 * 1000,\n cooldownMs: 10_000,\n },\n phases: ['light', 'standard', 'deep'],\n cheapModel: null,\n deepModel: null,\n onExceed: 'log',\n formEpisodes: true,\n importanceScoring: true,\n reflection: true,\n importanceThreshold: 3,\n reflectionMaxQuestions: 3,\n contextualRetrieval: 'late-chunk',\n },\n custom: {\n ceilings: {\n maxTokensPerDay: 0,\n maxCostPerDay: 0,\n maxConcurrentRuns: 1,\n maxRunDurationMs: 5 * 60 * 1000,\n cooldownMs: 60_000,\n },\n phases: ['light'],\n cheapModel: null,\n deepModel: null,\n onExceed: 'pause',\n formEpisodes: false,\n importanceScoring: false,\n reflection: false,\n importanceThreshold: 3,\n reflectionMaxQuestions: 3,\n contextualRetrieval: 'late-chunk',\n },\n});\n"],"mappings":";;;;;;;;AA4ZA,MAAaA,6BAiBT,OAAO,OAAO;CAChB,MAAM;EACJ,UAAU;GACR,iBAAiB;GACjB,eAAe;GACf,mBAAmB;GACnB,kBAAkB,MAAS;GAC3B,YAAY;GACb;EACD,QAAQ,CAAC,QAAQ;EACjB,YAAY;EACZ,WAAW;EACX,UAAU;EACV,cAAc;EACd,mBAAmB;EACnB,YAAY;EACZ,qBAAqB;EACrB,wBAAwB;EACxB,qBAAqB;EACtB;CACD,OAAO;EACL,UAAU;GACR,iBAAiB;GACjB,eAAe;GACf,mBAAmB;GACnB,kBAAkB,MAAS;GAC3B,YAAY;GACb;EACD,QAAQ,CAAC,SAAS,WAAW;EAC7B,YAAY;EACZ,WAAW;EACX,UAAU;EACV,cAAc;EACd,mBAAmB;EACnB,YAAY;EACZ,qBAAqB;EACrB,wBAAwB;EACxB,qBAAqB;EACtB;CACD,UAAU;EACR,UAAU;GACR,iBAAiB;GACjB,eAAe;GACf,mBAAmB;GACnB,kBAAkB,MAAU;GAC5B,YAAY;GACb;EACD,QAAQ;GAAC;GAAS;GAAY;GAAO;EACrC,YAAY;EACZ,WAAW;EACX,UAAU;EACV,cAAc;EACd,mBAAmB;EACnB,YAAY;EACZ,qBAAqB;EACrB,wBAAwB;EACxB,qBAAqB;EACtB;CACD,MAAM;EACJ,UAAU;GACR,iBAAiB;GACjB,eAAe;GACf,mBAAmB;GACnB,kBAAkB,MAAU;GAC5B,YAAY;GACb;EACD,QAAQ;GAAC;GAAS;GAAY;GAAO;EACrC,YAAY;EACZ,WAAW;EACX,UAAU;EACV,cAAc;EACd,mBAAmB;EACnB,YAAY;EACZ,qBAAqB;EACrB,wBAAwB;EACxB,qBAAqB;EACtB;CACD,QAAQ;EACN,UAAU;GACR,iBAAiB;GACjB,eAAe;GACf,mBAAmB;GACnB,kBAAkB,MAAS;GAC3B,YAAY;GACb;EACD,QAAQ,CAAC,QAAQ;EACjB,YAAY;EACZ,WAAW;EACX,UAAU;EACV,cAAc;EACd,mBAAmB;EACnB,YAAY;EACZ,qBAAqB;EACrB,wBAAwB;EACxB,qBAAqB;EACtB;CACF,CAAC"}