@soleri/core 9.0.4 → 9.2.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 (701) hide show
  1. package/dist/brain/intelligence.d.ts +27 -0
  2. package/dist/brain/intelligence.d.ts.map +1 -1
  3. package/dist/brain/intelligence.js +160 -14
  4. package/dist/brain/intelligence.js.map +1 -1
  5. package/dist/brain/learning-radar.d.ts +4 -0
  6. package/dist/brain/learning-radar.d.ts.map +1 -1
  7. package/dist/brain/learning-radar.js +20 -1
  8. package/dist/brain/learning-radar.js.map +1 -1
  9. package/dist/brain/strength-scorer.d.ts +31 -0
  10. package/dist/brain/strength-scorer.d.ts.map +1 -0
  11. package/dist/brain/strength-scorer.js +264 -0
  12. package/dist/brain/strength-scorer.js.map +1 -0
  13. package/dist/chat/agent-loop.d.ts.map +1 -1
  14. package/dist/chat/agent-loop.js +2 -0
  15. package/dist/chat/agent-loop.js.map +1 -1
  16. package/dist/chat/notifications.d.ts.map +1 -1
  17. package/dist/chat/notifications.js +2 -0
  18. package/dist/chat/notifications.js.map +1 -1
  19. package/dist/claudemd/compose.js +1 -1
  20. package/dist/claudemd/compose.js.map +1 -1
  21. package/dist/control/intent-router.d.ts.map +1 -1
  22. package/dist/control/intent-router.js +12 -4
  23. package/dist/control/intent-router.js.map +1 -1
  24. package/dist/curator/contradiction-detector.d.ts +27 -0
  25. package/dist/curator/contradiction-detector.d.ts.map +1 -0
  26. package/dist/curator/contradiction-detector.js +62 -0
  27. package/dist/curator/contradiction-detector.js.map +1 -0
  28. package/dist/curator/curator.d.ts +3 -4
  29. package/dist/curator/curator.d.ts.map +1 -1
  30. package/dist/curator/curator.js +90 -525
  31. package/dist/curator/curator.js.map +1 -1
  32. package/dist/curator/duplicate-detector.d.ts +14 -0
  33. package/dist/curator/duplicate-detector.d.ts.map +1 -0
  34. package/dist/curator/duplicate-detector.js +77 -0
  35. package/dist/curator/duplicate-detector.js.map +1 -0
  36. package/dist/curator/health-audit.d.ts +15 -0
  37. package/dist/curator/health-audit.d.ts.map +1 -0
  38. package/dist/curator/health-audit.js +97 -0
  39. package/dist/curator/health-audit.js.map +1 -0
  40. package/dist/curator/metadata-enricher.d.ts +17 -0
  41. package/dist/curator/metadata-enricher.d.ts.map +1 -0
  42. package/dist/curator/metadata-enricher.js +60 -0
  43. package/dist/curator/metadata-enricher.js.map +1 -0
  44. package/dist/curator/schema.d.ts +7 -0
  45. package/dist/curator/schema.d.ts.map +1 -0
  46. package/dist/curator/schema.js +62 -0
  47. package/dist/curator/schema.js.map +1 -0
  48. package/dist/curator/tag-manager.d.ts +36 -0
  49. package/dist/curator/tag-manager.d.ts.map +1 -0
  50. package/dist/curator/tag-manager.js +78 -0
  51. package/dist/curator/tag-manager.js.map +1 -0
  52. package/dist/engine/bin/soleri-engine.js +24 -3
  53. package/dist/engine/bin/soleri-engine.js.map +1 -1
  54. package/dist/engine/core-ops.d.ts.map +1 -1
  55. package/dist/engine/core-ops.js +23 -8
  56. package/dist/engine/core-ops.js.map +1 -1
  57. package/dist/engine/module-manifest.d.ts.map +1 -1
  58. package/dist/engine/module-manifest.js +22 -2
  59. package/dist/engine/module-manifest.js.map +1 -1
  60. package/dist/engine/register-engine.d.ts.map +1 -1
  61. package/dist/engine/register-engine.js +26 -2
  62. package/dist/engine/register-engine.js.map +1 -1
  63. package/dist/errors/retry.d.ts.map +1 -1
  64. package/dist/errors/retry.js +2 -0
  65. package/dist/errors/retry.js.map +1 -1
  66. package/dist/facades/types.d.ts +1 -1
  67. package/dist/flows/chain-types.d.ts +18 -18
  68. package/dist/flows/gate-evaluator.d.ts.map +1 -1
  69. package/dist/flows/gate-evaluator.js +22 -0
  70. package/dist/flows/gate-evaluator.js.map +1 -1
  71. package/dist/flows/types.d.ts +157 -28
  72. package/dist/flows/types.d.ts.map +1 -1
  73. package/dist/flows/types.js +4 -0
  74. package/dist/flows/types.js.map +1 -1
  75. package/dist/index.d.ts +10 -2
  76. package/dist/index.d.ts.map +1 -1
  77. package/dist/index.js +9 -1
  78. package/dist/index.js.map +1 -1
  79. package/dist/intake/intake-pipeline.d.ts.map +1 -1
  80. package/dist/intake/intake-pipeline.js +1 -0
  81. package/dist/intake/intake-pipeline.js.map +1 -1
  82. package/dist/intake/text-ingester.d.ts.map +1 -1
  83. package/dist/intake/text-ingester.js +2 -0
  84. package/dist/intake/text-ingester.js.map +1 -1
  85. package/dist/llm/key-pool.d.ts +1 -1
  86. package/dist/llm/key-pool.d.ts.map +1 -1
  87. package/dist/llm/key-pool.js +3 -4
  88. package/dist/llm/key-pool.js.map +1 -1
  89. package/dist/llm/utils.d.ts.map +1 -1
  90. package/dist/llm/utils.js +2 -0
  91. package/dist/llm/utils.js.map +1 -1
  92. package/dist/migrations/migration-runner.test-helpers.d.ts +13 -0
  93. package/dist/migrations/migration-runner.test-helpers.d.ts.map +1 -0
  94. package/dist/migrations/migration-runner.test-helpers.js +47 -0
  95. package/dist/migrations/migration-runner.test-helpers.js.map +1 -0
  96. package/dist/operator/operator-profile.d.ts +44 -0
  97. package/dist/operator/operator-profile.d.ts.map +1 -0
  98. package/dist/operator/operator-profile.js +377 -0
  99. package/dist/operator/operator-profile.js.map +1 -0
  100. package/dist/operator/operator-signals.d.ts +45 -0
  101. package/dist/operator/operator-signals.d.ts.map +1 -0
  102. package/dist/operator/operator-signals.js +228 -0
  103. package/dist/operator/operator-signals.js.map +1 -0
  104. package/dist/operator/operator-types.d.ts +360 -0
  105. package/dist/operator/operator-types.d.ts.map +1 -0
  106. package/dist/operator/operator-types.js +24 -0
  107. package/dist/operator/operator-types.js.map +1 -0
  108. package/dist/packs/types.d.ts +27 -27
  109. package/dist/paths.d.ts +40 -0
  110. package/dist/paths.d.ts.map +1 -0
  111. package/dist/paths.js +98 -0
  112. package/dist/paths.js.map +1 -0
  113. package/dist/persistence/index.d.ts +1 -1
  114. package/dist/persistence/index.d.ts.map +1 -1
  115. package/dist/persistence/index.js +1 -1
  116. package/dist/persistence/index.js.map +1 -1
  117. package/dist/persistence/sqlite-provider.d.ts +2 -0
  118. package/dist/persistence/sqlite-provider.d.ts.map +1 -1
  119. package/dist/persistence/sqlite-provider.js +8 -5
  120. package/dist/persistence/sqlite-provider.js.map +1 -1
  121. package/dist/planning/evidence-collector.d.ts +13 -1
  122. package/dist/planning/evidence-collector.d.ts.map +1 -1
  123. package/dist/planning/evidence-collector.js +33 -0
  124. package/dist/planning/evidence-collector.js.map +1 -1
  125. package/dist/planning/gap-analysis.d.ts +5 -4
  126. package/dist/planning/gap-analysis.d.ts.map +1 -1
  127. package/dist/planning/gap-analysis.js +7 -341
  128. package/dist/planning/gap-analysis.js.map +1 -1
  129. package/dist/planning/gap-passes.d.ts +19 -0
  130. package/dist/planning/gap-passes.d.ts.map +1 -0
  131. package/dist/planning/gap-passes.js +157 -0
  132. package/dist/planning/gap-passes.js.map +1 -0
  133. package/dist/planning/gap-patterns.d.ts +29 -0
  134. package/dist/planning/gap-patterns.d.ts.map +1 -0
  135. package/dist/planning/gap-patterns.js +129 -0
  136. package/dist/planning/gap-patterns.js.map +1 -0
  137. package/dist/planning/gap-types.d.ts +1 -1
  138. package/dist/planning/gap-types.d.ts.map +1 -1
  139. package/dist/planning/gap-types.js +1 -0
  140. package/dist/planning/gap-types.js.map +1 -1
  141. package/dist/planning/github-projection.d.ts +122 -0
  142. package/dist/planning/github-projection.d.ts.map +1 -0
  143. package/dist/planning/github-projection.js +294 -0
  144. package/dist/planning/github-projection.js.map +1 -0
  145. package/dist/planning/impact-analyzer.d.ts +26 -0
  146. package/dist/planning/impact-analyzer.d.ts.map +1 -0
  147. package/dist/planning/impact-analyzer.js +199 -0
  148. package/dist/planning/impact-analyzer.js.map +1 -0
  149. package/dist/planning/plan-lifecycle.d.ts +136 -0
  150. package/dist/planning/plan-lifecycle.d.ts.map +1 -0
  151. package/dist/planning/plan-lifecycle.js +296 -0
  152. package/dist/planning/plan-lifecycle.js.map +1 -0
  153. package/dist/planning/planner-types.d.ts +202 -0
  154. package/dist/planning/planner-types.d.ts.map +1 -0
  155. package/dist/planning/planner-types.js +6 -0
  156. package/dist/planning/planner-types.js.map +1 -0
  157. package/dist/planning/planner.d.ts +31 -383
  158. package/dist/planning/planner.d.ts.map +1 -1
  159. package/dist/planning/planner.js +154 -878
  160. package/dist/planning/planner.js.map +1 -1
  161. package/dist/planning/rationalization-detector.d.ts +32 -0
  162. package/dist/planning/rationalization-detector.d.ts.map +1 -0
  163. package/dist/planning/rationalization-detector.js +89 -0
  164. package/dist/planning/rationalization-detector.js.map +1 -0
  165. package/dist/planning/reconciliation-engine.d.ts +47 -0
  166. package/dist/planning/reconciliation-engine.d.ts.map +1 -0
  167. package/dist/planning/reconciliation-engine.js +128 -0
  168. package/dist/planning/reconciliation-engine.js.map +1 -0
  169. package/dist/planning/task-verifier.d.ts +85 -0
  170. package/dist/planning/task-verifier.d.ts.map +1 -0
  171. package/dist/planning/task-verifier.js +227 -0
  172. package/dist/planning/task-verifier.js.map +1 -0
  173. package/dist/plugins/types.d.ts +4 -4
  174. package/dist/runtime/admin-ops.d.ts +2 -2
  175. package/dist/runtime/admin-ops.d.ts.map +1 -1
  176. package/dist/runtime/admin-ops.js +44 -17
  177. package/dist/runtime/admin-ops.js.map +1 -1
  178. package/dist/runtime/admin-setup-ops.d.ts.map +1 -1
  179. package/dist/runtime/admin-setup-ops.js +21 -46
  180. package/dist/runtime/admin-setup-ops.js.map +1 -1
  181. package/dist/runtime/archive-ops.d.ts +10 -0
  182. package/dist/runtime/archive-ops.d.ts.map +1 -0
  183. package/dist/runtime/archive-ops.js +310 -0
  184. package/dist/runtime/archive-ops.js.map +1 -0
  185. package/dist/runtime/capture-ops.d.ts.map +1 -1
  186. package/dist/runtime/capture-ops.js +42 -7
  187. package/dist/runtime/capture-ops.js.map +1 -1
  188. package/dist/runtime/claude-md-helpers.js +1 -1
  189. package/dist/runtime/claude-md-helpers.js.map +1 -1
  190. package/dist/runtime/context-health.d.ts +31 -0
  191. package/dist/runtime/context-health.d.ts.map +1 -0
  192. package/dist/runtime/context-health.js +57 -0
  193. package/dist/runtime/context-health.js.map +1 -0
  194. package/dist/runtime/facades/archive-facade.d.ts +10 -0
  195. package/dist/runtime/facades/archive-facade.d.ts.map +1 -0
  196. package/dist/runtime/facades/archive-facade.js +11 -0
  197. package/dist/runtime/facades/archive-facade.js.map +1 -0
  198. package/dist/runtime/facades/brain-facade.d.ts.map +1 -1
  199. package/dist/runtime/facades/brain-facade.js +2 -0
  200. package/dist/runtime/facades/brain-facade.js.map +1 -1
  201. package/dist/runtime/facades/chat-facade.d.ts +7 -0
  202. package/dist/runtime/facades/chat-facade.d.ts.map +1 -1
  203. package/dist/runtime/facades/chat-facade.js +15 -800
  204. package/dist/runtime/facades/chat-facade.js.map +1 -1
  205. package/dist/runtime/facades/chat-service-ops.d.ts +9 -0
  206. package/dist/runtime/facades/chat-service-ops.d.ts.map +1 -0
  207. package/dist/runtime/facades/chat-service-ops.js +330 -0
  208. package/dist/runtime/facades/chat-service-ops.js.map +1 -0
  209. package/dist/runtime/facades/chat-session-ops.d.ts +8 -0
  210. package/dist/runtime/facades/chat-session-ops.d.ts.map +1 -0
  211. package/dist/runtime/facades/chat-session-ops.js +136 -0
  212. package/dist/runtime/facades/chat-session-ops.js.map +1 -0
  213. package/dist/runtime/facades/chat-state.d.ts +31 -0
  214. package/dist/runtime/facades/chat-state.d.ts.map +1 -0
  215. package/dist/runtime/facades/chat-state.js +32 -0
  216. package/dist/runtime/facades/chat-state.js.map +1 -0
  217. package/dist/runtime/facades/chat-transport-ops.d.ts +9 -0
  218. package/dist/runtime/facades/chat-transport-ops.d.ts.map +1 -0
  219. package/dist/runtime/facades/chat-transport-ops.js +337 -0
  220. package/dist/runtime/facades/chat-transport-ops.js.map +1 -0
  221. package/dist/runtime/facades/control-facade.d.ts.map +1 -1
  222. package/dist/runtime/facades/control-facade.js +4 -1
  223. package/dist/runtime/facades/control-facade.js.map +1 -1
  224. package/dist/runtime/facades/index.d.ts.map +1 -1
  225. package/dist/runtime/facades/index.js +6 -0
  226. package/dist/runtime/facades/index.js.map +1 -1
  227. package/dist/runtime/facades/memory-facade.d.ts.map +1 -1
  228. package/dist/runtime/facades/memory-facade.js +75 -6
  229. package/dist/runtime/facades/memory-facade.js.map +1 -1
  230. package/dist/runtime/facades/operator-facade.d.ts +8 -0
  231. package/dist/runtime/facades/operator-facade.d.ts.map +1 -0
  232. package/dist/runtime/facades/operator-facade.js +220 -0
  233. package/dist/runtime/facades/operator-facade.js.map +1 -0
  234. package/dist/runtime/facades/orchestrate-facade.js +3 -3
  235. package/dist/runtime/facades/orchestrate-facade.js.map +1 -1
  236. package/dist/runtime/facades/plan-facade.d.ts.map +1 -1
  237. package/dist/runtime/facades/plan-facade.js +39 -6
  238. package/dist/runtime/facades/plan-facade.js.map +1 -1
  239. package/dist/runtime/facades/review-facade.d.ts +7 -0
  240. package/dist/runtime/facades/review-facade.d.ts.map +1 -0
  241. package/dist/runtime/facades/review-facade.js +8 -0
  242. package/dist/runtime/facades/review-facade.js.map +1 -0
  243. package/dist/runtime/facades/sync-facade.d.ts +7 -0
  244. package/dist/runtime/facades/sync-facade.d.ts.map +1 -0
  245. package/dist/runtime/facades/sync-facade.js +8 -0
  246. package/dist/runtime/facades/sync-facade.js.map +1 -0
  247. package/dist/runtime/facades/vault-facade.d.ts +4 -1
  248. package/dist/runtime/facades/vault-facade.d.ts.map +1 -1
  249. package/dist/runtime/facades/vault-facade.js +13 -66
  250. package/dist/runtime/facades/vault-facade.js.map +1 -1
  251. package/dist/runtime/github-integration.d.ts +49 -0
  252. package/dist/runtime/github-integration.d.ts.map +1 -0
  253. package/dist/runtime/github-integration.js +113 -0
  254. package/dist/runtime/github-integration.js.map +1 -0
  255. package/dist/runtime/grading-ops.js +1 -1
  256. package/dist/runtime/grading-ops.js.map +1 -1
  257. package/dist/runtime/memory-extra-ops.d.ts.map +1 -1
  258. package/dist/runtime/memory-extra-ops.js +6 -2
  259. package/dist/runtime/memory-extra-ops.js.map +1 -1
  260. package/dist/runtime/orchestrate-ops.d.ts.map +1 -1
  261. package/dist/runtime/orchestrate-ops.js +367 -40
  262. package/dist/runtime/orchestrate-ops.js.map +1 -1
  263. package/dist/runtime/planning-extra-ops.d.ts.map +1 -1
  264. package/dist/runtime/planning-extra-ops.js +69 -4
  265. package/dist/runtime/planning-extra-ops.js.map +1 -1
  266. package/dist/runtime/review-ops.d.ts +10 -0
  267. package/dist/runtime/review-ops.d.ts.map +1 -0
  268. package/dist/runtime/review-ops.js +97 -0
  269. package/dist/runtime/review-ops.js.map +1 -0
  270. package/dist/runtime/runtime.d.ts.map +1 -1
  271. package/dist/runtime/runtime.js +27 -12
  272. package/dist/runtime/runtime.js.map +1 -1
  273. package/dist/runtime/session-briefing.d.ts +3 -0
  274. package/dist/runtime/session-briefing.d.ts.map +1 -1
  275. package/dist/runtime/session-briefing.js +68 -1
  276. package/dist/runtime/session-briefing.js.map +1 -1
  277. package/dist/runtime/sync-ops.d.ts +12 -0
  278. package/dist/runtime/sync-ops.d.ts.map +1 -0
  279. package/dist/runtime/sync-ops.js +288 -0
  280. package/dist/runtime/sync-ops.js.map +1 -0
  281. package/dist/runtime/types.d.ts +10 -4
  282. package/dist/runtime/types.d.ts.map +1 -1
  283. package/dist/runtime/vault-extra-ops.d.ts +5 -4
  284. package/dist/runtime/vault-extra-ops.d.ts.map +1 -1
  285. package/dist/runtime/vault-extra-ops.js +5 -300
  286. package/dist/runtime/vault-extra-ops.js.map +1 -1
  287. package/dist/runtime/vault-sharing-ops.d.ts +4 -4
  288. package/dist/runtime/vault-sharing-ops.d.ts.map +1 -1
  289. package/dist/runtime/vault-sharing-ops.js +5 -300
  290. package/dist/runtime/vault-sharing-ops.js.map +1 -1
  291. package/dist/skills/sync-skills.d.ts +27 -0
  292. package/dist/skills/sync-skills.d.ts.map +1 -0
  293. package/dist/skills/sync-skills.js +81 -0
  294. package/dist/skills/sync-skills.js.map +1 -0
  295. package/dist/update-check.d.ts +14 -0
  296. package/dist/update-check.d.ts.map +1 -0
  297. package/dist/update-check.js +96 -0
  298. package/dist/update-check.js.map +1 -0
  299. package/dist/vault/linking.d.ts +10 -12
  300. package/dist/vault/linking.d.ts.map +1 -1
  301. package/dist/vault/linking.js +104 -161
  302. package/dist/vault/linking.js.map +1 -1
  303. package/dist/vault/vault-entries.d.ts +69 -0
  304. package/dist/vault/vault-entries.d.ts.map +1 -0
  305. package/dist/vault/vault-entries.js +257 -0
  306. package/dist/vault/vault-entries.js.map +1 -0
  307. package/dist/vault/vault-interfaces.d.ts +153 -0
  308. package/dist/vault/vault-interfaces.d.ts.map +1 -0
  309. package/dist/vault/vault-interfaces.js +2 -0
  310. package/dist/vault/vault-interfaces.js.map +1 -0
  311. package/dist/vault/vault-maintenance.d.ts +40 -0
  312. package/dist/vault/vault-maintenance.d.ts.map +1 -0
  313. package/dist/vault/vault-maintenance.js +142 -0
  314. package/dist/vault/vault-maintenance.js.map +1 -0
  315. package/dist/vault/vault-markdown-sync.d.ts +22 -0
  316. package/dist/vault/vault-markdown-sync.d.ts.map +1 -0
  317. package/dist/vault/vault-markdown-sync.js +143 -0
  318. package/dist/vault/vault-markdown-sync.js.map +1 -0
  319. package/dist/vault/vault-memories.d.ts +61 -0
  320. package/dist/vault/vault-memories.d.ts.map +1 -0
  321. package/dist/vault/vault-memories.js +240 -0
  322. package/dist/vault/vault-memories.js.map +1 -0
  323. package/dist/vault/vault-schema.d.ts +9 -0
  324. package/dist/vault/vault-schema.d.ts.map +1 -0
  325. package/dist/vault/vault-schema.js +179 -0
  326. package/dist/vault/vault-schema.js.map +1 -0
  327. package/dist/vault/vault.d.ts +29 -81
  328. package/dist/vault/vault.d.ts.map +1 -1
  329. package/dist/vault/vault.js +78 -931
  330. package/dist/vault/vault.js.map +1 -1
  331. package/package.json +1 -1
  332. package/src/agency/agency-manager.test.ts +600 -0
  333. package/src/agency/default-rules.test.ts +228 -0
  334. package/src/{__tests__ → brain}/brain-intelligence.test.ts +37 -14
  335. package/src/{__tests__ → brain}/brain.test.ts +1 -1
  336. package/src/brain/intelligence.ts +196 -15
  337. package/src/brain/learning-radar.ts +22 -1
  338. package/src/{__tests__ → brain}/second-brain-features.test.ts +4 -4
  339. package/src/{__tests__ → brain}/session-lifecycle.test.ts +2 -2
  340. package/src/brain/strength-scorer.ts +404 -0
  341. package/src/capabilities/chain-mapping.test.ts +66 -0
  342. package/src/capabilities/registry.test.ts +369 -0
  343. package/src/chat/agent-loop.test.ts +394 -0
  344. package/src/chat/agent-loop.ts +2 -0
  345. package/src/{__tests__ → chat}/chat-differentiators.test.ts +3 -3
  346. package/src/{__tests__ → chat}/chat-enhanced.test.ts +4 -4
  347. package/src/{__tests__ → chat}/chat-transport.test.ts +6 -6
  348. package/src/chat/mcp-bridge.test.ts +173 -0
  349. package/src/chat/notifications.ts +2 -0
  350. package/src/chat/output-compressor.test.ts +164 -0
  351. package/src/claudemd/compose.test.ts +178 -0
  352. package/src/claudemd/compose.ts +1 -1
  353. package/src/claudemd/inject.test.ts +211 -0
  354. package/src/context/context-engine.test.ts +461 -0
  355. package/src/control/identity-manager.test.ts +305 -0
  356. package/src/control/intent-router.test.ts +360 -0
  357. package/src/control/intent-router.ts +13 -4
  358. package/src/curator/classifier.test.ts +104 -0
  359. package/src/curator/contradiction-detector.test.ts +180 -0
  360. package/src/curator/contradiction-detector.ts +87 -0
  361. package/src/{__tests__ → curator}/curator-pipeline-e2e.test.ts +10 -10
  362. package/src/{__tests__ → curator}/curator.test.ts +77 -1
  363. package/src/curator/curator.ts +115 -777
  364. package/src/curator/duplicate-detector.test.ts +183 -0
  365. package/src/curator/duplicate-detector.ts +103 -0
  366. package/src/curator/health-audit.ts +126 -0
  367. package/src/curator/metadata-enricher.ts +84 -0
  368. package/src/curator/quality-gate.test.ts +135 -0
  369. package/src/curator/schema.ts +65 -0
  370. package/src/curator/tag-manager.test.ts +165 -0
  371. package/src/curator/tag-manager.ts +109 -0
  372. package/src/domain-packs/inject-rules.test.ts +117 -0
  373. package/src/domain-packs/knowledge-installer.test.ts +171 -0
  374. package/src/domain-packs/loader.test.ts +86 -0
  375. package/src/domain-packs/pack-runtime.test.ts +140 -0
  376. package/src/domain-packs/skills-installer.test.ts +135 -0
  377. package/src/domain-packs/token-resolver.test.ts +150 -0
  378. package/src/domain-packs/types.test.ts +130 -0
  379. package/src/enforcement/adapters/claude-code.test.ts +216 -0
  380. package/src/enforcement/registry.test.ts +264 -0
  381. package/src/engine/bin/soleri-engine.ts +28 -4
  382. package/src/engine/core-ops.test.ts +254 -0
  383. package/src/engine/core-ops.ts +25 -8
  384. package/src/engine/module-manifest.test.ts +124 -0
  385. package/src/engine/module-manifest.ts +22 -2
  386. package/src/engine/register-engine.test.ts +230 -0
  387. package/src/engine/register-engine.ts +26 -2
  388. package/src/errors/classify.test.ts +199 -0
  389. package/src/errors/retry.test.ts +156 -0
  390. package/src/errors/retry.ts +2 -0
  391. package/src/errors/types.test.ts +108 -0
  392. package/src/events/event-bus.test.ts +149 -0
  393. package/src/extensions/middleware.test.ts +234 -0
  394. package/src/facades/facade-factory.test.ts +424 -0
  395. package/src/flows/chain-runner.test.ts +273 -0
  396. package/src/flows/context-router.test.ts +52 -0
  397. package/src/flows/dispatch-registry.test.ts +128 -0
  398. package/src/flows/epilogue.test.ts +107 -0
  399. package/src/flows/executor.test.ts +263 -0
  400. package/src/flows/gate-evaluator.test.ts +194 -0
  401. package/src/flows/gate-evaluator.ts +25 -0
  402. package/src/flows/types.ts +4 -0
  403. package/src/governance/governance.test.ts +726 -0
  404. package/src/health/health-registry.test.ts +186 -0
  405. package/src/health/vault-integrity.test.ts +110 -0
  406. package/src/index.ts +92 -0
  407. package/src/intake/content-classifier.test.ts +209 -0
  408. package/src/intake/dedup-gate.test.ts +131 -0
  409. package/src/intake/intake-pipeline.test.ts +506 -0
  410. package/src/intake/intake-pipeline.ts +1 -0
  411. package/src/intake/text-ingester.test.ts +194 -0
  412. package/src/intake/text-ingester.ts +2 -0
  413. package/src/llm/key-pool.test.ts +236 -0
  414. package/src/llm/key-pool.ts +3 -4
  415. package/src/llm/llm-client.test.ts +345 -0
  416. package/src/llm/oauth-discovery.test.ts +180 -0
  417. package/src/llm/utils.test.ts +327 -0
  418. package/src/llm/utils.ts +2 -0
  419. package/src/{__tests__ → logging}/logger.test.ts +41 -62
  420. package/src/loop/loop-manager.test.ts +519 -0
  421. package/src/migrations/migration-runner.edge-cases.test.ts +319 -0
  422. package/src/migrations/migration-runner.test-helpers.ts +64 -0
  423. package/src/migrations/migration-runner.test.ts +385 -0
  424. package/src/operator/auto-signal-pipeline.test.ts +207 -0
  425. package/src/operator/operator-profile-extended.test.ts +320 -0
  426. package/src/operator/operator-profile.test.ts +314 -0
  427. package/src/operator/operator-profile.ts +469 -0
  428. package/src/operator/operator-signals-extended.test.ts +245 -0
  429. package/src/operator/operator-signals.test.ts +281 -0
  430. package/src/operator/operator-signals.ts +261 -0
  431. package/src/operator/operator-types.ts +444 -0
  432. package/src/operator/prompts/hook-precompact-operator-dispatch.md +94 -0
  433. package/src/operator/prompts/subagent-soft-signal-extractor.md +125 -0
  434. package/src/operator/prompts/subagent-synthesis-cognition.md +181 -0
  435. package/src/operator/prompts/subagent-synthesis-communication.md +140 -0
  436. package/src/operator/prompts/subagent-synthesis-technical.md +160 -0
  437. package/src/operator/prompts/subagent-synthesis-trust.md +143 -0
  438. package/src/{__tests__ → packs}/pack-lockfile.test.ts +3 -3
  439. package/src/{__tests__ → packs}/pack-system.test.ts +2 -2
  440. package/src/paths.ts +115 -0
  441. package/src/persistence/index.ts +1 -1
  442. package/src/persistence/sqlite-provider.test.ts +540 -0
  443. package/src/persistence/sqlite-provider.ts +8 -5
  444. package/src/persona/defaults.test.ts +59 -0
  445. package/src/persona/loader.test.ts +67 -0
  446. package/src/persona/prompt-generator.test.ts +127 -0
  447. package/src/planning/evidence-collector.test.ts +406 -0
  448. package/src/planning/evidence-collector.ts +50 -0
  449. package/src/planning/gap-analysis-alternatives.test.ts +169 -0
  450. package/src/planning/gap-analysis.ts +21 -636
  451. package/src/planning/gap-passes.test.ts +372 -0
  452. package/src/planning/gap-passes.ts +298 -0
  453. package/src/planning/gap-patterns.test.ts +320 -0
  454. package/src/planning/gap-patterns.ts +234 -0
  455. package/src/planning/gap-types.ts +4 -1
  456. package/src/planning/github-projection.test.ts +177 -0
  457. package/src/planning/github-projection.ts +425 -0
  458. package/src/planning/impact-analyzer.test.ts +180 -0
  459. package/src/planning/impact-analyzer.ts +264 -0
  460. package/src/planning/plan-lifecycle.test.ts +312 -0
  461. package/src/planning/plan-lifecycle.ts +346 -0
  462. package/src/planning/planner-types.ts +215 -0
  463. package/src/{__tests__ → planning}/planner.test.ts +169 -15
  464. package/src/planning/planner.ts +197 -1228
  465. package/src/planning/rationalization-detector.test.ts +171 -0
  466. package/src/planning/rationalization-detector.ts +138 -0
  467. package/src/planning/reconciliation-engine.test.ts +141 -0
  468. package/src/planning/reconciliation-engine.ts +162 -0
  469. package/src/planning/task-verifier.test.ts +235 -0
  470. package/src/planning/task-verifier.ts +303 -0
  471. package/src/planning/verification-protocol.test.ts +201 -0
  472. package/src/playbooks/generic/generic-playbooks.test.ts +438 -0
  473. package/src/playbooks/index.test.ts +77 -0
  474. package/src/playbooks/playbook-executor.test.ts +255 -0
  475. package/src/playbooks/playbook-registry.test.ts +232 -0
  476. package/src/playbooks/playbook-seeder.test.ts +153 -0
  477. package/src/plugins/plugin-loader.test.ts +212 -0
  478. package/src/plugins/plugin-registry.test.ts +272 -0
  479. package/src/project/project-registry.test.ts +428 -0
  480. package/src/prompts/parser.test.ts +100 -0
  481. package/src/prompts/template-manager.test.ts +109 -0
  482. package/src/{__tests__ → queue}/async-infrastructure.test.ts +3 -3
  483. package/src/queue/job-queue.test.ts +331 -0
  484. package/src/queue/pipeline-runner.test.ts +209 -0
  485. package/src/runtime/admin-extra-ops.test.ts +527 -0
  486. package/src/runtime/admin-ops.test.ts +257 -0
  487. package/src/runtime/admin-ops.ts +45 -17
  488. package/src/runtime/admin-setup-ops.test.ts +328 -0
  489. package/src/runtime/admin-setup-ops.ts +20 -43
  490. package/src/runtime/archive-ops.test.ts +269 -0
  491. package/src/runtime/archive-ops.ts +347 -0
  492. package/src/runtime/capture-ops.test.ts +433 -0
  493. package/src/runtime/capture-ops.ts +50 -8
  494. package/src/runtime/chain-ops.test.ts +149 -0
  495. package/src/runtime/claude-md-helpers.test.ts +191 -0
  496. package/src/runtime/claude-md-helpers.ts +1 -1
  497. package/src/runtime/context-health.test.ts +78 -0
  498. package/src/runtime/context-health.ts +85 -0
  499. package/src/runtime/curator-extra-ops.test.ts +202 -0
  500. package/src/runtime/deprecation.test.ts +98 -0
  501. package/src/runtime/domain-ops.test.ts +268 -0
  502. package/src/runtime/facades/admin-facade.test.ts +333 -0
  503. package/src/runtime/facades/agency-facade.test.ts +278 -0
  504. package/src/runtime/facades/archive-facade.test.ts +294 -0
  505. package/src/runtime/facades/archive-facade.ts +14 -0
  506. package/src/runtime/facades/brain-facade.test.ts +714 -0
  507. package/src/runtime/facades/brain-facade.ts +2 -0
  508. package/src/runtime/facades/chat-facade.test.ts +166 -0
  509. package/src/runtime/facades/chat-facade.ts +15 -906
  510. package/src/runtime/facades/chat-service-ops.test.ts +276 -0
  511. package/src/runtime/facades/chat-service-ops.ts +374 -0
  512. package/src/runtime/facades/chat-session-ops.test.ts +197 -0
  513. package/src/runtime/facades/chat-session-ops.ts +146 -0
  514. package/src/runtime/facades/chat-state.ts +60 -0
  515. package/src/runtime/facades/chat-transport-ops.test.ts +269 -0
  516. package/src/runtime/facades/chat-transport-ops.ts +380 -0
  517. package/src/runtime/facades/context-facade.test.ts +108 -0
  518. package/src/runtime/facades/control-facade.test.ts +436 -0
  519. package/src/runtime/facades/control-facade.ts +6 -1
  520. package/src/runtime/facades/curator-facade.test.ts +303 -0
  521. package/src/runtime/facades/index.ts +6 -0
  522. package/src/runtime/facades/loop-facade.test.ts +245 -0
  523. package/src/runtime/facades/memory-facade.test.ts +269 -0
  524. package/src/runtime/facades/memory-facade.ts +78 -6
  525. package/src/runtime/facades/operator-facade.test.ts +208 -0
  526. package/src/runtime/facades/operator-facade.ts +236 -0
  527. package/src/runtime/facades/orchestrate-facade.test.ts +185 -0
  528. package/src/runtime/facades/orchestrate-facade.ts +3 -3
  529. package/src/runtime/facades/plan-facade.test.ts +266 -0
  530. package/src/runtime/facades/plan-facade.ts +42 -6
  531. package/src/runtime/facades/review-facade.test.ts +82 -0
  532. package/src/runtime/facades/review-facade.ts +11 -0
  533. package/src/runtime/facades/sync-facade.test.ts +113 -0
  534. package/src/runtime/facades/sync-facade.ts +11 -0
  535. package/src/runtime/facades/vault-facade.test.ts +631 -0
  536. package/src/runtime/facades/vault-facade.ts +15 -70
  537. package/src/runtime/feature-flags.test.ts +140 -0
  538. package/src/runtime/github-integration.test.ts +89 -0
  539. package/src/runtime/github-integration.ts +159 -0
  540. package/src/runtime/grading-ops.test.ts +141 -0
  541. package/src/runtime/grading-ops.ts +1 -1
  542. package/src/runtime/intake-ops.test.ts +208 -0
  543. package/src/runtime/loop-ops.test.ts +238 -0
  544. package/src/runtime/memory-cross-project-ops.test.ts +177 -0
  545. package/src/runtime/memory-extra-ops.test.ts +453 -0
  546. package/src/runtime/memory-extra-ops.ts +6 -2
  547. package/src/runtime/orchestrate-ops.test.ts +302 -0
  548. package/src/runtime/orchestrate-ops.ts +435 -46
  549. package/src/runtime/pack-ops.test.ts +158 -0
  550. package/src/runtime/planning-extra-ops.test.ts +583 -0
  551. package/src/runtime/planning-extra-ops.ts +72 -4
  552. package/src/{__tests__ → runtime}/playbook-ops-execution.test.ts +3 -3
  553. package/src/runtime/playbook-ops.test.ts +262 -0
  554. package/src/runtime/plugin-ops.test.ts +201 -0
  555. package/src/runtime/project-ops.test.ts +235 -0
  556. package/src/runtime/review-ops.test.ts +142 -0
  557. package/src/runtime/review-ops.ts +99 -0
  558. package/src/runtime/runtime.test.ts +363 -0
  559. package/src/runtime/runtime.ts +39 -12
  560. package/src/runtime/session-briefing.test.ts +302 -0
  561. package/src/runtime/session-briefing.ts +80 -1
  562. package/src/runtime/sync-ops.test.ts +221 -0
  563. package/src/runtime/sync-ops.ts +325 -0
  564. package/src/runtime/telemetry-ops.test.ts +132 -0
  565. package/src/runtime/types.ts +10 -4
  566. package/src/runtime/vault-extra-ops.test.ts +246 -0
  567. package/src/runtime/vault-extra-ops.ts +5 -332
  568. package/src/runtime/vault-linking-ops.test.ts +237 -0
  569. package/src/runtime/vault-sharing-ops.test.ts +130 -0
  570. package/src/runtime/vault-sharing-ops.ts +5 -329
  571. package/src/skills/sync-skills.ts +108 -0
  572. package/src/streams/normalize.test.ts +95 -0
  573. package/src/streams/replayable-stream.test.ts +166 -0
  574. package/src/telemetry/telemetry.test.ts +143 -0
  575. package/src/transport/http-server.test.ts +394 -0
  576. package/src/transport/lsp-server.test.ts +458 -0
  577. package/src/transport/rate-limiter.test.ts +126 -0
  578. package/src/transport/session-manager.test.ts +133 -0
  579. package/src/transport/token-auth.test.ts +136 -0
  580. package/src/transport/ws-server.test.ts +294 -0
  581. package/src/update-check.ts +111 -0
  582. package/src/vault/__tests__/vault-characterization.test.ts +168 -0
  583. package/src/vault/content-hash.test.ts +78 -0
  584. package/src/vault/git-vault-sync.test.ts +234 -0
  585. package/src/vault/knowledge-review.test.ts +269 -0
  586. package/src/vault/linking.test.ts +358 -0
  587. package/src/vault/linking.ts +149 -183
  588. package/src/vault/obsidian-sync.test.ts +342 -0
  589. package/src/vault/playbook.test.ts +152 -0
  590. package/src/vault/scope-detector.test.ts +187 -0
  591. package/src/vault/vault-branching.test.ts +250 -0
  592. package/src/{__tests__ → vault}/vault-connect.test.ts +1 -1
  593. package/src/vault/vault-entries.ts +282 -0
  594. package/src/vault/vault-interfaces.ts +56 -0
  595. package/src/vault/vault-maintenance.ts +205 -0
  596. package/src/vault/vault-manager.test.ts +206 -0
  597. package/src/vault/vault-markdown-sync.test.ts +203 -0
  598. package/src/vault/vault-markdown-sync.ts +160 -0
  599. package/src/vault/vault-memories.ts +339 -0
  600. package/src/{__tests__ → vault}/vault-scaling.test.ts +1 -1
  601. package/src/vault/vault-schema.ts +181 -0
  602. package/src/{__tests__ → vault}/vault-sharing.test.ts +4 -4
  603. package/src/{__tests__ → vault}/vault.test.ts +2 -2
  604. package/src/vault/vault.ts +89 -1171
  605. package/dist/cognee/client.d.ts +0 -43
  606. package/dist/cognee/client.d.ts.map +0 -1
  607. package/dist/cognee/client.js +0 -375
  608. package/dist/cognee/client.js.map +0 -1
  609. package/dist/cognee/sync-manager.d.ts +0 -153
  610. package/dist/cognee/sync-manager.d.ts.map +0 -1
  611. package/dist/cognee/sync-manager.js +0 -390
  612. package/dist/cognee/sync-manager.js.map +0 -1
  613. package/dist/cognee/types.d.ts +0 -62
  614. package/dist/cognee/types.d.ts.map +0 -1
  615. package/dist/cognee/types.js +0 -3
  616. package/dist/cognee/types.js.map +0 -1
  617. package/dist/governance/index.d.ts +0 -3
  618. package/dist/governance/index.d.ts.map +0 -1
  619. package/dist/governance/index.js +0 -2
  620. package/dist/governance/index.js.map +0 -1
  621. package/dist/health/doctor-checks.d.ts +0 -15
  622. package/dist/health/doctor-checks.d.ts.map +0 -1
  623. package/dist/health/doctor-checks.js +0 -98
  624. package/dist/health/doctor-checks.js.map +0 -1
  625. package/dist/persistence/postgres-provider.d.ts +0 -81
  626. package/dist/persistence/postgres-provider.d.ts.map +0 -1
  627. package/dist/persistence/postgres-provider.js +0 -256
  628. package/dist/persistence/postgres-provider.js.map +0 -1
  629. package/dist/runtime/cognee-sync-ops.d.ts +0 -12
  630. package/dist/runtime/cognee-sync-ops.d.ts.map +0 -1
  631. package/dist/runtime/cognee-sync-ops.js +0 -93
  632. package/dist/runtime/cognee-sync-ops.js.map +0 -1
  633. package/dist/runtime/core-ops.d.ts +0 -23
  634. package/dist/runtime/core-ops.d.ts.map +0 -1
  635. package/dist/runtime/core-ops.js +0 -1296
  636. package/dist/runtime/core-ops.js.map +0 -1
  637. package/dist/runtime/facades/cognee-facade.d.ts +0 -8
  638. package/dist/runtime/facades/cognee-facade.d.ts.map +0 -1
  639. package/dist/runtime/facades/cognee-facade.js +0 -156
  640. package/dist/runtime/facades/cognee-facade.js.map +0 -1
  641. package/src/__tests__/admin-extra-ops.test.ts +0 -484
  642. package/src/__tests__/admin-ops.test.ts +0 -268
  643. package/src/__tests__/admin-setup-ops.test.ts +0 -355
  644. package/src/__tests__/agency-manager.test.ts +0 -374
  645. package/src/__tests__/agent-loop.test.ts +0 -256
  646. package/src/__tests__/capture-ops.test.ts +0 -784
  647. package/src/__tests__/claudemd.test.ts +0 -282
  648. package/src/__tests__/content-hash.test.ts +0 -60
  649. package/src/__tests__/context-engine.test.ts +0 -251
  650. package/src/__tests__/core-ops.test.ts +0 -550
  651. package/src/__tests__/curator-extra-ops.test.ts +0 -383
  652. package/src/__tests__/deprecation.test.ts +0 -78
  653. package/src/__tests__/domain-ops.test.ts +0 -226
  654. package/src/__tests__/domain-packs.test.ts +0 -421
  655. package/src/__tests__/enforcement.test.ts +0 -153
  656. package/src/__tests__/errors.test.ts +0 -388
  657. package/src/__tests__/extensions.test.ts +0 -233
  658. package/src/__tests__/facade-factory.test.ts +0 -271
  659. package/src/__tests__/feature-flags.test.ts +0 -137
  660. package/src/__tests__/flows.test.ts +0 -604
  661. package/src/__tests__/git-vault-sync.test.ts +0 -230
  662. package/src/__tests__/governance.test.ts +0 -522
  663. package/src/__tests__/grading-ops.test.ts +0 -361
  664. package/src/__tests__/health-registry.test.ts +0 -173
  665. package/src/__tests__/identity-manager.test.ts +0 -243
  666. package/src/__tests__/intake-pipeline.test.ts +0 -162
  667. package/src/__tests__/intent-router.test.ts +0 -222
  668. package/src/__tests__/knowledge-review.test.ts +0 -104
  669. package/src/__tests__/llm-client.test.ts +0 -69
  670. package/src/__tests__/llm.test.ts +0 -556
  671. package/src/__tests__/loader.test.ts +0 -176
  672. package/src/__tests__/loop-ops.test.ts +0 -469
  673. package/src/__tests__/lsp-transport.test.ts +0 -442
  674. package/src/__tests__/memory-cross-project-ops.test.ts +0 -248
  675. package/src/__tests__/memory-extra-ops.test.ts +0 -352
  676. package/src/__tests__/migration-runner.test.ts +0 -170
  677. package/src/__tests__/module-manifest-drift.test.ts +0 -59
  678. package/src/__tests__/normalize.test.ts +0 -85
  679. package/src/__tests__/obsidian-sync.test.ts +0 -354
  680. package/src/__tests__/orchestrate-ops.test.ts +0 -289
  681. package/src/__tests__/pack-ops.test.ts +0 -146
  682. package/src/__tests__/persistence.test.ts +0 -291
  683. package/src/__tests__/planning-extra-ops.test.ts +0 -706
  684. package/src/__tests__/playbook-executor.test.ts +0 -249
  685. package/src/__tests__/playbook-registry.test.ts +0 -326
  686. package/src/__tests__/playbook-seeder.test.ts +0 -163
  687. package/src/__tests__/playbook.test.ts +0 -389
  688. package/src/__tests__/plugin-ops.test.ts +0 -411
  689. package/src/__tests__/plugin-system.test.ts +0 -509
  690. package/src/__tests__/project-ops.test.ts +0 -381
  691. package/src/__tests__/replayable-stream.test.ts +0 -177
  692. package/src/__tests__/runtime.test.ts +0 -95
  693. package/src/__tests__/scope-detector.test.ts +0 -121
  694. package/src/__tests__/template-manager.test.ts +0 -222
  695. package/src/__tests__/token-resolver.test.ts +0 -79
  696. package/src/__tests__/transport.test.ts +0 -758
  697. package/src/__tests__/vault-branching.test.ts +0 -274
  698. package/src/__tests__/vault-extra-ops.test.ts +0 -482
  699. package/src/__tests__/vault-integrity.test.ts +0 -71
  700. package/src/__tests__/vault-manager.test.ts +0 -238
  701. package/src/__tests__/ws-transport.test.ts +0 -479
@@ -0,0 +1,228 @@
1
+ /**
2
+ * Default Suggestion Rules — colocated contract tests.
3
+ *
4
+ * Validates each of the 6 built-in rules: condition triggers and generate output shape.
5
+ */
6
+
7
+ import { describe, it, expect } from 'vitest';
8
+ import { DEFAULT_SUGGESTION_RULES } from './default-rules.js';
9
+ import type { SuggestionContext, Warning, SurfacedPattern } from './types.js';
10
+
11
+ // ─── Helpers ────────────────────────────────────────────────────────
12
+
13
+ function makeContext(overrides?: Partial<SuggestionContext>): SuggestionContext {
14
+ return {
15
+ recentFiles: [],
16
+ pendingWarnings: [],
17
+ surfacedPatterns: [],
18
+ fileChangesProcessed: 0,
19
+ ...overrides,
20
+ };
21
+ }
22
+
23
+ function makeWarning(overrides?: Partial<Warning>): Warning {
24
+ return {
25
+ id: 'w-1',
26
+ file: '/test.ts',
27
+ severity: 'warning',
28
+ category: 'test',
29
+ message: 'test warning',
30
+ ...overrides,
31
+ };
32
+ }
33
+
34
+ function makePattern(overrides?: Partial<SurfacedPattern>): SurfacedPattern {
35
+ return {
36
+ entryId: 'p-1',
37
+ title: 'Test pattern',
38
+ domain: 'general',
39
+ relevance: 0.8,
40
+ trigger: '/test.ts',
41
+ ...overrides,
42
+ };
43
+ }
44
+
45
+ function findRule(name: string) {
46
+ return DEFAULT_SUGGESTION_RULES.find(r => r.name === name)!;
47
+ }
48
+
49
+ describe('DEFAULT_SUGGESTION_RULES', () => {
50
+ it('exports exactly 6 rules', () => {
51
+ expect(DEFAULT_SUGGESTION_RULES).toHaveLength(6);
52
+ });
53
+
54
+ it('each rule has name, description, condition, and generate', () => {
55
+ for (const rule of DEFAULT_SUGGESTION_RULES) {
56
+ expect(typeof rule.name).toBe('string');
57
+ expect(typeof rule.description).toBe('string');
58
+ expect(typeof rule.condition).toBe('function');
59
+ expect(typeof rule.generate).toBe('function');
60
+ }
61
+ });
62
+
63
+ // ─── many-warnings ────────────────────────────────────────────────
64
+
65
+ describe('many-warnings', () => {
66
+ const rule = findRule('many-warnings');
67
+
68
+ it('fires when 5+ warnings pending', () => {
69
+ const warnings = Array.from({ length: 5 }, (_, i) => makeWarning({ id: `w-${i}` }));
70
+ expect(rule.condition(makeContext({ pendingWarnings: warnings }))).toBe(true);
71
+ });
72
+
73
+ it('does not fire with fewer than 5 warnings', () => {
74
+ expect(rule.condition(makeContext({ pendingWarnings: [makeWarning()] }))).toBe(false);
75
+ });
76
+
77
+ it('generates high priority suggestion with count in title', () => {
78
+ const warnings = Array.from({ length: 7 }, (_, i) => makeWarning({ id: `w-${i}` }));
79
+ const s = rule.generate(makeContext({ pendingWarnings: warnings }));
80
+ expect(s.rule).toBe('many-warnings');
81
+ expect(s.priority).toBe('high');
82
+ expect(s.title).toContain('7');
83
+ });
84
+ });
85
+
86
+ // ─── stale-patterns ───────────────────────────────────────────────
87
+
88
+ describe('stale-patterns', () => {
89
+ const rule = findRule('stale-patterns');
90
+
91
+ it('fires when no patterns surfaced after 20+ changes', () => {
92
+ expect(rule.condition(makeContext({ fileChangesProcessed: 21 }))).toBe(true);
93
+ });
94
+
95
+ it('does not fire with patterns present', () => {
96
+ expect(rule.condition(makeContext({
97
+ fileChangesProcessed: 30,
98
+ surfacedPatterns: [makePattern()],
99
+ }))).toBe(false);
100
+ });
101
+
102
+ it('does not fire with few changes', () => {
103
+ expect(rule.condition(makeContext({ fileChangesProcessed: 5 }))).toBe(false);
104
+ });
105
+
106
+ it('generates medium priority suggestion', () => {
107
+ const s = rule.generate(makeContext({ fileChangesProcessed: 25 }));
108
+ expect(s.rule).toBe('stale-patterns');
109
+ expect(s.priority).toBe('medium');
110
+ });
111
+ });
112
+
113
+ // ─── high-activity-no-capture ─────────────────────────────────────
114
+
115
+ describe('high-activity-no-capture', () => {
116
+ const rule = findRule('high-activity-no-capture');
117
+
118
+ it('fires when 50+ changes and no patterns', () => {
119
+ expect(rule.condition(makeContext({ fileChangesProcessed: 51 }))).toBe(true);
120
+ });
121
+
122
+ it('does not fire with patterns', () => {
123
+ expect(rule.condition(makeContext({
124
+ fileChangesProcessed: 60,
125
+ surfacedPatterns: [makePattern()],
126
+ }))).toBe(false);
127
+ });
128
+
129
+ it('does not fire with few changes', () => {
130
+ expect(rule.condition(makeContext({ fileChangesProcessed: 10 }))).toBe(false);
131
+ });
132
+
133
+ it('generates suggestion with change count', () => {
134
+ const s = rule.generate(makeContext({ fileChangesProcessed: 55 }));
135
+ expect(s.rule).toBe('high-activity-no-capture');
136
+ expect(s.priority).toBe('medium');
137
+ expect(s.description).toContain('55');
138
+ });
139
+ });
140
+
141
+ // ─── critical-warnings ────────────────────────────────────────────
142
+
143
+ describe('critical-warnings', () => {
144
+ const rule = findRule('critical-warnings');
145
+
146
+ it('fires when critical severity warnings exist', () => {
147
+ const ctx = makeContext({
148
+ pendingWarnings: [makeWarning({ severity: 'critical' })],
149
+ });
150
+ expect(rule.condition(ctx)).toBe(true);
151
+ });
152
+
153
+ it('does not fire with only non-critical warnings', () => {
154
+ const ctx = makeContext({
155
+ pendingWarnings: [makeWarning({ severity: 'warning' }), makeWarning({ severity: 'info' })],
156
+ });
157
+ expect(rule.condition(ctx)).toBe(false);
158
+ });
159
+
160
+ it('generates high priority with count and messages', () => {
161
+ const ctx = makeContext({
162
+ pendingWarnings: [
163
+ makeWarning({ severity: 'critical', message: 'sec issue' }),
164
+ makeWarning({ severity: 'critical', message: 'another issue' }),
165
+ makeWarning({ severity: 'warning', message: 'minor' }),
166
+ ],
167
+ });
168
+ const s = rule.generate(ctx);
169
+ expect(s.rule).toBe('critical-warnings');
170
+ expect(s.priority).toBe('high');
171
+ expect(s.title).toContain('2');
172
+ expect(s.description).toContain('sec issue');
173
+ });
174
+ });
175
+
176
+ // ─── pattern-surfaced ─────────────────────────────────────────────
177
+
178
+ describe('pattern-surfaced', () => {
179
+ const rule = findRule('pattern-surfaced');
180
+
181
+ it('fires when patterns are surfaced', () => {
182
+ expect(rule.condition(makeContext({ surfacedPatterns: [makePattern()] }))).toBe(true);
183
+ });
184
+
185
+ it('does not fire with empty patterns', () => {
186
+ expect(rule.condition(makeContext())).toBe(false);
187
+ });
188
+
189
+ it('generates low priority with pattern titles', () => {
190
+ const ctx = makeContext({
191
+ surfacedPatterns: [
192
+ makePattern({ title: 'React hooks', domain: 'react' }),
193
+ makePattern({ title: 'CSS Grid', domain: 'styling' }),
194
+ ],
195
+ });
196
+ const s = rule.generate(ctx);
197
+ expect(s.rule).toBe('pattern-surfaced');
198
+ expect(s.priority).toBe('low');
199
+ expect(s.description).toContain('React hooks');
200
+ expect(s.description).toContain('CSS Grid');
201
+ });
202
+ });
203
+
204
+ // ─── first-session ────────────────────────────────────────────────
205
+
206
+ describe('first-session', () => {
207
+ const rule = findRule('first-session');
208
+
209
+ it('fires on fresh state (0 changes, 0 warnings)', () => {
210
+ expect(rule.condition(makeContext())).toBe(true);
211
+ });
212
+
213
+ it('does not fire after changes processed', () => {
214
+ expect(rule.condition(makeContext({ fileChangesProcessed: 1 }))).toBe(false);
215
+ });
216
+
217
+ it('does not fire when warnings exist', () => {
218
+ expect(rule.condition(makeContext({ pendingWarnings: [makeWarning()] }))).toBe(false);
219
+ });
220
+
221
+ it('generates low priority welcome message', () => {
222
+ const s = rule.generate(makeContext());
223
+ expect(s.rule).toBe('first-session');
224
+ expect(s.priority).toBe('low');
225
+ expect(s.title).toContain('ready');
226
+ });
227
+ });
228
+ });
@@ -4,7 +4,7 @@ import { join } from 'node:path';
4
4
  import { tmpdir } from 'node:os';
5
5
  import { createAgentRuntime } from '../runtime/runtime.js';
6
6
  import type { AgentRuntime } from '../runtime/types.js';
7
- import type { BrainExportData } from '../brain/types.js';
7
+ import type { BrainExportData } from './types.js';
8
8
 
9
9
  describe('BrainIntelligence', () => {
10
10
  let runtime: AgentRuntime;
@@ -367,17 +367,25 @@ describe('BrainIntelligence', () => {
367
367
  // ─── Proposals ─────────────────────────────────────────────────
368
368
 
369
369
  it('should list proposals', () => {
370
+ // Use plan_completed (confidence 0.65) — below auto-promote threshold (0.8)
370
371
  runtime.brainIntelligence.lifecycle({
371
372
  action: 'start',
372
373
  sessionId: 'prop-1',
373
- toolsUsed: ['a', 'a', 'a'],
374
+ planId: 'plan-list-1',
375
+ });
376
+ runtime.brainIntelligence.lifecycle({
377
+ action: 'end',
378
+ sessionId: 'prop-1',
379
+ planId: 'plan-list-1',
380
+ planOutcome: 'completed',
374
381
  });
375
- runtime.brainIntelligence.lifecycle({ action: 'end', sessionId: 'prop-1' });
376
- runtime.brainIntelligence.extractKnowledge('prop-1');
377
382
 
378
383
  const proposals = runtime.brainIntelligence.getProposals();
379
384
  expect(proposals.length).toBeGreaterThan(0);
380
- expect(proposals[0].promoted).toBe(false);
385
+ // plan_completed confidence is 0.65 — below auto-promote threshold
386
+ const planProposals = proposals.filter((p) => p.rule === 'plan_completed');
387
+ expect(planProposals.length).toBeGreaterThan(0);
388
+ expect(planProposals[0].promoted).toBe(false);
381
389
  });
382
390
 
383
391
  it('should filter proposals by session', () => {
@@ -404,15 +412,23 @@ describe('BrainIntelligence', () => {
404
412
  });
405
413
 
406
414
  it('should promote proposals to vault', () => {
415
+ // Use plan_completed (confidence 0.65) to avoid auto-promote (threshold 0.8)
407
416
  runtime.brainIntelligence.lifecycle({
408
417
  action: 'start',
409
418
  sessionId: 'promo-1',
410
- toolsUsed: ['z', 'z', 'z'],
419
+ planId: 'plan-promo-1',
420
+ });
421
+ runtime.brainIntelligence.lifecycle({
422
+ action: 'end',
423
+ sessionId: 'promo-1',
424
+ planId: 'plan-promo-1',
425
+ planOutcome: 'completed',
411
426
  });
412
- runtime.brainIntelligence.lifecycle({ action: 'end', sessionId: 'promo-1' });
413
- runtime.brainIntelligence.extractKnowledge('promo-1');
414
427
 
415
- const proposals = runtime.brainIntelligence.getProposals({ sessionId: 'promo-1' });
428
+ const proposals = runtime.brainIntelligence.getProposals({
429
+ sessionId: 'promo-1',
430
+ promoted: false,
431
+ });
416
432
  expect(proposals.length).toBeGreaterThan(0);
417
433
 
418
434
  const result = runtime.brainIntelligence.promoteProposals([proposals[0].id]);
@@ -432,16 +448,23 @@ describe('BrainIntelligence', () => {
432
448
  });
433
449
 
434
450
  it('should gate promote through governance when strict preset', () => {
435
- // Create a brain session and extract proposals
451
+ // Use plan_completed (confidence 0.65) to avoid auto-promote (threshold 0.8)
436
452
  runtime.brainIntelligence.lifecycle({
437
453
  action: 'start',
438
454
  sessionId: 'gov-promo-1',
439
- toolsUsed: ['w', 'w', 'w'],
455
+ planId: 'plan-gov-1',
456
+ });
457
+ runtime.brainIntelligence.lifecycle({
458
+ action: 'end',
459
+ sessionId: 'gov-promo-1',
460
+ planId: 'plan-gov-1',
461
+ planOutcome: 'completed',
440
462
  });
441
- runtime.brainIntelligence.lifecycle({ action: 'end', sessionId: 'gov-promo-1' });
442
- runtime.brainIntelligence.extractKnowledge('gov-promo-1');
443
463
 
444
- const proposals = runtime.brainIntelligence.getProposals({ sessionId: 'gov-promo-1' });
464
+ const proposals = runtime.brainIntelligence.getProposals({
465
+ sessionId: 'gov-promo-1',
466
+ promoted: false,
467
+ });
445
468
  expect(proposals.length).toBeGreaterThan(0);
446
469
 
447
470
  // Apply strict preset — requireReview: true
@@ -1,6 +1,6 @@
1
1
  import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
2
  import { Vault } from '../vault/vault.js';
3
- import { Brain } from '../brain/brain.js';
3
+ import { Brain } from './brain.js';
4
4
  import type { IntelligenceEntry } from '../intelligence/types.js';
5
5
 
6
6
  function makeEntry(overrides: Partial<IntelligenceEntry> = {}): IntelligenceEntry {
@@ -10,6 +10,8 @@ import { randomUUID } from 'node:crypto';
10
10
  import type { Vault } from '../vault/vault.js';
11
11
  import type { Brain } from './brain.js';
12
12
  import type { PersistenceProvider } from '../persistence/types.js';
13
+ import type { OperatorProfileStore } from '../operator/operator-profile.js';
14
+ import { extractFromBrainStrengths } from '../operator/operator-signals.js';
13
15
  import type {
14
16
  PatternStrength,
15
17
  StrengthsQuery,
@@ -38,6 +40,10 @@ const EXTRACTION_TOOL_THRESHOLD = 3;
38
40
  const EXTRACTION_FILE_THRESHOLD = 3;
39
41
  const EXTRACTION_LONG_SESSION_MINUTES = 30;
40
42
  const EXTRACTION_HIGH_FEEDBACK_RATIO = 0.8;
43
+ const AUTO_PROMOTE_THRESHOLD = 0.8;
44
+ const AUTO_PROMOTE_PENDING_MIN = 0.4;
45
+ const AUTO_BUILD_INTELLIGENCE_EVERY_N_SESSIONS = 3;
46
+ const AUTO_BUILD_INTELLIGENCE_EVERY_N_FEEDBACK = 5;
41
47
 
42
48
  // ─── Class ──────────────────────────────────────────────────────────
43
49
 
@@ -45,6 +51,7 @@ export class BrainIntelligence {
45
51
  private vault: Vault;
46
52
  private brain: Brain;
47
53
  private provider: PersistenceProvider;
54
+ private operatorProfile: OperatorProfileStore | null = null;
48
55
 
49
56
  constructor(vault: Vault, brain: Brain) {
50
57
  this.vault = vault;
@@ -53,6 +60,11 @@ export class BrainIntelligence {
53
60
  this.initializeTables();
54
61
  }
55
62
 
63
+ /** Wire operator profile for automatic signal extraction. */
64
+ setOperatorProfile(profile: OperatorProfileStore): void {
65
+ this.operatorProfile = profile;
66
+ }
67
+
56
68
  // ─── Table Initialization ─────────────────────────────────────────
57
69
 
58
70
  private initializeTables(): void {
@@ -116,6 +128,12 @@ export class BrainIntelligence {
116
128
  last_activity TEXT NOT NULL DEFAULT (datetime('now')),
117
129
  updated_at TEXT NOT NULL DEFAULT (datetime('now'))
118
130
  );
131
+
132
+ CREATE TABLE IF NOT EXISTS brain_metadata (
133
+ key TEXT PRIMARY KEY,
134
+ value TEXT NOT NULL,
135
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
136
+ );
119
137
  `);
120
138
  }
121
139
 
@@ -177,6 +195,12 @@ export class BrainIntelligence {
177
195
  * Attempt auto-extraction after session end if the session has enough signal.
178
196
  * Gate: at least 1 tool used OR 1 file modified OR a plan was associated.
179
197
  * Silently skips if already extracted or insufficient data.
198
+ *
199
+ * After extraction, auto-promotes high-confidence proposals (>= 0.8) via
200
+ * enrichAndCapture() (which has built-in dedup). Proposals between 0.4-0.8
201
+ * are queued as pending. Below 0.4 are logged only.
202
+ *
203
+ * Also tracks completed sessions and auto-builds intelligence every N sessions.
180
204
  */
181
205
  private autoExtractIfReady(session: BrainSession): void {
182
206
  if (!session.endedAt) return;
@@ -188,12 +212,124 @@ export class BrainIntelligence {
188
212
  if (!hasSignal) return;
189
213
 
190
214
  try {
191
- this.extractKnowledge(session.id);
215
+ const result = this.extractKnowledge(session.id);
216
+ this.autoPromoteProposals(result.proposals);
217
+ } catch {
218
+ // Non-critical — don't break session end
219
+ }
220
+
221
+ // Auto-build intelligence after N completed plan sessions
222
+ if (session.planOutcome === 'completed') {
223
+ this.maybeAutoBuildIntelligence();
224
+ }
225
+ }
226
+
227
+ /**
228
+ * Auto-promote high-confidence proposals via enrichAndCapture().
229
+ * Dedup in enrichAndCapture() handles novelty gating:
230
+ * - TF-IDF similarity >= 0.8 → blocked (near-duplicate)
231
+ * - Content-hash match → blocked (exact duplicate)
232
+ */
233
+ private autoPromoteProposals(proposals: KnowledgeProposal[]): void {
234
+ for (const p of proposals) {
235
+ if (p.confidence >= AUTO_PROMOTE_THRESHOLD) {
236
+ // High confidence — auto-promote through dedup pipeline
237
+ try {
238
+ const vaultType: 'pattern' | 'anti-pattern' | 'rule' =
239
+ p.type === 'anti-pattern' ? 'anti-pattern' : 'pattern';
240
+ const result = this.brain.enrichAndCapture({
241
+ id: `proposal-${p.id}`,
242
+ type: vaultType,
243
+ domain: 'brain-intelligence',
244
+ title: p.title,
245
+ severity: 'suggestion',
246
+ description: p.description,
247
+ tags: ['auto-extracted', 'auto-promoted', p.rule],
248
+ });
249
+ if (result.captured) {
250
+ this.provider.run('UPDATE brain_proposals SET promoted = 1 WHERE id = ?', [p.id]);
251
+ }
252
+ // If blocked by dedup, leave as unpromoted — that's correct behavior
253
+ } catch {
254
+ // Non-critical — proposal stays as pending
255
+ }
256
+ } else if (p.confidence < AUTO_PROMOTE_PENDING_MIN) {
257
+ // Low confidence — mark as not surfaceable (promoted = false is already default)
258
+ // Just log, don't surface in briefings
259
+ }
260
+ // Medium confidence (0.4-0.8) — stays as pending, surfaced in briefing
261
+ }
262
+ }
263
+
264
+ /**
265
+ * Track completed sessions and auto-trigger buildIntelligence() every N sessions.
266
+ */
267
+ private maybeAutoBuildIntelligence(): void {
268
+ try {
269
+ const row = this.provider.get<{ value: string }>(
270
+ "SELECT value FROM brain_metadata WHERE key = 'sessions_since_last_build'",
271
+ );
272
+ const current = row ? parseInt(row.value, 10) : 0;
273
+ const next = current + 1;
274
+
275
+ if (next >= AUTO_BUILD_INTELLIGENCE_EVERY_N_SESSIONS) {
276
+ this.buildIntelligence();
277
+ this.provider.run(
278
+ `INSERT OR REPLACE INTO brain_metadata (key, value, updated_at)
279
+ VALUES ('sessions_since_last_build', '0', datetime('now'))`,
280
+ );
281
+ // Reset feedback counter too — avoid double-trigger
282
+ this.provider.run(
283
+ `INSERT OR REPLACE INTO brain_metadata (key, value, updated_at)
284
+ VALUES ('feedback_since_last_build', '0', datetime('now'))`,
285
+ );
286
+ } else {
287
+ this.provider.run(
288
+ `INSERT OR REPLACE INTO brain_metadata (key, value, updated_at)
289
+ VALUES ('sessions_since_last_build', ?, datetime('now'))`,
290
+ [String(next)],
291
+ );
292
+ }
192
293
  } catch {
193
294
  // Non-critical — don't break session end
194
295
  }
195
296
  }
196
297
 
298
+ /**
299
+ * Auto-rebuild intelligence after N feedback entries accumulate.
300
+ * Called from facade after record_feedback / brain_feedback ops.
301
+ */
302
+ maybeAutoBuildOnFeedback(): void {
303
+ try {
304
+ const row = this.provider.get<{ value: string }>(
305
+ "SELECT value FROM brain_metadata WHERE key = 'feedback_since_last_build'",
306
+ );
307
+ const current = row ? parseInt(row.value, 10) : 0;
308
+ const next = current + 1;
309
+
310
+ if (next >= AUTO_BUILD_INTELLIGENCE_EVERY_N_FEEDBACK) {
311
+ this.buildIntelligence();
312
+ this.provider.run(
313
+ `INSERT OR REPLACE INTO brain_metadata (key, value, updated_at)
314
+ VALUES ('feedback_since_last_build', '0', datetime('now'))`,
315
+ );
316
+ // Reset session counter too — avoid double-trigger
317
+ this.provider.run(
318
+ `INSERT OR REPLACE INTO brain_metadata (key, value, updated_at)
319
+ VALUES ('sessions_since_last_build', '0', datetime('now'))`,
320
+ );
321
+ } else {
322
+ this.provider.run(
323
+ `INSERT OR REPLACE INTO brain_metadata (key, value, updated_at)
324
+ VALUES ('feedback_since_last_build', ?, datetime('now'))`,
325
+ [String(next)],
326
+ );
327
+ }
328
+ } catch {
329
+ // Non-critical — don't block feedback recording
330
+ }
331
+ }
332
+
197
333
  getSessionContext(limit = 10): SessionContext {
198
334
  const rows = this.provider.all<{
199
335
  id: string;
@@ -249,6 +385,24 @@ export class BrainIntelligence {
249
385
  return this.getSession(id);
250
386
  }
251
387
 
388
+ getSessionByPlanId(planId: string): BrainSession | null {
389
+ const row = this.provider.get<{
390
+ id: string;
391
+ started_at: string;
392
+ ended_at: string | null;
393
+ domain: string | null;
394
+ context: string | null;
395
+ tools_used: string;
396
+ files_modified: string;
397
+ plan_id: string | null;
398
+ plan_outcome: string | null;
399
+ extracted_at: string | null;
400
+ }>('SELECT * FROM brain_sessions WHERE plan_id = ? ORDER BY started_at DESC LIMIT 1', [planId]);
401
+
402
+ if (!row) return null;
403
+ return this.rowToSession(row);
404
+ }
405
+
252
406
  listSessions(query?: SessionListQuery): BrainSession[] {
253
407
  const conditions: string[] = [];
254
408
  const values: unknown[] = [];
@@ -595,19 +749,34 @@ export class BrainIntelligence {
595
749
  }
596
750
  }
597
751
 
598
- // Rule 2: Multi-file edits (3+ files)
752
+ // Rule 2: Multi-file edits (3+ files sharing a common parent directory)
599
753
  if (session.filesModified.length >= EXTRACTION_FILE_THRESHOLD) {
600
- rulesApplied.push('multi_file_edit');
601
- proposals.push(
602
- this.createProposal(sessionId, 'multi_file_edit', 'pattern', {
603
- title: `Multi-file change pattern (${session.filesModified.length} files)`,
604
- description: `Session modified ${session.filesModified.length} files: ${session.filesModified.slice(0, 5).join(', ')}${session.filesModified.length > 5 ? '...' : ''}. This may indicate an architectural pattern.`,
605
- confidence: Math.min(0.8, 0.4 + session.filesModified.length * 0.05),
606
- }),
754
+ // Group files by parent directory to filter noise
755
+ const dirGroups = new Map<string, string[]>();
756
+ for (const f of session.filesModified) {
757
+ const dir = f.includes('/') ? f.slice(0, f.lastIndexOf('/')) : '.';
758
+ const list = dirGroups.get(dir) ?? [];
759
+ list.push(f);
760
+ dirGroups.set(dir, list);
761
+ }
762
+ // Only fire if at least 3 files share a common parent directory
763
+ const significantDirs = [...dirGroups.entries()].filter(
764
+ ([, files]) => files.length >= EXTRACTION_FILE_THRESHOLD,
607
765
  );
766
+ if (significantDirs.length > 0) {
767
+ const [topDir, topFiles] = significantDirs.sort((a, b) => b[1].length - a[1].length)[0];
768
+ rulesApplied.push('multi_file_edit');
769
+ proposals.push(
770
+ this.createProposal(sessionId, 'multi_file_edit', 'pattern', {
771
+ title: `Multi-file change pattern in ${topDir} (${topFiles.length} files)`,
772
+ description: `Session modified ${topFiles.length} files in ${topDir}: ${topFiles.slice(0, 5).join(', ')}${topFiles.length > 5 ? '...' : ''}. This may indicate an architectural pattern.`,
773
+ confidence: Math.min(0.8, 0.4 + topFiles.length * 0.05),
774
+ }),
775
+ );
776
+ }
608
777
  }
609
778
 
610
- // Rule 3: Long session (>30min)
779
+ // Rule 3: Long session (>30min) — neutral observation, not anti-pattern
611
780
  if (session.endedAt && session.startedAt) {
612
781
  const durationMs =
613
782
  new Date(session.endedAt).getTime() - new Date(session.startedAt).getTime();
@@ -615,23 +784,23 @@ export class BrainIntelligence {
615
784
  if (durationMin > EXTRACTION_LONG_SESSION_MINUTES) {
616
785
  rulesApplied.push('long_session');
617
786
  proposals.push(
618
- this.createProposal(sessionId, 'long_session', 'anti-pattern', {
787
+ this.createProposal(sessionId, 'long_session', 'pattern', {
619
788
  title: `Long session (${Math.round(durationMin)} minutes)`,
620
- description: `Session lasted ${Math.round(durationMin)} minutes. Consider breaking complex tasks into smaller steps or improving automation.`,
621
- confidence: 0.5,
789
+ description: `Session lasted ${Math.round(durationMin)} minutes. Deep work session review if this duration was productive or indicates a need for better tooling.`,
790
+ confidence: 0.3,
622
791
  }),
623
792
  );
624
793
  }
625
794
  }
626
795
 
627
- // Rule 4: Plan completed
796
+ // Rule 4: Plan completed — moderate confidence to avoid auto-promoting generic entries
628
797
  if (session.planId && session.planOutcome === 'completed') {
629
798
  rulesApplied.push('plan_completed');
630
799
  proposals.push(
631
800
  this.createProposal(sessionId, 'plan_completed', 'workflow', {
632
801
  title: `Successful plan: ${session.planId}`,
633
802
  description: `Plan ${session.planId} completed successfully. This workflow can be reused for similar tasks.`,
634
- confidence: 0.8,
803
+ confidence: 0.65,
635
804
  }),
636
805
  );
637
806
  }
@@ -887,6 +1056,18 @@ export class BrainIntelligence {
887
1056
  // Step 3: Build domain profiles
888
1057
  const domainProfiles = this.buildDomainProfiles(strengths);
889
1058
 
1059
+ // Step 4: Extract operator signals from domain expertise
1060
+ try {
1061
+ if (this.operatorProfile && strengths.length > 0) {
1062
+ const signals = extractFromBrainStrengths(strengths);
1063
+ if (signals.length > 0) {
1064
+ this.operatorProfile.accumulateSignals(signals);
1065
+ }
1066
+ }
1067
+ } catch {
1068
+ // Signal extraction must never break intelligence pipeline
1069
+ }
1070
+
890
1071
  return {
891
1072
  strengthsComputed: strengths.length,
892
1073
  globalPatterns,
@@ -13,6 +13,8 @@
13
13
  import type { Vault } from '../vault/vault.js';
14
14
  import type { PersistenceProvider } from '../persistence/types.js';
15
15
  import type { Brain } from './brain.js';
16
+ import type { OperatorProfileStore } from '../operator/operator-profile.js';
17
+ import { extractFromRadar } from '../operator/operator-signals.js';
16
18
 
17
19
  // ─── Types ───────────────────────────────────────────────────────────
18
20
 
@@ -97,6 +99,7 @@ export class LearningRadar {
97
99
  private provider: PersistenceProvider;
98
100
  private vault: Vault;
99
101
  private brain: Brain;
102
+ private operatorProfile: OperatorProfileStore | null = null;
100
103
 
101
104
  constructor(vault: Vault, brain: Brain) {
102
105
  this.vault = vault;
@@ -105,6 +108,11 @@ export class LearningRadar {
105
108
  this.initializeTable();
106
109
  }
107
110
 
111
+ /** Wire operator profile for automatic signal extraction. */
112
+ setOperatorProfile(profile: OperatorProfileStore): void {
113
+ this.operatorProfile = profile;
114
+ }
115
+
108
116
  private initializeTable(): void {
109
117
  this.provider.execSql(`
110
118
  CREATE TABLE IF NOT EXISTS radar_candidates (
@@ -163,7 +171,20 @@ export class LearningRadar {
163
171
  this.captureCandidate(id, signal.title, signal.description, suggestedType, signal.type);
164
172
  }
165
173
 
166
- return this.getCandidate(id);
174
+ // ─── Auto-signal extraction (never breaks radar) ───
175
+ const candidate = this.getCandidate(id);
176
+ try {
177
+ if (this.operatorProfile && candidate) {
178
+ const signals = extractFromRadar(candidate);
179
+ if (signals.length > 0) {
180
+ this.operatorProfile.accumulateSignals(signals);
181
+ }
182
+ }
183
+ } catch {
184
+ // Signal extraction must never break radar analysis
185
+ }
186
+
187
+ return candidate;
167
188
  }
168
189
 
169
190
  /**