@soleri/core 9.2.0 → 9.3.1

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 (316) hide show
  1. package/data/flows/build.flow.yaml +8 -9
  2. package/data/flows/deliver.flow.yaml +9 -10
  3. package/data/flows/design.flow.yaml +3 -4
  4. package/data/flows/enhance.flow.yaml +5 -6
  5. package/data/flows/explore.flow.yaml +3 -4
  6. package/data/flows/fix.flow.yaml +5 -6
  7. package/data/flows/plan.flow.yaml +4 -5
  8. package/data/flows/review.flow.yaml +3 -4
  9. package/dist/curator/curator.d.ts.map +1 -1
  10. package/dist/curator/curator.js +98 -22
  11. package/dist/curator/curator.js.map +1 -1
  12. package/dist/engine/bin/soleri-engine.js.map +1 -1
  13. package/dist/engine/module-manifest.d.ts +2 -0
  14. package/dist/engine/module-manifest.d.ts.map +1 -1
  15. package/dist/engine/module-manifest.js +136 -1
  16. package/dist/engine/module-manifest.js.map +1 -1
  17. package/dist/engine/register-engine.d.ts.map +1 -1
  18. package/dist/engine/register-engine.js +25 -1
  19. package/dist/engine/register-engine.js.map +1 -1
  20. package/dist/flows/gate-evaluator.js.map +1 -1
  21. package/dist/index.d.ts +2 -0
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +2 -0
  24. package/dist/index.js.map +1 -1
  25. package/dist/operator/operator-profile.d.ts.map +1 -1
  26. package/dist/operator/operator-profile.js +11 -5
  27. package/dist/operator/operator-profile.js.map +1 -1
  28. package/dist/operator/operator-signals.d.ts.map +1 -1
  29. package/dist/operator/operator-signals.js.map +1 -1
  30. package/dist/planning/evidence-collector.js.map +1 -1
  31. package/dist/planning/gap-passes.d.ts.map +1 -1
  32. package/dist/planning/gap-passes.js +23 -6
  33. package/dist/planning/gap-passes.js.map +1 -1
  34. package/dist/planning/gap-patterns.d.ts.map +1 -1
  35. package/dist/planning/gap-patterns.js +57 -11
  36. package/dist/planning/gap-patterns.js.map +1 -1
  37. package/dist/planning/github-projection.d.ts.map +1 -1
  38. package/dist/planning/github-projection.js +39 -20
  39. package/dist/planning/github-projection.js.map +1 -1
  40. package/dist/planning/impact-analyzer.d.ts.map +1 -1
  41. package/dist/planning/impact-analyzer.js +20 -18
  42. package/dist/planning/impact-analyzer.js.map +1 -1
  43. package/dist/planning/plan-lifecycle.d.ts.map +1 -1
  44. package/dist/planning/plan-lifecycle.js +22 -9
  45. package/dist/planning/plan-lifecycle.js.map +1 -1
  46. package/dist/planning/planner.d.ts.map +1 -1
  47. package/dist/planning/planner.js +60 -17
  48. package/dist/planning/planner.js.map +1 -1
  49. package/dist/planning/rationalization-detector.d.ts.map +1 -1
  50. package/dist/planning/rationalization-detector.js.map +1 -1
  51. package/dist/planning/reconciliation-engine.d.ts.map +1 -1
  52. package/dist/planning/reconciliation-engine.js.map +1 -1
  53. package/dist/planning/task-complexity-assessor.d.ts +42 -0
  54. package/dist/planning/task-complexity-assessor.d.ts.map +1 -0
  55. package/dist/planning/task-complexity-assessor.js +132 -0
  56. package/dist/planning/task-complexity-assessor.js.map +1 -0
  57. package/dist/planning/task-verifier.d.ts.map +1 -1
  58. package/dist/planning/task-verifier.js +14 -6
  59. package/dist/planning/task-verifier.js.map +1 -1
  60. package/dist/runtime/admin-ops.d.ts.map +1 -1
  61. package/dist/runtime/admin-ops.js +18 -0
  62. package/dist/runtime/admin-ops.js.map +1 -1
  63. package/dist/runtime/admin-setup-ops.d.ts.map +1 -1
  64. package/dist/runtime/admin-setup-ops.js +2 -1
  65. package/dist/runtime/admin-setup-ops.js.map +1 -1
  66. package/dist/runtime/branching-ops.d.ts +12 -0
  67. package/dist/runtime/branching-ops.d.ts.map +1 -0
  68. package/dist/runtime/branching-ops.js +100 -0
  69. package/dist/runtime/branching-ops.js.map +1 -0
  70. package/dist/runtime/context-health.d.ts.map +1 -1
  71. package/dist/runtime/context-health.js.map +1 -1
  72. package/dist/runtime/facades/branching-facade.d.ts +7 -0
  73. package/dist/runtime/facades/branching-facade.d.ts.map +1 -0
  74. package/dist/runtime/facades/branching-facade.js +8 -0
  75. package/dist/runtime/facades/branching-facade.js.map +1 -0
  76. package/dist/runtime/facades/chat-service-ops.d.ts.map +1 -1
  77. package/dist/runtime/facades/chat-service-ops.js +3 -1
  78. package/dist/runtime/facades/chat-service-ops.js.map +1 -1
  79. package/dist/runtime/facades/chat-transport-ops.d.ts.map +1 -1
  80. package/dist/runtime/facades/chat-transport-ops.js.map +1 -1
  81. package/dist/runtime/facades/index.d.ts.map +1 -1
  82. package/dist/runtime/facades/index.js +42 -0
  83. package/dist/runtime/facades/index.js.map +1 -1
  84. package/dist/runtime/facades/intake-facade.d.ts +9 -0
  85. package/dist/runtime/facades/intake-facade.d.ts.map +1 -0
  86. package/dist/runtime/facades/intake-facade.js +11 -0
  87. package/dist/runtime/facades/intake-facade.js.map +1 -0
  88. package/dist/runtime/facades/links-facade.d.ts +9 -0
  89. package/dist/runtime/facades/links-facade.d.ts.map +1 -0
  90. package/dist/runtime/facades/links-facade.js +10 -0
  91. package/dist/runtime/facades/links-facade.js.map +1 -0
  92. package/dist/runtime/facades/operator-facade.d.ts.map +1 -1
  93. package/dist/runtime/facades/operator-facade.js.map +1 -1
  94. package/dist/runtime/facades/plan-facade.d.ts.map +1 -1
  95. package/dist/runtime/facades/plan-facade.js +4 -1
  96. package/dist/runtime/facades/plan-facade.js.map +1 -1
  97. package/dist/runtime/facades/tier-facade.d.ts +7 -0
  98. package/dist/runtime/facades/tier-facade.d.ts.map +1 -0
  99. package/dist/runtime/facades/tier-facade.js +8 -0
  100. package/dist/runtime/facades/tier-facade.js.map +1 -0
  101. package/dist/runtime/facades/vault-facade.d.ts +9 -1
  102. package/dist/runtime/facades/vault-facade.d.ts.map +1 -1
  103. package/dist/runtime/facades/vault-facade.js +44 -187
  104. package/dist/runtime/facades/vault-facade.js.map +1 -1
  105. package/dist/runtime/github-integration.d.ts.map +1 -1
  106. package/dist/runtime/github-integration.js +11 -4
  107. package/dist/runtime/github-integration.js.map +1 -1
  108. package/dist/runtime/orchestrate-ops.d.ts.map +1 -1
  109. package/dist/runtime/orchestrate-ops.js +75 -42
  110. package/dist/runtime/orchestrate-ops.js.map +1 -1
  111. package/dist/runtime/planning-extra-ops.d.ts.map +1 -1
  112. package/dist/runtime/planning-extra-ops.js.map +1 -1
  113. package/dist/runtime/runtime.d.ts.map +1 -1
  114. package/dist/runtime/runtime.js +3 -1
  115. package/dist/runtime/runtime.js.map +1 -1
  116. package/dist/runtime/session-briefing.d.ts.map +1 -1
  117. package/dist/runtime/session-briefing.js +5 -1
  118. package/dist/runtime/session-briefing.js.map +1 -1
  119. package/dist/runtime/tier-ops.d.ts +13 -0
  120. package/dist/runtime/tier-ops.d.ts.map +1 -0
  121. package/dist/runtime/tier-ops.js +110 -0
  122. package/dist/runtime/tier-ops.js.map +1 -0
  123. package/dist/skills/sync-skills.d.ts.map +1 -1
  124. package/dist/skills/sync-skills.js +1 -1
  125. package/dist/skills/sync-skills.js.map +1 -1
  126. package/dist/vault/linking.d.ts.map +1 -1
  127. package/dist/vault/linking.js +41 -5
  128. package/dist/vault/linking.js.map +1 -1
  129. package/dist/vault/vault-entries.d.ts.map +1 -1
  130. package/dist/vault/vault-entries.js +68 -26
  131. package/dist/vault/vault-entries.js.map +1 -1
  132. package/dist/vault/vault-maintenance.d.ts.map +1 -1
  133. package/dist/vault/vault-maintenance.js +6 -2
  134. package/dist/vault/vault-maintenance.js.map +1 -1
  135. package/dist/vault/vault-markdown-sync.d.ts.map +1 -1
  136. package/dist/vault/vault-markdown-sync.js.map +1 -1
  137. package/dist/vault/vault-memories.d.ts.map +1 -1
  138. package/dist/vault/vault-memories.js +3 -1
  139. package/dist/vault/vault-memories.js.map +1 -1
  140. package/dist/vault/vault-schema.js +36 -10
  141. package/dist/vault/vault-schema.js.map +1 -1
  142. package/dist/vault/vault.d.ts.map +1 -1
  143. package/dist/vault/vault.js +5 -1
  144. package/dist/vault/vault.js.map +1 -1
  145. package/package.json +7 -7
  146. package/src/agency/agency-manager.test.ts +60 -40
  147. package/src/agency/default-rules.test.ts +17 -9
  148. package/src/capabilities/registry.test.ts +2 -12
  149. package/src/chat/agent-loop.test.ts +33 -43
  150. package/src/chat/mcp-bridge.test.ts +7 -2
  151. package/src/claudemd/inject.test.ts +2 -12
  152. package/src/context/context-engine.test.ts +96 -51
  153. package/src/control/intent-router.test.ts +3 -3
  154. package/src/curator/classifier.test.ts +14 -8
  155. package/src/curator/contradiction-detector.test.ts +30 -5
  156. package/src/curator/curator.ts +278 -56
  157. package/src/curator/duplicate-detector.test.ts +77 -15
  158. package/src/curator/quality-gate.test.ts +71 -31
  159. package/src/curator/tag-manager.test.ts +12 -4
  160. package/src/domain-packs/knowledge-installer.test.ts +2 -10
  161. package/src/domain-packs/token-resolver.test.ts +1 -3
  162. package/src/domain-packs/types.test.ts +16 -2
  163. package/src/enforcement/registry.test.ts +2 -8
  164. package/src/engine/bin/soleri-engine.ts +3 -1
  165. package/src/engine/module-manifest.test.ts +48 -4
  166. package/src/engine/module-manifest.ts +138 -1
  167. package/src/engine/register-engine.test.ts +6 -1
  168. package/src/engine/register-engine.ts +26 -3
  169. package/src/errors/classify.test.ts +6 -2
  170. package/src/errors/retry.test.ts +1 -4
  171. package/src/facades/facade-factory.test.ts +110 -64
  172. package/src/flows/epilogue.test.ts +16 -10
  173. package/src/flows/gate-evaluator.test.ts +12 -6
  174. package/src/flows/gate-evaluator.ts +1 -3
  175. package/src/governance/governance.test.ts +137 -21
  176. package/src/health/health-registry.test.ts +8 -1
  177. package/src/index.ts +8 -0
  178. package/src/intake/content-classifier.test.ts +121 -51
  179. package/src/intake/dedup-gate.test.ts +38 -22
  180. package/src/intake/intake-pipeline.test.ts +5 -3
  181. package/src/intake/text-ingester.test.ts +26 -20
  182. package/src/llm/key-pool.test.ts +1 -3
  183. package/src/llm/llm-client.test.ts +1 -4
  184. package/src/llm/oauth-discovery.test.ts +16 -16
  185. package/src/llm/utils.test.ts +62 -18
  186. package/src/logging/logger.test.ts +4 -1
  187. package/src/loop/loop-manager.test.ts +2 -6
  188. package/src/migrations/migration-runner.edge-cases.test.ts +2 -7
  189. package/src/operator/operator-profile-extended.test.ts +15 -5
  190. package/src/operator/operator-profile.test.ts +26 -8
  191. package/src/operator/operator-profile.ts +38 -22
  192. package/src/operator/operator-signals-extended.test.ts +35 -23
  193. package/src/operator/operator-signals.test.ts +6 -10
  194. package/src/operator/operator-signals.ts +2 -1
  195. package/src/operator/prompts/hook-precompact-operator-dispatch.md +10 -6
  196. package/src/operator/prompts/subagent-soft-signal-extractor.md +5 -0
  197. package/src/operator/prompts/subagent-synthesis-cognition.md +19 -10
  198. package/src/operator/prompts/subagent-synthesis-communication.md +13 -7
  199. package/src/operator/prompts/subagent-synthesis-technical.md +19 -9
  200. package/src/operator/prompts/subagent-synthesis-trust.md +27 -21
  201. package/src/persona/defaults.test.ts +1 -5
  202. package/src/planning/evidence-collector.test.ts +147 -38
  203. package/src/planning/evidence-collector.ts +1 -4
  204. package/src/planning/gap-analysis-alternatives.test.ts +41 -11
  205. package/src/planning/gap-passes.test.ts +215 -33
  206. package/src/planning/gap-passes.ts +115 -46
  207. package/src/planning/gap-patterns.test.ts +87 -13
  208. package/src/planning/gap-patterns.ts +114 -31
  209. package/src/planning/github-projection.test.ts +6 -1
  210. package/src/planning/github-projection.ts +41 -20
  211. package/src/planning/impact-analyzer.test.ts +10 -23
  212. package/src/planning/impact-analyzer.ts +33 -46
  213. package/src/planning/plan-lifecycle.test.ts +103 -36
  214. package/src/planning/plan-lifecycle.ts +49 -18
  215. package/src/planning/planner.test.ts +12 -2
  216. package/src/planning/planner.ts +198 -58
  217. package/src/planning/rationalization-detector.test.ts +5 -20
  218. package/src/planning/rationalization-detector.ts +14 -16
  219. package/src/planning/reconciliation-engine.test.ts +20 -3
  220. package/src/planning/reconciliation-engine.ts +1 -2
  221. package/src/planning/task-complexity-assessor.test.ts +298 -0
  222. package/src/planning/task-complexity-assessor.ts +183 -0
  223. package/src/planning/task-verifier.test.ts +59 -27
  224. package/src/planning/task-verifier.ts +15 -9
  225. package/src/playbooks/playbook-executor.test.ts +1 -3
  226. package/src/plugins/plugin-loader.test.ts +19 -14
  227. package/src/plugins/plugin-registry.test.ts +45 -33
  228. package/src/project/project-registry.test.ts +23 -12
  229. package/src/prompts/template-manager.test.ts +4 -1
  230. package/src/queue/job-queue.test.ts +10 -14
  231. package/src/runtime/admin-extra-ops.test.ts +5 -19
  232. package/src/runtime/admin-ops.test.ts +22 -1
  233. package/src/runtime/admin-ops.ts +19 -0
  234. package/src/runtime/admin-setup-ops.test.ts +3 -4
  235. package/src/runtime/admin-setup-ops.ts +9 -2
  236. package/src/runtime/archive-ops.test.ts +4 -1
  237. package/src/runtime/branching-ops.test.ts +144 -0
  238. package/src/runtime/branching-ops.ts +107 -0
  239. package/src/runtime/capture-ops.test.ts +7 -21
  240. package/src/runtime/chain-ops.test.ts +16 -6
  241. package/src/runtime/claude-md-helpers.test.ts +1 -3
  242. package/src/runtime/context-health.test.ts +1 -3
  243. package/src/runtime/context-health.ts +1 -3
  244. package/src/runtime/curator-extra-ops.test.ts +3 -1
  245. package/src/runtime/domain-ops.test.ts +46 -36
  246. package/src/runtime/facades/admin-facade.test.ts +1 -4
  247. package/src/runtime/facades/archive-facade.test.ts +21 -7
  248. package/src/runtime/facades/brain-facade.test.ts +176 -72
  249. package/src/runtime/facades/branching-facade.test.ts +43 -0
  250. package/src/runtime/facades/branching-facade.ts +11 -0
  251. package/src/runtime/facades/chat-facade.test.ts +81 -28
  252. package/src/runtime/facades/chat-service-ops.test.ts +178 -73
  253. package/src/runtime/facades/chat-service-ops.ts +3 -1
  254. package/src/runtime/facades/chat-session-ops.test.ts +25 -10
  255. package/src/runtime/facades/chat-transport-ops.test.ts +101 -34
  256. package/src/runtime/facades/chat-transport-ops.ts +0 -1
  257. package/src/runtime/facades/context-facade.test.ts +19 -4
  258. package/src/runtime/facades/control-facade.test.ts +3 -3
  259. package/src/runtime/facades/index.ts +42 -0
  260. package/src/runtime/facades/intake-facade.test.ts +215 -0
  261. package/src/runtime/facades/intake-facade.ts +14 -0
  262. package/src/runtime/facades/links-facade.test.ts +203 -0
  263. package/src/runtime/facades/links-facade.ts +13 -0
  264. package/src/runtime/facades/loop-facade.test.ts +22 -5
  265. package/src/runtime/facades/memory-facade.test.ts +19 -5
  266. package/src/runtime/facades/operator-facade.test.ts +17 -4
  267. package/src/runtime/facades/operator-facade.ts +11 -3
  268. package/src/runtime/facades/orchestrate-facade.test.ts +7 -1
  269. package/src/runtime/facades/plan-facade.test.ts +29 -12
  270. package/src/runtime/facades/plan-facade.ts +7 -2
  271. package/src/runtime/facades/tier-facade.test.ts +47 -0
  272. package/src/runtime/facades/tier-facade.ts +11 -0
  273. package/src/runtime/facades/vault-facade.test.ts +174 -242
  274. package/src/runtime/facades/vault-facade.ts +55 -199
  275. package/src/runtime/github-integration.ts +11 -8
  276. package/src/runtime/grading-ops.test.ts +39 -8
  277. package/src/runtime/intake-ops.test.ts +69 -16
  278. package/src/runtime/loop-ops.test.ts +16 -6
  279. package/src/runtime/memory-cross-project-ops.test.ts +25 -14
  280. package/src/runtime/orchestrate-ops.test.ts +204 -0
  281. package/src/runtime/orchestrate-ops.ts +103 -65
  282. package/src/runtime/pack-ops.test.ts +23 -6
  283. package/src/runtime/planning-extra-ops.test.ts +17 -7
  284. package/src/runtime/planning-extra-ops.ts +3 -1
  285. package/src/runtime/playbook-ops.test.ts +26 -3
  286. package/src/runtime/plugin-ops.test.ts +83 -25
  287. package/src/runtime/project-ops.test.ts +26 -6
  288. package/src/runtime/runtime.ts +3 -1
  289. package/src/runtime/session-briefing.test.ts +183 -54
  290. package/src/runtime/session-briefing.ts +8 -2
  291. package/src/runtime/sync-ops.test.ts +3 -12
  292. package/src/runtime/telemetry-ops.test.ts +31 -6
  293. package/src/runtime/tier-ops.test.ts +159 -0
  294. package/src/runtime/tier-ops.ts +119 -0
  295. package/src/runtime/vault-extra-ops.test.ts +32 -8
  296. package/src/runtime/vault-sharing-ops.test.ts +1 -4
  297. package/src/skills/sync-skills.ts +2 -12
  298. package/src/transport/ws-server.test.ts +7 -4
  299. package/src/vault/__tests__/vault-characterization.test.ts +492 -81
  300. package/src/vault/linking.test.ts +50 -17
  301. package/src/vault/linking.ts +48 -7
  302. package/src/vault/obsidian-sync.test.ts +6 -3
  303. package/src/vault/scope-detector.test.ts +1 -3
  304. package/src/vault/vault-branching.test.ts +9 -7
  305. package/src/vault/vault-entries.ts +209 -65
  306. package/src/vault/vault-maintenance.ts +7 -12
  307. package/src/vault/vault-manager.test.ts +10 -10
  308. package/src/vault/vault-markdown-sync.ts +4 -1
  309. package/src/vault/vault-memories.ts +7 -7
  310. package/src/vault/vault-scaling.test.ts +5 -5
  311. package/src/vault/vault-schema.ts +72 -15
  312. package/src/vault/vault.ts +55 -9
  313. package/src/brain/strength-scorer.ts +0 -404
  314. package/src/engine/index.ts +0 -21
  315. package/src/persona/index.ts +0 -9
  316. package/src/vault/vault-interfaces.ts +0 -56
@@ -31,12 +31,20 @@ describe('evaluateQuality', () => {
31
31
  });
32
32
 
33
33
  it('returns ACCEPT for high-quality entry', async () => {
34
- const llm = mockLLM(JSON.stringify({
35
- verdict: 'ACCEPT',
36
- overallScore: 85,
37
- scores: { novelty: 80, actionability: 90, specificity: 85, relevance: 80, informationDensity: 90 },
38
- reasoning: 'High quality entry with specific guidance.',
39
- }));
34
+ const llm = mockLLM(
35
+ JSON.stringify({
36
+ verdict: 'ACCEPT',
37
+ overallScore: 85,
38
+ scores: {
39
+ novelty: 80,
40
+ actionability: 90,
41
+ specificity: 85,
42
+ relevance: 80,
43
+ informationDensity: 90,
44
+ },
45
+ reasoning: 'High quality entry with specific guidance.',
46
+ }),
47
+ );
40
48
 
41
49
  const result = await evaluateQuality(makeEntry(), llm);
42
50
  expect(result.evaluated).toBe(true);
@@ -45,13 +53,21 @@ describe('evaluateQuality', () => {
45
53
  });
46
54
 
47
55
  it('returns REJECT for low-quality entry', async () => {
48
- const llm = mockLLM(JSON.stringify({
49
- verdict: 'REJECT',
50
- overallScore: 30,
51
- scores: { novelty: 10, actionability: 30, specificity: 40, relevance: 50, informationDensity: 20 },
52
- reasoning: 'Too generic.',
53
- rejectReasons: ['Low novelty', 'Not actionable'],
54
- }));
56
+ const llm = mockLLM(
57
+ JSON.stringify({
58
+ verdict: 'REJECT',
59
+ overallScore: 30,
60
+ scores: {
61
+ novelty: 10,
62
+ actionability: 30,
63
+ specificity: 40,
64
+ relevance: 50,
65
+ informationDensity: 20,
66
+ },
67
+ reasoning: 'Too generic.',
68
+ rejectReasons: ['Low novelty', 'Not actionable'],
69
+ }),
70
+ );
55
71
 
56
72
  const result = await evaluateQuality(makeEntry(), llm);
57
73
  expect(result.evaluated).toBe(true);
@@ -87,24 +103,40 @@ describe('evaluateQuality', () => {
87
103
  });
88
104
 
89
105
  it('normalizes non-REJECT verdict to ACCEPT', async () => {
90
- const llm = mockLLM(JSON.stringify({
91
- verdict: 'MAYBE',
92
- overallScore: 60,
93
- scores: { novelty: 60, actionability: 60, specificity: 60, relevance: 60, informationDensity: 60 },
94
- reasoning: 'Borderline entry.',
95
- }));
106
+ const llm = mockLLM(
107
+ JSON.stringify({
108
+ verdict: 'MAYBE',
109
+ overallScore: 60,
110
+ scores: {
111
+ novelty: 60,
112
+ actionability: 60,
113
+ specificity: 60,
114
+ relevance: 60,
115
+ informationDensity: 60,
116
+ },
117
+ reasoning: 'Borderline entry.',
118
+ }),
119
+ );
96
120
 
97
121
  const result = await evaluateQuality(makeEntry(), llm);
98
122
  expect(result.verdict).toBe('ACCEPT');
99
123
  });
100
124
 
101
125
  it('includes optional entry fields in prompt', async () => {
102
- const llm = mockLLM(JSON.stringify({
103
- verdict: 'ACCEPT',
104
- overallScore: 70,
105
- scores: { novelty: 70, actionability: 70, specificity: 70, relevance: 70, informationDensity: 70 },
106
- reasoning: 'OK.',
107
- }));
126
+ const llm = mockLLM(
127
+ JSON.stringify({
128
+ verdict: 'ACCEPT',
129
+ overallScore: 70,
130
+ scores: {
131
+ novelty: 70,
132
+ actionability: 70,
133
+ specificity: 70,
134
+ relevance: 70,
135
+ informationDensity: 70,
136
+ },
137
+ reasoning: 'OK.',
138
+ }),
139
+ );
108
140
 
109
141
  const entry = makeEntry();
110
142
  entry.why = 'Because security matters';
@@ -120,12 +152,20 @@ describe('evaluateQuality', () => {
120
152
  });
121
153
 
122
154
  it('uses low temperature for consistent scoring', async () => {
123
- const llm = mockLLM(JSON.stringify({
124
- verdict: 'ACCEPT',
125
- overallScore: 70,
126
- scores: { novelty: 70, actionability: 70, specificity: 70, relevance: 70, informationDensity: 70 },
127
- reasoning: 'OK.',
128
- }));
155
+ const llm = mockLLM(
156
+ JSON.stringify({
157
+ verdict: 'ACCEPT',
158
+ overallScore: 70,
159
+ scores: {
160
+ novelty: 70,
161
+ actionability: 70,
162
+ specificity: 70,
163
+ relevance: 70,
164
+ informationDensity: 70,
165
+ },
166
+ reasoning: 'OK.',
167
+ }),
168
+ );
129
169
 
130
170
  await evaluateQuality(makeEntry(), llm);
131
171
 
@@ -16,8 +16,12 @@ function mockTagStore(): TagStore {
16
16
 
17
17
  return {
18
18
  getAlias: vi.fn((lower: string) => aliases.get(lower) ?? null),
19
- insertCanonical: vi.fn((tag: string) => { canonicals.set(tag, null); }),
20
- upsertAlias: vi.fn((alias: string, canonical: string) => { aliases.set(alias, canonical); }),
19
+ insertCanonical: vi.fn((tag: string) => {
20
+ canonicals.set(tag, null);
21
+ }),
22
+ upsertAlias: vi.fn((alias: string, canonical: string) => {
23
+ aliases.set(alias, canonical);
24
+ }),
21
25
  getCanonicalRows: vi.fn(() =>
22
26
  Array.from(canonicals.entries()).map(([tag, description]) => ({
23
27
  tag,
@@ -59,7 +63,11 @@ describe('tag-manager', () => {
59
63
 
60
64
  it('returns lowercased tag when no alias found', () => {
61
65
  const result = normalizeTag('MyCustomTag', store);
62
- expect(result).toEqual({ original: 'MyCustomTag', normalized: 'mycustomtag', wasAliased: false });
66
+ expect(result).toEqual({
67
+ original: 'MyCustomTag',
68
+ normalized: 'mycustomtag',
69
+ wasAliased: false,
70
+ });
63
71
  });
64
72
 
65
73
  it('trims whitespace', () => {
@@ -92,7 +100,7 @@ describe('tag-manager', () => {
92
100
  describe('normalizeAndDedup', () => {
93
101
  it('deduplicates after normalization', () => {
94
102
  (store.getAlias as ReturnType<typeof vi.fn>)
95
- .mockReturnValueOnce('styling') // css -> styling
103
+ .mockReturnValueOnce('styling') // css -> styling
96
104
  .mockReturnValueOnce('styling'); // tailwind -> styling
97
105
  const { results, dedupedTags, changed } = normalizeAndDedup(['css', 'tailwind'], store);
98
106
  expect(results).toHaveLength(2);
@@ -128,11 +128,7 @@ describe('installKnowledge', () => {
128
128
  const canonicalDir = join(tempDir, 'canonical');
129
129
  writeMdFiles(canonicalDir, { 'tagged.md': 'Tagged entry.' });
130
130
  const runtime = mockRuntime();
131
- await installKnowledge(
132
- mockPack({ knowledge: { canonical: 'canonical' } }),
133
- runtime,
134
- tempDir,
135
- );
131
+ await installKnowledge(mockPack({ knowledge: { canonical: 'canonical' } }), runtime, tempDir);
136
132
  const addCall = (runtime.vault.add as unknown).mock.calls[0][0];
137
133
  expect(addCall.tags).toContain('pack:test-pack');
138
134
  expect(addCall.tags).toContain('tier:canonical');
@@ -144,11 +140,7 @@ describe('installKnowledge', () => {
144
140
  const curatedDir = join(tempDir, 'curated');
145
141
  writeMdFiles(curatedDir, { 'my-pattern.md': 'Content.' });
146
142
  const runtime = mockRuntime();
147
- await installKnowledge(
148
- mockPack({ knowledge: { curated: 'curated' } }),
149
- runtime,
150
- tempDir,
151
- );
143
+ await installKnowledge(mockPack({ knowledge: { curated: 'curated' } }), runtime, tempDir);
152
144
  const addCall = (runtime.vault.add as unknown).mock.calls[0][0];
153
145
  expect(addCall.id).toBe('pack-test-pack-my-pattern');
154
146
  });
@@ -75,9 +75,7 @@ describe('resolveToken', () => {
75
75
  });
76
76
 
77
77
  it('throws for unknown token', () => {
78
- expect(() => resolveToken('unknown-token', emptyProject())).toThrow(
79
- /Cannot resolve token/,
80
- );
78
+ expect(() => resolveToken('unknown-token', emptyProject())).toThrow(/Cannot resolve token/);
81
79
  });
82
80
 
83
81
  it('throws for unknown color scale', () => {
@@ -53,7 +53,9 @@ describe('validateDomainPack', () => {
53
53
  });
54
54
 
55
55
  it('accepts pack with rules string', () => {
56
- const result = validateDomainPack(minimalPack({ rules: '## Token Rules\nUse semantic tokens.' }));
56
+ const result = validateDomainPack(
57
+ minimalPack({ rules: '## Token Rules\nUse semantic tokens.' }),
58
+ );
57
59
  expect(result.success).toBe(true);
58
60
  });
59
61
 
@@ -122,7 +124,19 @@ describe('SEMANTIC_FACADE_NAMES', () => {
122
124
  });
123
125
 
124
126
  it('contains all core engine facades', () => {
125
- const expected = ['vault', 'plan', 'brain', 'memory', 'admin', 'curator', 'loop', 'orchestrate', 'control', 'cognee', 'governance'];
127
+ const expected = [
128
+ 'vault',
129
+ 'plan',
130
+ 'brain',
131
+ 'memory',
132
+ 'admin',
133
+ 'curator',
134
+ 'loop',
135
+ 'orchestrate',
136
+ 'control',
137
+ 'cognee',
138
+ 'governance',
139
+ ];
126
140
  for (const name of expected) {
127
141
  expect(SEMANTIC_FACADE_NAMES).toContain(name);
128
142
  }
@@ -74,10 +74,7 @@ describe('EnforcementRegistry', () => {
74
74
 
75
75
  describe('getEnabledRules', () => {
76
76
  it('excludes disabled rules', () => {
77
- registry.addRules([
78
- makeRule({ id: 'active' }),
79
- makeRule({ id: 'disabled', enabled: false }),
80
- ]);
77
+ registry.addRules([makeRule({ id: 'active' }), makeRule({ id: 'disabled', enabled: false })]);
81
78
  const enabled = registry.getEnabledRules();
82
79
  expect(enabled).toHaveLength(1);
83
80
  expect(enabled[0].id).toBe('active');
@@ -91,10 +88,7 @@ describe('EnforcementRegistry', () => {
91
88
 
92
89
  describe('getConfig', () => {
93
90
  it('returns config with only enabled rules', () => {
94
- registry.addRules([
95
- makeRule({ id: 'on' }),
96
- makeRule({ id: 'off', enabled: false }),
97
- ]);
91
+ registry.addRules([makeRule({ id: 'on' }), makeRule({ id: 'off', enabled: false })]);
98
92
  const config = registry.getConfig();
99
93
  expect(config.rules).toHaveLength(1);
100
94
  expect(config.rules[0].id).toBe('on');
@@ -169,7 +169,9 @@ async function main(): Promise<void> {
169
169
  const syncResult = syncSkillsToClaudeCode([skillsDir], config.name as string);
170
170
  const total = syncResult.installed.length + syncResult.updated.length;
171
171
  if (total > 0) {
172
- console.error(`${tag} Skills synced: ${syncResult.installed.length} new, ${syncResult.updated.length} updated`);
172
+ console.error(
173
+ `${tag} Skills synced: ${syncResult.installed.length} new, ${syncResult.updated.length} updated`,
174
+ );
173
175
  }
174
176
  }
175
177
 
@@ -29,10 +29,11 @@ describe('ENGINE_MODULE_MANIFEST', () => {
29
29
  expect(suffixes).toContain('agency');
30
30
  expect(suffixes).toContain('chat');
31
31
  expect(suffixes).toContain('operator');
32
+ expect(suffixes).toContain('intake');
32
33
  });
33
34
 
34
- it('has exactly 16 modules', () => {
35
- expect(ENGINE_MODULE_MANIFEST).toHaveLength(16);
35
+ it('has exactly 20 modules', () => {
36
+ expect(ENGINE_MODULE_MANIFEST).toHaveLength(20);
36
37
  });
37
38
 
38
39
  it('has no duplicate suffixes', () => {
@@ -88,6 +89,49 @@ describe('ENGINE_MODULE_MANIFEST', () => {
88
89
  expect(testEntry.suffix).toBe('test');
89
90
  expect(testEntry.conditional).toBeUndefined();
90
91
  });
92
+
93
+ it('intentSignals is optional and a Record<string, string> when present', () => {
94
+ for (const entry of ENGINE_MODULE_MANIFEST) {
95
+ if (entry.intentSignals !== undefined) {
96
+ expect(typeof entry.intentSignals).toBe('object');
97
+ for (const [phrase, op] of Object.entries(entry.intentSignals)) {
98
+ expect(typeof phrase).toBe('string');
99
+ expect(phrase.length).toBeGreaterThan(0);
100
+ expect(typeof op).toBe('string');
101
+ expect(op.length).toBeGreaterThan(0);
102
+ }
103
+ }
104
+ }
105
+ });
106
+
107
+ it('every module has intentSignals defined', () => {
108
+ for (const entry of ENGINE_MODULE_MANIFEST) {
109
+ expect(entry.intentSignals).toBeDefined();
110
+ expect(Object.keys(entry.intentSignals!).length).toBeGreaterThanOrEqual(2);
111
+ expect(Object.keys(entry.intentSignals!).length).toBeLessThanOrEqual(6);
112
+ }
113
+ });
114
+
115
+ it('intentSignals values reference known keyOps or valid op names', () => {
116
+ for (const entry of ENGINE_MODULE_MANIFEST) {
117
+ if (entry.intentSignals) {
118
+ for (const op of Object.values(entry.intentSignals)) {
119
+ // Op should be a non-empty snake_case string
120
+ expect(op).toMatch(/^[a-z][a-z0-9_]*$/);
121
+ }
122
+ }
123
+ }
124
+ });
125
+
126
+ it('intentSignals phrases are unique across all modules', () => {
127
+ const allPhrases: string[] = [];
128
+ for (const entry of ENGINE_MODULE_MANIFEST) {
129
+ if (entry.intentSignals) {
130
+ allPhrases.push(...Object.keys(entry.intentSignals));
131
+ }
132
+ }
133
+ expect(new Set(allPhrases).size).toBe(allPhrases.length);
134
+ });
91
135
  });
92
136
 
93
137
  describe('CORE_KEY_OPS', () => {
@@ -118,7 +162,7 @@ describe('manifest order stability', () => {
118
162
  expect(ENGINE_MODULE_MANIFEST[0].suffix).toBe('vault');
119
163
  });
120
164
 
121
- it('review is the last module', () => {
122
- expect(ENGINE_MODULE_MANIFEST[ENGINE_MODULE_MANIFEST.length - 1].suffix).toBe('review');
165
+ it('tier is the last module', () => {
166
+ expect(ENGINE_MODULE_MANIFEST[ENGINE_MODULE_MANIFEST.length - 1].suffix).toBe('tier');
123
167
  });
124
168
  });
@@ -16,6 +16,8 @@ export interface ModuleManifestEntry {
16
16
  keyOps: string[];
17
17
  /** If true, module requires a runtime condition to register */
18
18
  conditional?: boolean;
19
+ /** Intent phrases that map to this module's ops — used for dynamic tool routing */
20
+ intentSignals?: Record<string, string>;
19
21
  }
20
22
 
21
23
  /**
@@ -25,84 +27,219 @@ export interface ModuleManifestEntry {
25
27
  export const ENGINE_MODULE_MANIFEST: ModuleManifestEntry[] = [
26
28
  {
27
29
  suffix: 'vault',
28
- description: 'Knowledge management — search, CRUD, import/export, intake, sharing, linking.',
30
+ description: 'Knowledge management — search, CRUD, capture, sharing scope.',
29
31
  keyOps: ['search_intelligent', 'capture_knowledge', 'capture_quick'],
32
+ intentSignals: {
33
+ 'search knowledge': 'search_intelligent',
34
+ 'find pattern': 'search_intelligent',
35
+ 'best practice': 'search_intelligent',
36
+ 'save this': 'capture_knowledge',
37
+ 'remember this': 'capture_knowledge',
38
+ 'capture this': 'capture_quick',
39
+ },
30
40
  },
31
41
  {
32
42
  suffix: 'plan',
33
43
  description: 'Plan lifecycle — create, approve, execute, reconcile, complete, grading.',
34
44
  keyOps: ['create_plan', 'approve_plan', 'plan_split', 'plan_reconcile'],
45
+ intentSignals: {
46
+ 'plan this': 'create_plan',
47
+ 'break this down': 'create_plan',
48
+ 'approve the plan': 'approve_plan',
49
+ 'split into tasks': 'plan_split',
50
+ 'how did it go': 'plan_reconcile',
51
+ },
35
52
  },
36
53
  {
37
54
  suffix: 'brain',
38
55
  description: 'Learning system — intelligence pipeline, strengths, feedback, sessions.',
39
56
  keyOps: ['recommend', 'strengths', 'feedback'],
57
+ intentSignals: {
58
+ 'what works': 'recommend',
59
+ 'recommendations': 'recommend',
60
+ 'pattern strengths': 'strengths',
61
+ 'give feedback': 'feedback',
62
+ },
40
63
  },
41
64
  {
42
65
  suffix: 'memory',
43
66
  description: 'Session & cross-project memory — capture, search, dedup, promote.',
44
67
  keyOps: ['memory_search', 'memory_capture', 'session_capture'],
68
+ intentSignals: {
69
+ 'recall past work': 'memory_search',
70
+ 'what did we do': 'memory_search',
71
+ 'last time': 'memory_search',
72
+ 'wrap up session': 'session_capture',
73
+ 'summarize session': 'session_capture',
74
+ },
45
75
  },
46
76
  {
47
77
  suffix: 'admin',
48
78
  description: 'Infrastructure — health, config, telemetry, tokens, LLM, prompts.',
49
79
  keyOps: ['admin_health', 'admin_tool_list', 'admin_diagnostic'],
80
+ intentSignals: {
81
+ 'health check': 'admin_health',
82
+ 'system status': 'admin_health',
83
+ 'what tools exist': 'admin_tool_list',
84
+ 'run diagnostics': 'admin_diagnostic',
85
+ },
50
86
  },
51
87
  {
52
88
  suffix: 'curator',
53
89
  description: 'Quality — duplicate detection, contradictions, grooming, health audit.',
54
90
  keyOps: ['curator_groom', 'curator_status', 'curator_health'],
91
+ intentSignals: {
92
+ 'clean up vault': 'curator_groom',
93
+ 'find duplicates': 'curator_groom',
94
+ 'vault quality': 'curator_status',
95
+ 'audit knowledge': 'curator_health',
96
+ },
55
97
  },
56
98
  {
57
99
  suffix: 'loop',
58
100
  description: 'Iterative validation loops — start, iterate, cancel, complete, history.',
59
101
  keyOps: ['loop_start', 'loop_status', 'loop_cancel'],
102
+ intentSignals: {
103
+ 'start a loop': 'loop_start',
104
+ 'iterate on this': 'loop_start',
105
+ 'loop status': 'loop_status',
106
+ 'stop the loop': 'loop_cancel',
107
+ },
60
108
  },
61
109
  {
62
110
  suffix: 'orchestrate',
63
111
  description:
64
112
  'Execution orchestration — project registration, playbooks, plan/execute/complete.',
65
113
  keyOps: ['orchestrate_plan', 'orchestrate_execute', 'orchestrate_complete'],
114
+ intentSignals: {
115
+ 'do this task': 'orchestrate_plan',
116
+ 'build this': 'orchestrate_plan',
117
+ 'execute the plan': 'orchestrate_execute',
118
+ 'finish up': 'orchestrate_complete',
119
+ },
66
120
  },
67
121
  {
68
122
  suffix: 'control',
69
123
  description: 'Agent behavior — identity, intent routing, morphing, guidelines, governance.',
70
124
  keyOps: ['route_intent', 'morph', 'get_behavior_rules'],
125
+ intentSignals: {
126
+ 'what should I do': 'route_intent',
127
+ 'change persona': 'morph',
128
+ 'behavior rules': 'get_behavior_rules',
129
+ },
71
130
  },
72
131
  {
73
132
  suffix: 'context',
74
133
  description: 'Context analysis — entity extraction, knowledge retrieval, confidence scoring.',
75
134
  keyOps: ['context_extract_entities', 'context_retrieve_knowledge', 'context_analyze'],
135
+ intentSignals: {
136
+ 'extract entities': 'context_extract_entities',
137
+ 'get context': 'context_retrieve_knowledge',
138
+ 'analyze this': 'context_analyze',
139
+ },
76
140
  },
77
141
  {
78
142
  suffix: 'agency',
79
143
  description: 'Proactive intelligence — file watching, pattern surfacing, warnings.',
80
144
  keyOps: ['agency_scan_file', 'agency_surface_patterns', 'agency_warnings'],
145
+ intentSignals: {
146
+ 'scan this file': 'agency_scan_file',
147
+ 'surface patterns': 'agency_surface_patterns',
148
+ 'any warnings': 'agency_warnings',
149
+ },
81
150
  },
82
151
  {
83
152
  suffix: 'chat',
84
153
  description: 'Chat transport — session management, response chunking, authentication.',
85
154
  keyOps: ['chat_send', 'chat_history', 'chat_session'],
155
+ intentSignals: {
156
+ 'send message': 'chat_send',
157
+ 'chat history': 'chat_history',
158
+ 'start chat': 'chat_session',
159
+ },
86
160
  },
87
161
  {
88
162
  suffix: 'operator',
89
163
  description: 'Operator profile — personality learning, signals, adaptation.',
90
164
  keyOps: ['profile_get', 'signal_accumulate', 'synthesis_check'],
165
+ intentSignals: {
166
+ 'who am I': 'profile_get',
167
+ 'my profile': 'profile_get',
168
+ 'learn my style': 'signal_accumulate',
169
+ },
91
170
  },
92
171
  {
93
172
  suffix: 'archive',
94
173
  description: 'Archival, lifecycle, and knowledge maintenance.',
95
174
  keyOps: ['vault_archive', 'vault_restore', 'vault_optimize', 'knowledge_audit'],
175
+ intentSignals: {
176
+ 'archive entries': 'vault_archive',
177
+ 'restore archived': 'vault_restore',
178
+ 'optimize vault': 'vault_optimize',
179
+ 'knowledge audit': 'knowledge_audit',
180
+ },
96
181
  },
97
182
  {
98
183
  suffix: 'sync',
99
184
  description: 'Git, Obsidian, and pack sync operations.',
100
185
  keyOps: ['vault_git_push', 'vault_git_pull', 'obsidian_sync'],
186
+ intentSignals: {
187
+ 'push vault': 'vault_git_push',
188
+ 'pull vault': 'vault_git_pull',
189
+ 'sync obsidian': 'obsidian_sync',
190
+ },
101
191
  },
102
192
  {
103
193
  suffix: 'review',
104
194
  description: 'Knowledge review workflow.',
105
195
  keyOps: ['vault_submit_review', 'vault_approve', 'vault_reject'],
196
+ intentSignals: {
197
+ 'submit for review': 'vault_submit_review',
198
+ 'approve entry': 'vault_approve',
199
+ 'reject entry': 'vault_reject',
200
+ },
201
+ },
202
+ {
203
+ suffix: 'intake',
204
+ description: 'Content ingestion — books, URLs, text, batch import.',
205
+ keyOps: ['intake_ingest_book', 'ingest_url', 'ingest_text', 'ingest_batch'],
206
+ intentSignals: {
207
+ 'ingest a book': 'intake_ingest_book',
208
+ 'import from URL': 'ingest_url',
209
+ 'ingest text': 'ingest_text',
210
+ 'batch import': 'ingest_batch',
211
+ },
212
+ },
213
+ {
214
+ suffix: 'links',
215
+ description: 'Entry linking — create, traverse, suggest, orphan detection.',
216
+ keyOps: ['link_entries', 'traverse', 'suggest_links', 'get_orphans'],
217
+ intentSignals: {
218
+ 'link entries': 'link_entries',
219
+ 'explore connections': 'traverse',
220
+ 'suggest links': 'suggest_links',
221
+ 'find orphans': 'get_orphans',
222
+ },
223
+ },
224
+ {
225
+ suffix: 'branching',
226
+ description: 'Vault branching — create, list, merge, delete branches.',
227
+ keyOps: ['vault_branch', 'vault_branch_list', 'vault_merge_branch'],
228
+ intentSignals: {
229
+ 'create branch': 'vault_branch',
230
+ 'list branches': 'vault_branch_list',
231
+ 'merge branch': 'vault_merge_branch',
232
+ },
233
+ },
234
+ {
235
+ suffix: 'tier',
236
+ description: 'Multi-vault tiers — connect, disconnect, search across sources.',
237
+ keyOps: ['vault_connect_source', 'vault_search_all', 'vault_list_sources'],
238
+ intentSignals: {
239
+ 'connect source': 'vault_connect_source',
240
+ 'search all vaults': 'vault_search_all',
241
+ 'list sources': 'vault_list_sources',
242
+ },
106
243
  },
107
244
  ];
108
245
 
@@ -97,7 +97,12 @@ describe('registerEngine — core ops', () => {
97
97
  it('registers core facade when coreOps provided', () => {
98
98
  const server = makeServer();
99
99
  const coreOps: OpDefinition[] = [
100
- { name: 'health', description: 'Health check', auth: 'read', handler: async () => ({ ok: true }) },
100
+ {
101
+ name: 'health',
102
+ description: 'Health check',
103
+ auth: 'read',
104
+ handler: async () => ({ ok: true }),
105
+ },
101
106
  ];
102
107
  const result = registerEngine(server, runtime, { agentId: 'core', coreOps });
103
108
  expect(result.tools).toContain('core_core');
@@ -39,6 +39,10 @@ import { createOperatorFacadeOps } from '../runtime/facades/operator-facade.js';
39
39
  import { createArchiveFacadeOps } from '../runtime/facades/archive-facade.js';
40
40
  import { createSyncFacadeOps } from '../runtime/facades/sync-facade.js';
41
41
  import { createReviewFacadeOps } from '../runtime/facades/review-facade.js';
42
+ import { createIntakeFacadeOps } from '../runtime/facades/intake-facade.js';
43
+ import { createLinksFacadeOps } from '../runtime/facades/links-facade.js';
44
+ import { createBranchingFacadeOps } from '../runtime/facades/branching-facade.js';
45
+ import { createTierFacadeOps } from '../runtime/facades/tier-facade.js';
42
46
  import { createDomainFacade } from '../runtime/domain-ops.js';
43
47
 
44
48
  // ─── Types ────────────────────────────────────────────────────────────
@@ -88,7 +92,7 @@ interface ModuleDef {
88
92
  export const ENGINE_MODULES: ModuleDef[] = [
89
93
  {
90
94
  suffix: 'vault',
91
- description: 'Knowledge management — search, CRUD, import/export, intake, sharing, linking.',
95
+ description: 'Knowledge management — search, CRUD, capture, sharing scope.',
92
96
  createOps: createVaultFacadeOps,
93
97
  },
94
98
  {
@@ -123,8 +127,7 @@ export const ENGINE_MODULES: ModuleDef[] = [
123
127
  },
124
128
  {
125
129
  suffix: 'orchestrate',
126
- description:
127
- 'Execution orchestration — session start, playbooks, plan/execute/complete.',
130
+ description: 'Execution orchestration — session start, playbooks, plan/execute/complete.',
128
131
  createOps: createOrchestrateFacadeOps,
129
132
  },
130
133
  {
@@ -167,6 +170,26 @@ export const ENGINE_MODULES: ModuleDef[] = [
167
170
  description: 'Knowledge review workflow.',
168
171
  createOps: createReviewFacadeOps,
169
172
  },
173
+ {
174
+ suffix: 'intake',
175
+ description: 'Content ingestion — books, URLs, text, batch import.',
176
+ createOps: createIntakeFacadeOps,
177
+ },
178
+ {
179
+ suffix: 'links',
180
+ description: 'Entry linking — create, traverse, suggest, orphan detection.',
181
+ createOps: createLinksFacadeOps,
182
+ },
183
+ {
184
+ suffix: 'branching',
185
+ description: 'Vault branching — create, list, merge, delete branches.',
186
+ createOps: createBranchingFacadeOps,
187
+ },
188
+ {
189
+ suffix: 'tier',
190
+ description: 'Multi-vault tiers — connect, disconnect, search across sources.',
191
+ createOps: createTierFacadeOps,
192
+ },
170
193
  ];
171
194
 
172
195
  // ─── Core Registration ────────────────────────────────────────────────