@remnic/core 9.3.734 → 9.3.736

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 (256) hide show
  1. package/dist/access-boundary.d.ts +8 -6
  2. package/dist/access-boundary.js +9 -9
  3. package/dist/access-cli.js +24 -24
  4. package/dist/access-http.d.ts +8 -6
  5. package/dist/access-http.js +14 -14
  6. package/dist/access-mcp.d.ts +8 -6
  7. package/dist/access-mcp.js +13 -13
  8. package/dist/access-operations-batch.js +11 -11
  9. package/dist/access-operations.d.ts +8 -6
  10. package/dist/access-operations.js +12 -12
  11. package/dist/{access-service-rjFfmfKB.d.ts → access-service-CdC0q4pr.d.ts} +3 -3
  12. package/dist/access-service.d.ts +8 -6
  13. package/dist/access-service.js +8 -8
  14. package/dist/access-surface-catalog.d.ts +8 -6
  15. package/dist/action-confidence.d.ts +1 -1
  16. package/dist/active-memory-bridge.d.ts +1 -1
  17. package/dist/active-memory-bridge.js +3 -3
  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 +7 -5
  22. package/dist/briefing.d.ts +1 -1
  23. package/dist/buffer-surprise-report.d.ts +1 -1
  24. package/dist/buffer.d.ts +1 -1
  25. package/dist/calibration.d.ts +1 -1
  26. package/dist/capabilities.d.ts +101 -2
  27. package/dist/capabilities.js +13 -3
  28. package/dist/{catalog-DHYXzM4-.d.ts → catalog-D2NLDg4S.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-trajectory-graph.d.ts +1 -1
  32. package/dist/{chunk-IWMGBNXY.js → chunk-2T2N7ISV.js} +3 -3
  33. package/dist/{chunk-K7PAILHO.js → chunk-5BOQNB2K.js} +3 -3
  34. package/dist/{chunk-Q5LGXWNG.js → chunk-AAIHDIMD.js} +6 -6
  35. package/dist/{chunk-WHQ2JB35.js → chunk-AB2E5DCN.js} +2 -2
  36. package/dist/{chunk-Z7J3OAPR.js → chunk-AE2HPUP7.js} +726 -645
  37. package/dist/chunk-AE2HPUP7.js.map +1 -0
  38. package/dist/{chunk-FAGERSH2.js → chunk-AE7NTZ75.js} +3 -3
  39. package/dist/{chunk-V5OVSGB6.js → chunk-AESC5OQJ.js} +2 -2
  40. package/dist/{chunk-7FPJFCXL.js → chunk-BXPG5AVX.js} +4 -4
  41. package/dist/{chunk-UH3NYOHN.js → chunk-CHJIWG2H.js} +2 -2
  42. package/dist/{chunk-IDIXGGDN.js → chunk-E4LYJ7PY.js} +6 -6
  43. package/dist/{chunk-WTTVFSCO.js → chunk-FF36YNKY.js} +3 -3
  44. package/dist/{chunk-TJSQHO4Q.js → chunk-FLPKEMSO.js} +2 -2
  45. package/dist/{chunk-UF3N7IRP.js → chunk-G54IDCD3.js} +45 -41
  46. package/dist/chunk-G54IDCD3.js.map +1 -0
  47. package/dist/{chunk-UK6U5C3N.js → chunk-GB2FZOWB.js} +3 -3
  48. package/dist/{chunk-5OYHJIJN.js → chunk-GYICIICQ.js} +3 -3
  49. package/dist/{chunk-PEF2XOIV.js → chunk-HFXZIF3V.js} +3 -3
  50. package/dist/{chunk-PKO5NJ65.js → chunk-HLPYL6LC.js} +27 -24
  51. package/dist/chunk-HLPYL6LC.js.map +1 -0
  52. package/dist/{chunk-ET5HXSQL.js → chunk-IPI45Q4S.js} +2 -2
  53. package/dist/{chunk-2L5RTVMO.js → chunk-IX4L7E5G.js} +2 -2
  54. package/dist/{chunk-SYX73XD7.js → chunk-IXGXALRV.js} +10 -7
  55. package/dist/chunk-IXGXALRV.js.map +1 -0
  56. package/dist/{chunk-SHJGBAIW.js → chunk-JWDE7OVJ.js} +44 -2
  57. package/dist/{chunk-SHJGBAIW.js.map → chunk-JWDE7OVJ.js.map} +1 -1
  58. package/dist/{chunk-IZLTOS5L.js → chunk-K3Y2SJTN.js} +4 -4
  59. package/dist/{chunk-CILX2XW7.js → chunk-NDKW67ER.js} +2 -2
  60. package/dist/{chunk-54RCE5Z3.js → chunk-NNJKEAP2.js} +2 -2
  61. package/dist/{chunk-LV32K4OP.js → chunk-OYHYBHHI.js} +2 -2
  62. package/dist/{chunk-5DIKZKOD.js → chunk-P6VLG7KE.js} +2 -2
  63. package/dist/{chunk-T7CGPTFU.js → chunk-QNTLWH3T.js} +3 -3
  64. package/dist/{chunk-6U7TES2M.js → chunk-UO6MPN77.js} +13 -12
  65. package/dist/chunk-UO6MPN77.js.map +1 -0
  66. package/dist/{chunk-NDYQIN6C.js → chunk-VOEVVIP3.js} +3 -3
  67. package/dist/{chunk-3QETM5NG.js → chunk-ZBZ4XULO.js} +3 -3
  68. package/dist/{cli-XVpmSoQs.d.ts → cli-BHy6Bo6u.d.ts} +3 -3
  69. package/dist/cli.d.ts +9 -7
  70. package/dist/cli.js +20 -20
  71. package/dist/compounding/engine.d.ts +1 -1
  72. package/dist/compounding/engine.js +2 -2
  73. package/dist/compounding/preference-consolidator.d.ts +1 -1
  74. package/dist/compression-optimizer.d.ts +1 -1
  75. package/dist/config.d.ts +1 -1
  76. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  77. package/dist/connectors/codex-materialize.d.ts +1 -1
  78. package/dist/connectors/index.d.ts +1 -1
  79. package/dist/consolidation-provenance-check.d.ts +1 -1
  80. package/dist/consolidation-undo.d.ts +1 -1
  81. package/dist/contradiction/index.d.ts +1 -1
  82. package/dist/contradiction/index.js +2 -2
  83. package/dist/{contradiction-scan-OUHMCUBT.js → contradiction-scan-2B4AE4TI.js} +3 -3
  84. package/dist/conversation-index/backend.d.ts +1 -1
  85. package/dist/conversation-index/chunker.d.ts +1 -1
  86. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  87. package/dist/conversation-index/indexer.d.ts +1 -1
  88. package/dist/conversation-index/search.d.ts +1 -1
  89. package/dist/day-summary.d.ts +1 -1
  90. package/dist/delinearize.d.ts +1 -1
  91. package/dist/direct-answer-wiring.d.ts +1 -1
  92. package/dist/direct-answer.d.ts +1 -1
  93. package/dist/embedding-fallback.d.ts +1 -1
  94. package/dist/embedding-fallback.js +2 -2
  95. package/dist/enrichment/index.d.ts +1 -1
  96. package/dist/entity-retrieval.d.ts +1 -1
  97. package/dist/entity-retrieval.js +2 -2
  98. package/dist/entity-schema.d.ts +1 -1
  99. package/dist/explicit-capture.d.ts +7 -5
  100. package/dist/explicit-capture.js +2 -2
  101. package/dist/extraction-faithfulness.d.ts +1 -1
  102. package/dist/extraction-judge-telemetry.d.ts +1 -1
  103. package/dist/extraction-judge-training.d.ts +1 -1
  104. package/dist/extraction-judge.d.ts +1 -1
  105. package/dist/extraction.d.ts +1 -1
  106. package/dist/extraction.js +3 -3
  107. package/dist/fallback-llm.d.ts +1 -1
  108. package/dist/{first-start-migration-W4U6XDKI.js → first-start-migration-2RQYDIZ7.js} +6 -5
  109. package/dist/first-start-migration-2RQYDIZ7.js.map +1 -0
  110. package/dist/graph-dashboard-diff.d.ts +1 -1
  111. package/dist/graph-dashboard-key.d.ts +1 -1
  112. package/dist/graph-dashboard-parser.d.ts +1 -1
  113. package/dist/graph-edge-reinforcement.d.ts +1 -1
  114. package/dist/graph-snapshot.d.ts +1 -1
  115. package/dist/graph.d.ts +1 -1
  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 +30 -30
  120. package/dist/intent.d.ts +1 -1
  121. package/dist/lcm/engine.d.ts +1 -1
  122. package/dist/lcm/index.d.ts +1 -1
  123. package/dist/lcm/tools.d.ts +1 -1
  124. package/dist/lifecycle.d.ts +1 -1
  125. package/dist/live-connectors-runner.d.ts +1 -1
  126. package/dist/local-llm.d.ts +1 -1
  127. package/dist/local-llm.js +2 -2
  128. package/dist/local-model-endpoint.d.ts +1 -1
  129. package/dist/maintenance/memory-governance.d.ts +1 -1
  130. package/dist/mcp-memory-inspector-app.d.ts +8 -6
  131. package/dist/memory-action-policy.d.ts +1 -1
  132. package/dist/memory-cache.d.ts +1 -1
  133. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  134. package/dist/memory-projection-store.d.ts +1 -1
  135. package/dist/memory-provenance.d.ts +1 -1
  136. package/dist/memory-worth-outcomes.d.ts +1 -1
  137. package/dist/models-json.d.ts +1 -1
  138. package/dist/namespaces/migrate.d.ts +2 -2
  139. package/dist/namespaces/migrate.js +6 -6
  140. package/dist/namespaces/principal.d.ts +1 -1
  141. package/dist/namespaces/principal.js +2 -2
  142. package/dist/namespaces/search.d.ts +1 -1
  143. package/dist/namespaces/search.js +4 -4
  144. package/dist/namespaces/storage.d.ts +2 -2
  145. package/dist/namespaces/storage.js +2 -2
  146. package/dist/native-knowledge.d.ts +1 -1
  147. package/dist/operator-toolkit.d.ts +1 -1
  148. package/dist/operator-toolkit.js +11 -11
  149. package/dist/orchestration/compression-guideline-coordinator.d.ts +1 -1
  150. package/dist/orchestration/compression-guideline-coordinator.js +2 -1
  151. package/dist/orchestration/maintenance.d.ts +2 -2
  152. package/dist/orchestration/maintenance.js +6 -6
  153. package/dist/{orchestrator-BXi-gadS.d.ts → orchestrator-C-xp_rtZ.d.ts} +141 -18
  154. package/dist/orchestrator.d.ts +7 -5
  155. package/dist/orchestrator.js +19 -21
  156. package/dist/patterns-cli.d.ts +1 -1
  157. package/dist/policy-runtime.d.ts +1 -1
  158. package/dist/provenance.d.ts +1 -1
  159. package/dist/qmd-recall-cache.d.ts +1 -1
  160. package/dist/qmd.d.ts +1 -1
  161. package/dist/recall-disclosure-escalation.d.ts +1 -1
  162. package/dist/recall-explain-renderer.d.ts +1 -1
  163. package/dist/recall-planner-llm.d.ts +1 -1
  164. package/dist/recall-state.d.ts +1 -1
  165. package/dist/recall-tag-filter.d.ts +1 -1
  166. package/dist/recall-xray-cli.d.ts +1 -1
  167. package/dist/recall-xray-renderer.d.ts +1 -1
  168. package/dist/recall-xray.d.ts +1 -1
  169. package/dist/resolve-auth-token.d.ts +1 -1
  170. package/dist/retrieval-agents.d.ts +1 -1
  171. package/dist/retrieval-tiers.d.ts +1 -1
  172. package/dist/routing/engine.d.ts +1 -1
  173. package/dist/routing/store.d.ts +1 -1
  174. package/dist/search/embed-helper.d.ts +1 -1
  175. package/dist/search/embed-helper.js +2 -2
  176. package/dist/search/factory.d.ts +1 -1
  177. package/dist/search/factory.js +3 -3
  178. package/dist/search/index.d.ts +1 -1
  179. package/dist/search/index.js +3 -3
  180. package/dist/search/lancedb-backend.d.ts +1 -1
  181. package/dist/search/meilisearch-backend.d.ts +1 -1
  182. package/dist/search/noop-backend.d.ts +1 -1
  183. package/dist/search/orama-backend.d.ts +1 -1
  184. package/dist/search/port.d.ts +1 -1
  185. package/dist/search/remote-backend.d.ts +1 -1
  186. package/dist/{semantic-consolidation-DeL5grLx.d.ts → semantic-consolidation-COdwU-me.d.ts} +1 -1
  187. package/dist/semantic-consolidation.d.ts +2 -2
  188. package/dist/semantic-rule-verifier.d.ts +1 -1
  189. package/dist/session-observer-bands.d.ts +1 -1
  190. package/dist/session-observer-state.d.ts +1 -1
  191. package/dist/shared-context/manager.d.ts +1 -1
  192. package/dist/signal.d.ts +1 -1
  193. package/dist/storage.d.ts +1 -1
  194. package/dist/summarizer.d.ts +1 -1
  195. package/dist/summarizer.js +3 -3
  196. package/dist/summary-snapshot.d.ts +1 -1
  197. package/dist/temporal-supersession.d.ts +1 -1
  198. package/dist/temporal-validity.d.ts +1 -1
  199. package/dist/threading.d.ts +1 -1
  200. package/dist/tier-migration.d.ts +1 -1
  201. package/dist/tier-routing.d.ts +1 -1
  202. package/dist/{tier-stats-LSM35HZY.js → tier-stats-KPDIISG7.js} +6 -5
  203. package/dist/tier-stats-KPDIISG7.js.map +1 -0
  204. package/dist/topics.d.ts +1 -1
  205. package/dist/transcript.d.ts +1 -1
  206. package/dist/trust-score-stage.d.ts +1 -1
  207. package/dist/trust-score.d.ts +1 -1
  208. package/dist/{types-CpFz51Pv.d.ts → types-w3Y232yi.d.ts} +1 -1
  209. package/dist/types.d.ts +1 -1
  210. package/dist/utility-runtime.d.ts +1 -1
  211. package/package.json +2 -2
  212. package/src/access-service.ts +20 -20
  213. package/src/capabilities.test.ts +197 -0
  214. package/src/capabilities.ts +206 -0
  215. package/src/cli/creation-ledger-commands.ts +2 -2
  216. package/src/cli/research-status-commands.ts +13 -13
  217. package/src/cli.ts +17 -17
  218. package/src/maintenance/first-start-migration.ts +3 -3
  219. package/src/maintenance/tier-stats.ts +3 -3
  220. package/src/operator-toolkit.ts +8 -8
  221. package/src/orchestration/compression-guideline-coordinator.ts +7 -6
  222. package/src/orchestration/entity-synthesis-coordinator.ts +319 -0
  223. package/src/orchestration/lifecycle-policy-coordinator.ts +504 -0
  224. package/src/orchestrator.ts +40 -618
  225. package/dist/chunk-6U7TES2M.js.map +0 -1
  226. package/dist/chunk-PKO5NJ65.js.map +0 -1
  227. package/dist/chunk-SYX73XD7.js.map +0 -1
  228. package/dist/chunk-UF3N7IRP.js.map +0 -1
  229. package/dist/chunk-Z7J3OAPR.js.map +0 -1
  230. package/dist/first-start-migration-W4U6XDKI.js.map +0 -1
  231. package/dist/tier-stats-LSM35HZY.js.map +0 -1
  232. /package/dist/{chunk-IWMGBNXY.js.map → chunk-2T2N7ISV.js.map} +0 -0
  233. /package/dist/{chunk-K7PAILHO.js.map → chunk-5BOQNB2K.js.map} +0 -0
  234. /package/dist/{chunk-Q5LGXWNG.js.map → chunk-AAIHDIMD.js.map} +0 -0
  235. /package/dist/{chunk-WHQ2JB35.js.map → chunk-AB2E5DCN.js.map} +0 -0
  236. /package/dist/{chunk-FAGERSH2.js.map → chunk-AE7NTZ75.js.map} +0 -0
  237. /package/dist/{chunk-V5OVSGB6.js.map → chunk-AESC5OQJ.js.map} +0 -0
  238. /package/dist/{chunk-7FPJFCXL.js.map → chunk-BXPG5AVX.js.map} +0 -0
  239. /package/dist/{chunk-UH3NYOHN.js.map → chunk-CHJIWG2H.js.map} +0 -0
  240. /package/dist/{chunk-IDIXGGDN.js.map → chunk-E4LYJ7PY.js.map} +0 -0
  241. /package/dist/{chunk-WTTVFSCO.js.map → chunk-FF36YNKY.js.map} +0 -0
  242. /package/dist/{chunk-TJSQHO4Q.js.map → chunk-FLPKEMSO.js.map} +0 -0
  243. /package/dist/{chunk-UK6U5C3N.js.map → chunk-GB2FZOWB.js.map} +0 -0
  244. /package/dist/{chunk-5OYHJIJN.js.map → chunk-GYICIICQ.js.map} +0 -0
  245. /package/dist/{chunk-PEF2XOIV.js.map → chunk-HFXZIF3V.js.map} +0 -0
  246. /package/dist/{chunk-ET5HXSQL.js.map → chunk-IPI45Q4S.js.map} +0 -0
  247. /package/dist/{chunk-2L5RTVMO.js.map → chunk-IX4L7E5G.js.map} +0 -0
  248. /package/dist/{chunk-IZLTOS5L.js.map → chunk-K3Y2SJTN.js.map} +0 -0
  249. /package/dist/{chunk-CILX2XW7.js.map → chunk-NDKW67ER.js.map} +0 -0
  250. /package/dist/{chunk-54RCE5Z3.js.map → chunk-NNJKEAP2.js.map} +0 -0
  251. /package/dist/{chunk-LV32K4OP.js.map → chunk-OYHYBHHI.js.map} +0 -0
  252. /package/dist/{chunk-5DIKZKOD.js.map → chunk-P6VLG7KE.js.map} +0 -0
  253. /package/dist/{chunk-T7CGPTFU.js.map → chunk-QNTLWH3T.js.map} +0 -0
  254. /package/dist/{chunk-NDYQIN6C.js.map → chunk-VOEVVIP3.js.map} +0 -0
  255. /package/dist/{chunk-3QETM5NG.js.map → chunk-ZBZ4XULO.js.map} +0 -0
  256. /package/dist/{contradiction-scan-OUHMCUBT.js.map → contradiction-scan-2B4AE4TI.js.map} +0 -0
@@ -7,10 +7,10 @@ import {
7
7
  } from "./chunk-OZECYVGI.js";
8
8
  import {
9
9
  CompressionGuidelineCoordinator
10
- } from "./chunk-SYX73XD7.js";
10
+ } from "./chunk-IXGXALRV.js";
11
11
  import {
12
12
  MaintenanceScheduler
13
- } from "./chunk-5OYHJIJN.js";
13
+ } from "./chunk-GYICIICQ.js";
14
14
  import {
15
15
  runPeerProfileReasoner
16
16
  } from "./chunk-I74SUMNI.js";
@@ -29,7 +29,7 @@ import {
29
29
  import {
30
30
  CompoundingEngine,
31
31
  defaultTierMigrationCycleBudget
32
- } from "./chunk-ET5HXSQL.js";
32
+ } from "./chunk-IPI45Q4S.js";
33
33
  import {
34
34
  SharedContextManager
35
35
  } from "./chunk-UFS7OXGL.js";
@@ -63,7 +63,7 @@ import {
63
63
  } from "./chunk-UHGBNIOS.js";
64
64
  import {
65
65
  HourlySummarizer
66
- } from "./chunk-PEF2XOIV.js";
66
+ } from "./chunk-HFXZIF3V.js";
67
67
  import {
68
68
  buildTargetedFactRecallSection,
69
69
  shouldRecallTargetedFactEvidence
@@ -160,7 +160,7 @@ import {
160
160
  } from "./chunk-LTHVM4XN.js";
161
161
  import {
162
162
  ExtractionEngine
163
- } from "./chunk-WTTVFSCO.js";
163
+ } from "./chunk-FF36YNKY.js";
164
164
  import {
165
165
  parseMemoryActionEligibilityContext
166
166
  } from "./chunk-5GSUBCZM.js";
@@ -169,7 +169,7 @@ import {
169
169
  } from "./chunk-PWFWCGOO.js";
170
170
  import {
171
171
  LocalLlmClient
172
- } from "./chunk-2L5RTVMO.js";
172
+ } from "./chunk-IX4L7E5G.js";
173
173
  import {
174
174
  buildFocusedListRecallSection,
175
175
  shouldRecallFocusedListEvidence
@@ -193,12 +193,12 @@ import {
193
193
  } from "./chunk-Q6IP2ARR.js";
194
194
  import {
195
195
  EmbeddingFallback
196
- } from "./chunk-UH3NYOHN.js";
196
+ } from "./chunk-CHJIWG2H.js";
197
197
  import {
198
198
  buildEntityRecallSection,
199
199
  entityRecentTranscriptLookbackHours,
200
200
  readRecentEntityTranscriptEntries
201
- } from "./chunk-V5OVSGB6.js";
201
+ } from "./chunk-AESC5OQJ.js";
202
202
  import {
203
203
  RoutingRulesStore
204
204
  } from "./chunk-WIWPSQYU.js";
@@ -228,14 +228,14 @@ import {
228
228
  import {
229
229
  runNamespaceMaintenanceFanout,
230
230
  summarizeNamespaceMaintenanceHealth
231
- } from "./chunk-FAGERSH2.js";
231
+ } from "./chunk-AE7NTZ75.js";
232
232
  import {
233
233
  NamespaceCatalog,
234
234
  planNamespaceMaintenance
235
- } from "./chunk-7FPJFCXL.js";
235
+ } from "./chunk-BXPG5AVX.js";
236
236
  import {
237
237
  NamespaceStorageRouter
238
- } from "./chunk-54RCE5Z3.js";
238
+ } from "./chunk-NNJKEAP2.js";
239
239
  import {
240
240
  searchHarmonicRetrieval
241
241
  } from "./chunk-AV5ZEH4M.js";
@@ -333,14 +333,14 @@ import {
333
333
  resolveNamespaceFromStorageDir,
334
334
  resolveScopePlan,
335
335
  resolveScopeProfilePlan
336
- } from "./chunk-UK6U5C3N.js";
336
+ } from "./chunk-GB2FZOWB.js";
337
337
  import {
338
338
  NamespaceSearchRouter
339
- } from "./chunk-3QETM5NG.js";
339
+ } from "./chunk-ZBZ4XULO.js";
340
340
  import {
341
341
  createConversationIndexRuntime,
342
342
  createSearchBackend
343
- } from "./chunk-K7PAILHO.js";
343
+ } from "./chunk-5BOQNB2K.js";
344
344
  import {
345
345
  NoopSearchBackend
346
346
  } from "./chunk-CYEPCZN5.js";
@@ -363,7 +363,7 @@ import {
363
363
  } from "./chunk-QDW3E4RD.js";
364
364
  import {
365
365
  shouldSkipImplicitExtraction
366
- } from "./chunk-CILX2XW7.js";
366
+ } from "./chunk-NDKW67ER.js";
367
367
  import {
368
368
  searchCausalTrajectories
369
369
  } from "./chunk-SQNED75R.js";
@@ -465,18 +465,23 @@ import {
465
465
  defaultNamespaceForPrincipal,
466
466
  recallNamespacesForPrincipal,
467
467
  resolvePrincipal
468
- } from "./chunk-LV32K4OP.js";
468
+ } from "./chunk-OYHYBHHI.js";
469
469
  import {
470
470
  resolveCapabilities,
471
+ resolveCompressionCapabilities,
471
472
  resolveCreationMemoryCapabilities,
473
+ resolveEvalCapabilities,
472
474
  resolveGraphConstructionCapabilities,
473
475
  resolveIdentityContinuityCapabilities,
474
476
  resolveIndexingCapabilities,
475
477
  resolveLocalLlmCapabilities,
476
478
  resolveMemoryLifecycleCapabilities,
477
479
  resolveNamespaceCapabilities,
478
- resolveQmdCapabilities
479
- } from "./chunk-SHJGBAIW.js";
480
+ resolveObjectiveStateCapabilities,
481
+ resolveQmdCapabilities,
482
+ resolveSecurityCapabilities,
483
+ resolveUtilityLearningCapabilities
484
+ } from "./chunk-JWDE7OVJ.js";
480
485
  import {
481
486
  isSafeRouteNamespace,
482
487
  selectRouteRule
@@ -501,19 +506,19 @@ import {
501
506
  } from "./chunk-PVGDJXVK.js";
502
507
 
503
508
  // src/orchestrator.ts
504
- import path3 from "path";
509
+ import path4 from "path";
505
510
  import os2 from "os";
506
- import { createHash, randomBytes } from "crypto";
511
+ import { createHash as createHash2, randomBytes } from "crypto";
507
512
  import { existsSync, readFileSync } from "fs";
508
513
  import {
509
514
  lstat,
510
- mkdir as mkdir2,
515
+ mkdir as mkdir3,
511
516
  readdir,
512
517
  readFile as readFile2,
513
518
  realpath,
514
519
  stat,
515
520
  unlink,
516
- writeFile as writeFile2
521
+ writeFile as writeFile3
517
522
  } from "fs/promises";
518
523
 
519
524
  // src/procedural/procedure-recall.ts
@@ -1065,68 +1070,559 @@ var SemanticConsolidationCoordinator = class {
1065
1070
  result.memoriesArchived++;
1066
1071
  }
1067
1072
  }
1068
- log.info(
1069
- `[semantic-consolidation] consolidated ${cluster.memories.length} memories \u2192 ${canonicalId}`
1070
- );
1071
- } catch (err) {
1072
- log.warn(
1073
- `[semantic-consolidation] cluster processing failed: ${err instanceof Error ? err.message : String(err)}`
1074
- );
1075
- result.errors++;
1076
- } finally {
1077
- if (canonicalWriteCompleted) {
1073
+ log.info(
1074
+ `[semantic-consolidation] consolidated ${cluster.memories.length} memories \u2192 ${canonicalId}`
1075
+ );
1076
+ } catch (err) {
1077
+ log.warn(
1078
+ `[semantic-consolidation] cluster processing failed: ${err instanceof Error ? err.message : String(err)}`
1079
+ );
1080
+ result.errors++;
1081
+ } finally {
1082
+ if (canonicalWriteCompleted) {
1083
+ }
1084
+ }
1085
+ }
1086
+ if (result.memoriesArchived > 0) {
1087
+ await this.deps.saveContentHashIndexes().catch(
1088
+ (err) => log.warn(
1089
+ `[semantic-consolidation] content-hash index save failed: ${err}`
1090
+ )
1091
+ );
1092
+ }
1093
+ log.info(
1094
+ `[semantic-consolidation] complete: clusters=${result.clustersFound}, consolidated=${result.memoriesConsolidated}, archived=${result.memoriesArchived}, errors=${result.errors}`
1095
+ );
1096
+ try {
1097
+ await materializeAfterSemanticConsolidation({
1098
+ config: this.config,
1099
+ memoryDir: targetStorage.dir
1100
+ });
1101
+ } catch (err) {
1102
+ log.warn(
1103
+ `[semantic-consolidation] Codex materialize post-hook failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`
1104
+ );
1105
+ }
1106
+ if (this.config.peerProfileReasonerEnabled) {
1107
+ try {
1108
+ const peerLlm = new FallbackLlmClient(
1109
+ this.config.gatewayConfig,
1110
+ fallbackLlmRuntimeContextFromConfig(this.config)
1111
+ );
1112
+ const peerResult = await runPeerProfileReasoner({
1113
+ memoryDir: targetStorage.dir,
1114
+ enabled: true,
1115
+ llm: peerLlm,
1116
+ model: this.config.peerProfileReasonerModel,
1117
+ minInteractions: this.config.peerProfileReasonerMinInteractions,
1118
+ maxFieldsPerRun: this.config.peerProfileReasonerMaxFieldsPerRun,
1119
+ log: {
1120
+ debug: (msg) => log.debug(msg),
1121
+ info: (msg) => log.info(msg),
1122
+ warn: (msg) => log.warn(msg)
1123
+ }
1124
+ });
1125
+ log.info(
1126
+ `[peer-profile-reasoner] complete: peers=${peerResult.peersConsidered}, processed=${peerResult.peersProcessed}, fields=${peerResult.fieldsApplied}`
1127
+ );
1128
+ } catch (err) {
1129
+ log.warn(
1130
+ `[peer-profile-reasoner] post-consolidation hook failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`
1131
+ );
1132
+ }
1133
+ }
1134
+ return result;
1135
+ }
1136
+ };
1137
+
1138
+ // src/orchestration/lifecycle-policy-coordinator.ts
1139
+ import path2 from "path";
1140
+ import { mkdir, writeFile } from "fs/promises";
1141
+ var LifecyclePolicyCoordinator = class {
1142
+ constructor(deps) {
1143
+ this.deps = deps;
1144
+ }
1145
+ deps;
1146
+ get config() {
1147
+ return this.deps.config;
1148
+ }
1149
+ // -------------------------------------------------------------------------
1150
+ // Action-outcome priors (feeds lifecycle transition decisions)
1151
+ // -------------------------------------------------------------------------
1152
+ actionOutcomePriorDelta(event) {
1153
+ if (event.outcome === "failed") return -0.3;
1154
+ if (event.policyDecision === "deny") return -0.22;
1155
+ if (event.policyDecision === "defer") return -0.14;
1156
+ if (event.outcome === "skipped") return -0.1;
1157
+ if (event.outcome !== "applied") return 0;
1158
+ switch (event.action) {
1159
+ case "store_episode":
1160
+ case "store_note":
1161
+ case "update_note":
1162
+ return 0.08;
1163
+ case "create_artifact":
1164
+ case "summarize_node":
1165
+ case "link_graph":
1166
+ return 0.04;
1167
+ case "discard":
1168
+ return -0.03;
1169
+ default:
1170
+ return 0;
1171
+ }
1172
+ }
1173
+ async buildLifecycleActionPriors(storage = this.deps.getStorage()) {
1174
+ const events = await storage.readMemoryActionEvents(1200);
1175
+ if (events.length === 0) return /* @__PURE__ */ new Map();
1176
+ const nowMs = Date.now();
1177
+ const windowMs = 14 * 24 * 60 * 60 * 1e3;
1178
+ const byMemory = /* @__PURE__ */ new Map();
1179
+ for (const event of events) {
1180
+ if (typeof event.memoryId !== "string" || event.memoryId.trim().length === 0)
1181
+ continue;
1182
+ const ts = Date.parse(event.timestamp);
1183
+ if (!Number.isFinite(ts)) continue;
1184
+ const ageMs = nowMs - ts;
1185
+ if (ageMs < 0 || ageMs > windowMs) continue;
1186
+ const delta = this.actionOutcomePriorDelta(event);
1187
+ if (delta === 0) continue;
1188
+ const recencyWeight = Math.max(0.2, 1 - ageMs / windowMs);
1189
+ const list = byMemory.get(event.memoryId) ?? [];
1190
+ if (list.length >= 8) list.shift();
1191
+ list.push({
1192
+ weightedDelta: delta * recencyWeight,
1193
+ weight: recencyWeight
1194
+ });
1195
+ byMemory.set(event.memoryId, list);
1196
+ }
1197
+ const out = /* @__PURE__ */ new Map();
1198
+ for (const [memoryId, deltas] of byMemory.entries()) {
1199
+ if (deltas.length === 0) continue;
1200
+ const weightedSum = deltas.reduce(
1201
+ (sum, item) => sum + item.weightedDelta,
1202
+ 0
1203
+ );
1204
+ const weightTotal = deltas.reduce((sum, item) => sum + item.weight, 0);
1205
+ if (weightTotal <= 0) continue;
1206
+ const score = weightedSum / weightTotal;
1207
+ out.set(memoryId, Math.max(-0.25, Math.min(0.15, score)));
1208
+ }
1209
+ return out;
1210
+ }
1211
+ // -------------------------------------------------------------------------
1212
+ // Lifecycle policy pass (heat/decay scoring + transition)
1213
+ // -------------------------------------------------------------------------
1214
+ async runLifecyclePolicyPass(allMemories, storage = this.deps.getStorage()) {
1215
+ const now = /* @__PURE__ */ new Date();
1216
+ const nowIso = now.toISOString();
1217
+ const countsByState = {
1218
+ candidate: 0,
1219
+ validated: 0,
1220
+ active: 0,
1221
+ stale: 0,
1222
+ archived: 0
1223
+ };
1224
+ const transitionCounts = {};
1225
+ let updatedCount = 0;
1226
+ let disputedCount = 0;
1227
+ let evaluatedCount = 0;
1228
+ const lifecycleCaps = resolveMemoryLifecycleCapabilities(this.config);
1229
+ const thresholds = this.deps.getEffectiveLifecycleThresholds();
1230
+ const policy = {
1231
+ promoteHeatThreshold: thresholds.promoteHeatThreshold,
1232
+ staleDecayThreshold: thresholds.staleDecayThreshold,
1233
+ archiveDecayThreshold: thresholds.archiveDecayThreshold,
1234
+ protectedCategories: this.config.lifecycleProtectedCategories
1235
+ };
1236
+ const actionPriors = await this.buildLifecycleActionPriors(storage);
1237
+ for (const memory of allMemories) {
1238
+ if (memory.frontmatter.status === "superseded" || memory.frontmatter.status === "forgotten") {
1239
+ continue;
1240
+ }
1241
+ evaluatedCount += 1;
1242
+ const currentState = resolveLifecycleState(memory.frontmatter);
1243
+ const actionPriorScore = actionPriors.get(memory.frontmatter.id);
1244
+ const signals = typeof actionPriorScore === "number" && Number.isFinite(actionPriorScore) ? { actionPriorScore } : void 0;
1245
+ const decision = decideLifecycleTransition(memory, policy, now, signals);
1246
+ const nextState = memory.frontmatter.status === "archived" ? "archived" : decision.nextState;
1247
+ countsByState[nextState] += 1;
1248
+ if (memory.frontmatter.verificationState === "disputed") {
1249
+ disputedCount += 1;
1250
+ }
1251
+ if (nextState !== currentState) {
1252
+ const key = `${currentState}->${nextState}`;
1253
+ transitionCounts[key] = (transitionCounts[key] ?? 0) + 1;
1254
+ }
1255
+ const prevHeat = memory.frontmatter.heatScore;
1256
+ const prevDecay = memory.frontmatter.decayScore;
1257
+ const scoreDelta = Math.abs((prevHeat ?? -1) - decision.heatScore) + Math.abs((prevDecay ?? -1) - decision.decayScore);
1258
+ const shouldPersist = memory.frontmatter.lifecycleState !== nextState || memory.frontmatter.heatScore === void 0 || memory.frontmatter.decayScore === void 0 || memory.frontmatter.lastValidatedAt === void 0 || scoreDelta >= 0.01;
1259
+ if (!shouldPersist) continue;
1260
+ const wrote = await storage.writeMemoryFrontmatter(memory, {
1261
+ lifecycleState: nextState,
1262
+ heatScore: decision.heatScore,
1263
+ decayScore: decision.decayScore,
1264
+ lastValidatedAt: nowIso
1265
+ });
1266
+ if (wrote) updatedCount += 1;
1267
+ }
1268
+ if (!lifecycleCaps.lifecycleMetrics) return updatedCount;
1269
+ const total = evaluatedCount;
1270
+ const metrics = {
1271
+ generatedAt: nowIso,
1272
+ memoriesEvaluated: total,
1273
+ memoriesUpdated: updatedCount,
1274
+ countsByLifecycleState: countsByState,
1275
+ transitionCounts,
1276
+ staleRatio: total > 0 ? countsByState.stale / total : 0,
1277
+ disputedRatio: total > 0 ? disputedCount / total : 0,
1278
+ policy: {
1279
+ promoteHeatThreshold: thresholds.promoteHeatThreshold,
1280
+ staleDecayThreshold: thresholds.staleDecayThreshold,
1281
+ archiveDecayThreshold: thresholds.archiveDecayThreshold,
1282
+ protectedCategories: this.config.lifecycleProtectedCategories
1283
+ }
1284
+ };
1285
+ const metricsPath = path2.join(
1286
+ storage.dir,
1287
+ "state",
1288
+ "lifecycle-metrics.json"
1289
+ );
1290
+ await mkdir(path2.dirname(metricsPath), { recursive: true });
1291
+ await writeFile(metricsPath, JSON.stringify(metrics, null, 2), "utf-8");
1292
+ return updatedCount;
1293
+ }
1294
+ // -------------------------------------------------------------------------
1295
+ // Fact archival
1296
+ // -------------------------------------------------------------------------
1297
+ /**
1298
+ * Archive old, low-importance, rarely-accessed facts (v6.0).
1299
+ * Moves eligible facts from facts/ to archive/YYYY-MM-DD/.
1300
+ * Returns the number of archived facts.
1301
+ */
1302
+ async runFactArchival(allMemories) {
1303
+ const storage = this.deps.getStorage();
1304
+ const now = Date.now();
1305
+ const ageCutoffMs = this.config.factArchivalAgeDays * 24 * 60 * 60 * 1e3;
1306
+ const protectedCategories = new Set(
1307
+ this.config.factArchivalProtectedCategories
1308
+ );
1309
+ let archivedCount = 0;
1310
+ for (const memory of allMemories) {
1311
+ const fm = memory.frontmatter;
1312
+ if (fm.status && fm.status !== "active") continue;
1313
+ if (protectedCategories.has(fm.category)) continue;
1314
+ if (fm.category === "correction") continue;
1315
+ const createdMs = new Date(fm.created).getTime();
1316
+ if (now - createdMs < ageCutoffMs) continue;
1317
+ const importanceScore = fm.importance?.score ?? 0.5;
1318
+ if (importanceScore >= this.config.factArchivalMaxImportance) continue;
1319
+ const accessCount = fm.accessCount ?? 0;
1320
+ if (accessCount > this.config.factArchivalMaxAccessCount) continue;
1321
+ const result = await storage.archiveMemory(memory);
1322
+ if (result) {
1323
+ await this.deps.removeContentHashForMemory(
1324
+ storage,
1325
+ memory,
1326
+ "fact-archival"
1327
+ );
1328
+ await this.deps.embeddingFallback.removeFromIndex(memory.frontmatter.id);
1329
+ if (resolveIndexingCapabilities(this.config).queryAwareIndexing && memory.path && memory.frontmatter?.created) {
1330
+ deindexMemory(
1331
+ this.config.memoryDir,
1332
+ memory.path,
1333
+ memory.frontmatter.created,
1334
+ memory.frontmatter.tags ?? []
1335
+ );
1336
+ }
1337
+ archivedCount++;
1338
+ }
1339
+ }
1340
+ if (archivedCount > 0) {
1341
+ await this.deps.saveContentHashIndexes().catch(
1342
+ (err) => log.warn(`content-hash index save failed during archival: ${err}`)
1343
+ );
1344
+ }
1345
+ return archivedCount;
1346
+ }
1347
+ // -------------------------------------------------------------------------
1348
+ // Summarization (Phase 4A)
1349
+ // -------------------------------------------------------------------------
1350
+ /**
1351
+ * Run memory summarization if memory count exceeds threshold (Phase 4A).
1352
+ */
1353
+ async runSummarization(allMemories) {
1354
+ const storage = this.deps.getStorage();
1355
+ const activeMemories = allMemories.filter(
1356
+ (m) => isActiveMemoryStatus(m.frontmatter.status)
1357
+ );
1358
+ if (activeMemories.length < this.config.summarizationTriggerCount) {
1359
+ return;
1360
+ }
1361
+ log.info(
1362
+ `memory count (${activeMemories.length}) exceeds threshold (${this.config.summarizationTriggerCount}) \u2014 running summarization`
1363
+ );
1364
+ const sorted = activeMemories.sort(
1365
+ (a, b) => new Date(a.frontmatter.created).getTime() - new Date(b.frontmatter.created).getTime()
1366
+ );
1367
+ const recentToKeep = Math.max(0, this.config.summarizationRecentToKeep);
1368
+ const toSummarize = recentToKeep > 0 ? sorted.slice(0, -recentToKeep) : sorted;
1369
+ const candidates = toSummarize.filter((m) => {
1370
+ if (m.frontmatter.entityRef) return false;
1371
+ const protectedTags = this.config.summarizationProtectedTags;
1372
+ if (m.frontmatter.tags.some((t) => protectedTags.includes(t)))
1373
+ return false;
1374
+ const importance = m.frontmatter.importance?.score ?? 0.5;
1375
+ if (importance >= this.config.summarizationImportanceThreshold)
1376
+ return false;
1377
+ return true;
1378
+ });
1379
+ if (candidates.length < 50) {
1380
+ log.debug(
1381
+ `only ${candidates.length} candidates for summarization \u2014 skipping`
1382
+ );
1383
+ return;
1384
+ }
1385
+ const batchSize = 50;
1386
+ for (let i = 0; i < candidates.length; i += batchSize) {
1387
+ const batch = candidates.slice(i, i + batchSize);
1388
+ const batchData = batch.map((m) => ({
1389
+ id: m.frontmatter.id,
1390
+ content: m.content,
1391
+ category: m.frontmatter.category,
1392
+ created: m.frontmatter.created
1393
+ }));
1394
+ const result = await this.deps.extraction.summarizeMemories(batchData);
1395
+ if (!result) continue;
1396
+ const summary = {
1397
+ id: `summary-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
1398
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1399
+ timeRangeStart: batch[0].frontmatter.created,
1400
+ timeRangeEnd: batch[batch.length - 1].frontmatter.created,
1401
+ summaryText: result.summaryText,
1402
+ keyFacts: result.keyFacts,
1403
+ keyEntities: result.keyEntities,
1404
+ sourceEpisodeIds: batch.map((m) => m.frontmatter.id)
1405
+ };
1406
+ await storage.writeSummary(summary);
1407
+ const archived = await storage.archiveMemories(
1408
+ batch.map((m) => m.frontmatter.id),
1409
+ summary.id
1410
+ );
1411
+ log.info(
1412
+ `created summary ${summary.id} from ${batch.length} memories, archived ${archived}`
1413
+ );
1414
+ }
1415
+ }
1416
+ // -------------------------------------------------------------------------
1417
+ // Topic extraction (Phase 4B)
1418
+ // -------------------------------------------------------------------------
1419
+ /**
1420
+ * Run topic extraction on all memories (Phase 4B).
1421
+ */
1422
+ async runTopicExtraction(allMemories) {
1423
+ const storage = this.deps.getStorage();
1424
+ const activeMemories = allMemories.filter(
1425
+ (m) => isActiveMemoryStatus(m.frontmatter.status)
1426
+ );
1427
+ if (activeMemories.length === 0) return;
1428
+ const topics = extractTopics(
1429
+ activeMemories,
1430
+ this.config.topicExtractionTopN
1431
+ );
1432
+ await storage.saveTopics(topics);
1433
+ log.debug(
1434
+ `extracted ${topics.length} topics from ${activeMemories.length} memories`
1435
+ );
1436
+ }
1437
+ };
1438
+
1439
+ // src/orchestration/entity-synthesis-coordinator.ts
1440
+ import { createHash } from "crypto";
1441
+ function dedupeEntitySynthesisEvidenceEntries(entries) {
1442
+ const dedupedEvidenceEntries = [];
1443
+ const evidenceByFact = /* @__PURE__ */ new Map();
1444
+ for (const entry of entries) {
1445
+ const normalizedFact = entry.text.trim();
1446
+ if (!normalizedFact) continue;
1447
+ const existing = evidenceByFact.get(normalizedFact);
1448
+ if (!existing) {
1449
+ evidenceByFact.set(normalizedFact, { newest: entry, oldest: entry });
1450
+ continue;
1451
+ }
1452
+ if (compareEntityTimestamps(entry.timestamp, existing.newest.timestamp) > 0) {
1453
+ existing.newest = entry;
1454
+ }
1455
+ if (compareEntityTimestamps(entry.timestamp, existing.oldest.timestamp) < 0) {
1456
+ existing.oldest = entry;
1457
+ }
1458
+ }
1459
+ for (const { newest, oldest } of evidenceByFact.values()) {
1460
+ dedupedEvidenceEntries.push(newest);
1461
+ const newestKey = [
1462
+ newest.timestamp,
1463
+ newest.source ?? "",
1464
+ newest.sessionKey ?? "",
1465
+ newest.principal ?? "",
1466
+ newest.text
1467
+ ].join("\0");
1468
+ const oldestKey = [
1469
+ oldest.timestamp,
1470
+ oldest.source ?? "",
1471
+ oldest.sessionKey ?? "",
1472
+ oldest.principal ?? "",
1473
+ oldest.text
1474
+ ].join("\0");
1475
+ if (oldestKey !== newestKey) {
1476
+ dedupedEvidenceEntries.push(oldest);
1477
+ }
1478
+ }
1479
+ return dedupedEvidenceEntries;
1480
+ }
1481
+ function flattenStructuredSectionEvidence(sections) {
1482
+ return (sections ?? []).flatMap(
1483
+ (section) => section.facts.map((fact) => fact.trim()).filter((fact) => fact.length > 0).map((fact) => ({
1484
+ timestamp: "",
1485
+ text: fact,
1486
+ source: `section:${section.title}`
1487
+ }))
1488
+ );
1489
+ }
1490
+ function fingerprintEntitySynthesisEvidence(entity) {
1491
+ const fingerprint = createHash("sha256");
1492
+ const timelineEntries = entity.timeline.map((entry) => [
1493
+ entry.timestamp,
1494
+ entry.source ?? "",
1495
+ entry.sessionKey ?? "",
1496
+ entry.principal ?? "",
1497
+ entry.text
1498
+ ].join("\0")).sort();
1499
+ const timelineEntrySeparator = String.fromCharCode(1);
1500
+ const structuredFactsSeparator = String.fromCharCode(2);
1501
+ fingerprint.update(timelineEntries.join(timelineEntrySeparator));
1502
+ fingerprint.update(structuredFactsSeparator);
1503
+ fingerprint.update(fingerprintEntityStructuredFacts(entity) ?? "");
1504
+ return fingerprint.digest("hex");
1505
+ }
1506
+ var EntitySynthesisCoordinator = class {
1507
+ constructor(deps) {
1508
+ this.deps = deps;
1509
+ }
1510
+ deps;
1511
+ /**
1512
+ * Process up to `maxEntities` entities from the synthesis queue for the
1513
+ * given namespace. Returns the number of entities whose synthesis was
1514
+ * successfully refreshed.
1515
+ */
1516
+ async processQueue(namespace, maxEntities = 5) {
1517
+ const { config } = this.deps;
1518
+ if (!config.entitySummaryEnabled || maxEntities <= 0 || config.entitySynthesisMaxTokens <= 0) return 0;
1519
+ const storage = await this.deps.getStorage(namespace);
1520
+ const queued = await storage.refreshEntitySynthesisQueue();
1521
+ let processed = 0;
1522
+ let attempted = 0;
1523
+ for (const entityName of queued) {
1524
+ if (attempted >= maxEntities) break;
1525
+ attempted += 1;
1526
+ try {
1527
+ const raw = await storage.readEntity(entityName);
1528
+ if (!raw) continue;
1529
+ const entity = parseEntityFile(raw, config.entitySchemas);
1530
+ const previousSynthesis = entity.synthesis || entity.summary || "";
1531
+ const sortedTimelineEntries = entity.timeline.slice().sort((left, right) => compareEntityTimestamps(right.timestamp, left.timestamp));
1532
+ const newerTimelineEntries = sortedTimelineEntries.filter(
1533
+ (entry) => !entity.synthesisUpdatedAt || compareEntityTimestamps(entry.timestamp, entity.synthesisUpdatedAt) > 0
1534
+ );
1535
+ const appendedTimelineEntries = entity.synthesisTimelineCount === void 0 ? [] : entity.timeline.slice(Math.max(0, entity.synthesisTimelineCount));
1536
+ const structuredEvidenceEntries = flattenStructuredSectionEvidence(entity.structuredSections);
1537
+ const structuredEvidenceCount = structuredEvidenceEntries.length;
1538
+ const structuredEvidenceDigest = fingerprintEntityStructuredFacts(entity);
1539
+ const structuredEvidenceDrifted = structuredEvidenceDigest !== (entity.synthesisStructuredFactDigest?.trim() || void 0);
1540
+ const appendedStructuredEvidenceEntries = entity.synthesisStructuredFactCount === void 0 || structuredEvidenceDrifted ? structuredEvidenceEntries : structuredEvidenceEntries.slice(Math.max(0, entity.synthesisStructuredFactCount));
1541
+ const candidateEvidenceEntries = [
1542
+ ...newerTimelineEntries,
1543
+ ...appendedTimelineEntries,
1544
+ ...appendedStructuredEvidenceEntries
1545
+ ].slice().sort((left, right) => compareEntityTimestamps(right.timestamp, left.timestamp));
1546
+ const dedupedEvidenceEntries = dedupeEntitySynthesisEvidenceEntries(
1547
+ candidateEvidenceEntries.length > 0 ? candidateEvidenceEntries : [...sortedTimelineEntries, ...structuredEvidenceEntries]
1548
+ );
1549
+ const chronologicalEvidenceEntries = dedupedEvidenceEntries.slice().sort((left, right) => compareEntityTimestamps(left.timestamp, right.timestamp));
1550
+ if (chronologicalEvidenceEntries.length === 0) continue;
1551
+ const latestEvidenceTimestamp = chronologicalEvidenceEntries.slice().reverse().map((entry) => entry.timestamp?.trim() || void 0).find((timestamp) => Boolean(timestamp));
1552
+ const previousSynthesisUpdatedAt = entity.synthesisUpdatedAt?.trim() || void 0;
1553
+ const nextSynthesisUpdatedAt = compareEntityTimestamps(
1554
+ latestEvidenceTimestamp,
1555
+ previousSynthesisUpdatedAt
1556
+ ) >= 0 ? latestEvidenceTimestamp : previousSynthesisUpdatedAt;
1557
+ const evidenceBatches = [];
1558
+ for (let index = 0; index < chronologicalEvidenceEntries.length; index += 8) {
1559
+ evidenceBatches.push(chronologicalEvidenceEntries.slice(index, index + 8));
1560
+ }
1561
+ let nextSynthesis = previousSynthesis;
1562
+ let batchFailed = false;
1563
+ for (const evidenceEntries of evidenceBatches) {
1564
+ const evidenceText = evidenceEntries.map((entry) => {
1565
+ const sectionTitle = entry.source?.startsWith("section:") ? entry.source.slice("section:".length) : "";
1566
+ const metadata = [
1567
+ `timestamp=${entry.timestamp}`,
1568
+ sectionTitle ? `section=${sectionTitle}` : entry.source ? `source=${entry.source}` : "",
1569
+ entry.sessionKey ? `session=${entry.sessionKey}` : "",
1570
+ entry.principal ? `principal=${entry.principal}` : ""
1571
+ ].filter(Boolean).join(", ");
1572
+ return `- ${metadata}: ${entry.text}`;
1573
+ }).join("\n");
1574
+ const response = await this.deps.fastChatCompletion(
1575
+ [
1576
+ {
1577
+ role: "system",
1578
+ content: "Rewrite the entity synthesis as compact current truth. Preserve uncertainty when evidence conflicts. Return plain text only."
1579
+ },
1580
+ {
1581
+ role: "user",
1582
+ content: [
1583
+ `Entity: ${entity.name} (${entity.type})`,
1584
+ nextSynthesis ? `Previous synthesis:
1585
+ ${nextSynthesis}` : "Previous synthesis: none",
1586
+ `New evidence:
1587
+ ${evidenceText}`
1588
+ ].join("\n\n")
1589
+ }
1590
+ ],
1591
+ {
1592
+ temperature: 0.2,
1593
+ maxTokens: config.entitySynthesisMaxTokens,
1594
+ operation: "entity_summary",
1595
+ priority: "background"
1596
+ }
1597
+ );
1598
+ const synthesis = response?.content?.trim().replace(/^["']|["']$/g, "");
1599
+ const maxSynthesisChars = Math.max(2e3, config.entitySynthesisMaxTokens * 8);
1600
+ if (!synthesis || synthesis.length < 10 || synthesis.length > maxSynthesisChars) {
1601
+ batchFailed = true;
1602
+ break;
1603
+ }
1604
+ nextSynthesis = synthesis;
1605
+ }
1606
+ if (batchFailed || nextSynthesis.length === 0) continue;
1607
+ const latestRaw = await storage.readEntity(entityName);
1608
+ if (!latestRaw) continue;
1609
+ const latestEntity = parseEntityFile(latestRaw, config.entitySchemas);
1610
+ if (fingerprintEntitySynthesisEvidence(latestEntity) !== fingerprintEntitySynthesisEvidence(entity)) {
1611
+ continue;
1078
1612
  }
1079
- }
1080
- }
1081
- if (result.memoriesArchived > 0) {
1082
- await this.deps.saveContentHashIndexes().catch(
1083
- (err) => log.warn(
1084
- `[semantic-consolidation] content-hash index save failed: ${err}`
1085
- )
1086
- );
1087
- }
1088
- log.info(
1089
- `[semantic-consolidation] complete: clusters=${result.clustersFound}, consolidated=${result.memoriesConsolidated}, archived=${result.memoriesArchived}, errors=${result.errors}`
1090
- );
1091
- try {
1092
- await materializeAfterSemanticConsolidation({
1093
- config: this.config,
1094
- memoryDir: targetStorage.dir
1095
- });
1096
- } catch (err) {
1097
- log.warn(
1098
- `[semantic-consolidation] Codex materialize post-hook failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`
1099
- );
1100
- }
1101
- if (this.config.peerProfileReasonerEnabled) {
1102
- try {
1103
- const peerLlm = new FallbackLlmClient(
1104
- this.config.gatewayConfig,
1105
- fallbackLlmRuntimeContextFromConfig(this.config)
1106
- );
1107
- const peerResult = await runPeerProfileReasoner({
1108
- memoryDir: targetStorage.dir,
1109
- enabled: true,
1110
- llm: peerLlm,
1111
- model: this.config.peerProfileReasonerModel,
1112
- minInteractions: this.config.peerProfileReasonerMinInteractions,
1113
- maxFieldsPerRun: this.config.peerProfileReasonerMaxFieldsPerRun,
1114
- log: {
1115
- debug: (msg) => log.debug(msg),
1116
- info: (msg) => log.info(msg),
1117
- warn: (msg) => log.warn(msg)
1118
- }
1613
+ await storage.updateEntitySynthesis(entityName, nextSynthesis, {
1614
+ entityUpdatedAt: (/* @__PURE__ */ new Date()).toISOString(),
1615
+ synthesisStructuredFactDigest: structuredEvidenceDigest,
1616
+ synthesisStructuredFactCount: structuredEvidenceCount,
1617
+ synthesisTimelineCount: entity.timeline.length,
1618
+ updatedAt: nextSynthesisUpdatedAt
1119
1619
  });
1120
- log.info(
1121
- `[peer-profile-reasoner] complete: peers=${peerResult.peersConsidered}, processed=${peerResult.peersProcessed}, fields=${peerResult.fieldsApplied}`
1122
- );
1620
+ processed += 1;
1123
1621
  } catch (err) {
1124
- log.warn(
1125
- `[peer-profile-reasoner] post-consolidation hook failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`
1126
- );
1622
+ log.debug(`entity synthesis refresh failed for ${entityName}: ${err}`);
1127
1623
  }
1128
1624
  }
1129
- return result;
1625
+ return processed;
1130
1626
  }
1131
1627
  };
1132
1628
 
@@ -1462,8 +1958,8 @@ function generateResolverDocument(taxonomy) {
1462
1958
  }
1463
1959
 
1464
1960
  // src/taxonomy/taxonomy-loader.ts
1465
- import { readFile, mkdir, writeFile } from "fs/promises";
1466
- import path2 from "path";
1961
+ import { readFile, mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
1962
+ import path3 from "path";
1467
1963
  var TAXONOMY_DIR = ".taxonomy";
1468
1964
  var TAXONOMY_FILE = "taxonomy.json";
1469
1965
  var MAX_SLUG_LENGTH = 32;
@@ -1561,7 +2057,7 @@ function validateTaxonomy(taxonomy) {
1561
2057
  }
1562
2058
  }
1563
2059
  async function loadTaxonomy(memoryDir) {
1564
- const taxonomyPath = path2.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
2060
+ const taxonomyPath = path3.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
1565
2061
  let raw;
1566
2062
  try {
1567
2063
  raw = await readFile(taxonomyPath, "utf-8");
@@ -1611,16 +2107,16 @@ async function loadTaxonomy(memoryDir) {
1611
2107
  }
1612
2108
  async function saveTaxonomy(memoryDir, taxonomy) {
1613
2109
  validateTaxonomy(taxonomy);
1614
- const dir = path2.join(memoryDir, TAXONOMY_DIR);
1615
- await mkdir(dir, { recursive: true });
1616
- const filePath = path2.join(dir, TAXONOMY_FILE);
1617
- await writeFile(filePath, JSON.stringify(taxonomy, null, 2) + "\n", "utf-8");
2110
+ const dir = path3.join(memoryDir, TAXONOMY_DIR);
2111
+ await mkdir2(dir, { recursive: true });
2112
+ const filePath = path3.join(dir, TAXONOMY_FILE);
2113
+ await writeFile2(filePath, JSON.stringify(taxonomy, null, 2) + "\n", "utf-8");
1618
2114
  }
1619
2115
  function getTaxonomyDir(memoryDir) {
1620
- return path2.join(memoryDir, TAXONOMY_DIR);
2116
+ return path3.join(memoryDir, TAXONOMY_DIR);
1621
2117
  }
1622
2118
  function getTaxonomyFilePath(memoryDir) {
1623
- return path2.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
2119
+ return path3.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
1624
2120
  }
1625
2121
 
1626
2122
  // src/wearables/registry.ts
@@ -2486,71 +2982,6 @@ var BulkImportBatchPartialFailureError = class extends Error {
2486
2982
  this.originalError = originalError;
2487
2983
  }
2488
2984
  };
2489
- function dedupeEntitySynthesisEvidenceEntries(entries) {
2490
- const dedupedEvidenceEntries = [];
2491
- const evidenceByFact = /* @__PURE__ */ new Map();
2492
- for (const entry of entries) {
2493
- const normalizedFact = entry.text.trim();
2494
- if (!normalizedFact) continue;
2495
- const existing = evidenceByFact.get(normalizedFact);
2496
- if (!existing) {
2497
- evidenceByFact.set(normalizedFact, { newest: entry, oldest: entry });
2498
- continue;
2499
- }
2500
- if (compareEntityTimestamps(entry.timestamp, existing.newest.timestamp) > 0) {
2501
- existing.newest = entry;
2502
- }
2503
- if (compareEntityTimestamps(entry.timestamp, existing.oldest.timestamp) < 0) {
2504
- existing.oldest = entry;
2505
- }
2506
- }
2507
- for (const { newest, oldest } of evidenceByFact.values()) {
2508
- dedupedEvidenceEntries.push(newest);
2509
- const newestKey = [
2510
- newest.timestamp,
2511
- newest.source ?? "",
2512
- newest.sessionKey ?? "",
2513
- newest.principal ?? "",
2514
- newest.text
2515
- ].join("\0");
2516
- const oldestKey = [
2517
- oldest.timestamp,
2518
- oldest.source ?? "",
2519
- oldest.sessionKey ?? "",
2520
- oldest.principal ?? "",
2521
- oldest.text
2522
- ].join("\0");
2523
- if (oldestKey !== newestKey) {
2524
- dedupedEvidenceEntries.push(oldest);
2525
- }
2526
- }
2527
- return dedupedEvidenceEntries;
2528
- }
2529
- function flattenStructuredSectionEvidence(sections) {
2530
- return (sections ?? []).flatMap(
2531
- (section) => section.facts.map((fact) => fact.trim()).filter((fact) => fact.length > 0).map((fact) => ({
2532
- timestamp: "",
2533
- text: fact,
2534
- source: `section:${section.title}`
2535
- }))
2536
- );
2537
- }
2538
- function fingerprintEntitySynthesisEvidence(entity) {
2539
- const fingerprint = createHash("sha256");
2540
- const timelineEntries = entity.timeline.map((entry) => [
2541
- entry.timestamp,
2542
- entry.source ?? "",
2543
- entry.sessionKey ?? "",
2544
- entry.principal ?? "",
2545
- entry.text
2546
- ].join("\0")).sort();
2547
- const timelineEntrySeparator = String.fromCharCode(1);
2548
- const structuredFactsSeparator = String.fromCharCode(2);
2549
- fingerprint.update(timelineEntries.join(timelineEntrySeparator));
2550
- fingerprint.update(structuredFactsSeparator);
2551
- fingerprint.update(fingerprintEntityStructuredFacts(entity) ?? "");
2552
- return fingerprint.digest("hex");
2553
- }
2554
2985
  function mapRecallSourceToXrayServedBy(source) {
2555
2986
  switch (source) {
2556
2987
  case "recent_scan":
@@ -2586,7 +3017,7 @@ async function raceRecallAbort(promise, signal, message = "recall aborted") {
2586
3017
  }
2587
3018
  }
2588
3019
  function qmdCollectionPathParts(resultPath) {
2589
- if (!resultPath || path3.isAbsolute(resultPath)) return null;
3020
+ if (!resultPath || path4.isAbsolute(resultPath)) return null;
2590
3021
  const normalized = resultPath.replace(/\\/g, "/").replace(/^\/+/, "");
2591
3022
  const slashIndex = normalized.indexOf("/");
2592
3023
  if (slashIndex <= 0 || slashIndex >= normalized.length - 1) return null;
@@ -2599,9 +3030,9 @@ function qmdCollectionPathParts(resultPath) {
2599
3030
  }
2600
3031
  function qmdResultPathCandidates(storageDir, resultPath) {
2601
3032
  const candidates = /* @__PURE__ */ new Set();
2602
- const storageRoot = path3.resolve(storageDir);
3033
+ const storageRoot = path4.resolve(storageDir);
2603
3034
  const addCandidate = (candidate) => {
2604
- const resolved = path3.resolve(candidate);
3035
+ const resolved = path4.resolve(candidate);
2605
3036
  if (isPathInsideStorageRoot(storageRoot, resolved)) {
2606
3037
  candidates.add(resolved);
2607
3038
  }
@@ -2609,12 +3040,12 @@ function qmdResultPathCandidates(storageDir, resultPath) {
2609
3040
  const addRelativeCandidates = (relativePath) => {
2610
3041
  const normalized = relativePath.replace(/\\/g, "/").replace(/^\/+/, "");
2611
3042
  if (!normalized) return;
2612
- addCandidate(path3.join(storageRoot, normalized));
3043
+ addCandidate(path4.join(storageRoot, normalized));
2613
3044
  if (/^\d{4}-\d{2}-\d{2}\//.test(normalized)) {
2614
- addCandidate(path3.join(storageRoot, "facts", normalized));
3045
+ addCandidate(path4.join(storageRoot, "facts", normalized));
2615
3046
  }
2616
3047
  };
2617
- if (path3.isAbsolute(resultPath)) {
3048
+ if (path4.isAbsolute(resultPath)) {
2618
3049
  addCandidate(resultPath);
2619
3050
  } else {
2620
3051
  addRelativeCandidates(resultPath);
@@ -2731,11 +3162,11 @@ async function qmdStartupCollectionCheckWithTimeout(promise, controller, label)
2731
3162
  return await Promise.race([checkedPromise, timeoutPromise]);
2732
3163
  }
2733
3164
  function defaultWorkspaceDir() {
2734
- return path3.join(os2.homedir(), ".openclaw", "workspace");
3165
+ return path4.join(os2.homedir(), ".openclaw", "workspace");
2735
3166
  }
2736
3167
  function sanitizeSessionKeyForFilename(sessionKey) {
2737
3168
  const readable = sessionKey.replace(/[^a-zA-Z0-9._-]/g, "_");
2738
- const hash = createHash("sha256").update(sessionKey).digest("hex").slice(0, 12);
3169
+ const hash = createHash2("sha256").update(sessionKey).digest("hex").slice(0, 12);
2739
3170
  return `${readable}-${hash}`;
2740
3171
  }
2741
3172
  function latestSourceValidAtFromTurns(turns) {
@@ -3024,11 +3455,11 @@ function mergeGraphExpandedResults(primary, expanded) {
3024
3455
  return Array.from(mergedByPath.values());
3025
3456
  }
3026
3457
  function graphPathRelativeToStorage(storageDir, candidatePath) {
3027
- const absolutePath = path3.isAbsolute(candidatePath) ? candidatePath : path3.resolve(storageDir, candidatePath);
3028
- const rel = path3.relative(storageDir, absolutePath);
3458
+ const absolutePath = path4.isAbsolute(candidatePath) ? candidatePath : path4.resolve(storageDir, candidatePath);
3459
+ const rel = path4.relative(storageDir, absolutePath);
3029
3460
  if (!rel || rel === ".") return null;
3030
3461
  if (rel.startsWith("..")) return null;
3031
- return rel.split(path3.sep).join("/");
3462
+ return rel.split(path4.sep).join("/");
3032
3463
  }
3033
3464
  function normalizeGraphActivationScore(score) {
3034
3465
  const bounded = Number.isFinite(score) && score > 0 ? score : 0;
@@ -3173,7 +3604,7 @@ function buildMemoryPathById(allMemsForGraph, storageDir) {
3173
3604
  for (const mem of allMemsForGraph ?? []) {
3174
3605
  const id = mem.frontmatter.id;
3175
3606
  if (!id) continue;
3176
- pathById.set(id, path3.relative(storageDir, mem.path));
3607
+ pathById.set(id, path4.relative(storageDir, mem.path));
3177
3608
  }
3178
3609
  return pathById;
3179
3610
  }
@@ -3181,7 +3612,7 @@ function appendMemoryToGraphContext(options) {
3181
3612
  if (!Array.isArray(options.allMemsForGraph)) return;
3182
3613
  const nowIso = (/* @__PURE__ */ new Date()).toISOString();
3183
3614
  options.allMemsForGraph.push({
3184
- path: path3.join(options.storageDir, options.memoryRelPath),
3615
+ path: path4.join(options.storageDir, options.memoryRelPath),
3185
3616
  content: options.content,
3186
3617
  frontmatter: {
3187
3618
  id: options.memoryId,
@@ -3201,16 +3632,16 @@ function resolvePersistedMemoryRelativePath(options) {
3201
3632
  const persisted = options.pathById.get(options.memoryId);
3202
3633
  if (persisted) return persisted;
3203
3634
  if (options.category === "correction") {
3204
- return path3.join("corrections", `${options.memoryId}.md`);
3635
+ return path4.join("corrections", `${options.memoryId}.md`);
3205
3636
  }
3206
3637
  const subtree = categoryDirName(options.category);
3207
3638
  const idParts = options.memoryId.split("-");
3208
3639
  const maybeTimestamp = Number(idParts[1]);
3209
3640
  if (Number.isFinite(maybeTimestamp) && maybeTimestamp > 0) {
3210
3641
  const day = new Date(maybeTimestamp).toISOString().slice(0, 10);
3211
- return path3.join(subtree, day, `${options.memoryId}.md`);
3642
+ return path4.join(subtree, day, `${options.memoryId}.md`);
3212
3643
  }
3213
- return path3.join(subtree, `${options.memoryId}.md`);
3644
+ return path4.join(subtree, `${options.memoryId}.md`);
3214
3645
  }
3215
3646
  var Orchestrator = class _Orchestrator {
3216
3647
  storage;
@@ -3290,6 +3721,8 @@ var Orchestrator = class _Orchestrator {
3290
3721
  tierMigrationCoordinator;
3291
3722
  compressionGuidelineCoordinator;
3292
3723
  semanticConsolidationCoordinator;
3724
+ lifecyclePolicyCoordinator;
3725
+ entitySynthesisCoordinator;
3293
3726
  /**
3294
3727
  * In-memory X-ray snapshot from the most recent `recall()` call that
3295
3728
  * was invoked with `xrayCapture: true` (issue #570 PR 1). Scope is
@@ -3671,7 +4104,7 @@ var Orchestrator = class _Orchestrator {
3671
4104
  const defaultNs = normalizeNamespaceIdentity(this.config.defaultNamespace);
3672
4105
  if (ns !== defaultNs && !isSafeRouteNamespace(ns)) return;
3673
4106
  if (!this.storageDirMatchesNamespaceHint(ns, storageDir)) return;
3674
- const resolvedStorageDir = path3.resolve(storageDir);
4107
+ const resolvedStorageDir = path4.resolve(storageDir);
3675
4108
  let hints = this.namespaceStorageDirHints.get(resolvedStorageDir);
3676
4109
  if (!hints) {
3677
4110
  hints = /* @__PURE__ */ new Set();
@@ -3682,21 +4115,21 @@ var Orchestrator = class _Orchestrator {
3682
4115
  storageDirMatchesNamespaceHint(namespace, storageDir) {
3683
4116
  const ns = normalizeNamespaceIdentity(namespace);
3684
4117
  if (!ns) return false;
3685
- const resolvedStorageDir = path3.resolve(storageDir);
3686
- const resolvedMemoryDir = path3.resolve(this.config.memoryDir);
4118
+ const resolvedStorageDir = path4.resolve(storageDir);
4119
+ const resolvedMemoryDir = path4.resolve(this.config.memoryDir);
3687
4120
  const defaultNs = normalizeNamespaceIdentity(this.config.defaultNamespace);
3688
4121
  if (resolvedStorageDir === resolvedMemoryDir) return ns === defaultNs;
3689
- const resolvedNamespacesDir = path3.join(resolvedMemoryDir, "namespaces");
4122
+ const resolvedNamespacesDir = path4.join(resolvedMemoryDir, "namespaces");
3690
4123
  if (!isPathInsideStorageRoot(resolvedNamespacesDir, resolvedStorageDir)) return false;
3691
- const rawRoot = path3.resolve(resolvedNamespacesDir, ns);
3692
- const tokenRoot = path3.resolve(resolvedNamespacesDir, namespaceIdentityToken(ns));
4124
+ const rawRoot = path4.resolve(resolvedNamespacesDir, ns);
4125
+ const tokenRoot = path4.resolve(resolvedNamespacesDir, namespaceIdentityToken(ns));
3693
4126
  return resolvedStorageDir === rawRoot || resolvedStorageDir === tokenRoot;
3694
4127
  }
3695
4128
  namespaceStorageDirHintOwnershipRank(record, resolvedStorageDir, configured) {
3696
- if (resolvedStorageDir === path3.resolve(this.config.memoryDir)) {
4129
+ if (resolvedStorageDir === path4.resolve(this.config.memoryDir)) {
3697
4130
  return record.namespace === normalizeNamespaceIdentity(this.config.defaultNamespace) ? 0 : 3;
3698
4131
  }
3699
- const leaf = path3.basename(resolvedStorageDir);
4132
+ const leaf = path4.basename(resolvedStorageDir);
3700
4133
  const tokenOwnsRoot = namespaceIdentityToken(record.namespace) === leaf;
3701
4134
  if (tokenOwnsRoot && configured.has(record.namespace)) return 0;
3702
4135
  if (record.namespace === leaf) return 1;
@@ -3724,7 +4157,7 @@ var Orchestrator = class _Orchestrator {
3724
4157
  loadNamespaceStorageDirHintsFromCatalog() {
3725
4158
  if (this.namespaceStorageDirHintsLoaded || !this.namespaceCatalog.enabled) return;
3726
4159
  this.namespaceStorageDirHintsLoaded = true;
3727
- const catalogPath = path3.join(this.config.memoryDir, "state", "namespaces.jsonl");
4160
+ const catalogPath = path4.join(this.config.memoryDir, "state", "namespaces.jsonl");
3728
4161
  if (!existsSync(catalogPath)) return;
3729
4162
  let body;
3730
4163
  try {
@@ -3761,7 +4194,7 @@ var Orchestrator = class _Orchestrator {
3761
4194
  if (!this.storageDirMatchesNamespaceHint(record.namespace, record.storageDir)) {
3762
4195
  continue;
3763
4196
  }
3764
- const resolvedStorageDir = path3.resolve(record.storageDir);
4197
+ const resolvedStorageDir = path4.resolve(record.storageDir);
3765
4198
  const current = preferredByStorageDir.get(resolvedStorageDir);
3766
4199
  preferredByStorageDir.set(
3767
4200
  resolvedStorageDir,
@@ -4025,7 +4458,7 @@ var Orchestrator = class _Orchestrator {
4025
4458
  this.config = config;
4026
4459
  this.profiler = new ProfilingCollector({
4027
4460
  enabled: config.profilingEnabled,
4028
- storageDir: config.profilingStorageDir || path3.join(config.memoryDir, "profiling"),
4461
+ storageDir: config.profilingStorageDir || path4.join(config.memoryDir, "profiling"),
4029
4462
  maxTraces: config.profilingMaxTraces
4030
4463
  });
4031
4464
  this.namespaceCatalog = new NamespaceCatalog(config);
@@ -4094,7 +4527,7 @@ var Orchestrator = class _Orchestrator {
4094
4527
  this.compounding = config.compoundingEnabled ? new CompoundingEngine(config, this.storage) : void 0;
4095
4528
  this.buffer = new SmartBuffer(config, this.storage);
4096
4529
  this.transcript = new TranscriptManager(config);
4097
- this.conversationIndexDir = path3.join(
4530
+ this.conversationIndexDir = path4.join(
4098
4531
  config.memoryDir,
4099
4532
  "conversation-index",
4100
4533
  "chunks"
@@ -4120,6 +4553,11 @@ var Orchestrator = class _Orchestrator {
4120
4553
  getStorage: () => this.storage,
4121
4554
  fastChatCompletion: (messages, options) => this.fastChatCompletion(messages, options)
4122
4555
  });
4556
+ this.entitySynthesisCoordinator = new EntitySynthesisCoordinator({
4557
+ config,
4558
+ getStorage: (namespace) => this.getStorage(namespace),
4559
+ fastChatCompletion: (messages, options) => this.fastChatCompletion(messages, options)
4560
+ });
4123
4561
  this.sessionObserver = new SessionObserverState({
4124
4562
  memoryDir: config.memoryDir,
4125
4563
  debounceMs: config.sessionObserverDebounceMs ?? 12e4,
@@ -4174,8 +4612,17 @@ var Orchestrator = class _Orchestrator {
4174
4612
  config.gatewayConfig,
4175
4613
  this.modelRegistry
4176
4614
  );
4615
+ this.lifecyclePolicyCoordinator = new LifecyclePolicyCoordinator({
4616
+ config,
4617
+ getStorage: () => this.storage,
4618
+ extraction: this.extraction,
4619
+ embeddingFallback: this.embeddingFallback,
4620
+ getEffectiveLifecycleThresholds: () => this.effectiveLifecycleThresholds(),
4621
+ removeContentHashForMemory: (targetStorage, memory, context) => this.removeContentHashForMemory(targetStorage, memory, context),
4622
+ saveContentHashIndexes: () => this.saveContentHashIndexes()
4623
+ });
4177
4624
  this.threading = new ThreadingManager(
4178
- path3.join(config.memoryDir, "threads"),
4625
+ path4.join(config.memoryDir, "threads"),
4179
4626
  config.threadingGapMinutes
4180
4627
  );
4181
4628
  const lifecycleCaps = resolveMemoryLifecycleCapabilities(config);
@@ -4255,7 +4702,7 @@ var Orchestrator = class _Orchestrator {
4255
4702
  utilityPromoteThresholdDelta: this.utilityRuntimeValues?.promoteThresholdDelta ?? 0,
4256
4703
  utilityDemoteThresholdDelta: this.utilityRuntimeValues?.demoteThresholdDelta ?? 0
4257
4704
  };
4258
- return createHash("sha256").update(JSON.stringify(payload)).digest("hex").slice(0, 12);
4705
+ return createHash2("sha256").update(JSON.stringify(payload)).digest("hex").slice(0, 12);
4259
4706
  }
4260
4707
  effectiveLifecycleThresholds() {
4261
4708
  const archiveDecayThreshold = this.config.lifecycleArchiveDecayThreshold;
@@ -4466,8 +4913,8 @@ var Orchestrator = class _Orchestrator {
4466
4913
  this.runtimePolicyValues = await this.policyRuntime.loadRuntimeValues();
4467
4914
  this.utilityRuntimeValues = await loadUtilityRuntimeValues({
4468
4915
  memoryDir: this.config.memoryDir,
4469
- memoryUtilityLearningEnabled: this.config.memoryUtilityLearningEnabled,
4470
- promotionByOutcomeEnabled: this.config.promotionByOutcomeEnabled
4916
+ memoryUtilityLearningEnabled: resolveUtilityLearningCapabilities(this.config).memoryUtilityLearning,
4917
+ promotionByOutcomeEnabled: resolveUtilityLearningCapabilities(this.config).promotionByOutcome
4471
4918
  });
4472
4919
  if (this.config.factDeduplicationEnabled) {
4473
4920
  this.contentHashIndex = this.storage.createContentHashIndex();
@@ -4498,7 +4945,7 @@ var Orchestrator = class _Orchestrator {
4498
4945
  const files = await readdir(wsDir).catch(() => []);
4499
4946
  for (const f of files) {
4500
4947
  if (!f.startsWith(".compaction-reset-signal-")) continue;
4501
- const fp = path3.join(wsDir, f);
4948
+ const fp = path4.join(wsDir, f);
4502
4949
  const s = await stat(fp).catch(() => null);
4503
4950
  if (s && Date.now() - s.mtimeMs >= COMPACTION_SIGNAL_MAX_AGE_MS) {
4504
4951
  await unlink(fp).catch(() => {
@@ -4693,7 +5140,7 @@ var Orchestrator = class _Orchestrator {
4693
5140
  if (signal.aborted) return;
4694
5141
  if (lifecycleCaps.lifecyclePolicy && resolveQmdCapabilities(this.config).qmdTierMigration) {
4695
5142
  try {
4696
- const { runFirstStartMigration } = await import("./first-start-migration-W4U6XDKI.js");
5143
+ const { runFirstStartMigration } = await import("./first-start-migration-2RQYDIZ7.js");
4697
5144
  const result = await runFirstStartMigration({
4698
5145
  storage: this.storage,
4699
5146
  config: this.config,
@@ -5007,15 +5454,15 @@ ${doc.content}` : doc.content,
5007
5454
  this.lastFileHygieneRunAtMs = now;
5008
5455
  if (hygiene.rotateEnabled) {
5009
5456
  for (const rel of hygiene.rotatePaths) {
5010
- const abs = path3.isAbsolute(rel) ? rel : path3.join(this.config.workspaceDir, rel);
5457
+ const abs = path4.isAbsolute(rel) ? rel : path4.join(this.config.workspaceDir, rel);
5011
5458
  try {
5012
5459
  const raw = await readFile2(abs, "utf-8");
5013
5460
  if (raw.length > hygiene.rotateMaxBytes) {
5014
- const archiveDir = path3.join(
5461
+ const archiveDir = path4.join(
5015
5462
  this.config.workspaceDir,
5016
5463
  hygiene.archiveDir
5017
5464
  );
5018
- const base = path3.basename(abs);
5465
+ const base = path4.basename(abs);
5019
5466
  const prefix = base.toUpperCase().replace(/\.MD$/i, "").replace(/[^A-Z0-9]+/g, "-") || "FILE";
5020
5467
  const { newContent } = await rotateMarkdownFileToArchive({
5021
5468
  filePath: abs,
@@ -5023,7 +5470,7 @@ ${doc.content}` : doc.content,
5023
5470
  archivePrefix: prefix,
5024
5471
  keepTailChars: hygiene.rotateKeepTailChars
5025
5472
  });
5026
- await writeFile2(abs, newContent, "utf-8");
5473
+ await writeFile3(abs, newContent, "utf-8");
5027
5474
  }
5028
5475
  } catch {
5029
5476
  }
@@ -5040,8 +5487,8 @@ ${doc.content}` : doc.content,
5040
5487
  log.warn(w.message);
5041
5488
  }
5042
5489
  if (hygiene.warningsLogEnabled && warnings.length > 0) {
5043
- const fp = path3.join(this.config.memoryDir, hygiene.warningsLogPath);
5044
- await mkdir2(path3.dirname(fp), { recursive: true });
5490
+ const fp = path4.join(this.config.memoryDir, hygiene.warningsLogPath);
5491
+ await mkdir3(path4.dirname(fp), { recursive: true });
5045
5492
  const stamp = (/* @__PURE__ */ new Date()).toISOString();
5046
5493
  const block = `
5047
5494
 
@@ -5054,7 +5501,7 @@ ${doc.content}` : doc.content,
5054
5501
  } catch {
5055
5502
  existing = "# Engram File Hygiene Warnings\n";
5056
5503
  }
5057
- await writeFile2(fp, existing + block, "utf-8");
5504
+ await writeFile3(fp, existing + block, "utf-8");
5058
5505
  }
5059
5506
  }
5060
5507
  }
@@ -5119,120 +5566,13 @@ ${doc.content}` : doc.content,
5119
5566
  }
5120
5567
  return true;
5121
5568
  }
5122
- async getStorage(namespace) {
5123
- const ns = namespace && namespace.length > 0 ? namespace : this.config.defaultNamespace;
5124
- return this.storageRouter.storageFor(ns);
5125
- }
5126
- async processEntitySynthesisQueue(namespace, maxEntities = 5) {
5127
- if (!this.config.entitySummaryEnabled || maxEntities <= 0 || this.config.entitySynthesisMaxTokens <= 0) return 0;
5128
- const storage = await this.getStorage(namespace);
5129
- const queued = await storage.refreshEntitySynthesisQueue();
5130
- let processed = 0;
5131
- let attempted = 0;
5132
- for (const entityName of queued) {
5133
- if (attempted >= maxEntities) break;
5134
- attempted += 1;
5135
- try {
5136
- const raw = await storage.readEntity(entityName);
5137
- if (!raw) continue;
5138
- const entity = parseEntityFile(raw, this.config.entitySchemas);
5139
- const previousSynthesis = entity.synthesis || entity.summary || "";
5140
- const sortedTimelineEntries = entity.timeline.slice().sort((left, right) => compareEntityTimestamps(right.timestamp, left.timestamp));
5141
- const newerTimelineEntries = sortedTimelineEntries.filter(
5142
- (entry) => !entity.synthesisUpdatedAt || compareEntityTimestamps(entry.timestamp, entity.synthesisUpdatedAt) > 0
5143
- );
5144
- const appendedTimelineEntries = entity.synthesisTimelineCount === void 0 ? [] : entity.timeline.slice(Math.max(0, entity.synthesisTimelineCount));
5145
- const structuredEvidenceEntries = flattenStructuredSectionEvidence(entity.structuredSections);
5146
- const structuredEvidenceCount = structuredEvidenceEntries.length;
5147
- const structuredEvidenceDigest = fingerprintEntityStructuredFacts(entity);
5148
- const structuredEvidenceDrifted = structuredEvidenceDigest !== (entity.synthesisStructuredFactDigest?.trim() || void 0);
5149
- const appendedStructuredEvidenceEntries = entity.synthesisStructuredFactCount === void 0 || structuredEvidenceDrifted ? structuredEvidenceEntries : structuredEvidenceEntries.slice(Math.max(0, entity.synthesisStructuredFactCount));
5150
- const candidateEvidenceEntries = [
5151
- ...newerTimelineEntries,
5152
- ...appendedTimelineEntries,
5153
- ...appendedStructuredEvidenceEntries
5154
- ].slice().sort((left, right) => compareEntityTimestamps(right.timestamp, left.timestamp));
5155
- const dedupedEvidenceEntries = dedupeEntitySynthesisEvidenceEntries(
5156
- candidateEvidenceEntries.length > 0 ? candidateEvidenceEntries : [...sortedTimelineEntries, ...structuredEvidenceEntries]
5157
- );
5158
- const chronologicalEvidenceEntries = dedupedEvidenceEntries.slice().sort((left, right) => compareEntityTimestamps(left.timestamp, right.timestamp));
5159
- if (chronologicalEvidenceEntries.length === 0) continue;
5160
- const latestEvidenceTimestamp = chronologicalEvidenceEntries.slice().reverse().map((entry) => entry.timestamp?.trim() || void 0).find((timestamp) => Boolean(timestamp));
5161
- const previousSynthesisUpdatedAt = entity.synthesisUpdatedAt?.trim() || void 0;
5162
- const nextSynthesisUpdatedAt = compareEntityTimestamps(
5163
- latestEvidenceTimestamp,
5164
- previousSynthesisUpdatedAt
5165
- ) >= 0 ? latestEvidenceTimestamp : previousSynthesisUpdatedAt;
5166
- const evidenceBatches = [];
5167
- for (let index = 0; index < chronologicalEvidenceEntries.length; index += 8) {
5168
- evidenceBatches.push(chronologicalEvidenceEntries.slice(index, index + 8));
5169
- }
5170
- let nextSynthesis = previousSynthesis;
5171
- let batchFailed = false;
5172
- for (const evidenceEntries of evidenceBatches) {
5173
- const evidenceText = evidenceEntries.map((entry) => {
5174
- const sectionTitle = entry.source?.startsWith("section:") ? entry.source.slice("section:".length) : "";
5175
- const metadata = [
5176
- `timestamp=${entry.timestamp}`,
5177
- sectionTitle ? `section=${sectionTitle}` : entry.source ? `source=${entry.source}` : "",
5178
- entry.sessionKey ? `session=${entry.sessionKey}` : "",
5179
- entry.principal ? `principal=${entry.principal}` : ""
5180
- ].filter(Boolean).join(", ");
5181
- return `- ${metadata}: ${entry.text}`;
5182
- }).join("\n");
5183
- const response = await this.fastChatCompletion(
5184
- [
5185
- {
5186
- role: "system",
5187
- content: "Rewrite the entity synthesis as compact current truth. Preserve uncertainty when evidence conflicts. Return plain text only."
5188
- },
5189
- {
5190
- role: "user",
5191
- content: [
5192
- `Entity: ${entity.name} (${entity.type})`,
5193
- nextSynthesis ? `Previous synthesis:
5194
- ${nextSynthesis}` : "Previous synthesis: none",
5195
- `New evidence:
5196
- ${evidenceText}`
5197
- ].join("\n\n")
5198
- }
5199
- ],
5200
- {
5201
- temperature: 0.2,
5202
- maxTokens: this.config.entitySynthesisMaxTokens,
5203
- operation: "entity_summary",
5204
- priority: "background"
5205
- }
5206
- );
5207
- const synthesis = response?.content?.trim().replace(/^["']|["']$/g, "");
5208
- const maxSynthesisChars = Math.max(2e3, this.config.entitySynthesisMaxTokens * 8);
5209
- if (!synthesis || synthesis.length < 10 || synthesis.length > maxSynthesisChars) {
5210
- batchFailed = true;
5211
- break;
5212
- }
5213
- nextSynthesis = synthesis;
5214
- }
5215
- if (batchFailed || nextSynthesis.length === 0) continue;
5216
- const latestRaw = await storage.readEntity(entityName);
5217
- if (!latestRaw) continue;
5218
- const latestEntity = parseEntityFile(latestRaw, this.config.entitySchemas);
5219
- if (fingerprintEntitySynthesisEvidence(latestEntity) !== fingerprintEntitySynthesisEvidence(entity)) {
5220
- continue;
5221
- }
5222
- await storage.updateEntitySynthesis(entityName, nextSynthesis, {
5223
- entityUpdatedAt: (/* @__PURE__ */ new Date()).toISOString(),
5224
- synthesisStructuredFactDigest: structuredEvidenceDigest,
5225
- synthesisStructuredFactCount: structuredEvidenceCount,
5226
- synthesisTimelineCount: entity.timeline.length,
5227
- updatedAt: nextSynthesisUpdatedAt
5228
- });
5229
- processed += 1;
5230
- } catch (err) {
5231
- log.debug(`entity synthesis refresh failed for ${entityName}: ${err}`);
5232
- }
5233
- }
5234
- return processed;
5235
- }
5569
+ async getStorage(namespace) {
5570
+ const ns = namespace && namespace.length > 0 ? namespace : this.config.defaultNamespace;
5571
+ return this.storageRouter.storageFor(ns);
5572
+ }
5573
+ async processEntitySynthesisQueue(namespace, maxEntities = 5) {
5574
+ return this.entitySynthesisCoordinator.processQueue(namespace, maxEntities);
5575
+ }
5236
5576
  async generateDaySummary(memories) {
5237
5577
  if (this.initPromise) {
5238
5578
  let initGateTimeoutHandle;
@@ -5287,7 +5627,7 @@ ${evidenceText}`
5287
5627
  for (const categoryDir of RECALL_FALLBACK_DIRS) {
5288
5628
  if (memoryRootReal === null) break;
5289
5629
  for (const date of datesToScan) {
5290
- const dateDir = path3.join(storage.dir, categoryDir, date);
5630
+ const dateDir = path4.join(storage.dir, categoryDir, date);
5291
5631
  try {
5292
5632
  const dirStat = await lstat(dateDir);
5293
5633
  if (dirStat.isSymbolicLink() || !dirStat.isDirectory()) continue;
@@ -5296,7 +5636,7 @@ ${evidenceText}`
5296
5636
  for (const entry of entries) {
5297
5637
  if (entry.isSymbolicLink()) continue;
5298
5638
  if (!entry.name.endsWith(".md")) continue;
5299
- const fullPath = path3.join(dateDir, entry.name);
5639
+ const fullPath = path4.join(dateDir, entry.name);
5300
5640
  try {
5301
5641
  assertPathInsideRoot(memoryRootReal, await realpath(fullPath), fullPath);
5302
5642
  const raw = await readFile2(fullPath, "utf-8");
@@ -5318,7 +5658,7 @@ ${evidenceText}`
5318
5658
  facts.push({
5319
5659
  path: fullPath,
5320
5660
  frontmatter: {
5321
- id: fm.id || path3.basename(entry.name, ".md"),
5661
+ id: fm.id || path4.basename(entry.name, ".md"),
5322
5662
  category: fm.category || "fact",
5323
5663
  created,
5324
5664
  updated: fm.updated || created,
@@ -5341,13 +5681,13 @@ ${evidenceText}`
5341
5681
  return a.frontmatter.created < b.frontmatter.created ? -1 : 1;
5342
5682
  });
5343
5683
  const hourlySummaries = [];
5344
- const hourlyBaseDir = path3.join(storage.dir, "summaries", "hourly");
5684
+ const hourlyBaseDir = path4.join(storage.dir, "summaries", "hourly");
5345
5685
  try {
5346
5686
  const sessionKeys = await readdir(hourlyBaseDir, { withFileTypes: true });
5347
5687
  for (const sk of sessionKeys) {
5348
5688
  if (!sk.isDirectory()) continue;
5349
5689
  for (const date of datesToScan) {
5350
- const summaryFile = path3.join(hourlyBaseDir, sk.name, `${date}.md`);
5690
+ const summaryFile = path4.join(hourlyBaseDir, sk.name, `${date}.md`);
5351
5691
  try {
5352
5692
  const raw = await readFile2(summaryFile, "utf-8");
5353
5693
  const filtered = filterHourlySummaryMarkdownForLocalDay(
@@ -5395,7 +5735,7 @@ ${evidenceText}`
5395
5735
  action: event.action,
5396
5736
  eligibility,
5397
5737
  options: {
5398
- actionsEnabled: this.config.contextCompressionActionsEnabled,
5738
+ actionsEnabled: resolveCompressionCapabilities(this.config).contextCompressionActions,
5399
5739
  maxCompressionTokensPerHour: this.config.maxCompressionTokensPerHour
5400
5740
  }
5401
5741
  });
@@ -5451,7 +5791,7 @@ ${evidenceText}`
5451
5791
  }
5452
5792
  async getLastGraphRecallSnapshot(namespace) {
5453
5793
  const storage = await this.getStorage(namespace);
5454
- const snapshotPath = path3.join(
5794
+ const snapshotPath = path4.join(
5455
5795
  storage.dir,
5456
5796
  "state",
5457
5797
  "last_graph_recall.json"
@@ -5490,7 +5830,7 @@ ${evidenceText}`
5490
5830
  }
5491
5831
  async getLastIntentSnapshot(namespace) {
5492
5832
  const storage = await this.getStorage(namespace);
5493
- const snapshotPath = path3.join(storage.dir, "state", "last_intent.json");
5833
+ const snapshotPath = path4.join(storage.dir, "state", "last_intent.json");
5494
5834
  try {
5495
5835
  const raw = await readFile2(snapshotPath, "utf-8");
5496
5836
  const parsed = JSON.parse(raw);
@@ -5523,7 +5863,7 @@ ${evidenceText}`
5523
5863
  }
5524
5864
  async getLastQmdRecallSnapshot(namespace) {
5525
5865
  const storage = await this.getStorage(namespace);
5526
- const snapshotPath = path3.join(
5866
+ const snapshotPath = path4.join(
5527
5867
  storage.dir,
5528
5868
  "state",
5529
5869
  "last_qmd_recall.json"
@@ -5676,7 +6016,7 @@ ${r.snippet.trim()}
5676
6016
  const entries = await readdir(dir, { withFileTypes: true });
5677
6017
  let total = 0;
5678
6018
  for (const entry of entries) {
5679
- const fullPath = path3.join(dir, entry.name);
6019
+ const fullPath = path4.join(dir, entry.name);
5680
6020
  if (entry.isDirectory()) {
5681
6021
  total += await this.countConversationChunkDocs(fullPath);
5682
6022
  continue;
@@ -6400,7 +6740,7 @@ ${r.snippet.trim()}
6400
6740
  if (!options.onDebugSnapshot) return;
6401
6741
  await options.onDebugSnapshot({
6402
6742
  recordedAt: (/* @__PURE__ */ new Date()).toISOString(),
6403
- queryHash: createHash("sha256").update(prompt).digest("hex"),
6743
+ queryHash: createHash2("sha256").update(prompt).digest("hex"),
6404
6744
  queryLength: prompt.length,
6405
6745
  collection: options.collection,
6406
6746
  namespaces: options.recallNamespaces,
@@ -6582,7 +6922,7 @@ ${r.snippet.trim()}
6582
6922
  resolvedPath = resolvedCold.result.path;
6583
6923
  resolvedResult = resolvedCold.result;
6584
6924
  }
6585
- if (!path3.isAbsolute(resolvedPath)) {
6925
+ if (!path4.isAbsolute(resolvedPath)) {
6586
6926
  resolvedAmbiguousSeeds.set(result.path, null);
6587
6927
  return null;
6588
6928
  }
@@ -6607,7 +6947,7 @@ ${r.snippet.trim()}
6607
6947
  }
6608
6948
  continue;
6609
6949
  }
6610
- if (path3.isAbsolute(result.path)) {
6950
+ if (path4.isAbsolute(result.path)) {
6611
6951
  const resolved = await resolveAmbiguousSeedOwner(result, null);
6612
6952
  if (resolved) {
6613
6953
  addResultForNamespace(resolved.namespace, resolved.result);
@@ -6650,7 +6990,7 @@ ${r.snippet.trim()}
6650
6990
  0
6651
6991
  );
6652
6992
  seedPaths.push(
6653
- ...seedRelativePaths.map((rel) => path3.join(storage.dir, rel))
6993
+ ...seedRelativePaths.map((rel) => path4.join(storage.dir, rel))
6654
6994
  );
6655
6995
  const seedSet = new Set(seedRelativePaths);
6656
6996
  const expanded = await this.graphIndexFor(storage).spreadingActivation(
@@ -6666,7 +7006,7 @@ ${r.snippet.trim()}
6666
7006
  for (const candidate of expanded.slice(0, perNamespaceExpandedCap)) {
6667
7007
  if (deadlineExpired()) break;
6668
7008
  if (seedSet.has(candidate.path)) continue;
6669
- const memoryPath = path3.resolve(storage.dir, candidate.path);
7009
+ const memoryPath = path4.resolve(storage.dir, candidate.path);
6670
7010
  const memory = await storage.readMemoryByPath(memoryPath);
6671
7011
  if (deadlineExpired()) break;
6672
7012
  if (!memory) continue;
@@ -6691,7 +7031,7 @@ ${r.snippet.trim()}
6691
7031
  path: memory.path,
6692
7032
  score,
6693
7033
  namespace,
6694
- seed: path3.resolve(storage.dir, candidate.seed),
7034
+ seed: path4.resolve(storage.dir, candidate.seed),
6695
7035
  hopDepth: candidate.hopDepth,
6696
7036
  decayedWeight: candidate.decayedWeight,
6697
7037
  graphType: candidate.graphType,
@@ -6712,12 +7052,12 @@ ${r.snippet.trim()}
6712
7052
  }
6713
7053
  async recordLastGraphRecallSnapshot(options) {
6714
7054
  try {
6715
- const snapshotPath = path3.join(
7055
+ const snapshotPath = path4.join(
6716
7056
  options.storage.dir,
6717
7057
  "state",
6718
7058
  "last_graph_recall.json"
6719
7059
  );
6720
- await mkdir2(path3.dirname(snapshotPath), { recursive: true });
7060
+ await mkdir3(path4.dirname(snapshotPath), { recursive: true });
6721
7061
  const now = (/* @__PURE__ */ new Date()).toISOString();
6722
7062
  const totalSeedCount = options.seedPaths.length;
6723
7063
  const totalExpandedCount = options.expandedPaths.length;
@@ -6729,7 +7069,7 @@ ${r.snippet.trim()}
6729
7069
  const payload = {
6730
7070
  recordedAt: now,
6731
7071
  mode: options.recallMode,
6732
- queryHash: createHash("sha256").update(options.prompt).digest("hex"),
7072
+ queryHash: createHash2("sha256").update(options.prompt).digest("hex"),
6733
7073
  queryLength: options.prompt.length,
6734
7074
  namespaces: options.recallNamespaces,
6735
7075
  seedCount: totalSeedCount,
@@ -6744,20 +7084,20 @@ ${r.snippet.trim()}
6744
7084
  finalResults: (options.finalResults ?? []).slice(0, 64),
6745
7085
  shadowComparison: options.shadowComparison
6746
7086
  };
6747
- await writeFile2(snapshotPath, JSON.stringify(payload, null, 2), "utf-8");
7087
+ await writeFile3(snapshotPath, JSON.stringify(payload, null, 2), "utf-8");
6748
7088
  } catch (err) {
6749
7089
  log.debug(`last graph recall write failed: ${err}`);
6750
7090
  }
6751
7091
  }
6752
7092
  async recordLastIntentSnapshot(options) {
6753
7093
  try {
6754
- const snapshotPath = path3.join(
7094
+ const snapshotPath = path4.join(
6755
7095
  options.storage.dir,
6756
7096
  "state",
6757
7097
  "last_intent.json"
6758
7098
  );
6759
- await mkdir2(path3.dirname(snapshotPath), { recursive: true });
6760
- await writeFile2(
7099
+ await mkdir3(path4.dirname(snapshotPath), { recursive: true });
7100
+ await writeFile3(
6761
7101
  snapshotPath,
6762
7102
  JSON.stringify(options.snapshot, null, 2),
6763
7103
  "utf-8"
@@ -6768,13 +7108,13 @@ ${r.snippet.trim()}
6768
7108
  }
6769
7109
  async recordLastQmdRecallSnapshot(options) {
6770
7110
  try {
6771
- const snapshotPath = path3.join(
7111
+ const snapshotPath = path4.join(
6772
7112
  options.storage.dir,
6773
7113
  "state",
6774
7114
  "last_qmd_recall.json"
6775
7115
  );
6776
- await mkdir2(path3.dirname(snapshotPath), { recursive: true });
6777
- await writeFile2(
7116
+ await mkdir3(path4.dirname(snapshotPath), { recursive: true });
7117
+ await writeFile3(
6778
7118
  snapshotPath,
6779
7119
  JSON.stringify(options.snapshot, null, 2),
6780
7120
  "utf-8"
@@ -6788,9 +7128,9 @@ ${r.snippet.trim()}
6788
7128
  const stateDir = await this.resolveStateDirForNamespace(
6789
7129
  options.namespace
6790
7130
  );
6791
- const snapshotPath = path3.join(stateDir, "last_intent.json");
6792
- await mkdir2(path3.dirname(snapshotPath), { recursive: true });
6793
- await writeFile2(
7131
+ const snapshotPath = path4.join(stateDir, "last_intent.json");
7132
+ await mkdir3(path4.dirname(snapshotPath), { recursive: true });
7133
+ await writeFile3(
6794
7134
  snapshotPath,
6795
7135
  JSON.stringify(options.snapshot, null, 2),
6796
7136
  "utf-8"
@@ -6801,12 +7141,12 @@ ${r.snippet.trim()}
6801
7141
  }
6802
7142
  async resolveStateDirForNamespace(namespace) {
6803
7143
  if (!resolveNamespaceCapabilities(this.config).namespaces) {
6804
- return path3.join(this.config.memoryDir, "state");
7144
+ return path4.join(this.config.memoryDir, "state");
6805
7145
  }
6806
7146
  if (namespace !== this.config.defaultNamespace) {
6807
- return path3.join(this.config.memoryDir, "namespaces", namespace, "state");
7147
+ return path4.join(this.config.memoryDir, "namespaces", namespace, "state");
6808
7148
  }
6809
- const candidate = path3.join(
7149
+ const candidate = path4.join(
6810
7150
  this.config.memoryDir,
6811
7151
  "namespaces",
6812
7152
  this.config.defaultNamespace
@@ -6814,11 +7154,11 @@ ${r.snippet.trim()}
6814
7154
  try {
6815
7155
  const candidateStat = await stat(candidate);
6816
7156
  if (candidateStat.isDirectory()) {
6817
- return path3.join(candidate, "state");
7157
+ return path4.join(candidate, "state");
6818
7158
  }
6819
7159
  } catch {
6820
7160
  }
6821
- return path3.join(this.config.memoryDir, "state");
7161
+ return path4.join(this.config.memoryDir, "state");
6822
7162
  }
6823
7163
  buildGraphRecallRankedResults(results, sourceLabelResolver, limit = 64) {
6824
7164
  return results.slice(0, limit).map((result) => ({
@@ -7071,8 +7411,8 @@ ${r.snippet.trim()}
7071
7411
  timings,
7072
7412
  logger: log
7073
7413
  });
7074
- const promptHash = createHash("sha256").update(prompt).digest("hex");
7075
- const traceId = createHash("sha256").update(`${sessionKey ?? "default"}:${recallStart}:${promptHash}`).digest("hex").slice(0, 16);
7414
+ const promptHash = createHash2("sha256").update(prompt).digest("hex");
7415
+ const traceId = createHash2("sha256").update(`${sessionKey ?? "default"}:${recallStart}:${promptHash}`).digest("hex").slice(0, 16);
7076
7416
  const sectionBuckets = /* @__PURE__ */ new Map();
7077
7417
  const queryPolicy = buildRecallQueryPolicy(prompt, sessionKey, {
7078
7418
  cronRecallPolicyEnabled: this.config.cronRecallPolicyEnabled,
@@ -7081,7 +7421,7 @@ ${r.snippet.trim()}
7081
7421
  cronConversationRecallMode: this.config.cronConversationRecallMode
7082
7422
  });
7083
7423
  const retrievalQuery = queryPolicy.retrievalQuery || prompt;
7084
- const retrievalQueryHash = createHash("sha256").update(retrievalQuery).digest("hex");
7424
+ const retrievalQueryHash = createHash2("sha256").update(retrievalQuery).digest("hex");
7085
7425
  const policyVersion = this.currentPolicyVersion();
7086
7426
  let impressionRecorded = false;
7087
7427
  let recallSource = "none";
@@ -7220,7 +7560,7 @@ ${r.snippet.trim()}
7220
7560
  const graphExpandedResultPaths = /* @__PURE__ */ new Set();
7221
7561
  const graphSourceLabelsForPath = (resultPath) => {
7222
7562
  const labels = [];
7223
- const normalizedPath = resultPath.split(path3.sep).join("/");
7563
+ const normalizedPath = resultPath.split(path4.sep).join("/");
7224
7564
  const isEntityPath = normalizedPath.startsWith("entities/") || normalizedPath.includes("/entities/");
7225
7565
  if (graphBaselinePaths.has(resultPath)) labels.push("baseline");
7226
7566
  if (graphExpandedResultPaths.has(resultPath))
@@ -7370,7 +7710,7 @@ ${r.snippet.trim()}
7370
7710
  profileStorageNamespaces.map((namespace) => this.storageRouter.storageFor(namespace))
7371
7711
  );
7372
7712
  const emptyProfileStorage = new Proxy(
7373
- { dir: path3.join(this.config.memoryDir, ".empty-scope-profile") },
7713
+ { dir: path4.join(this.config.memoryDir, ".empty-scope-profile") },
7374
7714
  {
7375
7715
  get(target, prop) {
7376
7716
  if (prop in target) return target[prop];
@@ -7852,9 +8192,9 @@ ${rows.join("\n")}
7852
8192
  })();
7853
8193
  const objectiveStatePromise = (async () => {
7854
8194
  const t0 = Date.now();
7855
- if (!this.config.objectiveStateMemoryEnabled || !this.config.objectiveStateRecallEnabled || !this.isRecallSectionEnabled(
8195
+ if (!resolveObjectiveStateCapabilities(this.config).objectiveStateMemory || !resolveObjectiveStateCapabilities(this.config).objectiveStateRecall || !this.isRecallSectionEnabled(
7856
8196
  "objective-state",
7857
- this.config.objectiveStateRecallEnabled === true
8197
+ resolveObjectiveStateCapabilities(this.config).objectiveStateRecall === true
7858
8198
  )) {
7859
8199
  recordRecallSectionMetric({
7860
8200
  section: "objectiveState",
@@ -8073,9 +8413,9 @@ ${rows.join("\n")}
8073
8413
  })();
8074
8414
  const trustZonePromise = (async () => {
8075
8415
  const t0 = Date.now();
8076
- if (!this.config.trustZonesEnabled || !this.config.trustZoneRecallEnabled || !this.isRecallSectionEnabled(
8416
+ if (!resolveSecurityCapabilities(this.config).trustZones || !resolveSecurityCapabilities(this.config).trustZoneRecall || !this.isRecallSectionEnabled(
8077
8417
  "trust-zones",
8078
- this.config.trustZoneRecallEnabled === true
8418
+ resolveSecurityCapabilities(this.config).trustZoneRecall === true
8079
8419
  )) {
8080
8420
  recordRecallSectionMetric({
8081
8421
  section: "trustZones",
@@ -8846,11 +9186,11 @@ ${formatted}`;
8846
9186
  if (!this.config.compactionResetEnabled) return null;
8847
9187
  const workspaceDir = compactionWorkspaceDir || this.config.workspaceDir || defaultWorkspaceDir();
8848
9188
  const safeSessionKey = sanitizeSessionKeyForFilename(effectiveSessionKey);
8849
- const signalPath = path3.join(
9189
+ const signalPath = path4.join(
8850
9190
  workspaceDir,
8851
9191
  `.compaction-reset-signal-${safeSessionKey}`
8852
9192
  );
8853
- const bootPath = path3.join(workspaceDir, "BOOT.md");
9193
+ const bootPath = path4.join(workspaceDir, "BOOT.md");
8854
9194
  try {
8855
9195
  const signalStat = await stat(signalPath).catch(() => null);
8856
9196
  if (!signalStat) return null;
@@ -10535,7 +10875,7 @@ ${tmtNode.summary}`
10535
10875
  });
10536
10876
  if (this.isRecallSectionEnabled(
10537
10877
  "compression-guidelines",
10538
- this.config.compressionGuidelineLearningEnabled === true
10878
+ resolveCompressionCapabilities(this.config).compressionGuidelineLearning === true
10539
10879
  )) {
10540
10880
  const compressionGuidelineSection = await this.buildCompressionGuidelineRecallSection();
10541
10881
  if (compressionGuidelineSection) {
@@ -11121,7 +11461,7 @@ _Context: ${topQuestion.context}_`
11121
11461
  const shouldUseStableBatchKey = turns.some(
11122
11462
  (turn) => turn.persistProcessedFingerprint === true || typeof turn.turnFingerprint === "string" && turn.turnFingerprint.length > 0
11123
11463
  );
11124
- const stableBatchFingerprint = shouldUseStableBatchKey ? createHash("sha256").update(
11464
+ const stableBatchFingerprint = shouldUseStableBatchKey ? createHash2("sha256").update(
11125
11465
  turns.map(
11126
11466
  (turn) => [
11127
11467
  turn.role,
@@ -11371,7 +11711,7 @@ _Context: ${topQuestion.context}_`
11371
11711
  buildExtractionFingerprint(turns, bufferKey) {
11372
11712
  const normalized = this.normalizeExtractionFingerprintTurns(turns).join("\n");
11373
11713
  if (!normalized) return null;
11374
- return createHash("sha256").update(`${bufferKey}
11714
+ return createHash2("sha256").update(`${bufferKey}
11375
11715
  ${normalized}`).digest("hex");
11376
11716
  }
11377
11717
  shouldQueueExtraction(turns, options = {}) {
@@ -13452,7 +13792,7 @@ ${normalized}`).digest("hex");
13452
13792
  const allMems = allMemsForGraph ?? [];
13453
13793
  for (const m of allMems) {
13454
13794
  if (m.frontmatter.entityRef === entityRef) {
13455
- const rel = path3.relative(storage.dir, m.path);
13795
+ const rel = path4.relative(storage.dir, m.path);
13456
13796
  if (rel !== memoryRelPath) entitySiblings.push(rel);
13457
13797
  }
13458
13798
  }
@@ -13776,7 +14116,7 @@ ${normalized}`).digest("hex");
13776
14116
  }
13777
14117
  if (this.config.semanticConsolidationEnabled) {
13778
14118
  try {
13779
- const stateFilePath = path3.join(
14119
+ const stateFilePath = path4.join(
13780
14120
  this.config.memoryDir,
13781
14121
  "state",
13782
14122
  "semantic-consolidation-last-run.json"
@@ -13824,9 +14164,9 @@ ${normalized}`).digest("hex");
13824
14164
  );
13825
14165
  }
13826
14166
  if (semResult.errors === 0 || semResult.memoriesArchived > 0) {
13827
- const stateDir = path3.join(this.config.memoryDir, "state");
13828
- await mkdir2(stateDir, { recursive: true });
13829
- await writeFile2(
14167
+ const stateDir = path4.join(this.config.memoryDir, "state");
14168
+ await mkdir3(stateDir, { recursive: true });
14169
+ await writeFile3(
13830
14170
  stateFilePath,
13831
14171
  JSON.stringify({ lastRunAt: (/* @__PURE__ */ new Date()).toISOString() }),
13832
14172
  "utf-8"
@@ -13951,65 +14291,6 @@ ${texts.map((t, i) => `[${i + 1}] ${t}`).join("\n\n")}`;
13951
14291
  async buildCompressionGuidelineRecallSection() {
13952
14292
  return this.compressionGuidelineCoordinator.buildCompressionGuidelineRecallSection();
13953
14293
  }
13954
- actionOutcomePriorDelta(event) {
13955
- if (event.outcome === "failed") return -0.3;
13956
- if (event.policyDecision === "deny") return -0.22;
13957
- if (event.policyDecision === "defer") return -0.14;
13958
- if (event.outcome === "skipped") return -0.1;
13959
- if (event.outcome !== "applied") return 0;
13960
- switch (event.action) {
13961
- case "store_episode":
13962
- case "store_note":
13963
- case "update_note":
13964
- return 0.08;
13965
- case "create_artifact":
13966
- case "summarize_node":
13967
- case "link_graph":
13968
- return 0.04;
13969
- case "discard":
13970
- return -0.03;
13971
- default:
13972
- return 0;
13973
- }
13974
- }
13975
- async buildLifecycleActionPriors(storage = this.storage) {
13976
- const events = await storage.readMemoryActionEvents(1200);
13977
- if (events.length === 0) return /* @__PURE__ */ new Map();
13978
- const nowMs = Date.now();
13979
- const windowMs = 14 * 24 * 60 * 60 * 1e3;
13980
- const byMemory = /* @__PURE__ */ new Map();
13981
- for (const event of events) {
13982
- if (typeof event.memoryId !== "string" || event.memoryId.trim().length === 0)
13983
- continue;
13984
- const ts = Date.parse(event.timestamp);
13985
- if (!Number.isFinite(ts)) continue;
13986
- const ageMs = nowMs - ts;
13987
- if (ageMs < 0 || ageMs > windowMs) continue;
13988
- const delta = this.actionOutcomePriorDelta(event);
13989
- if (delta === 0) continue;
13990
- const recencyWeight = Math.max(0.2, 1 - ageMs / windowMs);
13991
- const list = byMemory.get(event.memoryId) ?? [];
13992
- if (list.length >= 8) list.shift();
13993
- list.push({
13994
- weightedDelta: delta * recencyWeight,
13995
- weight: recencyWeight
13996
- });
13997
- byMemory.set(event.memoryId, list);
13998
- }
13999
- const out = /* @__PURE__ */ new Map();
14000
- for (const [memoryId, deltas] of byMemory.entries()) {
14001
- if (deltas.length === 0) continue;
14002
- const weightedSum = deltas.reduce(
14003
- (sum, item) => sum + item.weightedDelta,
14004
- 0
14005
- );
14006
- const weightTotal = deltas.reduce((sum, item) => sum + item.weight, 0);
14007
- if (weightTotal <= 0) continue;
14008
- const score = weightedSum / weightTotal;
14009
- out.set(memoryId, Math.max(-0.25, Math.min(0.15, score)));
14010
- }
14011
- return out;
14012
- }
14013
14294
  async recordScheduledDreamsPhaseRun(phase, itemsProcessed, notes, timing = {}) {
14014
14295
  try {
14015
14296
  const { recordDreamsPhaseRun } = await import("./dreams-ledger-6UODQOX6.js");
@@ -14033,215 +14314,16 @@ ${texts.map((t, i) => `[${i + 1}] ${t}`).join("\n\n")}`;
14033
14314
  return { memoriesAssessed: lifecycleCorpus.length };
14034
14315
  }
14035
14316
  async runLifecyclePolicyPass(allMemories, storage = this.storage) {
14036
- const now = /* @__PURE__ */ new Date();
14037
- const nowIso = now.toISOString();
14038
- const countsByState = {
14039
- candidate: 0,
14040
- validated: 0,
14041
- active: 0,
14042
- stale: 0,
14043
- archived: 0
14044
- };
14045
- const transitionCounts = {};
14046
- let updatedCount = 0;
14047
- let disputedCount = 0;
14048
- let evaluatedCount = 0;
14049
- const lifecycleCaps = resolveMemoryLifecycleCapabilities(this.config);
14050
- const thresholds = this.effectiveLifecycleThresholds();
14051
- const policy = {
14052
- promoteHeatThreshold: thresholds.promoteHeatThreshold,
14053
- staleDecayThreshold: thresholds.staleDecayThreshold,
14054
- archiveDecayThreshold: thresholds.archiveDecayThreshold,
14055
- protectedCategories: this.config.lifecycleProtectedCategories
14056
- };
14057
- const actionPriors = await this.buildLifecycleActionPriors(storage);
14058
- for (const memory of allMemories) {
14059
- if (memory.frontmatter.status === "superseded" || memory.frontmatter.status === "forgotten") {
14060
- continue;
14061
- }
14062
- evaluatedCount += 1;
14063
- const currentState = resolveLifecycleState(memory.frontmatter);
14064
- const actionPriorScore = actionPriors.get(memory.frontmatter.id);
14065
- const signals = typeof actionPriorScore === "number" && Number.isFinite(actionPriorScore) ? { actionPriorScore } : void 0;
14066
- const decision = decideLifecycleTransition(memory, policy, now, signals);
14067
- const nextState = memory.frontmatter.status === "archived" ? "archived" : decision.nextState;
14068
- countsByState[nextState] += 1;
14069
- if (memory.frontmatter.verificationState === "disputed") {
14070
- disputedCount += 1;
14071
- }
14072
- if (nextState !== currentState) {
14073
- const key = `${currentState}->${nextState}`;
14074
- transitionCounts[key] = (transitionCounts[key] ?? 0) + 1;
14075
- }
14076
- const prevHeat = memory.frontmatter.heatScore;
14077
- const prevDecay = memory.frontmatter.decayScore;
14078
- const scoreDelta = Math.abs((prevHeat ?? -1) - decision.heatScore) + Math.abs((prevDecay ?? -1) - decision.decayScore);
14079
- const shouldPersist = memory.frontmatter.lifecycleState !== nextState || memory.frontmatter.heatScore === void 0 || memory.frontmatter.decayScore === void 0 || memory.frontmatter.lastValidatedAt === void 0 || scoreDelta >= 0.01;
14080
- if (!shouldPersist) continue;
14081
- const wrote = await storage.writeMemoryFrontmatter(memory, {
14082
- lifecycleState: nextState,
14083
- heatScore: decision.heatScore,
14084
- decayScore: decision.decayScore,
14085
- lastValidatedAt: nowIso
14086
- });
14087
- if (wrote) updatedCount += 1;
14088
- }
14089
- if (!lifecycleCaps.lifecycleMetrics) return updatedCount;
14090
- const total = evaluatedCount;
14091
- const metrics = {
14092
- generatedAt: nowIso,
14093
- memoriesEvaluated: total,
14094
- memoriesUpdated: updatedCount,
14095
- countsByLifecycleState: countsByState,
14096
- transitionCounts,
14097
- staleRatio: total > 0 ? countsByState.stale / total : 0,
14098
- disputedRatio: total > 0 ? disputedCount / total : 0,
14099
- policy: {
14100
- promoteHeatThreshold: thresholds.promoteHeatThreshold,
14101
- staleDecayThreshold: thresholds.staleDecayThreshold,
14102
- archiveDecayThreshold: thresholds.archiveDecayThreshold,
14103
- protectedCategories: this.config.lifecycleProtectedCategories
14104
- }
14105
- };
14106
- const metricsPath = path3.join(
14107
- storage.dir,
14108
- "state",
14109
- "lifecycle-metrics.json"
14110
- );
14111
- await mkdir2(path3.dirname(metricsPath), { recursive: true });
14112
- await writeFile2(metricsPath, JSON.stringify(metrics, null, 2), "utf-8");
14113
- return updatedCount;
14317
+ return this.lifecyclePolicyCoordinator.runLifecyclePolicyPass(allMemories, storage);
14114
14318
  }
14115
- /**
14116
- * Archive old, low-importance, rarely-accessed facts (v6.0).
14117
- * Moves eligible facts from facts/ to archive/YYYY-MM-DD/.
14118
- * Returns the number of archived facts.
14119
- */
14120
14319
  async runFactArchival(allMemories) {
14121
- const now = Date.now();
14122
- const ageCutoffMs = this.config.factArchivalAgeDays * 24 * 60 * 60 * 1e3;
14123
- const protectedCategories = new Set(
14124
- this.config.factArchivalProtectedCategories
14125
- );
14126
- let archivedCount = 0;
14127
- for (const memory of allMemories) {
14128
- const fm = memory.frontmatter;
14129
- if (fm.status && fm.status !== "active") continue;
14130
- if (protectedCategories.has(fm.category)) continue;
14131
- if (fm.category === "correction") continue;
14132
- const createdMs = new Date(fm.created).getTime();
14133
- if (now - createdMs < ageCutoffMs) continue;
14134
- const importanceScore = fm.importance?.score ?? 0.5;
14135
- if (importanceScore >= this.config.factArchivalMaxImportance) continue;
14136
- const accessCount = fm.accessCount ?? 0;
14137
- if (accessCount > this.config.factArchivalMaxAccessCount) continue;
14138
- const result = await this.storage.archiveMemory(memory);
14139
- if (result) {
14140
- await this.removeContentHashForMemory(
14141
- this.storage,
14142
- memory,
14143
- "fact-archival"
14144
- );
14145
- await this.embeddingFallback.removeFromIndex(memory.frontmatter.id);
14146
- if (resolveIndexingCapabilities(this.config).queryAwareIndexing && memory.path && memory.frontmatter?.created) {
14147
- deindexMemory(
14148
- this.config.memoryDir,
14149
- memory.path,
14150
- memory.frontmatter.created,
14151
- memory.frontmatter.tags ?? []
14152
- );
14153
- }
14154
- archivedCount++;
14155
- }
14156
- }
14157
- if (archivedCount > 0) {
14158
- await this.saveContentHashIndexes().catch(
14159
- (err) => log.warn(`content-hash index save failed during archival: ${err}`)
14160
- );
14161
- }
14162
- return archivedCount;
14320
+ return this.lifecyclePolicyCoordinator.runFactArchival(allMemories);
14163
14321
  }
14164
- /**
14165
- * Run memory summarization if memory count exceeds threshold (Phase 4A).
14166
- */
14167
14322
  async runSummarization(allMemories) {
14168
- const activeMemories = allMemories.filter(
14169
- (m) => isActiveMemoryStatus(m.frontmatter.status)
14170
- );
14171
- if (activeMemories.length < this.config.summarizationTriggerCount) {
14172
- return;
14173
- }
14174
- log.info(
14175
- `memory count (${activeMemories.length}) exceeds threshold (${this.config.summarizationTriggerCount}) \u2014 running summarization`
14176
- );
14177
- const sorted = activeMemories.sort(
14178
- (a, b) => new Date(a.frontmatter.created).getTime() - new Date(b.frontmatter.created).getTime()
14179
- );
14180
- const recentToKeep = Math.max(0, this.config.summarizationRecentToKeep);
14181
- const toSummarize = recentToKeep > 0 ? sorted.slice(0, -recentToKeep) : sorted;
14182
- const candidates = toSummarize.filter((m) => {
14183
- if (m.frontmatter.entityRef) return false;
14184
- const protectedTags = this.config.summarizationProtectedTags;
14185
- if (m.frontmatter.tags.some((t) => protectedTags.includes(t)))
14186
- return false;
14187
- const importance = m.frontmatter.importance?.score ?? 0.5;
14188
- if (importance >= this.config.summarizationImportanceThreshold)
14189
- return false;
14190
- return true;
14191
- });
14192
- if (candidates.length < 50) {
14193
- log.debug(
14194
- `only ${candidates.length} candidates for summarization \u2014 skipping`
14195
- );
14196
- return;
14197
- }
14198
- const batchSize = 50;
14199
- for (let i = 0; i < candidates.length; i += batchSize) {
14200
- const batch = candidates.slice(i, i + batchSize);
14201
- const batchData = batch.map((m) => ({
14202
- id: m.frontmatter.id,
14203
- content: m.content,
14204
- category: m.frontmatter.category,
14205
- created: m.frontmatter.created
14206
- }));
14207
- const result = await this.extraction.summarizeMemories(batchData);
14208
- if (!result) continue;
14209
- const summary = {
14210
- id: `summary-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
14211
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
14212
- timeRangeStart: batch[0].frontmatter.created,
14213
- timeRangeEnd: batch[batch.length - 1].frontmatter.created,
14214
- summaryText: result.summaryText,
14215
- keyFacts: result.keyFacts,
14216
- keyEntities: result.keyEntities,
14217
- sourceEpisodeIds: batch.map((m) => m.frontmatter.id)
14218
- };
14219
- await this.storage.writeSummary(summary);
14220
- const archived = await this.storage.archiveMemories(
14221
- batch.map((m) => m.frontmatter.id),
14222
- summary.id
14223
- );
14224
- log.info(
14225
- `created summary ${summary.id} from ${batch.length} memories, archived ${archived}`
14226
- );
14227
- }
14323
+ return this.lifecyclePolicyCoordinator.runSummarization(allMemories);
14228
14324
  }
14229
- /**
14230
- * Run topic extraction on all memories (Phase 4B).
14231
- */
14232
14325
  async runTopicExtraction(allMemories) {
14233
- const activeMemories = allMemories.filter(
14234
- (m) => isActiveMemoryStatus(m.frontmatter.status)
14235
- );
14236
- if (activeMemories.length === 0) return;
14237
- const topics = extractTopics(
14238
- activeMemories,
14239
- this.config.topicExtractionTopN
14240
- );
14241
- await this.storage.saveTopics(topics);
14242
- log.debug(
14243
- `extracted ${topics.length} topics from ${activeMemories.length} memories`
14244
- );
14326
+ return this.lifecyclePolicyCoordinator.runTopicExtraction(allMemories);
14245
14327
  }
14246
14328
  /** Threshold (bytes) at which IDENTITY.md reflections get auto-consolidated */
14247
14329
  static IDENTITY_CONSOLIDATE_THRESHOLD = 8e3;
@@ -14589,7 +14671,7 @@ ${lines.join("\n\n")}`;
14589
14671
  }
14590
14672
  }
14591
14673
  queueEvalShadowRecall(record) {
14592
- if (!this.config.evalHarnessEnabled || !this.config.evalShadowModeEnabled)
14674
+ if (!resolveEvalCapabilities(this.config).evalHarness || !resolveEvalCapabilities(this.config).evalShadowMode)
14593
14675
  return;
14594
14676
  this.evalShadowWriteChain = this.evalShadowWriteChain.catch(() => void 0).then(async () => {
14595
14677
  try {
@@ -14651,7 +14733,7 @@ ${lines.join("\n\n")}`;
14651
14733
  const seenStorageDirs = /* @__PURE__ */ new Set();
14652
14734
  const addStorage = (storage) => {
14653
14735
  const storageDir = storageDirFor(storage);
14654
- const storageKey = storageDir ? path3.resolve(storageDir) : `storage-without-dir-${storages.length}`;
14736
+ const storageKey = storageDir ? path4.resolve(storageDir) : `storage-without-dir-${storages.length}`;
14655
14737
  if (seenStorageDirs.has(storageKey)) return;
14656
14738
  seenStorageDirs.add(storageKey);
14657
14739
  storages.push(storage);
@@ -14681,7 +14763,7 @@ ${lines.join("\n\n")}`;
14681
14763
  continue;
14682
14764
  }
14683
14765
  try {
14684
- const coldRoot = path3.join(storageDir, "cold");
14766
+ const coldRoot = path4.join(storageDir, "cold");
14685
14767
  for (const candidate of qmdResultPathCandidates(
14686
14768
  coldRoot,
14687
14769
  parts.relativePath
@@ -14722,7 +14804,7 @@ ${lines.join("\n\n")}`;
14722
14804
  return null;
14723
14805
  }
14724
14806
  }
14725
- if (path3.isAbsolute(resultPath)) {
14807
+ if (path4.isAbsolute(resultPath)) {
14726
14808
  if (!fallbackStorageDir) {
14727
14809
  return await fallbackStorage.readMemoryByPath(resultPath);
14728
14810
  }
@@ -14761,7 +14843,7 @@ ${lines.join("\n\n")}`;
14761
14843
  );
14762
14844
  if (!memory) return null;
14763
14845
  let ownerNamespace = null;
14764
- if (path3.isAbsolute(memory.path)) {
14846
+ if (path4.isAbsolute(memory.path)) {
14765
14847
  const ownerStorage = await this.storageForAbsoluteQmdResultPath(
14766
14848
  memory.path,
14767
14849
  fallbackStorage,
@@ -14785,16 +14867,16 @@ ${lines.join("\n\n")}`;
14785
14867
  };
14786
14868
  }
14787
14869
  async storageForAbsoluteQmdResultPath(resultPath, fallbackStorage, recallNamespaces = []) {
14788
- const resolvedPath = path3.resolve(resultPath);
14789
- const memoryRoot = path3.resolve(this.config.memoryDir);
14790
- const namespacesRoot = path3.join(memoryRoot, "namespaces");
14870
+ const resolvedPath = path4.resolve(resultPath);
14871
+ const memoryRoot = path4.resolve(this.config.memoryDir);
14872
+ const namespacesRoot = path4.join(memoryRoot, "namespaces");
14791
14873
  const fallbackStorageDir = typeof fallbackStorage.dir === "string" && fallbackStorage.dir ? fallbackStorage.dir : null;
14792
14874
  const matches = [];
14793
14875
  const seenDirs = /* @__PURE__ */ new Set();
14794
14876
  const maybeAddStorage = (storage, namespace) => {
14795
14877
  const storageDir = typeof storage.dir === "string" && storage.dir ? storage.dir : null;
14796
14878
  if (!storageDir) return;
14797
- const candidateRoot = path3.resolve(storageDir);
14879
+ const candidateRoot = path4.resolve(storageDir);
14798
14880
  if (seenDirs.has(candidateRoot)) return;
14799
14881
  if (!isPathInsideStorageRoot(candidateRoot, resolvedPath)) return;
14800
14882
  if (candidateRoot === memoryRoot && isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {
@@ -14812,7 +14894,7 @@ ${lines.join("\n\n")}`;
14812
14894
  candidateNamespaces.add(ns);
14813
14895
  }
14814
14896
  if (isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {
14815
- const relativeToNamespaces = path3.relative(namespacesRoot, resolvedPath);
14897
+ const relativeToNamespaces = path4.relative(namespacesRoot, resolvedPath);
14816
14898
  const [namespaceSegment] = relativeToNamespaces.split(/[\\/]/);
14817
14899
  if (namespaceSegment) {
14818
14900
  candidateNamespaces.add(
@@ -14857,7 +14939,7 @@ ${lines.join("\n\n")}`;
14857
14939
  nsMap = buildMemoryWorthCounterMap(memories);
14858
14940
  this.memoryWorthCounterCache.set(ns, { at: nowMs, counters: nsMap });
14859
14941
  }
14860
- for (const [path4, c] of nsMap) counters.set(path4, c);
14942
+ for (const [path5, c] of nsMap) counters.set(path5, c);
14861
14943
  } catch (err) {
14862
14944
  log.debug("memory-worth: failed to read namespace, skipping", {
14863
14945
  namespace: ns,
@@ -14940,7 +15022,7 @@ ${lines.join("\n\n")}`;
14940
15022
  namespaces,
14941
15023
  {
14942
15024
  readNamespaceMemories: async (ns) => (await this.getStorage(ns)).readAllMemories(),
14943
- readMemoryFrontmatter: async (path4) => {
15025
+ readMemoryFrontmatter: async (path5) => {
14944
15026
  if (!fallbackReader) {
14945
15027
  for (const ns of namespaces) {
14946
15028
  try {
@@ -14951,7 +15033,7 @@ ${lines.join("\n\n")}`;
14951
15033
  }
14952
15034
  }
14953
15035
  if (!fallbackReader) return null;
14954
- const memory = await this.readQmdResultMemory(path4, fallbackReader, namespaces);
15036
+ const memory = await this.readQmdResultMemory(path5, fallbackReader, namespaces);
14955
15037
  return memory ? memory.frontmatter : null;
14956
15038
  }
14957
15039
  },
@@ -15121,12 +15203,12 @@ ${lines.join("\n\n")}`;
15121
15203
  */
15122
15204
  semanticDedupScopeFor(targetStorage) {
15123
15205
  if (!resolveNamespaceCapabilities(this.config).namespaces) return {};
15124
- const memoryDir = path3.resolve(this.config.memoryDir);
15125
- const storageDir = path3.resolve(targetStorage.dir);
15206
+ const memoryDir = path4.resolve(this.config.memoryDir);
15207
+ const storageDir = path4.resolve(targetStorage.dir);
15126
15208
  if (storageDir === memoryDir) {
15127
15209
  return { pathExcludePrefixes: ["namespaces/"] };
15128
15210
  }
15129
- let rel = path3.relative(memoryDir, storageDir);
15211
+ let rel = path4.relative(memoryDir, storageDir);
15130
15212
  if (!rel || rel.startsWith("..")) {
15131
15213
  log.debug(
15132
15214
  `semantic dedup: target storage dir ${storageDir} is outside memoryDir ${memoryDir}; scoping lookup to absolute path prefix`
@@ -15145,7 +15227,7 @@ ${lines.join("\n\n")}`;
15145
15227
  if (hits.length === 0) return [];
15146
15228
  const results = [];
15147
15229
  for (const hit of hits) {
15148
- const fullPath = path3.isAbsolute(hit.path) ? hit.path : path3.join(this.config.memoryDir, hit.path);
15230
+ const fullPath = path4.isAbsolute(hit.path) ? hit.path : path4.join(this.config.memoryDir, hit.path);
15149
15231
  const memory = await this.storage.readMemoryByPath(fullPath);
15150
15232
  if (!memory) continue;
15151
15233
  results.push({
@@ -15342,7 +15424,7 @@ ${lines.join("\n\n")}`;
15342
15424
  const storage = await this.storageRouter.storageFor(namespace);
15343
15425
  const storageDir = typeof storage.dir === "string" && storage.dir ? storage.dir : null;
15344
15426
  if (!storageDir) continue;
15345
- const recallRoot = path3.resolve(storageDir);
15427
+ const recallRoot = path4.resolve(storageDir);
15346
15428
  if (seenRecallRoots.has(recallRoot)) continue;
15347
15429
  seenRecallRoots.add(recallRoot);
15348
15430
  recallRoots.push(recallRoot);
@@ -15366,8 +15448,8 @@ ${lines.join("\n\n")}`;
15366
15448
  if (resolvedCold) scopedResults.push(resolvedCold.result);
15367
15449
  continue;
15368
15450
  }
15369
- if (path3.isAbsolute(result.path)) {
15370
- const resolvedPath = path3.resolve(result.path);
15451
+ if (path4.isAbsolute(result.path)) {
15452
+ const resolvedPath = path4.resolve(result.path);
15371
15453
  if (recallRoots.some(
15372
15454
  (recallRoot) => isPathInsideStorageRoot(recallRoot, resolvedPath)
15373
15455
  )) {
@@ -16274,7 +16356,6 @@ export {
16274
16356
  WearablesService,
16275
16357
  locateTranscriptPath,
16276
16358
  BulkImportBatchPartialFailureError,
16277
- dedupeEntitySynthesisEvidenceEntries,
16278
16359
  defaultWorkspaceDir,
16279
16360
  sanitizeSessionKeyForFilename,
16280
16361
  isArtifactMemoryPath,
@@ -16302,4 +16383,4 @@ export {
16302
16383
  resolvePersistedMemoryRelativePath,
16303
16384
  Orchestrator
16304
16385
  };
16305
- //# sourceMappingURL=chunk-Z7J3OAPR.js.map
16386
+ //# sourceMappingURL=chunk-AE2HPUP7.js.map