@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,156 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { detectRationalizations } from './rationalization-detector.js';
3
+
4
+ const CRITERIA = [
5
+ 'All API endpoints return proper error codes',
6
+ 'Unit test coverage above 80%',
7
+ 'Database migrations are reversible',
8
+ ];
9
+
10
+ describe('detectRationalizations', () => {
11
+ // ─── Positive cases: each pattern detected ──────────────────
12
+
13
+ it('detects "out of scope" pattern', () => {
14
+ const report = detectRationalizations(
15
+ CRITERIA,
16
+ 'Database migrations are out of scope for this task.',
17
+ );
18
+ expect(report.detected).toBe(true);
19
+ expect(report.items).toHaveLength(1);
20
+ expect(report.items[0].pattern).toBe('out-of-scope');
21
+ });
22
+
23
+ it('detects "follow-up ticket" pattern', () => {
24
+ const report = detectRationalizations(
25
+ CRITERIA,
26
+ 'Error codes will be addressed in a follow-up issue.',
27
+ );
28
+ expect(report.detected).toBe(true);
29
+ expect(report.items).toHaveLength(1);
30
+ expect(report.items[0].pattern).toBe('follow-up-ticket');
31
+ });
32
+
33
+ it('detects "follow-up PR" pattern', () => {
34
+ const report = detectRationalizations(CRITERIA, 'Test coverage bump deferred to follow-up PR.');
35
+ expect(report.detected).toBe(true);
36
+ expect(report.items[0].pattern).toBe('follow-up-ticket');
37
+ });
38
+
39
+ it('detects "pre-existing issue" pattern', () => {
40
+ const report = detectRationalizations(
41
+ CRITERIA,
42
+ 'The missing error codes are a pre-existing bug in the codebase.',
43
+ );
44
+ expect(report.detected).toBe(true);
45
+ expect(report.items[0].pattern).toBe('pre-existing-issue');
46
+ });
47
+
48
+ it('detects "over-engineering" pattern', () => {
49
+ const report = detectRationalizations(
50
+ CRITERIA,
51
+ 'Making migrations reversible would be over-engineering at this stage.',
52
+ );
53
+ expect(report.detected).toBe(true);
54
+ expect(report.items[0].pattern).toBe('over-engineering');
55
+ });
56
+
57
+ it('detects "separate PR" pattern', () => {
58
+ const report = detectRationalizations(
59
+ CRITERIA,
60
+ 'Test coverage improvements will go in a separate PR.',
61
+ );
62
+ expect(report.detected).toBe(true);
63
+ expect(report.items[0].pattern).toBe('separate-pr');
64
+ });
65
+
66
+ it('detects "too complex for this task" pattern', () => {
67
+ const report = detectRationalizations(
68
+ CRITERIA,
69
+ 'Reversible migrations are too complex for this task, deferring.',
70
+ );
71
+ expect(report.detected).toBe(true);
72
+ expect(report.items[0].pattern).toBe('too-complex');
73
+ });
74
+
75
+ // ─── Negative cases: clean completion ───────────────────────
76
+
77
+ it('returns no detection for clean completion claim', () => {
78
+ const report = detectRationalizations(
79
+ CRITERIA,
80
+ 'All endpoints return proper error codes. Test coverage is at 85%. Migrations are reversible.',
81
+ );
82
+ expect(report.detected).toBe(false);
83
+ expect(report.items).toHaveLength(0);
84
+ });
85
+
86
+ it('returns no detection for unrelated text', () => {
87
+ const report = detectRationalizations(
88
+ CRITERIA,
89
+ 'Implemented the feature, ran all tests, everything passes.',
90
+ );
91
+ expect(report.detected).toBe(false);
92
+ expect(report.items).toHaveLength(0);
93
+ });
94
+
95
+ // ─── Case-insensitive matching ──────────────────────────────
96
+
97
+ it('matches case-insensitively (uppercase)', () => {
98
+ const report = detectRationalizations(CRITERIA, 'This is OUT OF SCOPE for the current work.');
99
+ expect(report.detected).toBe(true);
100
+ expect(report.items[0].pattern).toBe('out-of-scope');
101
+ });
102
+
103
+ it('matches case-insensitively (mixed case)', () => {
104
+ const report = detectRationalizations(CRITERIA, 'That is a Pre-Existing Issue we inherited.');
105
+ expect(report.detected).toBe(true);
106
+ expect(report.items[0].pattern).toBe('pre-existing-issue');
107
+ });
108
+
109
+ // ─── Empty/skip cases ──────────────────────────────────────
110
+
111
+ it('skips detection when acceptance criteria are empty', () => {
112
+ const report = detectRationalizations([], 'This is out of scope and a pre-existing issue.');
113
+ expect(report.detected).toBe(false);
114
+ expect(report.items).toHaveLength(0);
115
+ });
116
+
117
+ it('skips detection when completion claim is empty', () => {
118
+ const report = detectRationalizations(CRITERIA, '');
119
+ expect(report.detected).toBe(false);
120
+ expect(report.items).toHaveLength(0);
121
+ });
122
+
123
+ it('skips detection when completion claim is whitespace only', () => {
124
+ const report = detectRationalizations(CRITERIA, ' ');
125
+ expect(report.detected).toBe(false);
126
+ expect(report.items).toHaveLength(0);
127
+ });
128
+
129
+ // ─── Multiple rationalizations ─────────────────────────────
130
+
131
+ it('detects multiple rationalizations in one claim', () => {
132
+ const report = detectRationalizations(
133
+ CRITERIA,
134
+ 'Error codes are out of scope. Test coverage will go in a separate PR. ' +
135
+ 'Reversible migrations are too complex for this task.',
136
+ );
137
+ expect(report.detected).toBe(true);
138
+ expect(report.items.length).toBeGreaterThanOrEqual(3);
139
+
140
+ const patterns = report.items.map((i) => i.pattern);
141
+ expect(patterns).toContain('out-of-scope');
142
+ expect(patterns).toContain('separate-pr');
143
+ expect(patterns).toContain('too-complex');
144
+ });
145
+
146
+ // ─── Suggestion is always present ──────────────────────────
147
+
148
+ it('provides actionable suggestions for each item', () => {
149
+ const report = detectRationalizations(CRITERIA, 'This is out of scope and over-engineering.');
150
+ expect(report.detected).toBe(true);
151
+ for (const item of report.items) {
152
+ expect(item.suggestion).toBeTruthy();
153
+ expect(item.suggestion.length).toBeGreaterThan(10);
154
+ }
155
+ });
156
+ });
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Rationalization detector — identifies completion claims that rationalize
3
+ * away unmet acceptance criteria instead of genuinely completing them.
4
+ *
5
+ * Used by orchestrate_complete to gate auto-completion.
6
+ */
7
+
8
+ // ─── Types ──────────────────────────────────────────────────────
9
+
10
+ export interface RationalizationItem {
11
+ /** The acceptance criterion being rationalized away. */
12
+ criterion: string;
13
+ /** The phrase in the completion claim that triggered detection. */
14
+ phrase: string;
15
+ /** The pattern name that matched. */
16
+ pattern: string;
17
+ /** Actionable suggestion for the user. */
18
+ suggestion: string;
19
+ }
20
+
21
+ export interface RationalizationReport {
22
+ /** Whether any rationalizations were detected. */
23
+ detected: boolean;
24
+ /** Individual rationalization items found. */
25
+ items: RationalizationItem[];
26
+ }
27
+
28
+ // ─── Patterns ───────────────────────────────────────────────────
29
+
30
+ interface RationalizationPattern {
31
+ name: string;
32
+ regex: RegExp;
33
+ suggestion: string;
34
+ }
35
+
36
+ const PATTERNS: RationalizationPattern[] = [
37
+ {
38
+ name: 'out-of-scope',
39
+ regex: /out\s+of\s+scope/i,
40
+ suggestion:
41
+ 'If it was in the acceptance criteria, it is in scope. Remove from criteria or complete it.',
42
+ },
43
+ {
44
+ name: 'follow-up-ticket',
45
+ regex: /follow[- ]?up\s+(ticket|issue|pr|task)/i,
46
+ suggestion:
47
+ 'Deferring to a follow-up means the criterion is unmet. Complete it now or revise the plan.',
48
+ },
49
+ {
50
+ name: 'pre-existing-issue',
51
+ regex: /pre[- ]?existing\s+(issue|bug|problem)/i,
52
+ suggestion:
53
+ 'Pre-existing or not, the criterion expects it resolved. Fix it or remove the criterion.',
54
+ },
55
+ {
56
+ name: 'over-engineering',
57
+ regex: /over[- ]?engineering/i,
58
+ suggestion:
59
+ 'Meeting acceptance criteria is not over-engineering. Implement what was agreed upon.',
60
+ },
61
+ {
62
+ name: 'separate-pr',
63
+ regex: /separate\s+(pr|task|ticket|issue)/i,
64
+ suggestion:
65
+ 'Splitting into a separate PR defers the work. Complete the criterion or update the plan.',
66
+ },
67
+ {
68
+ name: 'too-complex',
69
+ regex: /too\s+complex\s+for\s+this\s+(task|pr|ticket|issue|scope)/i,
70
+ suggestion:
71
+ 'Complexity was known at planning time. Revisit the plan or complete the criterion.',
72
+ },
73
+ ];
74
+
75
+ // ─── Detector ───────────────────────────────────────────────────
76
+
77
+ /**
78
+ * Scan a completion claim against acceptance criteria for rationalization
79
+ * language — phrases that excuse unmet criteria rather than completing them.
80
+ *
81
+ * @param acceptanceCriteria - The plan/task acceptance criteria
82
+ * @param completionClaim - The completion summary to scan
83
+ * @returns A report with detected rationalization items
84
+ */
85
+ export function detectRationalizations(
86
+ acceptanceCriteria: string[],
87
+ completionClaim: string,
88
+ ): RationalizationReport {
89
+ if (!acceptanceCriteria.length || !completionClaim.trim()) {
90
+ return { detected: false, items: [] };
91
+ }
92
+
93
+ const items: RationalizationItem[] = [];
94
+
95
+ for (const pattern of PATTERNS) {
96
+ const match = pattern.regex.exec(completionClaim);
97
+ if (!match) continue;
98
+
99
+ // Find which criterion is being rationalized (nearest mention)
100
+ const criterion = findRelatedCriterion(acceptanceCriteria, completionClaim, match.index);
101
+
102
+ items.push({
103
+ criterion,
104
+ phrase: match[0],
105
+ pattern: pattern.name,
106
+ suggestion: pattern.suggestion,
107
+ });
108
+ }
109
+
110
+ return { detected: items.length > 0, items };
111
+ }
112
+
113
+ // ─── Helpers ────────────────────────────────────────────────────
114
+
115
+ /**
116
+ * Find the acceptance criterion most related to the rationalization phrase
117
+ * by checking which criterion text appears closest to the match position.
118
+ */
119
+ function findRelatedCriterion(criteria: string[], claim: string, matchIndex: number): string {
120
+ const claimLower = claim.toLowerCase();
121
+ let bestCriterion = criteria[0];
122
+ let bestDistance = Infinity;
123
+
124
+ for (const c of criteria) {
125
+ const idx = claimLower.indexOf(c.toLowerCase());
126
+ if (idx !== -1) {
127
+ const dist = Math.abs(idx - matchIndex);
128
+ if (dist < bestDistance) {
129
+ bestDistance = dist;
130
+ bestCriterion = c;
131
+ }
132
+ }
133
+ }
134
+
135
+ return bestCriterion;
136
+ }
@@ -0,0 +1,158 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import {
3
+ DRIFT_WEIGHTS,
4
+ calculateDriftScore,
5
+ computeExecutionSummary,
6
+ buildReconciliationReport,
7
+ buildAutoReconcileInput,
8
+ } from './reconciliation-engine.js';
9
+ import type { DriftItem, PlanTask } from './planner-types.js';
10
+
11
+ describe('reconciliation-engine', () => {
12
+ describe('DRIFT_WEIGHTS', () => {
13
+ it('has correct weights', () => {
14
+ expect(DRIFT_WEIGHTS.high).toBe(20);
15
+ expect(DRIFT_WEIGHTS.medium).toBe(10);
16
+ expect(DRIFT_WEIGHTS.low).toBe(5);
17
+ });
18
+ });
19
+
20
+ describe('calculateDriftScore', () => {
21
+ it('returns 100 for no drift items', () => {
22
+ expect(calculateDriftScore([])).toBe(100);
23
+ });
24
+ it('deducts by impact weight', () => {
25
+ const items: DriftItem[] = [
26
+ { type: 'skipped', description: 'x', impact: 'medium', rationale: 'r' },
27
+ ];
28
+ expect(calculateDriftScore(items)).toBe(90);
29
+ });
30
+ it('accumulates multiple items', () => {
31
+ const items: DriftItem[] = [
32
+ { type: 'skipped', description: 'x', impact: 'high', rationale: 'r' },
33
+ { type: 'modified', description: 'y', impact: 'low', rationale: 'r' },
34
+ ];
35
+ expect(calculateDriftScore(items)).toBe(75);
36
+ });
37
+ it('floors at 0', () => {
38
+ const items: DriftItem[] = Array.from({ length: 10 }, () => ({
39
+ type: 'skipped' as const,
40
+ description: 'x',
41
+ impact: 'high' as const,
42
+ rationale: 'r',
43
+ }));
44
+ expect(calculateDriftScore(items)).toBe(0);
45
+ });
46
+ });
47
+
48
+ describe('computeExecutionSummary', () => {
49
+ it('returns zeros for empty tasks', () => {
50
+ const summary = computeExecutionSummary([]);
51
+ expect(summary.totalDurationMs).toBe(0);
52
+ expect(summary.tasksCompleted).toBe(0);
53
+ expect(summary.avgTaskDurationMs).toBe(0);
54
+ });
55
+ it('counts task statuses correctly', () => {
56
+ const tasks: PlanTask[] = [
57
+ { id: 't1', title: '', description: '', status: 'completed', updatedAt: 0 },
58
+ { id: 't2', title: '', description: '', status: 'skipped', updatedAt: 0 },
59
+ { id: 't3', title: '', description: '', status: 'failed', updatedAt: 0 },
60
+ { id: 't4', title: '', description: '', status: 'pending', updatedAt: 0 },
61
+ ];
62
+ const summary = computeExecutionSummary(tasks);
63
+ expect(summary.tasksCompleted).toBe(1);
64
+ expect(summary.tasksSkipped).toBe(1);
65
+ expect(summary.tasksFailed).toBe(1);
66
+ });
67
+ it('computes average duration from tasks with metrics', () => {
68
+ const tasks: PlanTask[] = [
69
+ {
70
+ id: 't1',
71
+ title: '',
72
+ description: '',
73
+ status: 'completed',
74
+ updatedAt: 0,
75
+ metrics: { durationMs: 100 },
76
+ },
77
+ {
78
+ id: 't2',
79
+ title: '',
80
+ description: '',
81
+ status: 'completed',
82
+ updatedAt: 0,
83
+ metrics: { durationMs: 200 },
84
+ },
85
+ { id: 't3', title: '', description: '', status: 'completed', updatedAt: 0 }, // no metrics
86
+ ];
87
+ const summary = computeExecutionSummary(tasks);
88
+ expect(summary.totalDurationMs).toBe(300);
89
+ expect(summary.avgTaskDurationMs).toBe(150);
90
+ });
91
+ });
92
+
93
+ describe('buildReconciliationReport', () => {
94
+ it('builds a report with accuracy score', () => {
95
+ const report = buildReconciliationReport('plan-1', {
96
+ actualOutcome: 'Done',
97
+ driftItems: [{ type: 'skipped', description: 'x', impact: 'low', rationale: 'r' }],
98
+ });
99
+ expect(report.planId).toBe('plan-1');
100
+ expect(report.accuracy).toBe(95);
101
+ expect(report.driftItems).toHaveLength(1);
102
+ expect(report.summary).toBe('Done');
103
+ expect(report.reconciledAt).toBeGreaterThan(0);
104
+ });
105
+ it('defaults to empty drift items', () => {
106
+ const report = buildReconciliationReport('plan-2', { actualOutcome: 'OK' });
107
+ expect(report.accuracy).toBe(100);
108
+ expect(report.driftItems).toEqual([]);
109
+ });
110
+ });
111
+
112
+ describe('buildAutoReconcileInput', () => {
113
+ it('allows auto-reconcile when all tasks completed', () => {
114
+ const tasks: PlanTask[] = [
115
+ { id: 't1', title: 'A', description: '', status: 'completed', updatedAt: 0 },
116
+ { id: 't2', title: 'B', description: '', status: 'completed', updatedAt: 0 },
117
+ ];
118
+ const result = buildAutoReconcileInput(tasks);
119
+ expect(result.canAutoReconcile).toBe(true);
120
+ expect(result.input?.actualOutcome).toContain('2/2 tasks completed');
121
+ });
122
+ it('rejects when tasks are in progress', () => {
123
+ const tasks: PlanTask[] = [
124
+ { id: 't1', title: 'A', description: '', status: 'in_progress', updatedAt: 0 },
125
+ ];
126
+ expect(buildAutoReconcileInput(tasks).canAutoReconcile).toBe(false);
127
+ });
128
+ it('rejects when too many pending/failed tasks', () => {
129
+ const tasks: PlanTask[] = [
130
+ { id: 't1', title: 'A', description: '', status: 'failed', updatedAt: 0 },
131
+ { id: 't2', title: 'B', description: '', status: 'failed', updatedAt: 0 },
132
+ { id: 't3', title: 'C', description: '', status: 'pending', updatedAt: 0 },
133
+ ];
134
+ expect(buildAutoReconcileInput(tasks).canAutoReconcile).toBe(false);
135
+ });
136
+ it('generates drift items for skipped and failed tasks', () => {
137
+ const tasks: PlanTask[] = [
138
+ { id: 't1', title: 'A', description: '', status: 'completed', updatedAt: 0 },
139
+ { id: 't2', title: 'B', description: '', status: 'skipped', updatedAt: 0 },
140
+ { id: 't3', title: 'C', description: '', status: 'failed', updatedAt: 0 },
141
+ ];
142
+ const result = buildAutoReconcileInput(tasks);
143
+ expect(result.canAutoReconcile).toBe(true);
144
+ expect(result.input?.driftItems).toHaveLength(2);
145
+ expect(result.input?.driftItems?.[0].type).toBe('skipped');
146
+ expect(result.input?.driftItems?.[1].type).toBe('modified');
147
+ });
148
+ it('generates drift items for pending tasks', () => {
149
+ const tasks: PlanTask[] = [
150
+ { id: 't1', title: 'Done', description: '', status: 'completed', updatedAt: 0 },
151
+ { id: 't2', title: 'Not started', description: '', status: 'pending', updatedAt: 0 },
152
+ ];
153
+ const result = buildAutoReconcileInput(tasks);
154
+ expect(result.canAutoReconcile).toBe(true);
155
+ expect(result.input?.driftItems?.[0].impact).toBe('low');
156
+ });
157
+ });
158
+ });
@@ -0,0 +1,161 @@
1
+ /**
2
+ * Reconciliation engine — drift detection, accuracy scoring, and auto-reconciliation.
3
+ * Extracted from planner.ts. All functions are pure (no persistence side-effects).
4
+ */
5
+
6
+ import type {
7
+ DriftItem,
8
+ ReconciliationReport,
9
+ ExecutionSummary,
10
+ PlanTask,
11
+ } from './planner-types.js';
12
+
13
+ // ─── Drift Scoring ───────────────────────────────────────────────
14
+
15
+ /**
16
+ * Severity weights for drift accuracy score calculation.
17
+ * Score = 100 - sum(drift_items * weight_per_impact)
18
+ * Ported from Salvador's plan-lifecycle-types.ts.
19
+ */
20
+ export const DRIFT_WEIGHTS: Record<DriftItem['impact'], number> = {
21
+ high: 20,
22
+ medium: 10,
23
+ low: 5,
24
+ };
25
+
26
+ /**
27
+ * Calculate drift accuracy score from drift items.
28
+ * Score = max(0, 100 - sum(weight_per_impact))
29
+ * Ported from Salvador's calculateDriftScore.
30
+ */
31
+ export function calculateDriftScore(items: ReadonlyArray<DriftItem>): number {
32
+ let deductions = 0;
33
+ for (const item of items) {
34
+ deductions += DRIFT_WEIGHTS[item.impact];
35
+ }
36
+ return Math.max(0, 100 - deductions);
37
+ }
38
+
39
+ // ─── Execution Summary ───────────────────────────────────────────
40
+
41
+ /**
42
+ * Compute aggregate execution summary from per-task metrics.
43
+ * Pure function — does not mutate state.
44
+ */
45
+ export function computeExecutionSummary(tasks: ReadonlyArray<PlanTask>): ExecutionSummary {
46
+ let totalDurationMs = 0;
47
+ let tasksCompleted = 0;
48
+ let tasksSkipped = 0;
49
+ let tasksFailed = 0;
50
+ let tasksWithDuration = 0;
51
+
52
+ for (const task of tasks) {
53
+ if (task.status === 'completed') tasksCompleted++;
54
+ else if (task.status === 'skipped') tasksSkipped++;
55
+ else if (task.status === 'failed') tasksFailed++;
56
+
57
+ if (task.metrics?.durationMs) {
58
+ totalDurationMs += task.metrics.durationMs;
59
+ tasksWithDuration++;
60
+ }
61
+ }
62
+
63
+ return {
64
+ totalDurationMs,
65
+ tasksCompleted,
66
+ tasksSkipped,
67
+ tasksFailed,
68
+ avgTaskDurationMs: tasksWithDuration > 0 ? Math.round(totalDurationMs / tasksWithDuration) : 0,
69
+ };
70
+ }
71
+
72
+ // ─── Reconciliation ──────────────────────────────────────────────
73
+
74
+ export interface ReconcileInput {
75
+ actualOutcome: string;
76
+ driftItems?: DriftItem[];
77
+ /** Who initiated the reconciliation. */
78
+ reconciledBy?: 'human' | 'auto';
79
+ }
80
+
81
+ /**
82
+ * Build a reconciliation report from drift items and outcome.
83
+ * Pure function — returns report without mutating state.
84
+ */
85
+ export function buildReconciliationReport(
86
+ planId: string,
87
+ input: ReconcileInput,
88
+ ): ReconciliationReport {
89
+ const driftItems = input.driftItems ?? [];
90
+ const accuracy = calculateDriftScore(driftItems);
91
+
92
+ return {
93
+ planId,
94
+ accuracy,
95
+ driftItems,
96
+ summary: input.actualOutcome,
97
+ reconciledAt: Date.now(),
98
+ };
99
+ }
100
+
101
+ // ─── Auto-Reconciliation ────────────────────────────────────────
102
+
103
+ export interface AutoReconcileResult {
104
+ canAutoReconcile: boolean;
105
+ input?: ReconcileInput;
106
+ }
107
+
108
+ /**
109
+ * Determine if a plan can be auto-reconciled and build the reconciliation input.
110
+ * Returns null input if auto-reconciliation is not possible.
111
+ *
112
+ * Rules:
113
+ * - Can't auto-reconcile if tasks are still in progress
114
+ * - Can't auto-reconcile if too many non-completed tasks (>2 pending + failed)
115
+ */
116
+ export function buildAutoReconcileInput(tasks: ReadonlyArray<PlanTask>): AutoReconcileResult {
117
+ const completed = tasks.filter((t) => t.status === 'completed').length;
118
+ const skipped = tasks.filter((t) => t.status === 'skipped').length;
119
+ const failed = tasks.filter((t) => t.status === 'failed').length;
120
+ const pending = tasks.filter((t) => t.status === 'pending').length;
121
+ const inProgress = tasks.filter((t) => t.status === 'in_progress').length;
122
+
123
+ if (inProgress > 0) return { canAutoReconcile: false };
124
+ if (pending + failed > 2) return { canAutoReconcile: false };
125
+
126
+ const driftItems: DriftItem[] = [];
127
+
128
+ for (const task of tasks) {
129
+ if (task.status === 'skipped') {
130
+ driftItems.push({
131
+ type: 'skipped',
132
+ description: `Task '${task.title}' was skipped`,
133
+ impact: 'medium',
134
+ rationale: 'Task not executed during plan implementation',
135
+ });
136
+ } else if (task.status === 'failed') {
137
+ driftItems.push({
138
+ type: 'modified',
139
+ description: `Task '${task.title}' failed`,
140
+ impact: 'high',
141
+ rationale: 'Task execution failed',
142
+ });
143
+ } else if (task.status === 'pending') {
144
+ driftItems.push({
145
+ type: 'skipped',
146
+ description: `Task '${task.title}' was never started`,
147
+ impact: 'low',
148
+ rationale: 'Task left in pending state',
149
+ });
150
+ }
151
+ }
152
+
153
+ return {
154
+ canAutoReconcile: true,
155
+ input: {
156
+ actualOutcome: `Auto-reconciled: ${completed}/${tasks.length} tasks completed, ${skipped} skipped, ${failed} failed`,
157
+ driftItems,
158
+ reconciledBy: 'auto',
159
+ },
160
+ };
161
+ }