@remnic/core 9.3.733 → 9.3.735

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 (304) hide show
  1. package/dist/access-boundary.d.ts +13 -11
  2. package/dist/access-boundary.js +9 -9
  3. package/dist/access-cli.js +26 -24
  4. package/dist/access-cli.js.map +1 -1
  5. package/dist/access-http.d.ts +13 -11
  6. package/dist/access-http.js +14 -14
  7. package/dist/access-mcp.d.ts +13 -11
  8. package/dist/access-mcp.js +13 -13
  9. package/dist/access-operations-batch.js +11 -11
  10. package/dist/access-operations.d.ts +13 -11
  11. package/dist/access-operations.js +12 -12
  12. package/dist/access-schema.d.ts +4 -4
  13. package/dist/{access-service-Byoe3HsT.d.ts → access-service-CVx7mmvK.d.ts} +4 -4
  14. package/dist/access-service.d.ts +13 -11
  15. package/dist/access-service.js +8 -8
  16. package/dist/access-surface-catalog.d.ts +13 -11
  17. package/dist/action-confidence.d.ts +1 -1
  18. package/dist/active-memory-bridge.d.ts +1 -1
  19. package/dist/active-memory-bridge.js +3 -2
  20. package/dist/active-recall.d.ts +1 -1
  21. package/dist/behavior-learner.d.ts +1 -1
  22. package/dist/behavior-signals.d.ts +1 -1
  23. package/dist/bootstrap.d.ts +12 -10
  24. package/dist/briefing.d.ts +1 -1
  25. package/dist/buffer-surprise-report.d.ts +1 -1
  26. package/dist/buffer.d.ts +1 -1
  27. package/dist/calibration.d.ts +1 -1
  28. package/dist/capabilities.d.ts +196 -2
  29. package/dist/capabilities.js +21 -3
  30. package/dist/{catalog-DM1nk7cM.d.ts → catalog-BVhDEUhT.d.ts} +2 -2
  31. package/dist/causal-behavior.d.ts +1 -1
  32. package/dist/causal-consolidation.d.ts +1 -1
  33. package/dist/causal-trajectory-graph.d.ts +1 -1
  34. package/dist/{chunk-CX77GNMB.js → chunk-2T2N7ISV.js} +6 -3
  35. package/dist/chunk-2T2N7ISV.js.map +1 -0
  36. package/dist/{chunk-HHNSLPX7.js → chunk-5BOQNB2K.js} +10 -9
  37. package/dist/chunk-5BOQNB2K.js.map +1 -0
  38. package/dist/{chunk-QZHF4BWN.js → chunk-AAIHDIMD.js} +6 -6
  39. package/dist/{chunk-H3MB3F62.js → chunk-AB2E5DCN.js} +4 -3
  40. package/dist/chunk-AB2E5DCN.js.map +1 -0
  41. package/dist/{chunk-KSJCXXOU.js → chunk-AE7NTZ75.js} +6 -3
  42. package/dist/chunk-AE7NTZ75.js.map +1 -0
  43. package/dist/{chunk-OTQE66IX.js → chunk-AESC5OQJ.js} +6 -3
  44. package/dist/chunk-AESC5OQJ.js.map +1 -0
  45. package/dist/{chunk-FFUCCKPN.js → chunk-BXPG5AVX.js} +10 -7
  46. package/dist/chunk-BXPG5AVX.js.map +1 -0
  47. package/dist/{chunk-P3VJCTVE.js → chunk-CHJIWG2H.js} +4 -3
  48. package/dist/chunk-CHJIWG2H.js.map +1 -0
  49. package/dist/{chunk-FYWUNVFZ.js → chunk-E4LYJ7PY.js} +6 -6
  50. package/dist/{chunk-NIZQH6AU.js → chunk-FF36YNKY.js} +8 -7
  51. package/dist/chunk-FF36YNKY.js.map +1 -0
  52. package/dist/{chunk-OUITHS6V.js → chunk-FLCYY5JX.js} +801 -711
  53. package/dist/chunk-FLCYY5JX.js.map +1 -0
  54. package/dist/{chunk-PLBIPT6I.js → chunk-FLPKEMSO.js} +7 -4
  55. package/dist/chunk-FLPKEMSO.js.map +1 -0
  56. package/dist/{chunk-6TUWSUUD.js → chunk-G54IDCD3.js} +59 -53
  57. package/dist/chunk-G54IDCD3.js.map +1 -0
  58. package/dist/{chunk-J6BH2OBA.js → chunk-GB2FZOWB.js} +8 -5
  59. package/dist/chunk-GB2FZOWB.js.map +1 -0
  60. package/dist/{chunk-CGPHMNL4.js → chunk-GYICIICQ.js} +10 -6
  61. package/dist/chunk-GYICIICQ.js.map +1 -0
  62. package/dist/{chunk-DKT3X5C3.js → chunk-HFXZIF3V.js} +7 -4
  63. package/dist/chunk-HFXZIF3V.js.map +1 -0
  64. package/dist/{chunk-646B5ERJ.js → chunk-HLPYL6LC.js} +71 -65
  65. package/dist/chunk-HLPYL6LC.js.map +1 -0
  66. package/dist/{chunk-ZVHRSR2R.js → chunk-IPI45Q4S.js} +6 -3
  67. package/dist/chunk-IPI45Q4S.js.map +1 -0
  68. package/dist/{chunk-24D66MMN.js → chunk-IX4L7E5G.js} +7 -4
  69. package/dist/chunk-IX4L7E5G.js.map +1 -0
  70. package/dist/{chunk-SYX73XD7.js → chunk-IXGXALRV.js} +10 -7
  71. package/dist/chunk-IXGXALRV.js.map +1 -0
  72. package/dist/{chunk-ESF7TRYJ.js → chunk-JWDE7OVJ.js} +79 -2
  73. package/dist/chunk-JWDE7OVJ.js.map +1 -0
  74. package/dist/{chunk-GGL34GCW.js → chunk-K3Y2SJTN.js} +7 -4
  75. package/dist/chunk-K3Y2SJTN.js.map +1 -0
  76. package/dist/{chunk-PMAQRUN4.js → chunk-NDKW67ER.js} +5 -2
  77. package/dist/chunk-NDKW67ER.js.map +1 -0
  78. package/dist/{chunk-ZQUAVZNG.js → chunk-NNJKEAP2.js} +7 -4
  79. package/dist/chunk-NNJKEAP2.js.map +1 -0
  80. package/dist/{chunk-UZYLX7M6.js → chunk-OYHYBHHI.js} +9 -6
  81. package/dist/chunk-OYHYBHHI.js.map +1 -0
  82. package/dist/{chunk-NOU77OHX.js → chunk-P6VLG7KE.js} +2 -2
  83. package/dist/{chunk-O4ZIBPIW.js → chunk-QNTLWH3T.js} +3 -3
  84. package/dist/{chunk-LUCARK4W.js → chunk-UO6MPN77.js} +37 -35
  85. package/dist/chunk-UO6MPN77.js.map +1 -0
  86. package/dist/{chunk-HJWQJUKQ.js → chunk-VOEVVIP3.js} +3 -3
  87. package/dist/{chunk-KQYGNGON.js → chunk-ZBZ4XULO.js} +6 -3
  88. package/dist/chunk-ZBZ4XULO.js.map +1 -0
  89. package/dist/{cli-Dt-tuiYH.d.ts → cli-Cx5Mxwk7.d.ts} +3 -3
  90. package/dist/cli.d.ts +14 -12
  91. package/dist/cli.js +20 -20
  92. package/dist/compounding/engine.d.ts +3 -2
  93. package/dist/compounding/engine.js +2 -1
  94. package/dist/compounding/preference-consolidator.d.ts +1 -1
  95. package/dist/compression-optimizer.d.ts +1 -1
  96. package/dist/config.d.ts +1 -1
  97. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  98. package/dist/connectors/codex-materialize.d.ts +1 -1
  99. package/dist/connectors/index.d.ts +1 -1
  100. package/dist/consolidation-provenance-check.d.ts +1 -1
  101. package/dist/consolidation-undo.d.ts +1 -1
  102. package/dist/contradiction/index.d.ts +2 -2
  103. package/dist/contradiction/index.js +2 -1
  104. package/dist/{contradiction-scan-HWGEOUDS.js → contradiction-scan-2B4AE4TI.js} +3 -2
  105. package/dist/conversation-index/backend.d.ts +1 -1
  106. package/dist/conversation-index/chunker.d.ts +1 -1
  107. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  108. package/dist/conversation-index/indexer.d.ts +1 -1
  109. package/dist/conversation-index/search.d.ts +1 -1
  110. package/dist/day-summary.d.ts +1 -1
  111. package/dist/delinearize.d.ts +1 -1
  112. package/dist/direct-answer-wiring.d.ts +1 -1
  113. package/dist/direct-answer.d.ts +1 -1
  114. package/dist/embedding-fallback.d.ts +1 -1
  115. package/dist/embedding-fallback.js +2 -2
  116. package/dist/enrichment/index.d.ts +1 -1
  117. package/dist/entity-retrieval.d.ts +1 -1
  118. package/dist/entity-retrieval.js +2 -1
  119. package/dist/entity-schema.d.ts +1 -1
  120. package/dist/explicit-capture.d.ts +12 -10
  121. package/dist/explicit-capture.js +2 -1
  122. package/dist/extraction-faithfulness.d.ts +1 -1
  123. package/dist/extraction-judge-telemetry.d.ts +1 -1
  124. package/dist/extraction-judge-training.d.ts +1 -1
  125. package/dist/extraction-judge.d.ts +1 -1
  126. package/dist/extraction.d.ts +1 -1
  127. package/dist/extraction.js +3 -3
  128. package/dist/fallback-llm.d.ts +1 -1
  129. package/dist/{first-start-migration-OOR57AYR.js → first-start-migration-2RQYDIZ7.js} +10 -8
  130. package/dist/first-start-migration-2RQYDIZ7.js.map +1 -0
  131. package/dist/graph-dashboard-diff.d.ts +1 -1
  132. package/dist/graph-dashboard-key.d.ts +1 -1
  133. package/dist/graph-dashboard-parser.d.ts +1 -1
  134. package/dist/graph-edge-reinforcement.d.ts +1 -1
  135. package/dist/graph-snapshot.d.ts +1 -1
  136. package/dist/graph.d.ts +1 -1
  137. package/dist/identity-continuity.d.ts +1 -1
  138. package/dist/importance.d.ts +1 -1
  139. package/dist/index.d.ts +12 -12
  140. package/dist/index.js +44 -44
  141. package/dist/intent.d.ts +1 -1
  142. package/dist/lcm/engine.d.ts +1 -1
  143. package/dist/lcm/index.d.ts +1 -1
  144. package/dist/lcm/tools.d.ts +1 -1
  145. package/dist/lifecycle.d.ts +1 -1
  146. package/dist/live-connectors-runner.d.ts +1 -1
  147. package/dist/local-llm.d.ts +1 -1
  148. package/dist/local-llm.js +2 -1
  149. package/dist/local-model-endpoint.d.ts +1 -1
  150. package/dist/maintenance/memory-governance.d.ts +1 -1
  151. package/dist/mcp-memory-inspector-app.d.ts +13 -11
  152. package/dist/memory-action-policy.d.ts +1 -1
  153. package/dist/memory-cache.d.ts +1 -1
  154. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  155. package/dist/memory-projection-store.d.ts +1 -1
  156. package/dist/memory-provenance.d.ts +1 -1
  157. package/dist/memory-worth-outcomes.d.ts +1 -1
  158. package/dist/models-json.d.ts +1 -1
  159. package/dist/namespaces/migrate.d.ts +2 -2
  160. package/dist/namespaces/migrate.js +6 -6
  161. package/dist/namespaces/principal.d.ts +1 -1
  162. package/dist/namespaces/principal.js +2 -1
  163. package/dist/namespaces/search.d.ts +1 -1
  164. package/dist/namespaces/search.js +4 -4
  165. package/dist/namespaces/storage.d.ts +2 -2
  166. package/dist/namespaces/storage.js +2 -1
  167. package/dist/native-knowledge.d.ts +1 -1
  168. package/dist/operator-toolkit.d.ts +1 -1
  169. package/dist/operator-toolkit.js +11 -11
  170. package/dist/orchestration/compression-guideline-coordinator.d.ts +1 -1
  171. package/dist/orchestration/compression-guideline-coordinator.js +2 -1
  172. package/dist/orchestration/maintenance.d.ts +2 -2
  173. package/dist/orchestration/maintenance.js +6 -5
  174. package/dist/{orchestrator-B4KjaOtY.d.ts → orchestrator-oF0cceBX.d.ts} +143 -18
  175. package/dist/orchestrator.d.ts +8 -6
  176. package/dist/orchestrator.js +21 -19
  177. package/dist/patterns-cli.d.ts +1 -1
  178. package/dist/policy-runtime.d.ts +1 -1
  179. package/dist/provenance.d.ts +1 -1
  180. package/dist/qmd-recall-cache.d.ts +1 -1
  181. package/dist/qmd.d.ts +1 -1
  182. package/dist/recall-disclosure-escalation.d.ts +1 -1
  183. package/dist/recall-explain-renderer.d.ts +1 -1
  184. package/dist/recall-planner-llm.d.ts +1 -1
  185. package/dist/recall-state.d.ts +1 -1
  186. package/dist/recall-tag-filter.d.ts +1 -1
  187. package/dist/recall-xray-cli.d.ts +1 -1
  188. package/dist/recall-xray-renderer.d.ts +1 -1
  189. package/dist/recall-xray.d.ts +1 -1
  190. package/dist/resolve-auth-token.d.ts +1 -1
  191. package/dist/retrieval-agents.d.ts +1 -1
  192. package/dist/retrieval-tiers.d.ts +1 -1
  193. package/dist/routing/engine.d.ts +1 -1
  194. package/dist/routing/store.d.ts +1 -1
  195. package/dist/schemas.d.ts +2 -2
  196. package/dist/search/embed-helper.d.ts +1 -1
  197. package/dist/search/embed-helper.js +2 -2
  198. package/dist/search/factory.d.ts +1 -1
  199. package/dist/search/factory.js +3 -3
  200. package/dist/search/index.d.ts +1 -1
  201. package/dist/search/index.js +3 -3
  202. package/dist/search/lancedb-backend.d.ts +1 -1
  203. package/dist/search/meilisearch-backend.d.ts +1 -1
  204. package/dist/search/noop-backend.d.ts +1 -1
  205. package/dist/search/orama-backend.d.ts +1 -1
  206. package/dist/search/port.d.ts +1 -1
  207. package/dist/search/remote-backend.d.ts +1 -1
  208. package/dist/{semantic-SLAa_prH.d.ts → semantic-DJR8_DMQ.d.ts} +1 -1
  209. package/dist/{semantic-consolidation-CstTvHPo.d.ts → semantic-consolidation-DKGbufYO.d.ts} +1 -1
  210. package/dist/semantic-consolidation.d.ts +2 -2
  211. package/dist/semantic-rule-verifier.d.ts +1 -1
  212. package/dist/session-observer-bands.d.ts +1 -1
  213. package/dist/session-observer-state.d.ts +1 -1
  214. package/dist/shared-context/manager.d.ts +3 -3
  215. package/dist/signal.d.ts +1 -1
  216. package/dist/storage.d.ts +1 -1
  217. package/dist/summarizer.d.ts +1 -1
  218. package/dist/summarizer.js +3 -2
  219. package/dist/summary-snapshot.d.ts +1 -1
  220. package/dist/temporal-supersession.d.ts +1 -1
  221. package/dist/temporal-validity.d.ts +1 -1
  222. package/dist/threading.d.ts +1 -1
  223. package/dist/tier-migration.d.ts +1 -1
  224. package/dist/tier-routing.d.ts +1 -1
  225. package/dist/{tier-stats-3LYQ3VV5.js → tier-stats-KPDIISG7.js} +8 -4
  226. package/dist/tier-stats-KPDIISG7.js.map +1 -0
  227. package/dist/topics.d.ts +1 -1
  228. package/dist/transcript.d.ts +1 -1
  229. package/dist/transfer/types.d.ts +30 -30
  230. package/dist/trust-score-stage.d.ts +1 -1
  231. package/dist/trust-score.d.ts +1 -1
  232. package/dist/{types-VkxElCHR.d.ts → types-C7UCxpuO.d.ts} +1 -1
  233. package/dist/types.d.ts +1 -1
  234. package/dist/utility-runtime.d.ts +1 -1
  235. package/package.json +2 -2
  236. package/src/access-service.ts +61 -56
  237. package/src/active-memory-bridge.ts +2 -1
  238. package/src/admin/admin-surfaces.ts +2 -1
  239. package/src/capabilities.test.ts +375 -0
  240. package/src/capabilities.ts +403 -0
  241. package/src/cli/creation-ledger-commands.ts +2 -2
  242. package/src/cli/research-status-commands.ts +13 -13
  243. package/src/cli.ts +29 -25
  244. package/src/compounding/engine.ts +4 -3
  245. package/src/contradiction/contradiction-scan.ts +4 -3
  246. package/src/embedding-fallback.ts +5 -2
  247. package/src/entity-retrieval.ts +3 -2
  248. package/src/explicit-capture.ts +2 -1
  249. package/src/extraction.ts +6 -3
  250. package/src/local-llm.ts +4 -3
  251. package/src/maintenance/first-start-migration.ts +8 -5
  252. package/src/maintenance/namespace-maintenance-fanout.ts +2 -1
  253. package/src/maintenance/namespace-planner.ts +4 -3
  254. package/src/maintenance/tier-stats.ts +4 -3
  255. package/src/namespaces/catalog.ts +2 -1
  256. package/src/namespaces/migrate.ts +2 -1
  257. package/src/namespaces/principal.ts +6 -5
  258. package/src/namespaces/scope-profiles.ts +2 -1
  259. package/src/namespaces/search.ts +2 -1
  260. package/src/namespaces/storage.ts +4 -3
  261. package/src/operator-toolkit.ts +27 -26
  262. package/src/orchestration/compression-guideline-coordinator.ts +7 -6
  263. package/src/orchestration/lifecycle-policy-coordinator.ts +504 -0
  264. package/src/orchestration/maintenance.ts +8 -4
  265. package/src/orchestration/semantic-consolidation-coordinator.ts +454 -0
  266. package/src/orchestration/tier-migration-coordinator.ts +5 -4
  267. package/src/orchestrator.ts +106 -800
  268. package/src/scopes/scope-plan.ts +3 -2
  269. package/src/search/embed-helper.ts +5 -2
  270. package/src/search/factory.ts +9 -6
  271. package/src/summarizer.ts +3 -2
  272. package/dist/chunk-24D66MMN.js.map +0 -1
  273. package/dist/chunk-646B5ERJ.js.map +0 -1
  274. package/dist/chunk-6TUWSUUD.js.map +0 -1
  275. package/dist/chunk-CGPHMNL4.js.map +0 -1
  276. package/dist/chunk-CX77GNMB.js.map +0 -1
  277. package/dist/chunk-DKT3X5C3.js.map +0 -1
  278. package/dist/chunk-ESF7TRYJ.js.map +0 -1
  279. package/dist/chunk-FFUCCKPN.js.map +0 -1
  280. package/dist/chunk-GGL34GCW.js.map +0 -1
  281. package/dist/chunk-H3MB3F62.js.map +0 -1
  282. package/dist/chunk-HHNSLPX7.js.map +0 -1
  283. package/dist/chunk-J6BH2OBA.js.map +0 -1
  284. package/dist/chunk-KQYGNGON.js.map +0 -1
  285. package/dist/chunk-KSJCXXOU.js.map +0 -1
  286. package/dist/chunk-LUCARK4W.js.map +0 -1
  287. package/dist/chunk-NIZQH6AU.js.map +0 -1
  288. package/dist/chunk-OTQE66IX.js.map +0 -1
  289. package/dist/chunk-OUITHS6V.js.map +0 -1
  290. package/dist/chunk-P3VJCTVE.js.map +0 -1
  291. package/dist/chunk-PLBIPT6I.js.map +0 -1
  292. package/dist/chunk-PMAQRUN4.js.map +0 -1
  293. package/dist/chunk-SYX73XD7.js.map +0 -1
  294. package/dist/chunk-UZYLX7M6.js.map +0 -1
  295. package/dist/chunk-ZQUAVZNG.js.map +0 -1
  296. package/dist/chunk-ZVHRSR2R.js.map +0 -1
  297. package/dist/first-start-migration-OOR57AYR.js.map +0 -1
  298. package/dist/tier-stats-3LYQ3VV5.js.map +0 -1
  299. /package/dist/{chunk-QZHF4BWN.js.map → chunk-AAIHDIMD.js.map} +0 -0
  300. /package/dist/{chunk-FYWUNVFZ.js.map → chunk-E4LYJ7PY.js.map} +0 -0
  301. /package/dist/{chunk-NOU77OHX.js.map → chunk-P6VLG7KE.js.map} +0 -0
  302. /package/dist/{chunk-O4ZIBPIW.js.map → chunk-QNTLWH3T.js.map} +0 -0
  303. /package/dist/{chunk-HJWQJUKQ.js.map → chunk-VOEVVIP3.js.map} +0 -0
  304. /package/dist/{contradiction-scan-HWGEOUDS.js.map → contradiction-scan-2B4AE4TI.js.map} +0 -0
@@ -7,6 +7,7 @@ import { StorageManager } from "../storage.js";
7
7
  import type { ContinuityIncidentRecord, PluginConfig } from "../types.js";
8
8
  import { resolveSharedContextDir, SharedFeedbackEntrySchema, type SharedFeedbackEntry } from "../shared-context/manager.js";
9
9
  import { parseContinuityImprovementLoops } from "../identity-continuity.js";
10
+ import { resolveQmdCapabilities, type QmdConfigProjection } from "../capabilities.js";
10
11
 
11
12
  type MistakesFile = {
12
13
  version?: number;
@@ -369,7 +370,7 @@ export interface TierMigrationCycleBudget {
369
370
  }
370
371
 
371
372
  export function defaultTierMigrationCycleBudget(
372
- config: Pick<PluginConfig, "qmdTierAutoBackfillEnabled">,
373
+ config: QmdConfigProjection,
373
374
  trigger: TierMigrationCycleTrigger,
374
375
  ): TierMigrationCycleBudget {
375
376
  if (trigger === "extraction") {
@@ -380,11 +381,11 @@ export function defaultTierMigrationCycleBudget(
380
381
  minIntervalMs: 60_000,
381
382
  };
382
383
  }
383
- const limit = config.qmdTierAutoBackfillEnabled ? 200 : 50;
384
+ const limit = resolveQmdCapabilities(config).qmdTierAutoBackfill ? 200 : 50;
384
385
  return {
385
386
  limit,
386
387
  scanLimit: limit * 4,
387
- minIntervalMs: config.qmdTierAutoBackfillEnabled ? 120_000 : 300_000,
388
+ minIntervalMs: resolveQmdCapabilities(config).qmdTierAutoBackfill ? 120_000 : 300_000,
388
389
  };
389
390
  }
390
391
 
@@ -14,6 +14,7 @@
14
14
  * 4. Cap per-run work at maxPairsPerRun.
15
15
  */
16
16
 
17
+ import { resolveNamespaceCapabilities } from "../capabilities.js";
17
18
  import type { StorageManager } from "../storage.js";
18
19
  import type { PluginConfig, MemoryFile, MemoryStatus } from "../types.js";
19
20
  import type { SemanticDedupLookup } from "../dedup/semantic.js";
@@ -107,7 +108,7 @@ export async function runContradictionScan(deps: ScanDependencies): Promise<Scan
107
108
  }
108
109
 
109
110
  const { storage: scanStorage, namespace } = await resolveScanStorage(deps, requestedNamespace);
110
- if (config.namespacesEnabled && namespace !== undefined && isDefaultNamespaceScan(config, requestedNamespace, namespace)) {
111
+ if (resolveNamespaceCapabilities(config).namespaces && namespace !== undefined && isDefaultNamespaceScan(config, requestedNamespace, namespace)) {
111
112
  const migrated = migrateUnscopedPairsToNamespace(memoryDir, namespace, { cooldownDays: scanConfig.cooldownDays });
112
113
  if (migrated > 0) {
113
114
  log.info("[contradiction-scan] migrated %d legacy unscoped review pairs to namespace %s", migrated, namespace);
@@ -382,7 +383,7 @@ async function resolveScanStorage(
382
383
  deps: ScanDependencies,
383
384
  namespace: string | undefined,
384
385
  ): Promise<ScanStorageResolution> {
385
- if (!deps.config.namespacesEnabled) {
386
+ if (!resolveNamespaceCapabilities(deps.config).namespaces) {
386
387
  const defaultNamespace = normalizeScanNamespace(deps.config.defaultNamespace);
387
388
  if (namespace && namespace !== defaultNamespace) {
388
389
  throw new Error(`unsupported namespace: ${namespace}`);
@@ -427,7 +428,7 @@ function isStorageManagerLike(value: unknown): value is StorageManager {
427
428
 
428
429
  function fallbackResolvedNamespace(deps: ScanDependencies, namespace: string | undefined): string | undefined {
429
430
  if (namespace) return namespace;
430
- return deps.config.namespacesEnabled ? deps.config.defaultNamespace : undefined;
431
+ return resolveNamespaceCapabilities(deps.config).namespaces ? deps.config.defaultNamespace : undefined;
431
432
  }
432
433
 
433
434
  function isDefaultNamespaceScan(
@@ -1,7 +1,10 @@
1
1
  import path from "node:path";
2
2
  import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
3
3
  import { log } from "./logger.js";
4
- import { resolveMemoryLifecycleCapabilities } from "./capabilities.js";
4
+ import {
5
+ resolveMemoryLifecycleCapabilities,
6
+ resolveLocalLlmCapabilities,
7
+ } from "./capabilities.js";
5
8
  import { readEnvVar } from "./runtime/env.js";
6
9
  import type { PluginConfig } from "./types.js";
7
10
  import {
@@ -461,7 +464,7 @@ export class EmbeddingFallback {
461
464
  }
462
465
 
463
466
  private createLocalProvider(): ProviderConfig | null {
464
- if (!this.config.localLlmEnabled || !this.config.localLlmUrl) return null;
467
+ if (!resolveLocalLlmCapabilities(this.config).localLlm || !this.config.localLlmUrl) return null;
465
468
  const base = this.config.localLlmUrl.replace(/\/$/, "");
466
469
  const endpoint = /\/v1$/i.test(base) ? `${base}/embeddings` : `${base}/v1/embeddings`;
467
470
  const headers: Record<string, string> = {
@@ -1,3 +1,4 @@
1
+ import { resolveNamespaceCapabilities } from "./capabilities.js";
1
2
  import { createHash } from "node:crypto";
2
3
  import { sanitizeMemoryContent } from "./sanitize.js";
3
4
  import { mkdir, readFile, writeFile } from "node:fs/promises";
@@ -329,7 +330,7 @@ async function readNativeChunks(
329
330
  workspaceDir: config.workspaceDir,
330
331
  memoryDir: config.memoryDir,
331
332
  config: config.nativeKnowledge,
332
- recallNamespaces: config.namespacesEnabled ? recallNamespaces : undefined,
333
+ recallNamespaces: resolveNamespaceCapabilities(config).namespaces ? recallNamespaces : undefined,
333
334
  defaultNamespace: config.defaultNamespace,
334
335
  }).catch(() => []);
335
336
  }
@@ -341,7 +342,7 @@ async function resolveEntityIndexStorages(
341
342
  namespaceStorage?: (namespace: string) => Promise<StorageManager>,
342
343
  ): Promise<StorageManager[]> {
343
344
  if (
344
- !config.namespacesEnabled ||
345
+ !resolveNamespaceCapabilities(config).namespaces ||
345
346
  !namespaceStorage ||
346
347
  !recallNamespaces ||
347
348
  recallNamespaces.length === 0
@@ -1,3 +1,4 @@
1
+ import { resolveNamespaceCapabilities } from "./capabilities.js";
1
2
  import { randomUUID } from "node:crypto";
2
3
  import type { Orchestrator } from "./orchestrator.js";
3
4
  import { isSafeRouteNamespace } from "./routing/engine.js";
@@ -175,7 +176,7 @@ function resolveExplicitCaptureNamespace(
175
176
  ): string | undefined {
176
177
  const normalized = asTrimmed(namespace);
177
178
  if (!normalized) return undefined;
178
- if (!orchestrator.config.namespacesEnabled) {
179
+ if (!resolveNamespaceCapabilities(orchestrator.config).namespaces) {
179
180
  if (normalized !== orchestrator.config.defaultNamespace) {
180
181
  throw new Error(`unsupported namespace: ${normalized}`);
181
182
  }
package/src/extraction.ts CHANGED
@@ -38,7 +38,10 @@ import { normalizeProcedureSteps } from "./procedural/procedure-types.js";
38
38
  import { normalizeReasoningTrace } from "./reasoning-trace-types.js";
39
39
  import { looksLikeMechanicalTelemetryTranscript } from "./telemetry-transcript.js";
40
40
  import { buildFactProvenance, type ProvenanceTurnInput } from "./provenance.js";
41
- import { resolveMemoryLifecycleCapabilities } from "./capabilities.js";
41
+ import {
42
+ resolveMemoryLifecycleCapabilities,
43
+ resolveLocalLlmCapabilities,
44
+ } from "./capabilities.js";
42
45
 
43
46
  type ExtractionQuestion = ExtractionResult["questions"][number];
44
47
  type ExtractedFactResult = ExtractionResult["facts"][number];
@@ -152,7 +155,7 @@ export class ExtractionEngine {
152
155
  * Disabled when gateway model source is active (gateway chain replaces local).
153
156
  */
154
157
  private get shouldUseLocalLlm(): boolean {
155
- return this.config.localLlmEnabled && !this.useGatewayModelSource;
158
+ return resolveLocalLlmCapabilities(this.config).localLlm && !this.useGatewayModelSource;
156
159
  }
157
160
 
158
161
  /**
@@ -1114,7 +1117,7 @@ export class ExtractionEngine {
1114
1117
  // --- profiling instrumentation ---
1115
1118
  const extractionTraceId = this.profiler.startTrace("extraction", undefined, {
1116
1119
  model: this.config.model,
1117
- localLlm: this.config.localLlmEnabled,
1120
+ localLlm: resolveLocalLlmCapabilities(this.config).localLlm,
1118
1121
  });
1119
1122
  this.profiler.startSpan("total", extractionTraceId);
1120
1123
 
package/src/local-llm.ts CHANGED
@@ -5,6 +5,7 @@ import os from "node:os";
5
5
  import type { ModelRegistry } from "./model-registry.js";
6
6
  import { launchProcessSync } from "./runtime/child-process.js";
7
7
  import { mergeEnv, readEnvVar } from "./runtime/env.js";
8
+ import { resolveLocalLlmCapabilities } from "./capabilities.js";
8
9
 
9
10
  /** Trim trailing slash characters without backtracking regex. */
10
11
  function trimTrailingSlashes(s: string): string {
@@ -934,7 +935,7 @@ export class LocalLlmClient {
934
935
  queueMeta?: { priority: LocalLlmRequestPriority; enqueuedAtMs: number },
935
936
  ): Promise<LocalLlmChatCompletionResult | null> {
936
937
  log.debug(
937
- `local LLM chatCompletion: localLlmEnabled=${this.config.localLlmEnabled}, model=${this.config.localLlmModel}`,
938
+ `local LLM chatCompletion: localLlmEnabled=${resolveLocalLlmCapabilities(this.config).localLlm}, model=${this.config.localLlmModel}`,
938
939
  );
939
940
 
940
941
  const operation = options.operation ?? "unspecified";
@@ -1389,7 +1390,7 @@ export class LocalLlmClient {
1389
1390
  messages: Array<{ role: string; content: string }>,
1390
1391
  options: LocalLlmChatCompletionOptions = {},
1391
1392
  ): Promise<LocalLlmChatCompletionResult | null> {
1392
- if (!this.config.localLlmEnabled) {
1393
+ if (!resolveLocalLlmCapabilities(this.config).localLlm) {
1393
1394
  log.debug("local LLM: disabled, returning null");
1394
1395
  return null;
1395
1396
  }
@@ -1444,7 +1445,7 @@ export class LocalLlmClient {
1444
1445
  operationName: string
1445
1446
  ): Promise<T> {
1446
1447
  // Try local LLM first if enabled
1447
- if (this.config.localLlmEnabled) {
1448
+ if (resolveLocalLlmCapabilities(this.config).localLlm) {
1448
1449
  const localResult = await localOperation();
1449
1450
  if (localResult !== null) {
1450
1451
  log.debug(`${operationName}: used local LLM`);
@@ -18,7 +18,10 @@
18
18
 
19
19
  import path from "node:path";
20
20
  import { access, mkdir, readFile, unlink, writeFile } from "node:fs/promises";
21
- import { resolveMemoryLifecycleCapabilities } from "../capabilities.js";
21
+ import {
22
+ resolveMemoryLifecycleCapabilities,
23
+ resolveQmdCapabilities,
24
+ resolveUtilityLearningCapabilities} from "../capabilities.js";
22
25
  import type { StorageManager } from "../storage.js";
23
26
  import type { PluginConfig } from "../types.js";
24
27
  import {
@@ -135,15 +138,15 @@ async function clearQmdRefreshPending(memoryDir: string): Promise<void> {
135
138
 
136
139
  async function buildTierRoutingPolicy(config: PluginConfig): Promise<TierRoutingPolicy> {
137
140
  const basePolicy: TierRoutingPolicy = {
138
- enabled: config.qmdTierMigrationEnabled,
141
+ enabled: resolveQmdCapabilities(config).qmdTierMigration,
139
142
  demotionMinAgeDays: config.qmdTierDemotionMinAgeDays,
140
143
  demotionValueThreshold: config.qmdTierDemotionValueThreshold,
141
144
  promotionValueThreshold: config.qmdTierPromotionValueThreshold,
142
145
  };
143
146
  const runtime = await loadUtilityRuntimeValues({
144
147
  memoryDir: config.memoryDir,
145
- memoryUtilityLearningEnabled: config.memoryUtilityLearningEnabled,
146
- promotionByOutcomeEnabled: config.promotionByOutcomeEnabled,
148
+ memoryUtilityLearningEnabled: resolveUtilityLearningCapabilities(config).memoryUtilityLearning,
149
+ promotionByOutcomeEnabled: resolveUtilityLearningCapabilities(config).promotionByOutcome,
147
150
  });
148
151
  return applyUtilityPromotionRuntimePolicy(basePolicy, runtime);
149
152
  }
@@ -207,7 +210,7 @@ export async function runFirstStartMigration(
207
210
  };
208
211
  }
209
212
 
210
- if (!config.qmdTierMigrationEnabled) {
213
+ if (!resolveQmdCapabilities(config).qmdTierMigration) {
211
214
  return {
212
215
  skipped: true,
213
216
  skipReason: "qmdTierMigrationEnabled is false",
@@ -24,6 +24,7 @@
24
24
  * - Per-namespace locks prevent duplicate concurrent runs (planner-provided).
25
25
  */
26
26
 
27
+ import { resolveNamespaceCapabilities } from "../capabilities.js";
27
28
  import type { NamespaceCatalog } from "../namespaces/catalog.js";
28
29
  import type { PluginConfig } from "../types.js";
29
30
  import {
@@ -262,7 +263,7 @@ export async function summarizeNamespaceMaintenanceHealth(
262
263
  return {
263
264
  generatedAt,
264
265
  fanoutEnabled: config.maintenanceNamespaceFanoutEnabled !== false,
265
- namespacesEnabled: config.namespacesEnabled,
266
+ namespacesEnabled: resolveNamespaceCapabilities(config).namespaces,
266
267
  maxNamespacesPerCycle: config.maintenanceMaxNamespacesPerCycle,
267
268
  jobs,
268
269
  totalRan,
@@ -1,3 +1,4 @@
1
+ import { resolveNamespaceCapabilities } from "../capabilities.js";
1
2
  import { createHash, randomUUID } from "node:crypto";
2
3
  import type { Dirent } from "node:fs";
3
4
  import { lstat, mkdir, open, readFile, readdir, rename, rm, rmdir, stat, utimes, writeFile } from "node:fs/promises";
@@ -211,7 +212,7 @@ export async function planNamespaceMaintenance(
211
212
  // policies) would make a mutating maintenance job process the SAME corpus
212
213
  // once per configured name. The #1500 contract is "namespaces disabled:
213
214
  // maintain the current default storage only," so collapse to the default.
214
- const configured = config.namespacesEnabled
215
+ const configured = resolveNamespaceCapabilities(config).namespaces
215
216
  ? getConfiguredNamespaces(config)
216
217
  : [config.defaultNamespace.trim()].filter(Boolean);
217
218
  const byNamespace = new Map<string, NamespaceMaintenanceCandidate>();
@@ -226,7 +227,7 @@ export async function planNamespaceMaintenance(
226
227
  });
227
228
  }
228
229
 
229
- if (config.namespacesEnabled && config.maintenanceNamespaceFanoutEnabled !== false) {
230
+ if (resolveNamespaceCapabilities(config).namespaces && config.maintenanceNamespaceFanoutEnabled !== false) {
230
231
  const configuredSet = new Set(configured);
231
232
  try {
232
233
  const records = options.catalog?.enabled ? await options.catalog.listNamespaces() : [];
@@ -267,7 +268,7 @@ export async function planNamespaceMaintenance(
267
268
  detail: error instanceof Error ? error.message : String(error),
268
269
  });
269
270
  }
270
- } else if (config.namespacesEnabled) {
271
+ } else if (resolveNamespaceCapabilities(config).namespaces) {
271
272
  skipped.push({
272
273
  namespace: "*",
273
274
  reason: "fanout_disabled",
@@ -25,6 +25,7 @@ import {
25
25
  type TierRoutingPolicy,
26
26
  type TierTransitionDecision,
27
27
  } from "../tier-routing.js";
28
+ import { resolveQmdCapabilities, resolveUtilityLearningCapabilities} from "../capabilities.js";
28
29
  import {
29
30
  applyUtilityPromotionRuntimePolicy,
30
31
  loadUtilityRuntimeValues,
@@ -82,15 +83,15 @@ async function tierRoutingPolicyFromConfig(
82
83
  config: PluginConfig,
83
84
  ): Promise<TierRoutingPolicy> {
84
85
  const basePolicy: TierRoutingPolicy = {
85
- enabled: config.qmdTierMigrationEnabled,
86
+ enabled: resolveQmdCapabilities(config).qmdTierMigration,
86
87
  demotionMinAgeDays: config.qmdTierDemotionMinAgeDays,
87
88
  demotionValueThreshold: config.qmdTierDemotionValueThreshold,
88
89
  promotionValueThreshold: config.qmdTierPromotionValueThreshold,
89
90
  };
90
91
  const runtime = await loadUtilityRuntimeValues({
91
92
  memoryDir: config.memoryDir,
92
- memoryUtilityLearningEnabled: config.memoryUtilityLearningEnabled,
93
- promotionByOutcomeEnabled: config.promotionByOutcomeEnabled,
93
+ memoryUtilityLearningEnabled: resolveUtilityLearningCapabilities(config).memoryUtilityLearning,
94
+ promotionByOutcomeEnabled: resolveUtilityLearningCapabilities(config).promotionByOutcome,
94
95
  });
95
96
  return applyUtilityPromotionRuntimePolicy(basePolicy, runtime);
96
97
  }
@@ -1,3 +1,4 @@
1
+ import { resolveNamespaceCapabilities } from "../capabilities.js";
1
2
  import path from "node:path";
2
3
  import type { Dirent } from "node:fs";
3
4
  import {
@@ -181,7 +182,7 @@ const MEMORY_DATA_CHILDREN = [
181
182
  function isCatalogEnabled(config: PluginConfig): boolean {
182
183
  // Inert unless namespaces are enabled. namespaceCatalogEnabled defaults to
183
184
  // true (undefined => enabled) but is only honored when namespacesEnabled.
184
- if (config.namespacesEnabled !== true) return false;
185
+ if (resolveNamespaceCapabilities(config).namespaces !== true) return false;
185
186
  return (config as { namespaceCatalogEnabled?: boolean }).namespaceCatalogEnabled !== false;
186
187
  }
187
188
 
@@ -1,3 +1,4 @@
1
+ import { resolveNamespaceCapabilities } from "../capabilities.js";
1
2
  import path from "node:path";
2
3
  import { access, lstat, mkdir, readdir, realpath, rename, rmdir } from "node:fs/promises";
3
4
  import type { PluginConfig } from "../types.js";
@@ -146,7 +147,7 @@ export async function runNamespaceMigration(options: {
146
147
  dryRun?: boolean;
147
148
  renameFn?: typeof rename;
148
149
  }): Promise<NamespaceMigrationReport> {
149
- if (!options.config.namespacesEnabled) {
150
+ if (!resolveNamespaceCapabilities(options.config).namespaces) {
150
151
  throw new Error("Namespaces are disabled.");
151
152
  }
152
153
 
@@ -1,3 +1,4 @@
1
+ import { resolveNamespaceCapabilities } from "../capabilities.js";
1
2
  import type { PluginConfig } from "../types.js";
2
3
  import { isLikelyUnsafeRegex } from "../routing/engine.js";
3
4
 
@@ -13,7 +14,7 @@ function compileSafePrincipalRegex(pattern: string): RegExp | null {
13
14
  }
14
15
 
15
16
  export function resolvePrincipal(sessionKey: string | undefined, config: PluginConfig): string | undefined {
16
- if (!config.namespacesEnabled) return "default";
17
+ if (!resolveNamespaceCapabilities(config).namespaces) return "default";
17
18
  const sk = typeof sessionKey === "string" && sessionKey.trim().length > 0
18
19
  ? sessionKey
19
20
  : "";
@@ -51,7 +52,7 @@ export function resolvePrincipal(sessionKey: string | undefined, config: PluginC
51
52
  }
52
53
 
53
54
  export function canReadNamespace(principal: string | undefined, namespace: string, config: PluginConfig): boolean {
54
- if (!config.namespacesEnabled) return true;
55
+ if (!resolveNamespaceCapabilities(config).namespaces) return true;
55
56
  if (!principal) return false;
56
57
  const policy = config.namespacePolicies.find((p) => p.name === namespace);
57
58
  if (!policy) return namespace === config.defaultNamespace || namespace === config.sharedNamespace;
@@ -59,7 +60,7 @@ export function canReadNamespace(principal: string | undefined, namespace: strin
59
60
  }
60
61
 
61
62
  export function canWriteNamespace(principal: string | undefined, namespace: string, config: PluginConfig): boolean {
62
- if (!config.namespacesEnabled) return true;
63
+ if (!resolveNamespaceCapabilities(config).namespaces) return true;
63
64
  if (!principal) return false;
64
65
  const policy = config.namespacePolicies.find((p) => p.name === namespace);
65
66
  if (!policy) return namespace === config.defaultNamespace;
@@ -74,7 +75,7 @@ export function canWriteNamespace(principal: string | undefined, namespace: stri
74
75
  * - Otherwise use config.defaultNamespace.
75
76
  */
76
77
  export function defaultNamespaceForPrincipal(principal: string | undefined, config: PluginConfig): string {
77
- if (!config.namespacesEnabled) return config.defaultNamespace;
78
+ if (!resolveNamespaceCapabilities(config).namespaces) return config.defaultNamespace;
78
79
  if (!principal) return config.defaultNamespace;
79
80
  const exists = config.namespacePolicies.some((p) => p.name === principal);
80
81
  return exists ? principal : config.defaultNamespace;
@@ -82,7 +83,7 @@ export function defaultNamespaceForPrincipal(principal: string | undefined, conf
82
83
 
83
84
  export function recallNamespacesForPrincipal(principal: string | undefined, config: PluginConfig): string[] {
84
85
  const out: string[] = [];
85
- if (!config.namespacesEnabled) return [config.defaultNamespace];
86
+ if (!resolveNamespaceCapabilities(config).namespaces) return [config.defaultNamespace];
86
87
  if (!principal) return out;
87
88
 
88
89
  const selfNs = defaultNamespaceForPrincipal(principal, config);
@@ -1,3 +1,4 @@
1
+ import { resolveNamespaceCapabilities } from "../capabilities.js";
1
2
  import { createHash } from "node:crypto";
2
3
 
3
4
  import { combineNamespaces, type CodingNamespaceOverlay } from "../coding/coding-namespace.js";
@@ -326,7 +327,7 @@ export function resolveScopeProfilePlan(
326
327
  options: ResolveScopeProfilePlanOptions,
327
328
  ): ResolvedScopeProfilePlan | null {
328
329
  const active = activeScopeProfile(options.config);
329
- if (!active || !options.config.namespacesEnabled) return null;
330
+ if (!active || !resolveNamespaceCapabilities(options.config).namespaces) return null;
330
331
 
331
332
  const baseNamespace = scopeProfileSelfNamespace(options.principal, options.config);
332
333
  const layerIds = Array.from(
@@ -1,3 +1,4 @@
1
+ import { resolveNamespaceCapabilities } from "../capabilities.js";
1
2
  import path from "node:path";
2
3
  import type { PluginConfig, QmdSearchResult } from "../types.js";
3
4
  import type {
@@ -350,7 +351,7 @@ export class NamespaceSearchRouter {
350
351
  const useLegacyDefaultCollection =
351
352
  key === this.config.defaultNamespace && storage.dir === this.config.memoryDir;
352
353
  const filtersNestedNamespaces =
353
- this.config.namespacesEnabled === true && useLegacyDefaultCollection;
354
+ resolveNamespaceCapabilities(this.config).namespaces === true && useLegacyDefaultCollection;
354
355
  const rootHostEmbeddingScope =
355
356
  (this.config as NamespaceScopedSearchConfig).hostEmbeddingProviderScope ??
356
357
  this.config.memoryDir;
@@ -1,3 +1,4 @@
1
+ import { resolveNamespaceCapabilities } from "../capabilities.js";
1
2
  import path from "node:path";
2
3
  import { access, lstat, readdir } from "node:fs/promises";
3
4
  import { isSafeRouteNamespace } from "../routing/engine.js";
@@ -139,7 +140,7 @@ export interface NamespaceStorageRouterHooks {
139
140
  * the default migrate into that tokenized/legacy-named dir.
140
141
  */
141
142
  export async function resolveDefaultNamespaceRoot(config: PluginConfig): Promise<string> {
142
- if (!config.namespacesEnabled) {
143
+ if (!resolveNamespaceCapabilities(config).namespaces) {
143
144
  return config.memoryDir;
144
145
  }
145
146
 
@@ -183,7 +184,7 @@ export async function resolveNamespaceStorageRoot(
183
184
  config: PluginConfig,
184
185
  namespace: string,
185
186
  ): Promise<string> {
186
- if (!config.namespacesEnabled) return config.memoryDir;
187
+ if (!resolveNamespaceCapabilities(config).namespaces) return config.memoryDir;
187
188
  // Compare on NORMALIZED identity so a whitespace-padded configured default name
188
189
  // still routes to the default root rather than a tokenized non-default dir
189
190
  // (NH-FH). The catalog keys records by the same normalized identity.
@@ -257,7 +258,7 @@ export class NamespaceStorageRouter {
257
258
 
258
259
  private async namespaceRoot(namespace: string): Promise<string> {
259
260
  // NOTE: only used after defaultNamespaceRoot() resolution.
260
- if (!this.config.namespacesEnabled) return this.config.memoryDir;
261
+ if (!resolveNamespaceCapabilities(this.config).namespaces) return this.config.memoryDir;
261
262
  if (normalizeNamespaceIdentity(namespace) === this.defaultNamespaceIdentity) {
262
263
  return this.defaultNsRootResolved ?? this.config.memoryDir;
263
264
  }
@@ -28,7 +28,8 @@ import {
28
28
  resolveAccessSetupCapabilities,
29
29
  resolveCapabilities,
30
30
  resolveGraphConstructionCapabilities,
31
- } from "./capabilities.js";
31
+ resolveQmdCapabilities,
32
+ resolveEvalCapabilities} from "./capabilities.js";
32
33
  import {
33
34
  analyzeSessionIntegrity,
34
35
  applySessionRepair,
@@ -742,7 +743,7 @@ export async function runOperatorSetup(options: OperatorSetupOptions): Promise<O
742
743
  await mkdir(options.orchestrator.config.workspaceDir, { recursive: true });
743
744
 
744
745
  const qmdAvailable = await options.orchestrator.qmd.probe();
745
- const collectionState = options.orchestrator.config.qmdEnabled
746
+ const collectionState = resolveQmdCapabilities(options.orchestrator.config).qmd
746
747
  ? await options.orchestrator.qmd.ensureCollection(
747
748
  options.orchestrator.config.memoryDir,
748
749
  options.orchestrator.config.qmdCollection,
@@ -813,7 +814,7 @@ export async function runOperatorSetup(options: OperatorSetupOptions): Promise<O
813
814
  workspaceDir: options.orchestrator.config.workspaceDir,
814
815
  directories,
815
816
  qmd: {
816
- enabled: options.orchestrator.config.qmdEnabled,
817
+ enabled: resolveQmdCapabilities(options.orchestrator.config).qmd,
817
818
  available: qmdAvailable,
818
819
  collectionState,
819
820
  debugStatus: options.orchestrator.qmd.debugStatus(),
@@ -949,12 +950,12 @@ async function buildOperatorConfigReviewReport(input: {
949
950
  }));
950
951
  }
951
952
 
952
- if (config.qmdEnabled && config.qmdDaemonEnabled === false) {
953
+ if (resolveQmdCapabilities(config).qmd && resolveQmdCapabilities(config).qmdDaemon === false) {
953
954
  findings.push(buildConfigReviewFinding({
954
955
  key: "qmd_daemon",
955
956
  status: "recommend",
956
957
  setting: "qmdDaemonEnabled",
957
- currentValue: config.qmdDaemonEnabled,
958
+ currentValue: resolveQmdCapabilities(config).qmdDaemon,
958
959
  defaultValue: true,
959
960
  recommendedValue: true,
960
961
  summary: "Enable the QMD daemon path when QMD powers recall.",
@@ -991,12 +992,12 @@ async function buildOperatorConfigReviewReport(input: {
991
992
  }));
992
993
  }
993
994
 
994
- if (searchBackend === "qmd" && config.qmdEnabled === false) {
995
+ if (searchBackend === "qmd" && resolveQmdCapabilities(config).qmd === false) {
995
996
  findings.push(buildConfigReviewFinding({
996
997
  key: "qmd_search_backend_disabled",
997
998
  status: "problem",
998
999
  setting: "qmdEnabled",
999
- currentValue: config.qmdEnabled,
1000
+ currentValue: resolveQmdCapabilities(config).qmd,
1000
1001
  defaultValue: true,
1001
1002
  recommendedValue: true,
1002
1003
  summary: "QMD search is selected but QMD is disabled.",
@@ -1005,12 +1006,12 @@ async function buildOperatorConfigReviewReport(input: {
1005
1006
  }));
1006
1007
  }
1007
1008
 
1008
- if (config.qmdColdTierEnabled === true && config.qmdEnabled === false) {
1009
+ if (resolveQmdCapabilities(config).qmdColdTier === true && resolveQmdCapabilities(config).qmd === false) {
1009
1010
  findings.push(buildConfigReviewFinding({
1010
1011
  key: "qmd_cold_tier_requires_qmd",
1011
1012
  status: "problem",
1012
1013
  setting: "qmdEnabled",
1013
- currentValue: config.qmdEnabled,
1014
+ currentValue: resolveQmdCapabilities(config).qmd,
1014
1015
  defaultValue: true,
1015
1016
  recommendedValue: true,
1016
1017
  summary: "Cold-tier QMD recall is enabled while QMD itself is disabled.",
@@ -1019,12 +1020,12 @@ async function buildOperatorConfigReviewReport(input: {
1019
1020
  }));
1020
1021
  }
1021
1022
 
1022
- if (config.qmdTierMigrationEnabled && config.qmdColdTierEnabled !== true) {
1023
+ if (resolveQmdCapabilities(config).qmdTierMigration && resolveQmdCapabilities(config).qmdColdTier !== true) {
1023
1024
  findings.push(buildConfigReviewFinding({
1024
1025
  key: "qmd_tier_migration_requires_cold_tier",
1025
1026
  status: "problem",
1026
1027
  setting: "qmdColdTierEnabled",
1027
- currentValue: config.qmdColdTierEnabled,
1028
+ currentValue: resolveQmdCapabilities(config).qmdColdTier,
1028
1029
  defaultValue: false,
1029
1030
  recommendedValue: true,
1030
1031
  summary: "Hot/cold tier migration is enabled without the cold tier itself.",
@@ -1033,12 +1034,12 @@ async function buildOperatorConfigReviewReport(input: {
1033
1034
  }));
1034
1035
  }
1035
1036
 
1036
- if (resolveIndexingCapabilities(config).conversationIndex && config.conversationIndexBackend === "qmd" && config.qmdEnabled === false) {
1037
+ if (resolveIndexingCapabilities(config).conversationIndex && config.conversationIndexBackend === "qmd" && resolveQmdCapabilities(config).qmd === false) {
1037
1038
  findings.push(buildConfigReviewFinding({
1038
1039
  key: "conversation_index_qmd_requires_qmd",
1039
1040
  status: "problem",
1040
1041
  setting: "qmdEnabled",
1041
- currentValue: config.qmdEnabled,
1042
+ currentValue: resolveQmdCapabilities(config).qmd,
1042
1043
  defaultValue: true,
1043
1044
  recommendedValue: true,
1044
1045
  summary: "The conversation index is configured for QMD while QMD is disabled.",
@@ -1063,8 +1064,8 @@ async function buildOperatorConfigReviewReport(input: {
1063
1064
  profile: {
1064
1065
  memoryOsPreset: config.memoryOsPreset,
1065
1066
  searchBackend,
1066
- qmdEnabled: config.qmdEnabled,
1067
- qmdDaemonEnabled: config.qmdDaemonEnabled,
1067
+ qmdEnabled: resolveQmdCapabilities(config).qmd,
1068
+ qmdDaemonEnabled: resolveQmdCapabilities(config).qmdDaemon,
1068
1069
  nativeKnowledgeEnabled: config.nativeKnowledge?.enabled === true,
1069
1070
  fileHygieneEnabled: config.fileHygiene?.enabled === true,
1070
1071
  conversationIndexEnabled: resolveIndexingCapabilities(config).conversationIndex,
@@ -1145,12 +1146,12 @@ export async function runOperatorDoctor(options: OperatorDoctorOptions): Promise
1145
1146
  });
1146
1147
 
1147
1148
  const qmdAvailable = await options.orchestrator.qmd.probe();
1148
- const collectionState = config.qmdEnabled
1149
+ const collectionState = resolveQmdCapabilities(config).qmd
1149
1150
  ? await options.orchestrator.qmd.ensureCollection(config.memoryDir, config.qmdCollection)
1150
1151
  : "skipped";
1151
1152
  checks.push({
1152
1153
  key: "qmd",
1153
- status: !config.qmdEnabled
1154
+ status: !resolveQmdCapabilities(config).qmd
1154
1155
  ? "warn"
1155
1156
  : !qmdAvailable
1156
1157
  ? "error"
@@ -1159,12 +1160,12 @@ export async function runOperatorDoctor(options: OperatorDoctorOptions): Promise
1159
1160
  : collectionState === "missing"
1160
1161
  ? "error"
1161
1162
  : "warn",
1162
- summary: !config.qmdEnabled
1163
+ summary: !resolveQmdCapabilities(config).qmd
1163
1164
  ? "QMD is disabled in config."
1164
1165
  : qmdAvailable
1165
1166
  ? `QMD is reachable (${collectionState}).`
1166
1167
  : "QMD is not currently reachable.",
1167
- remediation: !config.qmdEnabled
1168
+ remediation: !resolveQmdCapabilities(config).qmd
1168
1169
  ? "Enable `qmdEnabled` if you expect hybrid search."
1169
1170
  : !qmdAvailable
1170
1171
  ? "Ensure the `qmd` binary is installed and on PATH, or set `qmdPath`."
@@ -2262,17 +2263,17 @@ export async function runBenchmarkRecall(options: BenchmarkRecallOptions): Promi
2262
2263
  const status = await getEvalHarnessStatus({
2263
2264
  memoryDir: options.config.memoryDir,
2264
2265
  evalStoreDir: options.config.evalStoreDir,
2265
- enabled: options.config.evalHarnessEnabled,
2266
- shadowModeEnabled: options.config.evalShadowModeEnabled,
2267
- baselineSnapshotsEnabled: options.config.benchmarkBaselineSnapshotsEnabled,
2268
- 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,
2269
2270
  });
2270
2271
 
2271
2272
  if (options.createSnapshot && options.snapshotId) {
2272
2273
  const snapshot = await createEvalBaselineSnapshot({
2273
2274
  memoryDir: options.config.memoryDir,
2274
2275
  evalStoreDir: options.config.evalStoreDir,
2275
- baselineSnapshotsEnabled: options.config.benchmarkBaselineSnapshotsEnabled,
2276
+ baselineSnapshotsEnabled: resolveEvalCapabilities(options.config).benchmarkBaselineSnapshots,
2276
2277
  snapshotId: options.snapshotId,
2277
2278
  notes: options.snapshotNotes,
2278
2279
  gitRef: options.gitRef,
@@ -2308,7 +2309,7 @@ export async function runBenchmarkRecall(options: BenchmarkRecallOptions): Promi
2308
2309
  const baselineReport = await runEvalBaselineDeltaReport({
2309
2310
  memoryDir: options.config.memoryDir,
2310
2311
  evalStoreDir: options.config.evalStoreDir,
2311
- benchmarkDeltaReporterEnabled: options.config.benchmarkDeltaReporterEnabled,
2312
+ benchmarkDeltaReporterEnabled: resolveEvalCapabilities(options.config).benchmarkDeltaReporter,
2312
2313
  snapshotId: options.snapshotId,
2313
2314
  });
2314
2315
  return {
@@ -2322,7 +2323,7 @@ export async function runBenchmarkRecall(options: BenchmarkRecallOptions): Promi
2322
2323
 
2323
2324
  if (options.validatePath) {
2324
2325
  const validate = await validateEvalBenchmarkPack(options.validatePath, {
2325
- memoryRedTeamBenchEnabled: options.config.memoryRedTeamBenchEnabled,
2326
+ memoryRedTeamBenchEnabled: resolveEvalCapabilities(options.config).memoryRedTeamBench,
2326
2327
  });
2327
2328
  return {
2328
2329
  schemaVersion: 1,