@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
@@ -0,0 +1,236 @@
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(
97
+ rule.condition(
98
+ makeContext({
99
+ fileChangesProcessed: 30,
100
+ surfacedPatterns: [makePattern()],
101
+ }),
102
+ ),
103
+ ).toBe(false);
104
+ });
105
+
106
+ it('does not fire with few changes', () => {
107
+ expect(rule.condition(makeContext({ fileChangesProcessed: 5 }))).toBe(false);
108
+ });
109
+
110
+ it('generates medium priority suggestion', () => {
111
+ const s = rule.generate(makeContext({ fileChangesProcessed: 25 }));
112
+ expect(s.rule).toBe('stale-patterns');
113
+ expect(s.priority).toBe('medium');
114
+ });
115
+ });
116
+
117
+ // ─── high-activity-no-capture ─────────────────────────────────────
118
+
119
+ describe('high-activity-no-capture', () => {
120
+ const rule = findRule('high-activity-no-capture');
121
+
122
+ it('fires when 50+ changes and no patterns', () => {
123
+ expect(rule.condition(makeContext({ fileChangesProcessed: 51 }))).toBe(true);
124
+ });
125
+
126
+ it('does not fire with patterns', () => {
127
+ expect(
128
+ rule.condition(
129
+ makeContext({
130
+ fileChangesProcessed: 60,
131
+ surfacedPatterns: [makePattern()],
132
+ }),
133
+ ),
134
+ ).toBe(false);
135
+ });
136
+
137
+ it('does not fire with few changes', () => {
138
+ expect(rule.condition(makeContext({ fileChangesProcessed: 10 }))).toBe(false);
139
+ });
140
+
141
+ it('generates suggestion with change count', () => {
142
+ const s = rule.generate(makeContext({ fileChangesProcessed: 55 }));
143
+ expect(s.rule).toBe('high-activity-no-capture');
144
+ expect(s.priority).toBe('medium');
145
+ expect(s.description).toContain('55');
146
+ });
147
+ });
148
+
149
+ // ─── critical-warnings ────────────────────────────────────────────
150
+
151
+ describe('critical-warnings', () => {
152
+ const rule = findRule('critical-warnings');
153
+
154
+ it('fires when critical severity warnings exist', () => {
155
+ const ctx = makeContext({
156
+ pendingWarnings: [makeWarning({ severity: 'critical' })],
157
+ });
158
+ expect(rule.condition(ctx)).toBe(true);
159
+ });
160
+
161
+ it('does not fire with only non-critical warnings', () => {
162
+ const ctx = makeContext({
163
+ pendingWarnings: [makeWarning({ severity: 'warning' }), makeWarning({ severity: 'info' })],
164
+ });
165
+ expect(rule.condition(ctx)).toBe(false);
166
+ });
167
+
168
+ it('generates high priority with count and messages', () => {
169
+ const ctx = makeContext({
170
+ pendingWarnings: [
171
+ makeWarning({ severity: 'critical', message: 'sec issue' }),
172
+ makeWarning({ severity: 'critical', message: 'another issue' }),
173
+ makeWarning({ severity: 'warning', message: 'minor' }),
174
+ ],
175
+ });
176
+ const s = rule.generate(ctx);
177
+ expect(s.rule).toBe('critical-warnings');
178
+ expect(s.priority).toBe('high');
179
+ expect(s.title).toContain('2');
180
+ expect(s.description).toContain('sec issue');
181
+ });
182
+ });
183
+
184
+ // ─── pattern-surfaced ─────────────────────────────────────────────
185
+
186
+ describe('pattern-surfaced', () => {
187
+ const rule = findRule('pattern-surfaced');
188
+
189
+ it('fires when patterns are surfaced', () => {
190
+ expect(rule.condition(makeContext({ surfacedPatterns: [makePattern()] }))).toBe(true);
191
+ });
192
+
193
+ it('does not fire with empty patterns', () => {
194
+ expect(rule.condition(makeContext())).toBe(false);
195
+ });
196
+
197
+ it('generates low priority with pattern titles', () => {
198
+ const ctx = makeContext({
199
+ surfacedPatterns: [
200
+ makePattern({ title: 'React hooks', domain: 'react' }),
201
+ makePattern({ title: 'CSS Grid', domain: 'styling' }),
202
+ ],
203
+ });
204
+ const s = rule.generate(ctx);
205
+ expect(s.rule).toBe('pattern-surfaced');
206
+ expect(s.priority).toBe('low');
207
+ expect(s.description).toContain('React hooks');
208
+ expect(s.description).toContain('CSS Grid');
209
+ });
210
+ });
211
+
212
+ // ─── first-session ────────────────────────────────────────────────
213
+
214
+ describe('first-session', () => {
215
+ const rule = findRule('first-session');
216
+
217
+ it('fires on fresh state (0 changes, 0 warnings)', () => {
218
+ expect(rule.condition(makeContext())).toBe(true);
219
+ });
220
+
221
+ it('does not fire after changes processed', () => {
222
+ expect(rule.condition(makeContext({ fileChangesProcessed: 1 }))).toBe(false);
223
+ });
224
+
225
+ it('does not fire when warnings exist', () => {
226
+ expect(rule.condition(makeContext({ pendingWarnings: [makeWarning()] }))).toBe(false);
227
+ });
228
+
229
+ it('generates low priority welcome message', () => {
230
+ const s = rule.generate(makeContext());
231
+ expect(s.rule).toBe('first-session');
232
+ expect(s.priority).toBe('low');
233
+ expect(s.title).toContain('ready');
234
+ });
235
+ });
236
+ });
@@ -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,