@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
@@ -29,7 +29,7 @@ import {
29
29
  resolveCapabilities,
30
30
  resolveGraphConstructionCapabilities,
31
31
  resolveQmdCapabilities,
32
- } from "./capabilities.js";
32
+ resolveEvalCapabilities} from "./capabilities.js";
33
33
  import {
34
34
  analyzeSessionIntegrity,
35
35
  applySessionRepair,
@@ -2263,17 +2263,17 @@ export async function runBenchmarkRecall(options: BenchmarkRecallOptions): Promi
2263
2263
  const status = await getEvalHarnessStatus({
2264
2264
  memoryDir: options.config.memoryDir,
2265
2265
  evalStoreDir: options.config.evalStoreDir,
2266
- enabled: options.config.evalHarnessEnabled,
2267
- shadowModeEnabled: options.config.evalShadowModeEnabled,
2268
- baselineSnapshotsEnabled: options.config.benchmarkBaselineSnapshotsEnabled,
2269
- memoryRedTeamBenchEnabled: options.config.memoryRedTeamBenchEnabled,
2266
+ enabled: resolveEvalCapabilities(options.config).evalHarness,
2267
+ shadowModeEnabled: resolveEvalCapabilities(options.config).evalShadowMode,
2268
+ baselineSnapshotsEnabled: resolveEvalCapabilities(options.config).benchmarkBaselineSnapshots,
2269
+ memoryRedTeamBenchEnabled: resolveEvalCapabilities(options.config).memoryRedTeamBench,
2270
2270
  });
2271
2271
 
2272
2272
  if (options.createSnapshot && options.snapshotId) {
2273
2273
  const snapshot = await createEvalBaselineSnapshot({
2274
2274
  memoryDir: options.config.memoryDir,
2275
2275
  evalStoreDir: options.config.evalStoreDir,
2276
- baselineSnapshotsEnabled: options.config.benchmarkBaselineSnapshotsEnabled,
2276
+ baselineSnapshotsEnabled: resolveEvalCapabilities(options.config).benchmarkBaselineSnapshots,
2277
2277
  snapshotId: options.snapshotId,
2278
2278
  notes: options.snapshotNotes,
2279
2279
  gitRef: options.gitRef,
@@ -2309,7 +2309,7 @@ export async function runBenchmarkRecall(options: BenchmarkRecallOptions): Promi
2309
2309
  const baselineReport = await runEvalBaselineDeltaReport({
2310
2310
  memoryDir: options.config.memoryDir,
2311
2311
  evalStoreDir: options.config.evalStoreDir,
2312
- benchmarkDeltaReporterEnabled: options.config.benchmarkDeltaReporterEnabled,
2312
+ benchmarkDeltaReporterEnabled: resolveEvalCapabilities(options.config).benchmarkDeltaReporter,
2313
2313
  snapshotId: options.snapshotId,
2314
2314
  });
2315
2315
  return {
@@ -2323,7 +2323,7 @@ export async function runBenchmarkRecall(options: BenchmarkRecallOptions): Promi
2323
2323
 
2324
2324
  if (options.validatePath) {
2325
2325
  const validate = await validateEvalBenchmarkPack(options.validatePath, {
2326
- memoryRedTeamBenchEnabled: options.config.memoryRedTeamBenchEnabled,
2326
+ memoryRedTeamBenchEnabled: resolveEvalCapabilities(options.config).memoryRedTeamBench,
2327
2327
  });
2328
2328
  return {
2329
2329
  schemaVersion: 1,
@@ -24,6 +24,7 @@
24
24
  */
25
25
 
26
26
  import { createHash } from "node:crypto";
27
+ import { resolveCompressionCapabilities } from "../capabilities.js";
27
28
 
28
29
  // StorageManager type comes from the package barrel (type-only) so this
29
30
  // module does not add a direct storage.ts import (#1533 ratchet).
@@ -103,7 +104,7 @@ export class CompressionGuidelineCoordinator {
103
104
  ? draftState
104
105
  : activeState;
105
106
 
106
- if (!this.config.compressionGuidelineLearningEnabled) {
107
+ if (!resolveCompressionCapabilities(this.config).compressionGuidelineLearning) {
107
108
  return {
108
109
  enabled: false,
109
110
  dryRun,
@@ -152,7 +153,7 @@ export class CompressionGuidelineCoordinator {
152
153
  }
153
154
  const refinedCandidate =
154
155
  await refineCompressionGuidelineCandidateSemantically(candidate, {
155
- enabled: this.config.compressionGuidelineSemanticRefinementEnabled,
156
+ enabled: resolveCompressionCapabilities(this.config).compressionGuidelineSemanticRefinement,
156
157
  timeoutMs: this.config.compressionGuidelineSemanticTimeoutMs,
157
158
  runRefinement: async (baseline) => {
158
159
  const prompt = [
@@ -241,7 +242,7 @@ export class CompressionGuidelineCoordinator {
241
242
  | "guideline_version_mismatch"
242
243
  | "draft_changed";
243
244
  }> {
244
- if (!this.config.compressionGuidelineLearningEnabled) {
245
+ if (!resolveCompressionCapabilities(this.config).compressionGuidelineLearning) {
245
246
  return {
246
247
  enabled: false,
247
248
  activated: false,
@@ -312,7 +313,7 @@ export class CompressionGuidelineCoordinator {
312
313
 
313
314
  /** Consolidation-time hook: recompute the draft from recent events. */
314
315
  async runCompressionGuidelineLearningPass(): Promise<void> {
315
- if (!this.config.compressionGuidelineLearningEnabled) return;
316
+ if (!resolveCompressionCapabilities(this.config).compressionGuidelineLearning) return;
316
317
  try {
317
318
  const result = await this.optimizeCompressionGuidelines({
318
319
  dryRun: false,
@@ -328,8 +329,8 @@ export class CompressionGuidelineCoordinator {
328
329
 
329
330
  /** Recall-time hook: surface active guidelines as a recall section. */
330
331
  async buildCompressionGuidelineRecallSection(): Promise<string | null> {
331
- if (!this.config.contextCompressionActionsEnabled) return null;
332
- if (!this.config.compressionGuidelineLearningEnabled) return null;
332
+ if (!resolveCompressionCapabilities(this.config).contextCompressionActions) return null;
333
+ if (!resolveCompressionCapabilities(this.config).compressionGuidelineLearning) return null;
333
334
 
334
335
  const state = await this.storage
335
336
  .readCompressionGuidelineOptimizerState()
@@ -0,0 +1,319 @@
1
+ /**
2
+ * Entity synthesis coordinator — extracted from the orchestrator (issue #1526).
3
+ *
4
+ * Owns the entity-synthesis lifecycle: processing the queued entities whose
5
+ * evidence has changed since their last synthesis, gathering timeline +
6
+ * structured-section evidence, deduplicating it, batch-feeding it through the
7
+ * fast-tier LLM to produce a compact "current truth" synthesis, and persisting
8
+ * the result with drift/bookkeeping metadata.
9
+ *
10
+ * Moved here (behavior-preserving):
11
+ * - module-level helpers `dedupeEntitySynthesisEvidenceEntries`,
12
+ * `flattenStructuredSectionEvidence`, `fingerprintEntitySynthesisEvidence`
13
+ * - the orchestrator method `processEntitySynthesisQueue`
14
+ *
15
+ * The orchestrator constructs one instance and delegates the public entrypoint
16
+ * to it. Storage is resolved per-call via the injected accessor so namespace-
17
+ * scoped and default-namespace calls share one coordinator.
18
+ *
19
+ * Behavior-preserving move from orchestrator.ts. No logic changes — the
20
+ * orchestrator keeps a thin delegating `processEntitySynthesisQueue` so
21
+ * existing call sites (consolidation pass, access-service) and tests that
22
+ * exercise the public API continue to work.
23
+ */
24
+
25
+ import { createHash } from "node:crypto";
26
+
27
+ import type { StorageManager } from "../index.js";
28
+ import {
29
+ compareEntityTimestamps,
30
+ fingerprintEntityStructuredFacts,
31
+ parseEntityFile,
32
+ } from "../storage.js";
33
+ import type {
34
+ EntityStructuredSection,
35
+ EntityTimelineEntry,
36
+ PluginConfig,
37
+ } from "../types.js";
38
+ import { log } from "../logger.js";
39
+
40
+ // ---------------------------------------------------------------------------
41
+ // Evidence helpers (moved verbatim from orchestrator.ts module scope)
42
+ // ---------------------------------------------------------------------------
43
+
44
+ /**
45
+ * Deduplicate synthesis-evidence entries by normalized text, keeping the
46
+ * newest and oldest timestamp per unique fact when they differ.
47
+ */
48
+ export function dedupeEntitySynthesisEvidenceEntries(
49
+ entries: EntityTimelineEntry[],
50
+ ): EntityTimelineEntry[] {
51
+ const dedupedEvidenceEntries: EntityTimelineEntry[] = [];
52
+ const evidenceByFact = new Map<string, {
53
+ newest: EntityTimelineEntry;
54
+ oldest: EntityTimelineEntry;
55
+ }>();
56
+
57
+ for (const entry of entries) {
58
+ const normalizedFact = entry.text.trim();
59
+ if (!normalizedFact) continue;
60
+ const existing = evidenceByFact.get(normalizedFact);
61
+ if (!existing) {
62
+ evidenceByFact.set(normalizedFact, { newest: entry, oldest: entry });
63
+ continue;
64
+ }
65
+ if (compareEntityTimestamps(entry.timestamp, existing.newest.timestamp) > 0) {
66
+ existing.newest = entry;
67
+ }
68
+ if (compareEntityTimestamps(entry.timestamp, existing.oldest.timestamp) < 0) {
69
+ existing.oldest = entry;
70
+ }
71
+ }
72
+
73
+ for (const { newest, oldest } of evidenceByFact.values()) {
74
+ dedupedEvidenceEntries.push(newest);
75
+ const newestKey = [
76
+ newest.timestamp,
77
+ newest.source ?? "",
78
+ newest.sessionKey ?? "",
79
+ newest.principal ?? "",
80
+ newest.text,
81
+ ].join("\u0000");
82
+ const oldestKey = [
83
+ oldest.timestamp,
84
+ oldest.source ?? "",
85
+ oldest.sessionKey ?? "",
86
+ oldest.principal ?? "",
87
+ oldest.text,
88
+ ].join("\u0000");
89
+ if (oldestKey !== newestKey) {
90
+ dedupedEvidenceEntries.push(oldest);
91
+ }
92
+ }
93
+
94
+ return dedupedEvidenceEntries;
95
+ }
96
+
97
+ function flattenStructuredSectionEvidence(
98
+ sections: EntityStructuredSection[] | undefined,
99
+ ): EntityTimelineEntry[] {
100
+ return (sections ?? []).flatMap((section) =>
101
+ section.facts
102
+ .map((fact) => fact.trim())
103
+ .filter((fact) => fact.length > 0)
104
+ .map((fact) => ({
105
+ timestamp: "",
106
+ text: fact,
107
+ source: `section:${section.title}`,
108
+ })),
109
+ );
110
+ }
111
+
112
+ function fingerprintEntitySynthesisEvidence(entity: {
113
+ timeline: EntityTimelineEntry[];
114
+ structuredSections?: EntityStructuredSection[];
115
+ }): string {
116
+ const fingerprint = createHash("sha256");
117
+ const timelineEntries = entity.timeline
118
+ .map((entry) => [
119
+ entry.timestamp,
120
+ entry.source ?? "",
121
+ entry.sessionKey ?? "",
122
+ entry.principal ?? "",
123
+ entry.text,
124
+ ].join("\u0000"))
125
+ .sort();
126
+ const timelineEntrySeparator = String.fromCharCode(1);
127
+ const structuredFactsSeparator = String.fromCharCode(2);
128
+ fingerprint.update(timelineEntries.join(timelineEntrySeparator));
129
+ fingerprint.update(structuredFactsSeparator);
130
+ fingerprint.update(fingerprintEntityStructuredFacts(entity) ?? "");
131
+ return fingerprint.digest("hex");
132
+ }
133
+
134
+ // ---------------------------------------------------------------------------
135
+ // Coordinator
136
+ // ---------------------------------------------------------------------------
137
+
138
+ /** Dependencies injected by the orchestrator. */
139
+ export interface EntitySynthesisCoordinatorDeps {
140
+ config: PluginConfig;
141
+ /** Resolve the storage manager for a namespace (or the default). */
142
+ getStorage: (namespace?: string) => Promise<StorageManager>;
143
+ /** Fast-tier LLM completion (same signature as Orchestrator.fastChatCompletion). */
144
+ fastChatCompletion: (
145
+ messages: Array<{ role: string; content: string }>,
146
+ options: {
147
+ temperature?: number;
148
+ maxTokens?: number;
149
+ timeoutMs?: number;
150
+ operation?: string;
151
+ priority?: "background" | "recall-critical";
152
+ },
153
+ ) => Promise<{ content: string } | null>;
154
+ }
155
+
156
+ /**
157
+ * Coordinates entity synthesis refresh for queued entities. Owns the
158
+ * evidence-gathering, dedup, batched-LLM-synthesis, and persistence logic
159
+ * that previously lived inline in the orchestrator.
160
+ */
161
+ export class EntitySynthesisCoordinator {
162
+ constructor(private readonly deps: EntitySynthesisCoordinatorDeps) {}
163
+
164
+ /**
165
+ * Process up to `maxEntities` entities from the synthesis queue for the
166
+ * given namespace. Returns the number of entities whose synthesis was
167
+ * successfully refreshed.
168
+ */
169
+ async processQueue(
170
+ namespace?: string,
171
+ maxEntities: number = 5,
172
+ ): Promise<number> {
173
+ const { config } = this.deps;
174
+ if (
175
+ !config.entitySummaryEnabled
176
+ || maxEntities <= 0
177
+ || config.entitySynthesisMaxTokens <= 0
178
+ ) return 0;
179
+ const storage = await this.deps.getStorage(namespace);
180
+ const queued = await storage.refreshEntitySynthesisQueue();
181
+ let processed = 0;
182
+ let attempted = 0;
183
+
184
+ for (const entityName of queued) {
185
+ if (attempted >= maxEntities) break;
186
+ attempted += 1;
187
+ try {
188
+ const raw = await storage.readEntity(entityName);
189
+ if (!raw) continue;
190
+ const entity = parseEntityFile(raw, config.entitySchemas);
191
+ const previousSynthesis = entity.synthesis || entity.summary || "";
192
+ const sortedTimelineEntries = entity.timeline
193
+ .slice()
194
+ .sort((left, right) => compareEntityTimestamps(right.timestamp, left.timestamp));
195
+ const newerTimelineEntries = sortedTimelineEntries.filter(
196
+ (entry) =>
197
+ !entity.synthesisUpdatedAt
198
+ || compareEntityTimestamps(entry.timestamp, entity.synthesisUpdatedAt) > 0,
199
+ );
200
+ const appendedTimelineEntries = entity.synthesisTimelineCount === undefined
201
+ ? []
202
+ : entity.timeline.slice(Math.max(0, entity.synthesisTimelineCount));
203
+ const structuredEvidenceEntries = flattenStructuredSectionEvidence(entity.structuredSections);
204
+ const structuredEvidenceCount = structuredEvidenceEntries.length;
205
+ const structuredEvidenceDigest = fingerprintEntityStructuredFacts(entity);
206
+ const structuredEvidenceDrifted = structuredEvidenceDigest !== (entity.synthesisStructuredFactDigest?.trim() || undefined);
207
+ const appendedStructuredEvidenceEntries = entity.synthesisStructuredFactCount === undefined
208
+ || structuredEvidenceDrifted
209
+ ? structuredEvidenceEntries
210
+ : structuredEvidenceEntries.slice(Math.max(0, entity.synthesisStructuredFactCount));
211
+ const candidateEvidenceEntries = [
212
+ ...newerTimelineEntries,
213
+ ...appendedTimelineEntries,
214
+ ...appendedStructuredEvidenceEntries,
215
+ ]
216
+ .slice()
217
+ .sort((left, right) => compareEntityTimestamps(right.timestamp, left.timestamp));
218
+ const dedupedEvidenceEntries = dedupeEntitySynthesisEvidenceEntries(
219
+ candidateEvidenceEntries.length > 0
220
+ ? candidateEvidenceEntries
221
+ : [...sortedTimelineEntries, ...structuredEvidenceEntries],
222
+ );
223
+ const chronologicalEvidenceEntries = dedupedEvidenceEntries
224
+ .slice()
225
+ .sort((left, right) => compareEntityTimestamps(left.timestamp, right.timestamp));
226
+ if (chronologicalEvidenceEntries.length === 0) continue;
227
+ const latestEvidenceTimestamp = chronologicalEvidenceEntries
228
+ .slice()
229
+ .reverse()
230
+ .map((entry) => entry.timestamp?.trim() || undefined)
231
+ .find((timestamp) => Boolean(timestamp));
232
+ const previousSynthesisUpdatedAt = entity.synthesisUpdatedAt?.trim() || undefined;
233
+ const nextSynthesisUpdatedAt = compareEntityTimestamps(
234
+ latestEvidenceTimestamp,
235
+ previousSynthesisUpdatedAt,
236
+ ) >= 0
237
+ ? latestEvidenceTimestamp
238
+ : previousSynthesisUpdatedAt;
239
+ const evidenceBatches: typeof chronologicalEvidenceEntries[] = [];
240
+ for (let index = 0; index < chronologicalEvidenceEntries.length; index += 8) {
241
+ evidenceBatches.push(chronologicalEvidenceEntries.slice(index, index + 8));
242
+ }
243
+
244
+ let nextSynthesis = previousSynthesis;
245
+ let batchFailed = false;
246
+ for (const evidenceEntries of evidenceBatches) {
247
+ const evidenceText = evidenceEntries
248
+ .map((entry) => {
249
+ const sectionTitle = entry.source?.startsWith("section:")
250
+ ? entry.source.slice("section:".length)
251
+ : "";
252
+ const metadata = [
253
+ `timestamp=${entry.timestamp}`,
254
+ sectionTitle ? `section=${sectionTitle}` : entry.source ? `source=${entry.source}` : "",
255
+ entry.sessionKey ? `session=${entry.sessionKey}` : "",
256
+ entry.principal ? `principal=${entry.principal}` : "",
257
+ ]
258
+ .filter(Boolean)
259
+ .join(", ");
260
+ return `- ${metadata}: ${entry.text}`;
261
+ })
262
+ .join("\n");
263
+ const response = await this.deps.fastChatCompletion(
264
+ [
265
+ {
266
+ role: "system",
267
+ content:
268
+ "Rewrite the entity synthesis as compact current truth. Preserve uncertainty when evidence conflicts. Return plain text only.",
269
+ },
270
+ {
271
+ role: "user",
272
+ content: [
273
+ `Entity: ${entity.name} (${entity.type})`,
274
+ nextSynthesis ? `Previous synthesis:\n${nextSynthesis}` : "Previous synthesis: none",
275
+ `New evidence:\n${evidenceText}`,
276
+ ].join("\n\n"),
277
+ },
278
+ ],
279
+ {
280
+ temperature: 0.2,
281
+ maxTokens: config.entitySynthesisMaxTokens,
282
+ operation: "entity_summary",
283
+ priority: "background",
284
+ },
285
+ );
286
+ const synthesis = response?.content?.trim().replace(/^["']|["']$/g, "");
287
+ const maxSynthesisChars = Math.max(2_000, config.entitySynthesisMaxTokens * 8);
288
+ if (!synthesis || synthesis.length < 10 || synthesis.length > maxSynthesisChars) {
289
+ batchFailed = true;
290
+ break;
291
+ }
292
+ nextSynthesis = synthesis;
293
+ }
294
+ if (batchFailed || nextSynthesis.length === 0) continue;
295
+ const latestRaw = await storage.readEntity(entityName);
296
+ if (!latestRaw) continue;
297
+ const latestEntity = parseEntityFile(latestRaw, config.entitySchemas);
298
+ if (
299
+ fingerprintEntitySynthesisEvidence(latestEntity)
300
+ !== fingerprintEntitySynthesisEvidence(entity)
301
+ ) {
302
+ continue;
303
+ }
304
+ await storage.updateEntitySynthesis(entityName, nextSynthesis, {
305
+ entityUpdatedAt: new Date().toISOString(),
306
+ synthesisStructuredFactDigest: structuredEvidenceDigest,
307
+ synthesisStructuredFactCount: structuredEvidenceCount,
308
+ synthesisTimelineCount: entity.timeline.length,
309
+ updatedAt: nextSynthesisUpdatedAt,
310
+ });
311
+ processed += 1;
312
+ } catch (err) {
313
+ log.debug(`entity synthesis refresh failed for ${entityName}: ${err}`);
314
+ }
315
+ }
316
+
317
+ return processed;
318
+ }
319
+ }