@soleri/core 9.0.4 → 9.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (744) 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/brain/intelligence.d.ts +27 -0
  10. package/dist/brain/intelligence.d.ts.map +1 -1
  11. package/dist/brain/intelligence.js +160 -14
  12. package/dist/brain/intelligence.js.map +1 -1
  13. package/dist/brain/learning-radar.d.ts +4 -0
  14. package/dist/brain/learning-radar.d.ts.map +1 -1
  15. package/dist/brain/learning-radar.js +20 -1
  16. package/dist/brain/learning-radar.js.map +1 -1
  17. package/dist/brain/strength-scorer.d.ts +31 -0
  18. package/dist/brain/strength-scorer.d.ts.map +1 -0
  19. package/dist/brain/strength-scorer.js +264 -0
  20. package/dist/brain/strength-scorer.js.map +1 -0
  21. package/dist/chat/agent-loop.d.ts.map +1 -1
  22. package/dist/chat/agent-loop.js +2 -0
  23. package/dist/chat/agent-loop.js.map +1 -1
  24. package/dist/chat/notifications.d.ts.map +1 -1
  25. package/dist/chat/notifications.js +2 -0
  26. package/dist/chat/notifications.js.map +1 -1
  27. package/dist/claudemd/compose.js +1 -1
  28. package/dist/claudemd/compose.js.map +1 -1
  29. package/dist/control/intent-router.d.ts.map +1 -1
  30. package/dist/control/intent-router.js +12 -4
  31. package/dist/control/intent-router.js.map +1 -1
  32. package/dist/curator/contradiction-detector.d.ts +27 -0
  33. package/dist/curator/contradiction-detector.d.ts.map +1 -0
  34. package/dist/curator/contradiction-detector.js +62 -0
  35. package/dist/curator/contradiction-detector.js.map +1 -0
  36. package/dist/curator/curator.d.ts +3 -4
  37. package/dist/curator/curator.d.ts.map +1 -1
  38. package/dist/curator/curator.js +94 -453
  39. package/dist/curator/curator.js.map +1 -1
  40. package/dist/curator/duplicate-detector.d.ts +14 -0
  41. package/dist/curator/duplicate-detector.d.ts.map +1 -0
  42. package/dist/curator/duplicate-detector.js +77 -0
  43. package/dist/curator/duplicate-detector.js.map +1 -0
  44. package/dist/curator/health-audit.d.ts +15 -0
  45. package/dist/curator/health-audit.d.ts.map +1 -0
  46. package/dist/curator/health-audit.js +97 -0
  47. package/dist/curator/health-audit.js.map +1 -0
  48. package/dist/curator/metadata-enricher.d.ts +17 -0
  49. package/dist/curator/metadata-enricher.d.ts.map +1 -0
  50. package/dist/curator/metadata-enricher.js +60 -0
  51. package/dist/curator/metadata-enricher.js.map +1 -0
  52. package/dist/curator/schema.d.ts +7 -0
  53. package/dist/curator/schema.d.ts.map +1 -0
  54. package/dist/curator/schema.js +62 -0
  55. package/dist/curator/schema.js.map +1 -0
  56. package/dist/curator/tag-manager.d.ts +36 -0
  57. package/dist/curator/tag-manager.d.ts.map +1 -0
  58. package/dist/curator/tag-manager.js +78 -0
  59. package/dist/curator/tag-manager.js.map +1 -0
  60. package/dist/engine/bin/soleri-engine.js +24 -3
  61. package/dist/engine/bin/soleri-engine.js.map +1 -1
  62. package/dist/engine/core-ops.d.ts.map +1 -1
  63. package/dist/engine/core-ops.js +23 -8
  64. package/dist/engine/core-ops.js.map +1 -1
  65. package/dist/engine/module-manifest.d.ts.map +1 -1
  66. package/dist/engine/module-manifest.js +42 -2
  67. package/dist/engine/module-manifest.js.map +1 -1
  68. package/dist/engine/register-engine.d.ts.map +1 -1
  69. package/dist/engine/register-engine.js +50 -2
  70. package/dist/engine/register-engine.js.map +1 -1
  71. package/dist/errors/retry.d.ts.map +1 -1
  72. package/dist/errors/retry.js +2 -0
  73. package/dist/errors/retry.js.map +1 -1
  74. package/dist/facades/types.d.ts +1 -1
  75. package/dist/flows/chain-types.d.ts +18 -18
  76. package/dist/flows/gate-evaluator.d.ts.map +1 -1
  77. package/dist/flows/gate-evaluator.js +22 -0
  78. package/dist/flows/gate-evaluator.js.map +1 -1
  79. package/dist/flows/types.d.ts +157 -28
  80. package/dist/flows/types.d.ts.map +1 -1
  81. package/dist/flows/types.js +4 -0
  82. package/dist/flows/types.js.map +1 -1
  83. package/dist/index.d.ts +10 -2
  84. package/dist/index.d.ts.map +1 -1
  85. package/dist/index.js +9 -1
  86. package/dist/index.js.map +1 -1
  87. package/dist/intake/intake-pipeline.d.ts.map +1 -1
  88. package/dist/intake/intake-pipeline.js +1 -0
  89. package/dist/intake/intake-pipeline.js.map +1 -1
  90. package/dist/intake/text-ingester.d.ts.map +1 -1
  91. package/dist/intake/text-ingester.js +2 -0
  92. package/dist/intake/text-ingester.js.map +1 -1
  93. package/dist/llm/key-pool.d.ts +1 -1
  94. package/dist/llm/key-pool.d.ts.map +1 -1
  95. package/dist/llm/key-pool.js +3 -4
  96. package/dist/llm/key-pool.js.map +1 -1
  97. package/dist/llm/utils.d.ts.map +1 -1
  98. package/dist/llm/utils.js +2 -0
  99. package/dist/llm/utils.js.map +1 -1
  100. package/dist/migrations/migration-runner.test-helpers.d.ts +13 -0
  101. package/dist/migrations/migration-runner.test-helpers.d.ts.map +1 -0
  102. package/dist/migrations/migration-runner.test-helpers.js +47 -0
  103. package/dist/migrations/migration-runner.test-helpers.js.map +1 -0
  104. package/dist/operator/operator-profile.d.ts +44 -0
  105. package/dist/operator/operator-profile.d.ts.map +1 -0
  106. package/dist/operator/operator-profile.js +383 -0
  107. package/dist/operator/operator-profile.js.map +1 -0
  108. package/dist/operator/operator-signals.d.ts +45 -0
  109. package/dist/operator/operator-signals.d.ts.map +1 -0
  110. package/dist/operator/operator-signals.js +228 -0
  111. package/dist/operator/operator-signals.js.map +1 -0
  112. package/dist/operator/operator-types.d.ts +360 -0
  113. package/dist/operator/operator-types.d.ts.map +1 -0
  114. package/dist/operator/operator-types.js +24 -0
  115. package/dist/operator/operator-types.js.map +1 -0
  116. package/dist/packs/types.d.ts +27 -27
  117. package/dist/paths.d.ts +40 -0
  118. package/dist/paths.d.ts.map +1 -0
  119. package/dist/paths.js +98 -0
  120. package/dist/paths.js.map +1 -0
  121. package/dist/persistence/index.d.ts +1 -1
  122. package/dist/persistence/index.d.ts.map +1 -1
  123. package/dist/persistence/index.js +1 -1
  124. package/dist/persistence/index.js.map +1 -1
  125. package/dist/persistence/sqlite-provider.d.ts +2 -0
  126. package/dist/persistence/sqlite-provider.d.ts.map +1 -1
  127. package/dist/persistence/sqlite-provider.js +8 -5
  128. package/dist/persistence/sqlite-provider.js.map +1 -1
  129. package/dist/planning/evidence-collector.d.ts +13 -1
  130. package/dist/planning/evidence-collector.d.ts.map +1 -1
  131. package/dist/planning/evidence-collector.js +33 -0
  132. package/dist/planning/evidence-collector.js.map +1 -1
  133. package/dist/planning/gap-analysis.d.ts +5 -4
  134. package/dist/planning/gap-analysis.d.ts.map +1 -1
  135. package/dist/planning/gap-analysis.js +7 -341
  136. package/dist/planning/gap-analysis.js.map +1 -1
  137. package/dist/planning/gap-passes.d.ts +19 -0
  138. package/dist/planning/gap-passes.d.ts.map +1 -0
  139. package/dist/planning/gap-passes.js +174 -0
  140. package/dist/planning/gap-passes.js.map +1 -0
  141. package/dist/planning/gap-patterns.d.ts +29 -0
  142. package/dist/planning/gap-patterns.d.ts.map +1 -0
  143. package/dist/planning/gap-patterns.js +175 -0
  144. package/dist/planning/gap-patterns.js.map +1 -0
  145. package/dist/planning/gap-types.d.ts +1 -1
  146. package/dist/planning/gap-types.d.ts.map +1 -1
  147. package/dist/planning/gap-types.js +1 -0
  148. package/dist/planning/gap-types.js.map +1 -1
  149. package/dist/planning/github-projection.d.ts +122 -0
  150. package/dist/planning/github-projection.d.ts.map +1 -0
  151. package/dist/planning/github-projection.js +313 -0
  152. package/dist/planning/github-projection.js.map +1 -0
  153. package/dist/planning/impact-analyzer.d.ts +26 -0
  154. package/dist/planning/impact-analyzer.d.ts.map +1 -0
  155. package/dist/planning/impact-analyzer.js +201 -0
  156. package/dist/planning/impact-analyzer.js.map +1 -0
  157. package/dist/planning/plan-lifecycle.d.ts +136 -0
  158. package/dist/planning/plan-lifecycle.d.ts.map +1 -0
  159. package/dist/planning/plan-lifecycle.js +309 -0
  160. package/dist/planning/plan-lifecycle.js.map +1 -0
  161. package/dist/planning/planner-types.d.ts +202 -0
  162. package/dist/planning/planner-types.d.ts.map +1 -0
  163. package/dist/planning/planner-types.js +6 -0
  164. package/dist/planning/planner-types.js.map +1 -0
  165. package/dist/planning/planner.d.ts +31 -383
  166. package/dist/planning/planner.d.ts.map +1 -1
  167. package/dist/planning/planner.js +151 -832
  168. package/dist/planning/planner.js.map +1 -1
  169. package/dist/planning/rationalization-detector.d.ts +32 -0
  170. package/dist/planning/rationalization-detector.d.ts.map +1 -0
  171. package/dist/planning/rationalization-detector.js +89 -0
  172. package/dist/planning/rationalization-detector.js.map +1 -0
  173. package/dist/planning/reconciliation-engine.d.ts +47 -0
  174. package/dist/planning/reconciliation-engine.d.ts.map +1 -0
  175. package/dist/planning/reconciliation-engine.js +128 -0
  176. package/dist/planning/reconciliation-engine.js.map +1 -0
  177. package/dist/planning/task-verifier.d.ts +85 -0
  178. package/dist/planning/task-verifier.d.ts.map +1 -0
  179. package/dist/planning/task-verifier.js +235 -0
  180. package/dist/planning/task-verifier.js.map +1 -0
  181. package/dist/plugins/types.d.ts +4 -4
  182. package/dist/runtime/admin-ops.d.ts +2 -2
  183. package/dist/runtime/admin-ops.d.ts.map +1 -1
  184. package/dist/runtime/admin-ops.js +44 -17
  185. package/dist/runtime/admin-ops.js.map +1 -1
  186. package/dist/runtime/admin-setup-ops.d.ts.map +1 -1
  187. package/dist/runtime/admin-setup-ops.js +22 -46
  188. package/dist/runtime/admin-setup-ops.js.map +1 -1
  189. package/dist/runtime/archive-ops.d.ts +10 -0
  190. package/dist/runtime/archive-ops.d.ts.map +1 -0
  191. package/dist/runtime/archive-ops.js +310 -0
  192. package/dist/runtime/archive-ops.js.map +1 -0
  193. package/dist/runtime/branching-ops.d.ts +12 -0
  194. package/dist/runtime/branching-ops.d.ts.map +1 -0
  195. package/dist/runtime/branching-ops.js +100 -0
  196. package/dist/runtime/branching-ops.js.map +1 -0
  197. package/dist/runtime/capture-ops.d.ts.map +1 -1
  198. package/dist/runtime/capture-ops.js +42 -7
  199. package/dist/runtime/capture-ops.js.map +1 -1
  200. package/dist/runtime/claude-md-helpers.js +1 -1
  201. package/dist/runtime/claude-md-helpers.js.map +1 -1
  202. package/dist/runtime/context-health.d.ts +31 -0
  203. package/dist/runtime/context-health.d.ts.map +1 -0
  204. package/dist/runtime/context-health.js +57 -0
  205. package/dist/runtime/context-health.js.map +1 -0
  206. package/dist/runtime/facades/archive-facade.d.ts +10 -0
  207. package/dist/runtime/facades/archive-facade.d.ts.map +1 -0
  208. package/dist/runtime/facades/archive-facade.js +11 -0
  209. package/dist/runtime/facades/archive-facade.js.map +1 -0
  210. package/dist/runtime/facades/brain-facade.d.ts.map +1 -1
  211. package/dist/runtime/facades/brain-facade.js +2 -0
  212. package/dist/runtime/facades/brain-facade.js.map +1 -1
  213. package/dist/runtime/facades/branching-facade.d.ts +7 -0
  214. package/dist/runtime/facades/branching-facade.d.ts.map +1 -0
  215. package/dist/runtime/facades/branching-facade.js +8 -0
  216. package/dist/runtime/facades/branching-facade.js.map +1 -0
  217. package/dist/runtime/facades/chat-facade.d.ts +7 -0
  218. package/dist/runtime/facades/chat-facade.d.ts.map +1 -1
  219. package/dist/runtime/facades/chat-facade.js +15 -800
  220. package/dist/runtime/facades/chat-facade.js.map +1 -1
  221. package/dist/runtime/facades/chat-service-ops.d.ts +9 -0
  222. package/dist/runtime/facades/chat-service-ops.d.ts.map +1 -0
  223. package/dist/runtime/facades/chat-service-ops.js +332 -0
  224. package/dist/runtime/facades/chat-service-ops.js.map +1 -0
  225. package/dist/runtime/facades/chat-session-ops.d.ts +8 -0
  226. package/dist/runtime/facades/chat-session-ops.d.ts.map +1 -0
  227. package/dist/runtime/facades/chat-session-ops.js +136 -0
  228. package/dist/runtime/facades/chat-session-ops.js.map +1 -0
  229. package/dist/runtime/facades/chat-state.d.ts +31 -0
  230. package/dist/runtime/facades/chat-state.d.ts.map +1 -0
  231. package/dist/runtime/facades/chat-state.js +32 -0
  232. package/dist/runtime/facades/chat-state.js.map +1 -0
  233. package/dist/runtime/facades/chat-transport-ops.d.ts +9 -0
  234. package/dist/runtime/facades/chat-transport-ops.d.ts.map +1 -0
  235. package/dist/runtime/facades/chat-transport-ops.js +337 -0
  236. package/dist/runtime/facades/chat-transport-ops.js.map +1 -0
  237. package/dist/runtime/facades/control-facade.d.ts.map +1 -1
  238. package/dist/runtime/facades/control-facade.js +4 -1
  239. package/dist/runtime/facades/control-facade.js.map +1 -1
  240. package/dist/runtime/facades/index.d.ts.map +1 -1
  241. package/dist/runtime/facades/index.js +48 -0
  242. package/dist/runtime/facades/index.js.map +1 -1
  243. package/dist/runtime/facades/intake-facade.d.ts +9 -0
  244. package/dist/runtime/facades/intake-facade.d.ts.map +1 -0
  245. package/dist/runtime/facades/intake-facade.js +11 -0
  246. package/dist/runtime/facades/intake-facade.js.map +1 -0
  247. package/dist/runtime/facades/links-facade.d.ts +9 -0
  248. package/dist/runtime/facades/links-facade.d.ts.map +1 -0
  249. package/dist/runtime/facades/links-facade.js +10 -0
  250. package/dist/runtime/facades/links-facade.js.map +1 -0
  251. package/dist/runtime/facades/memory-facade.d.ts.map +1 -1
  252. package/dist/runtime/facades/memory-facade.js +75 -6
  253. package/dist/runtime/facades/memory-facade.js.map +1 -1
  254. package/dist/runtime/facades/operator-facade.d.ts +8 -0
  255. package/dist/runtime/facades/operator-facade.d.ts.map +1 -0
  256. package/dist/runtime/facades/operator-facade.js +220 -0
  257. package/dist/runtime/facades/operator-facade.js.map +1 -0
  258. package/dist/runtime/facades/orchestrate-facade.js +3 -3
  259. package/dist/runtime/facades/orchestrate-facade.js.map +1 -1
  260. package/dist/runtime/facades/plan-facade.d.ts.map +1 -1
  261. package/dist/runtime/facades/plan-facade.js +42 -6
  262. package/dist/runtime/facades/plan-facade.js.map +1 -1
  263. package/dist/runtime/facades/review-facade.d.ts +7 -0
  264. package/dist/runtime/facades/review-facade.d.ts.map +1 -0
  265. package/dist/runtime/facades/review-facade.js +8 -0
  266. package/dist/runtime/facades/review-facade.js.map +1 -0
  267. package/dist/runtime/facades/sync-facade.d.ts +7 -0
  268. package/dist/runtime/facades/sync-facade.d.ts.map +1 -0
  269. package/dist/runtime/facades/sync-facade.js +8 -0
  270. package/dist/runtime/facades/sync-facade.js.map +1 -0
  271. package/dist/runtime/facades/tier-facade.d.ts +7 -0
  272. package/dist/runtime/facades/tier-facade.d.ts.map +1 -0
  273. package/dist/runtime/facades/tier-facade.js +8 -0
  274. package/dist/runtime/facades/tier-facade.js.map +1 -0
  275. package/dist/runtime/facades/vault-facade.d.ts +12 -1
  276. package/dist/runtime/facades/vault-facade.d.ts.map +1 -1
  277. package/dist/runtime/facades/vault-facade.js +55 -251
  278. package/dist/runtime/facades/vault-facade.js.map +1 -1
  279. package/dist/runtime/github-integration.d.ts +49 -0
  280. package/dist/runtime/github-integration.d.ts.map +1 -0
  281. package/dist/runtime/github-integration.js +120 -0
  282. package/dist/runtime/github-integration.js.map +1 -0
  283. package/dist/runtime/grading-ops.js +1 -1
  284. package/dist/runtime/grading-ops.js.map +1 -1
  285. package/dist/runtime/memory-extra-ops.d.ts.map +1 -1
  286. package/dist/runtime/memory-extra-ops.js +6 -2
  287. package/dist/runtime/memory-extra-ops.js.map +1 -1
  288. package/dist/runtime/orchestrate-ops.d.ts.map +1 -1
  289. package/dist/runtime/orchestrate-ops.js +386 -37
  290. package/dist/runtime/orchestrate-ops.js.map +1 -1
  291. package/dist/runtime/planning-extra-ops.d.ts.map +1 -1
  292. package/dist/runtime/planning-extra-ops.js +69 -4
  293. package/dist/runtime/planning-extra-ops.js.map +1 -1
  294. package/dist/runtime/review-ops.d.ts +10 -0
  295. package/dist/runtime/review-ops.d.ts.map +1 -0
  296. package/dist/runtime/review-ops.js +97 -0
  297. package/dist/runtime/review-ops.js.map +1 -0
  298. package/dist/runtime/runtime.d.ts.map +1 -1
  299. package/dist/runtime/runtime.js +29 -12
  300. package/dist/runtime/runtime.js.map +1 -1
  301. package/dist/runtime/session-briefing.d.ts +3 -0
  302. package/dist/runtime/session-briefing.d.ts.map +1 -1
  303. package/dist/runtime/session-briefing.js +72 -1
  304. package/dist/runtime/session-briefing.js.map +1 -1
  305. package/dist/runtime/sync-ops.d.ts +12 -0
  306. package/dist/runtime/sync-ops.d.ts.map +1 -0
  307. package/dist/runtime/sync-ops.js +288 -0
  308. package/dist/runtime/sync-ops.js.map +1 -0
  309. package/dist/runtime/tier-ops.d.ts +13 -0
  310. package/dist/runtime/tier-ops.d.ts.map +1 -0
  311. package/dist/runtime/tier-ops.js +110 -0
  312. package/dist/runtime/tier-ops.js.map +1 -0
  313. package/dist/runtime/types.d.ts +10 -4
  314. package/dist/runtime/types.d.ts.map +1 -1
  315. package/dist/runtime/vault-extra-ops.d.ts +5 -4
  316. package/dist/runtime/vault-extra-ops.d.ts.map +1 -1
  317. package/dist/runtime/vault-extra-ops.js +5 -300
  318. package/dist/runtime/vault-extra-ops.js.map +1 -1
  319. package/dist/runtime/vault-sharing-ops.d.ts +4 -4
  320. package/dist/runtime/vault-sharing-ops.d.ts.map +1 -1
  321. package/dist/runtime/vault-sharing-ops.js +5 -300
  322. package/dist/runtime/vault-sharing-ops.js.map +1 -1
  323. package/dist/skills/sync-skills.d.ts +27 -0
  324. package/dist/skills/sync-skills.d.ts.map +1 -0
  325. package/dist/skills/sync-skills.js +81 -0
  326. package/dist/skills/sync-skills.js.map +1 -0
  327. package/dist/update-check.d.ts +14 -0
  328. package/dist/update-check.d.ts.map +1 -0
  329. package/dist/update-check.js +96 -0
  330. package/dist/update-check.js.map +1 -0
  331. package/dist/vault/linking.d.ts +10 -12
  332. package/dist/vault/linking.d.ts.map +1 -1
  333. package/dist/vault/linking.js +140 -161
  334. package/dist/vault/linking.js.map +1 -1
  335. package/dist/vault/vault-entries.d.ts +69 -0
  336. package/dist/vault/vault-entries.d.ts.map +1 -0
  337. package/dist/vault/vault-entries.js +299 -0
  338. package/dist/vault/vault-entries.js.map +1 -0
  339. package/dist/vault/vault-interfaces.d.ts +153 -0
  340. package/dist/vault/vault-interfaces.d.ts.map +1 -0
  341. package/dist/vault/vault-interfaces.js +2 -0
  342. package/dist/vault/vault-interfaces.js.map +1 -0
  343. package/dist/vault/vault-maintenance.d.ts +40 -0
  344. package/dist/vault/vault-maintenance.d.ts.map +1 -0
  345. package/dist/vault/vault-maintenance.js +146 -0
  346. package/dist/vault/vault-maintenance.js.map +1 -0
  347. package/dist/vault/vault-markdown-sync.d.ts +22 -0
  348. package/dist/vault/vault-markdown-sync.d.ts.map +1 -0
  349. package/dist/vault/vault-markdown-sync.js +143 -0
  350. package/dist/vault/vault-markdown-sync.js.map +1 -0
  351. package/dist/vault/vault-memories.d.ts +61 -0
  352. package/dist/vault/vault-memories.d.ts.map +1 -0
  353. package/dist/vault/vault-memories.js +242 -0
  354. package/dist/vault/vault-memories.js.map +1 -0
  355. package/dist/vault/vault-schema.d.ts +9 -0
  356. package/dist/vault/vault-schema.d.ts.map +1 -0
  357. package/dist/vault/vault-schema.js +205 -0
  358. package/dist/vault/vault-schema.js.map +1 -0
  359. package/dist/vault/vault.d.ts +29 -81
  360. package/dist/vault/vault.d.ts.map +1 -1
  361. package/dist/vault/vault.js +82 -931
  362. package/dist/vault/vault.js.map +1 -1
  363. package/package.json +7 -7
  364. package/src/agency/agency-manager.test.ts +620 -0
  365. package/src/agency/default-rules.test.ts +236 -0
  366. package/src/{__tests__ → brain}/brain-intelligence.test.ts +37 -14
  367. package/src/{__tests__ → brain}/brain.test.ts +1 -1
  368. package/src/brain/intelligence.ts +196 -15
  369. package/src/brain/learning-radar.ts +22 -1
  370. package/src/{__tests__ → brain}/second-brain-features.test.ts +4 -4
  371. package/src/{__tests__ → brain}/session-lifecycle.test.ts +2 -2
  372. package/src/capabilities/chain-mapping.test.ts +66 -0
  373. package/src/capabilities/registry.test.ts +359 -0
  374. package/src/chat/agent-loop.test.ts +384 -0
  375. package/src/chat/agent-loop.ts +2 -0
  376. package/src/{__tests__ → chat}/chat-differentiators.test.ts +3 -3
  377. package/src/{__tests__ → chat}/chat-enhanced.test.ts +4 -4
  378. package/src/{__tests__ → chat}/chat-transport.test.ts +6 -6
  379. package/src/chat/mcp-bridge.test.ts +178 -0
  380. package/src/chat/notifications.ts +2 -0
  381. package/src/chat/output-compressor.test.ts +164 -0
  382. package/src/claudemd/compose.test.ts +178 -0
  383. package/src/claudemd/compose.ts +1 -1
  384. package/src/claudemd/inject.test.ts +201 -0
  385. package/src/context/context-engine.test.ts +506 -0
  386. package/src/control/identity-manager.test.ts +305 -0
  387. package/src/control/intent-router.test.ts +360 -0
  388. package/src/control/intent-router.ts +13 -4
  389. package/src/curator/classifier.test.ts +110 -0
  390. package/src/curator/contradiction-detector.test.ts +205 -0
  391. package/src/curator/contradiction-detector.ts +87 -0
  392. package/src/{__tests__ → curator}/curator-pipeline-e2e.test.ts +10 -10
  393. package/src/{__tests__ → curator}/curator.test.ts +77 -1
  394. package/src/curator/curator.ts +160 -600
  395. package/src/curator/duplicate-detector.test.ts +245 -0
  396. package/src/curator/duplicate-detector.ts +103 -0
  397. package/src/curator/health-audit.ts +126 -0
  398. package/src/curator/metadata-enricher.ts +84 -0
  399. package/src/curator/quality-gate.test.ts +175 -0
  400. package/src/curator/schema.ts +65 -0
  401. package/src/curator/tag-manager.test.ts +173 -0
  402. package/src/curator/tag-manager.ts +109 -0
  403. package/src/domain-packs/inject-rules.test.ts +117 -0
  404. package/src/domain-packs/knowledge-installer.test.ts +163 -0
  405. package/src/domain-packs/loader.test.ts +86 -0
  406. package/src/domain-packs/pack-runtime.test.ts +140 -0
  407. package/src/domain-packs/skills-installer.test.ts +135 -0
  408. package/src/domain-packs/token-resolver.test.ts +148 -0
  409. package/src/domain-packs/types.test.ts +144 -0
  410. package/src/enforcement/adapters/claude-code.test.ts +216 -0
  411. package/src/enforcement/registry.test.ts +258 -0
  412. package/src/engine/bin/soleri-engine.ts +30 -4
  413. package/src/engine/core-ops.test.ts +254 -0
  414. package/src/engine/core-ops.ts +25 -8
  415. package/src/engine/module-manifest.test.ts +125 -0
  416. package/src/engine/module-manifest.ts +42 -2
  417. package/src/engine/register-engine.test.ts +235 -0
  418. package/src/engine/register-engine.ts +50 -3
  419. package/src/errors/classify.test.ts +203 -0
  420. package/src/errors/retry.test.ts +153 -0
  421. package/src/errors/retry.ts +2 -0
  422. package/src/errors/types.test.ts +108 -0
  423. package/src/events/event-bus.test.ts +149 -0
  424. package/src/extensions/middleware.test.ts +234 -0
  425. package/src/facades/facade-factory.test.ts +470 -0
  426. package/src/flows/chain-runner.test.ts +273 -0
  427. package/src/flows/context-router.test.ts +52 -0
  428. package/src/flows/dispatch-registry.test.ts +128 -0
  429. package/src/flows/epilogue.test.ts +113 -0
  430. package/src/flows/executor.test.ts +263 -0
  431. package/src/flows/gate-evaluator.test.ts +200 -0
  432. package/src/flows/gate-evaluator.ts +23 -0
  433. package/src/flows/types.ts +4 -0
  434. package/src/governance/governance.test.ts +842 -0
  435. package/src/{__tests__ → health}/health-registry.test.ts +75 -55
  436. package/src/health/vault-integrity.test.ts +110 -0
  437. package/src/index.ts +92 -0
  438. package/src/intake/content-classifier.test.ts +279 -0
  439. package/src/intake/dedup-gate.test.ts +147 -0
  440. package/src/intake/intake-pipeline.test.ts +508 -0
  441. package/src/intake/intake-pipeline.ts +1 -0
  442. package/src/intake/text-ingester.test.ts +200 -0
  443. package/src/intake/text-ingester.ts +2 -0
  444. package/src/llm/key-pool.test.ts +234 -0
  445. package/src/llm/key-pool.ts +3 -4
  446. package/src/llm/llm-client.test.ts +342 -0
  447. package/src/llm/oauth-discovery.test.ts +180 -0
  448. package/src/llm/utils.test.ts +371 -0
  449. package/src/llm/utils.ts +2 -0
  450. package/src/{__tests__ → logging}/logger.test.ts +44 -62
  451. package/src/loop/loop-manager.test.ts +515 -0
  452. package/src/migrations/migration-runner.edge-cases.test.ts +314 -0
  453. package/src/migrations/migration-runner.test-helpers.ts +64 -0
  454. package/src/migrations/migration-runner.test.ts +385 -0
  455. package/src/operator/auto-signal-pipeline.test.ts +207 -0
  456. package/src/operator/operator-profile-extended.test.ts +330 -0
  457. package/src/operator/operator-profile.test.ts +332 -0
  458. package/src/operator/operator-profile.ts +485 -0
  459. package/src/operator/operator-signals-extended.test.ts +257 -0
  460. package/src/operator/operator-signals.test.ts +277 -0
  461. package/src/operator/operator-signals.ts +262 -0
  462. package/src/operator/operator-types.ts +444 -0
  463. package/src/operator/prompts/hook-precompact-operator-dispatch.md +98 -0
  464. package/src/operator/prompts/subagent-soft-signal-extractor.md +130 -0
  465. package/src/operator/prompts/subagent-synthesis-cognition.md +190 -0
  466. package/src/operator/prompts/subagent-synthesis-communication.md +146 -0
  467. package/src/operator/prompts/subagent-synthesis-technical.md +170 -0
  468. package/src/operator/prompts/subagent-synthesis-trust.md +149 -0
  469. package/src/{__tests__ → packs}/pack-lockfile.test.ts +3 -3
  470. package/src/{__tests__ → packs}/pack-system.test.ts +2 -2
  471. package/src/paths.ts +115 -0
  472. package/src/persistence/index.ts +1 -1
  473. package/src/persistence/sqlite-provider.test.ts +540 -0
  474. package/src/persistence/sqlite-provider.ts +8 -5
  475. package/src/persona/defaults.test.ts +55 -0
  476. package/src/persona/loader.test.ts +67 -0
  477. package/src/persona/prompt-generator.test.ts +127 -0
  478. package/src/planning/evidence-collector.test.ts +515 -0
  479. package/src/planning/evidence-collector.ts +47 -0
  480. package/src/planning/gap-analysis-alternatives.test.ts +199 -0
  481. package/src/planning/gap-analysis.ts +21 -636
  482. package/src/planning/gap-passes.test.ts +554 -0
  483. package/src/planning/gap-passes.ts +367 -0
  484. package/src/planning/gap-patterns.test.ts +394 -0
  485. package/src/planning/gap-patterns.ts +317 -0
  486. package/src/planning/gap-types.ts +4 -1
  487. package/src/planning/github-projection.test.ts +182 -0
  488. package/src/planning/github-projection.ts +446 -0
  489. package/src/planning/impact-analyzer.test.ts +167 -0
  490. package/src/planning/impact-analyzer.ts +251 -0
  491. package/src/planning/plan-lifecycle.test.ts +379 -0
  492. package/src/planning/plan-lifecycle.ts +377 -0
  493. package/src/planning/planner-types.ts +215 -0
  494. package/src/{__tests__ → planning}/planner.test.ts +179 -15
  495. package/src/planning/planner.ts +221 -1112
  496. package/src/planning/rationalization-detector.test.ts +156 -0
  497. package/src/planning/rationalization-detector.ts +136 -0
  498. package/src/planning/reconciliation-engine.test.ts +158 -0
  499. package/src/planning/reconciliation-engine.ts +161 -0
  500. package/src/planning/task-verifier.test.ts +267 -0
  501. package/src/planning/task-verifier.ts +309 -0
  502. package/src/planning/verification-protocol.test.ts +201 -0
  503. package/src/playbooks/generic/generic-playbooks.test.ts +438 -0
  504. package/src/playbooks/index.test.ts +77 -0
  505. package/src/playbooks/playbook-executor.test.ts +253 -0
  506. package/src/playbooks/playbook-registry.test.ts +232 -0
  507. package/src/playbooks/playbook-seeder.test.ts +153 -0
  508. package/src/plugins/plugin-loader.test.ts +217 -0
  509. package/src/plugins/plugin-registry.test.ts +284 -0
  510. package/src/project/project-registry.test.ts +439 -0
  511. package/src/prompts/parser.test.ts +100 -0
  512. package/src/prompts/template-manager.test.ts +112 -0
  513. package/src/{__tests__ → queue}/async-infrastructure.test.ts +3 -3
  514. package/src/queue/job-queue.test.ts +327 -0
  515. package/src/queue/pipeline-runner.test.ts +209 -0
  516. package/src/runtime/admin-extra-ops.test.ts +513 -0
  517. package/src/runtime/admin-ops.test.ts +255 -0
  518. package/src/runtime/admin-ops.ts +45 -17
  519. package/src/runtime/admin-setup-ops.test.ts +327 -0
  520. package/src/runtime/admin-setup-ops.ts +26 -42
  521. package/src/runtime/archive-ops.test.ts +272 -0
  522. package/src/runtime/archive-ops.ts +347 -0
  523. package/src/runtime/branching-ops.test.ts +144 -0
  524. package/src/runtime/branching-ops.ts +107 -0
  525. package/src/runtime/capture-ops.test.ts +419 -0
  526. package/src/runtime/capture-ops.ts +50 -8
  527. package/src/runtime/chain-ops.test.ts +159 -0
  528. package/src/runtime/claude-md-helpers.test.ts +189 -0
  529. package/src/runtime/claude-md-helpers.ts +1 -1
  530. package/src/runtime/context-health.test.ts +76 -0
  531. package/src/runtime/context-health.ts +83 -0
  532. package/src/runtime/curator-extra-ops.test.ts +204 -0
  533. package/src/runtime/deprecation.test.ts +98 -0
  534. package/src/runtime/domain-ops.test.ts +278 -0
  535. package/src/runtime/facades/admin-facade.test.ts +330 -0
  536. package/src/runtime/facades/agency-facade.test.ts +278 -0
  537. package/src/runtime/facades/archive-facade.test.ts +308 -0
  538. package/src/runtime/facades/archive-facade.ts +14 -0
  539. package/src/runtime/facades/brain-facade.test.ts +818 -0
  540. package/src/runtime/facades/brain-facade.ts +2 -0
  541. package/src/runtime/facades/branching-facade.test.ts +43 -0
  542. package/src/runtime/facades/branching-facade.ts +11 -0
  543. package/src/runtime/facades/chat-facade.test.ts +219 -0
  544. package/src/runtime/facades/chat-facade.ts +15 -906
  545. package/src/runtime/facades/chat-service-ops.test.ts +381 -0
  546. package/src/runtime/facades/chat-service-ops.ts +376 -0
  547. package/src/runtime/facades/chat-session-ops.test.ts +212 -0
  548. package/src/runtime/facades/chat-session-ops.ts +146 -0
  549. package/src/runtime/facades/chat-state.ts +60 -0
  550. package/src/runtime/facades/chat-transport-ops.test.ts +336 -0
  551. package/src/runtime/facades/chat-transport-ops.ts +379 -0
  552. package/src/runtime/facades/context-facade.test.ts +123 -0
  553. package/src/runtime/facades/control-facade.test.ts +436 -0
  554. package/src/runtime/facades/control-facade.ts +6 -1
  555. package/src/runtime/facades/curator-facade.test.ts +303 -0
  556. package/src/runtime/facades/index.ts +48 -0
  557. package/src/runtime/facades/intake-facade.test.ts +215 -0
  558. package/src/runtime/facades/intake-facade.ts +14 -0
  559. package/src/runtime/facades/links-facade.test.ts +203 -0
  560. package/src/runtime/facades/links-facade.ts +13 -0
  561. package/src/runtime/facades/loop-facade.test.ts +262 -0
  562. package/src/runtime/facades/memory-facade.test.ts +283 -0
  563. package/src/runtime/facades/memory-facade.ts +78 -6
  564. package/src/runtime/facades/operator-facade.test.ts +221 -0
  565. package/src/runtime/facades/operator-facade.ts +244 -0
  566. package/src/runtime/facades/orchestrate-facade.test.ts +191 -0
  567. package/src/runtime/facades/orchestrate-facade.ts +3 -3
  568. package/src/runtime/facades/plan-facade.test.ts +283 -0
  569. package/src/runtime/facades/plan-facade.ts +47 -6
  570. package/src/runtime/facades/review-facade.test.ts +82 -0
  571. package/src/runtime/facades/review-facade.ts +11 -0
  572. package/src/runtime/facades/sync-facade.test.ts +113 -0
  573. package/src/runtime/facades/sync-facade.ts +11 -0
  574. package/src/runtime/facades/tier-facade.test.ts +47 -0
  575. package/src/runtime/facades/tier-facade.ts +11 -0
  576. package/src/runtime/facades/vault-facade.test.ts +563 -0
  577. package/src/runtime/facades/vault-facade.ts +66 -265
  578. package/src/runtime/feature-flags.test.ts +140 -0
  579. package/src/runtime/github-integration.test.ts +89 -0
  580. package/src/runtime/github-integration.ts +162 -0
  581. package/src/runtime/grading-ops.test.ts +172 -0
  582. package/src/runtime/grading-ops.ts +1 -1
  583. package/src/runtime/intake-ops.test.ts +261 -0
  584. package/src/runtime/loop-ops.test.ts +248 -0
  585. package/src/runtime/memory-cross-project-ops.test.ts +188 -0
  586. package/src/runtime/memory-extra-ops.test.ts +453 -0
  587. package/src/runtime/memory-extra-ops.ts +6 -2
  588. package/src/runtime/orchestrate-ops.test.ts +302 -0
  589. package/src/runtime/orchestrate-ops.ts +461 -45
  590. package/src/runtime/pack-ops.test.ts +175 -0
  591. package/src/runtime/planning-extra-ops.test.ts +593 -0
  592. package/src/runtime/planning-extra-ops.ts +74 -4
  593. package/src/{__tests__ → runtime}/playbook-ops-execution.test.ts +3 -3
  594. package/src/runtime/playbook-ops.test.ts +285 -0
  595. package/src/runtime/plugin-ops.test.ts +259 -0
  596. package/src/runtime/project-ops.test.ts +255 -0
  597. package/src/runtime/review-ops.test.ts +142 -0
  598. package/src/runtime/review-ops.ts +99 -0
  599. package/src/runtime/runtime.test.ts +363 -0
  600. package/src/runtime/runtime.ts +41 -12
  601. package/src/runtime/session-briefing.test.ts +431 -0
  602. package/src/runtime/session-briefing.ts +86 -1
  603. package/src/runtime/sync-ops.test.ts +212 -0
  604. package/src/runtime/sync-ops.ts +325 -0
  605. package/src/runtime/telemetry-ops.test.ts +157 -0
  606. package/src/runtime/tier-ops.test.ts +159 -0
  607. package/src/runtime/tier-ops.ts +119 -0
  608. package/src/runtime/types.ts +10 -4
  609. package/src/runtime/vault-extra-ops.test.ts +270 -0
  610. package/src/runtime/vault-extra-ops.ts +5 -332
  611. package/src/runtime/vault-linking-ops.test.ts +237 -0
  612. package/src/runtime/vault-sharing-ops.test.ts +127 -0
  613. package/src/runtime/vault-sharing-ops.ts +5 -329
  614. package/src/skills/sync-skills.ts +98 -0
  615. package/src/streams/normalize.test.ts +95 -0
  616. package/src/streams/replayable-stream.test.ts +166 -0
  617. package/src/telemetry/telemetry.test.ts +143 -0
  618. package/src/transport/http-server.test.ts +394 -0
  619. package/src/transport/lsp-server.test.ts +458 -0
  620. package/src/transport/rate-limiter.test.ts +126 -0
  621. package/src/transport/session-manager.test.ts +133 -0
  622. package/src/transport/token-auth.test.ts +136 -0
  623. package/src/transport/ws-server.test.ts +297 -0
  624. package/src/update-check.ts +111 -0
  625. package/src/vault/__tests__/vault-characterization.test.ts +579 -0
  626. package/src/vault/content-hash.test.ts +78 -0
  627. package/src/vault/git-vault-sync.test.ts +234 -0
  628. package/src/vault/knowledge-review.test.ts +269 -0
  629. package/src/vault/linking.test.ts +391 -0
  630. package/src/vault/linking.ts +188 -181
  631. package/src/vault/obsidian-sync.test.ts +345 -0
  632. package/src/vault/playbook.test.ts +152 -0
  633. package/src/vault/scope-detector.test.ts +185 -0
  634. package/src/vault/vault-branching.test.ts +252 -0
  635. package/src/{__tests__ → vault}/vault-connect.test.ts +1 -1
  636. package/src/vault/vault-entries.ts +426 -0
  637. package/src/vault/vault-maintenance.ts +200 -0
  638. package/src/vault/vault-manager.test.ts +206 -0
  639. package/src/vault/vault-markdown-sync.test.ts +203 -0
  640. package/src/vault/vault-markdown-sync.ts +163 -0
  641. package/src/vault/vault-memories.ts +339 -0
  642. package/src/{__tests__ → vault}/vault-scaling.test.ts +1 -1
  643. package/src/vault/vault-schema.ts +238 -0
  644. package/src/{__tests__ → vault}/vault-sharing.test.ts +4 -4
  645. package/src/{__tests__ → vault}/vault.test.ts +2 -2
  646. package/src/vault/vault.ts +87 -1123
  647. package/dist/cognee/client.d.ts +0 -43
  648. package/dist/cognee/client.d.ts.map +0 -1
  649. package/dist/cognee/client.js +0 -375
  650. package/dist/cognee/client.js.map +0 -1
  651. package/dist/cognee/sync-manager.d.ts +0 -153
  652. package/dist/cognee/sync-manager.d.ts.map +0 -1
  653. package/dist/cognee/sync-manager.js +0 -390
  654. package/dist/cognee/sync-manager.js.map +0 -1
  655. package/dist/cognee/types.d.ts +0 -62
  656. package/dist/cognee/types.d.ts.map +0 -1
  657. package/dist/cognee/types.js +0 -3
  658. package/dist/cognee/types.js.map +0 -1
  659. package/dist/governance/index.d.ts +0 -3
  660. package/dist/governance/index.d.ts.map +0 -1
  661. package/dist/governance/index.js +0 -2
  662. package/dist/governance/index.js.map +0 -1
  663. package/dist/health/doctor-checks.d.ts +0 -15
  664. package/dist/health/doctor-checks.d.ts.map +0 -1
  665. package/dist/health/doctor-checks.js +0 -98
  666. package/dist/health/doctor-checks.js.map +0 -1
  667. package/dist/persistence/postgres-provider.d.ts +0 -81
  668. package/dist/persistence/postgres-provider.d.ts.map +0 -1
  669. package/dist/persistence/postgres-provider.js +0 -256
  670. package/dist/persistence/postgres-provider.js.map +0 -1
  671. package/dist/runtime/cognee-sync-ops.d.ts +0 -12
  672. package/dist/runtime/cognee-sync-ops.d.ts.map +0 -1
  673. package/dist/runtime/cognee-sync-ops.js +0 -93
  674. package/dist/runtime/cognee-sync-ops.js.map +0 -1
  675. package/dist/runtime/core-ops.d.ts +0 -23
  676. package/dist/runtime/core-ops.d.ts.map +0 -1
  677. package/dist/runtime/core-ops.js +0 -1296
  678. package/dist/runtime/core-ops.js.map +0 -1
  679. package/dist/runtime/facades/cognee-facade.d.ts +0 -8
  680. package/dist/runtime/facades/cognee-facade.d.ts.map +0 -1
  681. package/dist/runtime/facades/cognee-facade.js +0 -156
  682. package/dist/runtime/facades/cognee-facade.js.map +0 -1
  683. package/src/__tests__/admin-extra-ops.test.ts +0 -484
  684. package/src/__tests__/admin-ops.test.ts +0 -268
  685. package/src/__tests__/admin-setup-ops.test.ts +0 -355
  686. package/src/__tests__/agency-manager.test.ts +0 -374
  687. package/src/__tests__/agent-loop.test.ts +0 -256
  688. package/src/__tests__/capture-ops.test.ts +0 -784
  689. package/src/__tests__/claudemd.test.ts +0 -282
  690. package/src/__tests__/content-hash.test.ts +0 -60
  691. package/src/__tests__/context-engine.test.ts +0 -251
  692. package/src/__tests__/core-ops.test.ts +0 -550
  693. package/src/__tests__/curator-extra-ops.test.ts +0 -383
  694. package/src/__tests__/deprecation.test.ts +0 -78
  695. package/src/__tests__/domain-ops.test.ts +0 -226
  696. package/src/__tests__/domain-packs.test.ts +0 -421
  697. package/src/__tests__/enforcement.test.ts +0 -153
  698. package/src/__tests__/errors.test.ts +0 -388
  699. package/src/__tests__/extensions.test.ts +0 -233
  700. package/src/__tests__/facade-factory.test.ts +0 -271
  701. package/src/__tests__/feature-flags.test.ts +0 -137
  702. package/src/__tests__/flows.test.ts +0 -604
  703. package/src/__tests__/git-vault-sync.test.ts +0 -230
  704. package/src/__tests__/governance.test.ts +0 -522
  705. package/src/__tests__/grading-ops.test.ts +0 -361
  706. package/src/__tests__/identity-manager.test.ts +0 -243
  707. package/src/__tests__/intake-pipeline.test.ts +0 -162
  708. package/src/__tests__/intent-router.test.ts +0 -222
  709. package/src/__tests__/knowledge-review.test.ts +0 -104
  710. package/src/__tests__/llm-client.test.ts +0 -69
  711. package/src/__tests__/llm.test.ts +0 -556
  712. package/src/__tests__/loader.test.ts +0 -176
  713. package/src/__tests__/loop-ops.test.ts +0 -469
  714. package/src/__tests__/lsp-transport.test.ts +0 -442
  715. package/src/__tests__/memory-cross-project-ops.test.ts +0 -248
  716. package/src/__tests__/memory-extra-ops.test.ts +0 -352
  717. package/src/__tests__/migration-runner.test.ts +0 -170
  718. package/src/__tests__/module-manifest-drift.test.ts +0 -59
  719. package/src/__tests__/normalize.test.ts +0 -85
  720. package/src/__tests__/obsidian-sync.test.ts +0 -354
  721. package/src/__tests__/orchestrate-ops.test.ts +0 -289
  722. package/src/__tests__/pack-ops.test.ts +0 -146
  723. package/src/__tests__/persistence.test.ts +0 -291
  724. package/src/__tests__/planning-extra-ops.test.ts +0 -706
  725. package/src/__tests__/playbook-executor.test.ts +0 -249
  726. package/src/__tests__/playbook-registry.test.ts +0 -326
  727. package/src/__tests__/playbook-seeder.test.ts +0 -163
  728. package/src/__tests__/playbook.test.ts +0 -389
  729. package/src/__tests__/plugin-ops.test.ts +0 -411
  730. package/src/__tests__/plugin-system.test.ts +0 -509
  731. package/src/__tests__/project-ops.test.ts +0 -381
  732. package/src/__tests__/replayable-stream.test.ts +0 -177
  733. package/src/__tests__/runtime.test.ts +0 -95
  734. package/src/__tests__/scope-detector.test.ts +0 -121
  735. package/src/__tests__/template-manager.test.ts +0 -222
  736. package/src/__tests__/token-resolver.test.ts +0 -79
  737. package/src/__tests__/transport.test.ts +0 -758
  738. package/src/__tests__/vault-branching.test.ts +0 -274
  739. package/src/__tests__/vault-extra-ops.test.ts +0 -482
  740. package/src/__tests__/vault-integrity.test.ts +0 -71
  741. package/src/__tests__/vault-manager.test.ts +0 -238
  742. package/src/__tests__/ws-transport.test.ts +0 -479
  743. package/src/engine/index.ts +0 -21
  744. package/src/persona/index.ts +0 -9
@@ -268,17 +268,26 @@ export class IntentRouter {
268
268
  // ─── Mode Management ───────────────────────────────────────────────
269
269
 
270
270
  morph(mode: OperationalMode): MorphResult {
271
- const row = this.provider.get<ModeRow>('SELECT * FROM agent_modes WHERE mode = ?', [mode]);
271
+ // Handle "reset" as a built-in alias for GENERAL-MODE
272
+ const resolvedMode: OperationalMode = (mode as string) === 'reset' ? 'GENERAL-MODE' : mode;
273
+
274
+ const row = this.provider.get<ModeRow>('SELECT * FROM agent_modes WHERE mode = ?', [
275
+ resolvedMode,
276
+ ]);
272
277
 
273
278
  if (!row) {
274
- throw new Error(`Unknown mode: ${mode}`);
279
+ const available = this.provider
280
+ .all<{ mode: string }>('SELECT mode FROM agent_modes ORDER BY mode')
281
+ .map((r) => r.mode)
282
+ .join(', ');
283
+ throw new Error(`Unknown mode: ${mode}. Available: ${available}`);
275
284
  }
276
285
 
277
286
  const previousMode = this.currentMode;
278
- this.currentMode = mode;
287
+ this.currentMode = resolvedMode;
279
288
  const behaviorRules = JSON.parse(row.behavior_rules) as string[];
280
289
 
281
- return { previousMode, currentMode: mode, behaviorRules };
290
+ return { previousMode, currentMode: resolvedMode, behaviorRules };
282
291
  }
283
292
 
284
293
  getCurrentMode(): OperationalMode {
@@ -0,0 +1,110 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { classifyEntry } from './classifier.js';
3
+ import type { IntelligenceEntry } from '../intelligence/types.js';
4
+ import type { LLMClient } from '../llm/llm-client.js';
5
+
6
+ function makeEntry(overrides: Partial<IntelligenceEntry> = {}): IntelligenceEntry {
7
+ return {
8
+ id: overrides.id ?? 'test-1',
9
+ type: overrides.type ?? 'pattern',
10
+ domain: overrides.domain ?? 'testing',
11
+ title: overrides.title ?? 'Test Pattern',
12
+ severity: overrides.severity ?? 'warning',
13
+ description: overrides.description ?? 'A test pattern.',
14
+ tags: overrides.tags ?? ['testing'],
15
+ };
16
+ }
17
+
18
+ function mockLLM(response: string): LLMClient {
19
+ return {
20
+ complete: vi.fn().mockResolvedValue({ text: response }),
21
+ } as unknown as LLMClient;
22
+ }
23
+
24
+ describe('classifyEntry', () => {
25
+ it('returns fallback when llm is null', async () => {
26
+ const result = await classifyEntry(makeEntry(), null);
27
+ expect(result.classified).toBe(false);
28
+ expect(result.suggestedDomain).toBeNull();
29
+ expect(result.suggestedSeverity).toBeNull();
30
+ expect(result.suggestedTags).toEqual([]);
31
+ expect(result.confidence).toBe(0);
32
+ });
33
+
34
+ it('classifies entry with valid LLM response', async () => {
35
+ const llm = mockLLM(
36
+ JSON.stringify({
37
+ domain: 'security',
38
+ severity: 'critical',
39
+ tags: ['auth', 'jwt', 'security'],
40
+ confidence: 0.9,
41
+ }),
42
+ );
43
+
44
+ const result = await classifyEntry(makeEntry({ title: 'Use JWT securely' }), llm);
45
+ expect(result.classified).toBe(true);
46
+ expect(result.suggestedDomain).toBe('security');
47
+ expect(result.suggestedSeverity).toBe('critical');
48
+ expect(result.suggestedTags).toEqual(['auth', 'jwt', 'security']);
49
+ expect(result.confidence).toBe(0.9);
50
+ });
51
+
52
+ it('returns fallback with error on LLM failure', async () => {
53
+ const llm = {
54
+ complete: vi.fn().mockRejectedValue(new Error('LLM unavailable')),
55
+ } as unknown as LLMClient;
56
+
57
+ const result = await classifyEntry(makeEntry(), llm);
58
+ expect(result.classified).toBe(false);
59
+ expect(result.error).toBe('LLM unavailable');
60
+ });
61
+
62
+ it('returns fallback with error on invalid JSON response', async () => {
63
+ const llm = mockLLM('not valid json');
64
+ const result = await classifyEntry(makeEntry(), llm);
65
+ expect(result.classified).toBe(false);
66
+ expect(result.error).toBeDefined();
67
+ });
68
+
69
+ it('handles missing fields in LLM response gracefully', async () => {
70
+ const llm = mockLLM(JSON.stringify({}));
71
+ const result = await classifyEntry(makeEntry(), llm);
72
+ expect(result.classified).toBe(true);
73
+ expect(result.suggestedDomain).toBeNull();
74
+ expect(result.suggestedSeverity).toBeNull();
75
+ expect(result.suggestedTags).toEqual([]);
76
+ expect(result.confidence).toBe(0.5);
77
+ });
78
+
79
+ it('passes entry fields to LLM prompt', async () => {
80
+ const llm = mockLLM(
81
+ JSON.stringify({ domain: 'test', severity: 'warning', tags: [], confidence: 0.5 }),
82
+ );
83
+ const entry = makeEntry({
84
+ title: 'Specific Title',
85
+ type: 'anti-pattern',
86
+ tags: ['tag-a', 'tag-b'],
87
+ description: 'Specific description.',
88
+ });
89
+
90
+ await classifyEntry(entry, llm);
91
+
92
+ const call = (llm.complete as ReturnType<typeof vi.fn>).mock.calls[0][0];
93
+ expect(call.userPrompt).toContain('Specific Title');
94
+ expect(call.userPrompt).toContain('anti-pattern');
95
+ expect(call.userPrompt).toContain('tag-a, tag-b');
96
+ expect(call.userPrompt).toContain('Specific description.');
97
+ });
98
+
99
+ it('uses empty tags placeholder when entry has no tags', async () => {
100
+ const llm = mockLLM(
101
+ JSON.stringify({ domain: 'test', severity: 'warning', tags: [], confidence: 0.5 }),
102
+ );
103
+ const entry = makeEntry({ tags: [] });
104
+
105
+ await classifyEntry(entry, llm);
106
+
107
+ const call = (llm.complete as ReturnType<typeof vi.fn>).mock.calls[0][0];
108
+ expect(call.userPrompt).toContain('none');
109
+ });
110
+ });
@@ -0,0 +1,205 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import type { IntelligenceEntry } from '../intelligence/types.js';
3
+ import { findContradictions, DEFAULT_CONTRADICTION_THRESHOLD } from './contradiction-detector.js';
4
+
5
+ function makeEntry(overrides: Partial<IntelligenceEntry> = {}): IntelligenceEntry {
6
+ return {
7
+ id: overrides.id ?? 'test-1',
8
+ type: overrides.type ?? 'pattern',
9
+ domain: overrides.domain ?? 'testing',
10
+ title: overrides.title ?? 'Test Pattern',
11
+ severity: overrides.severity ?? 'warning',
12
+ description: overrides.description ?? 'A test pattern for testing.',
13
+ tags: overrides.tags ?? ['testing'],
14
+ };
15
+ }
16
+
17
+ describe('contradiction-detector', () => {
18
+ describe('constants', () => {
19
+ it('exports DEFAULT_CONTRADICTION_THRESHOLD', () => {
20
+ expect(DEFAULT_CONTRADICTION_THRESHOLD).toBe(0.4);
21
+ });
22
+ });
23
+
24
+ describe('findContradictions', () => {
25
+ it('returns empty array when no entries', () => {
26
+ expect(findContradictions([])).toEqual([]);
27
+ });
28
+
29
+ it('returns empty array when no anti-patterns', () => {
30
+ const entries = [
31
+ makeEntry({ id: 'p1', type: 'pattern' }),
32
+ makeEntry({ id: 'p2', type: 'pattern' }),
33
+ ];
34
+ expect(findContradictions(entries)).toEqual([]);
35
+ });
36
+
37
+ it('returns empty array when no patterns', () => {
38
+ const entries = [
39
+ makeEntry({ id: 'ap1', type: 'anti-pattern' }),
40
+ makeEntry({ id: 'ap2', type: 'anti-pattern' }),
41
+ ];
42
+ expect(findContradictions(entries)).toEqual([]);
43
+ });
44
+
45
+ it('detects contradictions between similar pattern and anti-pattern', () => {
46
+ const entries = [
47
+ makeEntry({
48
+ id: 'p-inline',
49
+ type: 'pattern',
50
+ title: 'Use inline styles for dynamic values',
51
+ description: 'Apply inline styles when values are computed at runtime.',
52
+ tags: ['styling'],
53
+ }),
54
+ makeEntry({
55
+ id: 'ap-inline',
56
+ type: 'anti-pattern',
57
+ title: 'Avoid inline styles for styling',
58
+ description: 'Never use inline styles — prefer CSS classes.',
59
+ tags: ['styling'],
60
+ }),
61
+ ];
62
+ const results = findContradictions(entries, 0.2);
63
+ expect(results.length).toBeGreaterThan(0);
64
+ expect(results[0].patternId).toBe('p-inline');
65
+ expect(results[0].antipatternId).toBe('ap-inline');
66
+ expect(results[0].similarity).toBeGreaterThanOrEqual(0.2);
67
+ });
68
+
69
+ it('skips unrelated pattern/anti-pattern pairs', () => {
70
+ const entries = [
71
+ makeEntry({
72
+ id: 'p-auth',
73
+ type: 'pattern',
74
+ title: 'Use JWT for authentication',
75
+ description: 'JSON Web Tokens for stateless auth.',
76
+ tags: ['auth'],
77
+ }),
78
+ makeEntry({
79
+ id: 'ap-css',
80
+ type: 'anti-pattern',
81
+ title: 'Avoid CSS important',
82
+ description: 'Never use important in CSS declarations.',
83
+ tags: ['styling'],
84
+ }),
85
+ ];
86
+ const results = findContradictions(entries, 0.8);
87
+ expect(results.length).toBe(0);
88
+ });
89
+
90
+ it('uses searchFn when provided', () => {
91
+ const pattern = makeEntry({
92
+ id: 'p1',
93
+ type: 'pattern',
94
+ title: 'Use inline styles',
95
+ description: 'Apply inline styles.',
96
+ });
97
+ const antipattern = makeEntry({
98
+ id: 'ap1',
99
+ type: 'anti-pattern',
100
+ title: 'Avoid inline styles',
101
+ description: 'Do not use inline styles.',
102
+ });
103
+ const entries = [pattern, antipattern];
104
+
105
+ const searchFn = vi.fn().mockReturnValue([pattern]);
106
+ const results = findContradictions(entries, 0.2, searchFn);
107
+
108
+ expect(searchFn).toHaveBeenCalledWith('Avoid inline styles');
109
+ expect(results.length).toBeGreaterThan(0);
110
+ });
111
+
112
+ it('falls back to all patterns when searchFn returns empty', () => {
113
+ const entries = [
114
+ makeEntry({
115
+ id: 'p1',
116
+ type: 'pattern',
117
+ title: 'Use inline styles',
118
+ description: 'Inline.',
119
+ }),
120
+ makeEntry({
121
+ id: 'ap1',
122
+ type: 'anti-pattern',
123
+ title: 'Avoid inline styles',
124
+ description: 'No inline.',
125
+ }),
126
+ ];
127
+
128
+ const searchFn = vi.fn().mockReturnValue([]);
129
+ const results = findContradictions(entries, 0.2, searchFn);
130
+
131
+ expect(searchFn).toHaveBeenCalled();
132
+ // Should still detect — falls back to full scan
133
+ expect(results.length).toBeGreaterThan(0);
134
+ });
135
+
136
+ it('falls back to all patterns when searchFn throws', () => {
137
+ const entries = [
138
+ makeEntry({
139
+ id: 'p1',
140
+ type: 'pattern',
141
+ title: 'Use inline styles',
142
+ description: 'Inline.',
143
+ }),
144
+ makeEntry({
145
+ id: 'ap1',
146
+ type: 'anti-pattern',
147
+ title: 'Avoid inline styles',
148
+ description: 'No inline.',
149
+ }),
150
+ ];
151
+
152
+ const searchFn = vi.fn().mockImplementation(() => {
153
+ throw new Error('FTS5 unavailable');
154
+ });
155
+ const results = findContradictions(entries, 0.2, searchFn);
156
+
157
+ expect(results.length).toBeGreaterThan(0);
158
+ });
159
+
160
+ it('respects threshold — high threshold reduces detections', () => {
161
+ const entries = [
162
+ makeEntry({
163
+ id: 'p1',
164
+ type: 'pattern',
165
+ title: 'Prefer inline styles for dynamic',
166
+ description: 'Use inline for dynamic values.',
167
+ }),
168
+ makeEntry({
169
+ id: 'ap1',
170
+ type: 'anti-pattern',
171
+ title: 'Avoid inline styles completely',
172
+ description: 'Never use inline styles at all.',
173
+ }),
174
+ ];
175
+ const lowThreshold = findContradictions(entries, 0.1);
176
+ const highThreshold = findContradictions(entries, 0.99);
177
+ expect(highThreshold.length).toBeLessThanOrEqual(lowThreshold.length);
178
+ });
179
+
180
+ it('uses default threshold when none provided', () => {
181
+ const entries = [
182
+ makeEntry({ id: 'p1', type: 'pattern', title: 'A', description: 'B' }),
183
+ makeEntry({ id: 'ap1', type: 'anti-pattern', title: 'C', description: 'D' }),
184
+ ];
185
+ // Should not throw
186
+ const results = findContradictions(entries);
187
+ expect(Array.isArray(results)).toBe(true);
188
+ });
189
+
190
+ it('ignores entries that are neither pattern nor anti-pattern', () => {
191
+ const entries = [
192
+ makeEntry({ id: 'r1', type: 'rule', title: 'Use inline styles', description: 'Inline.' }),
193
+ makeEntry({
194
+ id: 'ap1',
195
+ type: 'anti-pattern',
196
+ title: 'Avoid inline styles',
197
+ description: 'No inline.',
198
+ }),
199
+ ];
200
+ // Rules should not be compared against anti-patterns
201
+ const results = findContradictions(entries, 0.1);
202
+ expect(results.length).toBe(0);
203
+ });
204
+ });
205
+ });
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Contradiction Detector — pure-logic module for finding contradictions
3
+ * between pattern and anti-pattern vault entries.
4
+ *
5
+ * Uses TF-IDF cosine similarity with optional FTS5 pre-filtering.
6
+ * Database persistence of detected contradictions is handled by the caller (Curator facade).
7
+ */
8
+
9
+ import type { IntelligenceEntry } from '../intelligence/types.js';
10
+ import { tokenize, calculateTfIdf, cosineSimilarity } from '../text/similarity.js';
11
+ import { buildVocabulary, entryToText } from './duplicate-detector.js';
12
+
13
+ // ─── Constants ──────────────────────────────────────────────────────
14
+
15
+ export const DEFAULT_CONTRADICTION_THRESHOLD = 0.4;
16
+
17
+ // ─── Types ──────────────────────────────────────────────────────────
18
+
19
+ export interface ContradictionCandidate {
20
+ patternId: string;
21
+ antipatternId: string;
22
+ similarity: number;
23
+ }
24
+
25
+ export interface SearchFn {
26
+ (title: string): IntelligenceEntry[];
27
+ }
28
+
29
+ // ─── Detect Contradictions ──────────────────────────────────────────
30
+
31
+ /**
32
+ * Find pattern/anti-pattern pairs with high textual similarity.
33
+ *
34
+ * @param entries - All vault entries
35
+ * @param threshold - Minimum cosine similarity to flag as contradiction
36
+ * @param searchFn - Optional FTS5-backed candidate retrieval (falls back to all patterns)
37
+ * @returns Array of contradiction candidates (not yet persisted)
38
+ */
39
+ export function findContradictions(
40
+ entries: IntelligenceEntry[],
41
+ threshold?: number,
42
+ searchFn?: SearchFn,
43
+ ): ContradictionCandidate[] {
44
+ const effectiveThreshold = threshold ?? DEFAULT_CONTRADICTION_THRESHOLD;
45
+ const antipatterns = entries.filter((e) => e.type === 'anti-pattern');
46
+ const patterns = entries.filter((e) => e.type === 'pattern');
47
+
48
+ if (antipatterns.length === 0 || patterns.length === 0) return [];
49
+
50
+ const vocabulary = buildVocabulary(entries);
51
+ const detected: ContradictionCandidate[] = [];
52
+
53
+ for (const ap of antipatterns) {
54
+ // Stage 1: FTS5 candidate retrieval (fall back to all patterns if FTS returns empty)
55
+ let candidates: IntelligenceEntry[];
56
+ if (searchFn) {
57
+ try {
58
+ const searchResults = searchFn(ap.title);
59
+ candidates = searchResults.length > 0 ? searchResults : patterns;
60
+ } catch {
61
+ candidates = patterns;
62
+ }
63
+ } else {
64
+ candidates = patterns;
65
+ }
66
+
67
+ // Stage 2: TF-IDF cosine similarity
68
+ const apText = entryToText(ap);
69
+ const apVec = calculateTfIdf(tokenize(apText), vocabulary);
70
+
71
+ for (const pattern of candidates) {
72
+ const pText = entryToText(pattern);
73
+ const pVec = calculateTfIdf(tokenize(pText), vocabulary);
74
+ const similarity = cosineSimilarity(apVec, pVec);
75
+
76
+ if (similarity >= effectiveThreshold) {
77
+ detected.push({
78
+ patternId: pattern.id,
79
+ antipatternId: ap.id,
80
+ similarity,
81
+ });
82
+ }
83
+ }
84
+ }
85
+
86
+ return detected;
87
+ }
@@ -8,19 +8,19 @@
8
8
  import { describe, it, expect, beforeAll, afterAll } from 'vitest';
9
9
  import { Vault } from '../vault/vault.js';
10
10
  import { Brain } from '../brain/brain.js';
11
- import { Curator } from '../curator/curator.js';
11
+ import { Curator } from './curator.js';
12
12
  import { JobQueue } from '../queue/job-queue.js';
13
13
  import { PipelineRunner } from '../queue/pipeline-runner.js';
14
14
  import { TypedEventBus } from '../events/event-bus.js';
15
15
  import { LinkManager } from '../vault/linking.js';
16
- import { evaluateQuality } from '../curator/quality-gate.js';
17
- import { classifyEntry } from '../curator/classifier.js';
16
+ import { evaluateQuality } from './quality-gate.js';
17
+ import { classifyEntry } from './classifier.js';
18
18
  import type { IntelligenceEntry } from '../intelligence/types.js';
19
19
 
20
20
  // ─── Shared Setup ────────────────────────────────────────────────────
21
21
 
22
22
  let vault: Vault;
23
- let brain: Brain;
23
+ let _brain: Brain;
24
24
  let curator: Curator;
25
25
  let queue: JobQueue;
26
26
  let runner: PipelineRunner;
@@ -60,7 +60,7 @@ const SEED: IntelligenceEntry[] = [
60
60
  beforeAll(() => {
61
61
  vault = new Vault(':memory:');
62
62
  vault.seed(SEED);
63
- brain = new Brain(vault);
63
+ _brain = new Brain(vault);
64
64
  curator = new Curator(vault);
65
65
  queue = new JobQueue(vault.getProvider());
66
66
  linkManager = new LinkManager(vault.getProvider());
@@ -153,7 +153,7 @@ describe('Job Queue — curator pipeline', () => {
153
153
 
154
154
  const step1 = queue.enqueue('tag-normalize', { entryId, pipelineId });
155
155
  const step2 = queue.enqueue('dedup-check', { entryId, pipelineId, dependsOn: [step1] });
156
- const step3 = queue.enqueue('auto-link', { entryId, pipelineId, dependsOn: [step2] });
156
+ queue.enqueue('auto-link', { entryId, pipelineId, dependsOn: [step2] });
157
157
 
158
158
  const jobs = queue.getByPipeline(pipelineId);
159
159
  expect(jobs.length).toBe(3);
@@ -400,13 +400,13 @@ describe('Full Salvador DAG — 7-step curator pipeline', () => {
400
400
  const step2 = queue.enqueue('enrich-frontmatter', { entryId, pipelineId, dependsOn: [step1] });
401
401
  const step3 = queue.enqueue('tag-normalize', { entryId, pipelineId, dependsOn: [step2] });
402
402
  const step4 = queue.enqueue('dedup-check', { entryId, pipelineId, dependsOn: [step3] });
403
- const step5 = queue.enqueue('detect-contradiction', {
403
+ const step5Id = queue.enqueue('detect-contradiction', {
404
404
  entryId,
405
405
  pipelineId,
406
406
  dependsOn: [step4],
407
407
  });
408
- const step6 = queue.enqueue('auto-link', { entryId, pipelineId, dependsOn: [step5] });
409
- const step7 = queue.enqueue('verify-searchable', { entryId, pipelineId, dependsOn: [step6] });
408
+ const step6Id = queue.enqueue('auto-link', { entryId, pipelineId, dependsOn: [step5Id] });
409
+ queue.enqueue('verify-searchable', { entryId, pipelineId, dependsOn: [step6Id] });
410
410
 
411
411
  // Drain the DAG
412
412
  for (let i = 0; i < 15; i++) {
@@ -492,7 +492,7 @@ describe('Full pipeline E2E — capture to completion', () => {
492
492
  const step2 = queue.enqueue('tag-normalize', { entryId, pipelineId, dependsOn: [step1] });
493
493
  const step3 = queue.enqueue('dedup-check', { entryId, pipelineId, dependsOn: [step2] });
494
494
  const step4 = queue.enqueue('classify', { entryId, pipelineId, dependsOn: [step3] });
495
- const step5 = queue.enqueue('auto-link', { entryId, pipelineId, dependsOn: [step4] });
495
+ queue.enqueue('auto-link', { entryId, pipelineId, dependsOn: [step4] });
496
496
 
497
497
  // Process all steps — run enough batches to drain DAG
498
498
  // (earlier tests may have left pending jobs, so process generously)
@@ -1,6 +1,6 @@
1
1
  import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
2
  import { Vault } from '../vault/vault.js';
3
- import { Curator } from '../curator/curator.js';
3
+ import { Curator } from './curator.js';
4
4
  import type { IntelligenceEntry } from '../intelligence/types.js';
5
5
 
6
6
  function makeEntry(overrides: Partial<IntelligenceEntry> = {}): IntelligenceEntry {
@@ -203,6 +203,82 @@ describe('Curator', () => {
203
203
  const results = curator.detectDuplicates();
204
204
  expect(results).toEqual([]);
205
205
  });
206
+
207
+ it('should NOT flag cross-domain entries as duplicates', () => {
208
+ vault.seed([
209
+ makeEntry({
210
+ id: 'cross-1',
211
+ domain: 'design',
212
+ title: 'Use semantic tokens for colors',
213
+ description: 'Always use semantic tokens instead of raw hex values for color styling.',
214
+ tags: ['tokens', 'colors'],
215
+ }),
216
+ makeEntry({
217
+ id: 'cross-2',
218
+ domain: 'architecture',
219
+ title: 'Use semantic tokens for colors',
220
+ description: 'Always use semantic tokens instead of raw hex values for color styling.',
221
+ tags: ['tokens', 'colors'],
222
+ }),
223
+ ]);
224
+ const results = curator.detectDuplicates(undefined, 0.3);
225
+ expect(results.length).toBe(0);
226
+ });
227
+
228
+ it('should still flag same-domain entries as duplicates', () => {
229
+ vault.seed([
230
+ makeEntry({
231
+ id: 'same-1',
232
+ domain: 'design',
233
+ title: 'Use semantic tokens for colors',
234
+ description: 'Always use semantic tokens instead of raw hex values for color styling.',
235
+ tags: ['tokens', 'colors'],
236
+ }),
237
+ makeEntry({
238
+ id: 'same-2',
239
+ domain: 'design',
240
+ title: 'Use semantic tokens for color values',
241
+ description: 'Prefer semantic color tokens over raw hex or rgb values in styling.',
242
+ tags: ['tokens', 'colors'],
243
+ }),
244
+ ]);
245
+ const results = curator.detectDuplicates(undefined, 0.3);
246
+ expect(results.length).toBeGreaterThan(0);
247
+ });
248
+
249
+ it('should improve health audit score for cross-domain vaults', () => {
250
+ // Seed entries across different domains with similar vocabulary
251
+ vault.seed([
252
+ makeEntry({
253
+ id: 'ha-1',
254
+ domain: 'design',
255
+ type: 'pattern',
256
+ title: 'Use semantic tokens for colors',
257
+ description: 'Always use semantic tokens instead of raw hex values.',
258
+ tags: ['tokens', 'colors'],
259
+ }),
260
+ makeEntry({
261
+ id: 'ha-2',
262
+ domain: 'architecture',
263
+ type: 'anti-pattern',
264
+ title: 'Use semantic tokens for API responses',
265
+ description: 'Always use semantic tokens instead of raw values in API.',
266
+ tags: ['tokens', 'api'],
267
+ }),
268
+ makeEntry({
269
+ id: 'ha-3',
270
+ domain: 'testing',
271
+ type: 'rule',
272
+ title: 'Use semantic assertions',
273
+ description: 'Always use semantic assertions for test clarity.',
274
+ tags: ['tokens', 'testing'],
275
+ }),
276
+ ]);
277
+ curator.groomAll();
278
+ const result = curator.healthAudit();
279
+ // Cross-domain entries should not be penalized as duplicates
280
+ expect(result.score).toBeGreaterThanOrEqual(90);
281
+ });
206
282
  });
207
283
 
208
284
  // ─── Contradictions ───────────────────────────────────────────