@soleri/core 9.0.4 → 9.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (701) hide show
  1. package/dist/brain/intelligence.d.ts +27 -0
  2. package/dist/brain/intelligence.d.ts.map +1 -1
  3. package/dist/brain/intelligence.js +160 -14
  4. package/dist/brain/intelligence.js.map +1 -1
  5. package/dist/brain/learning-radar.d.ts +4 -0
  6. package/dist/brain/learning-radar.d.ts.map +1 -1
  7. package/dist/brain/learning-radar.js +20 -1
  8. package/dist/brain/learning-radar.js.map +1 -1
  9. package/dist/brain/strength-scorer.d.ts +31 -0
  10. package/dist/brain/strength-scorer.d.ts.map +1 -0
  11. package/dist/brain/strength-scorer.js +264 -0
  12. package/dist/brain/strength-scorer.js.map +1 -0
  13. package/dist/chat/agent-loop.d.ts.map +1 -1
  14. package/dist/chat/agent-loop.js +2 -0
  15. package/dist/chat/agent-loop.js.map +1 -1
  16. package/dist/chat/notifications.d.ts.map +1 -1
  17. package/dist/chat/notifications.js +2 -0
  18. package/dist/chat/notifications.js.map +1 -1
  19. package/dist/claudemd/compose.js +1 -1
  20. package/dist/claudemd/compose.js.map +1 -1
  21. package/dist/control/intent-router.d.ts.map +1 -1
  22. package/dist/control/intent-router.js +12 -4
  23. package/dist/control/intent-router.js.map +1 -1
  24. package/dist/curator/contradiction-detector.d.ts +27 -0
  25. package/dist/curator/contradiction-detector.d.ts.map +1 -0
  26. package/dist/curator/contradiction-detector.js +62 -0
  27. package/dist/curator/contradiction-detector.js.map +1 -0
  28. package/dist/curator/curator.d.ts +3 -4
  29. package/dist/curator/curator.d.ts.map +1 -1
  30. package/dist/curator/curator.js +90 -525
  31. package/dist/curator/curator.js.map +1 -1
  32. package/dist/curator/duplicate-detector.d.ts +14 -0
  33. package/dist/curator/duplicate-detector.d.ts.map +1 -0
  34. package/dist/curator/duplicate-detector.js +77 -0
  35. package/dist/curator/duplicate-detector.js.map +1 -0
  36. package/dist/curator/health-audit.d.ts +15 -0
  37. package/dist/curator/health-audit.d.ts.map +1 -0
  38. package/dist/curator/health-audit.js +97 -0
  39. package/dist/curator/health-audit.js.map +1 -0
  40. package/dist/curator/metadata-enricher.d.ts +17 -0
  41. package/dist/curator/metadata-enricher.d.ts.map +1 -0
  42. package/dist/curator/metadata-enricher.js +60 -0
  43. package/dist/curator/metadata-enricher.js.map +1 -0
  44. package/dist/curator/schema.d.ts +7 -0
  45. package/dist/curator/schema.d.ts.map +1 -0
  46. package/dist/curator/schema.js +62 -0
  47. package/dist/curator/schema.js.map +1 -0
  48. package/dist/curator/tag-manager.d.ts +36 -0
  49. package/dist/curator/tag-manager.d.ts.map +1 -0
  50. package/dist/curator/tag-manager.js +78 -0
  51. package/dist/curator/tag-manager.js.map +1 -0
  52. package/dist/engine/bin/soleri-engine.js +24 -3
  53. package/dist/engine/bin/soleri-engine.js.map +1 -1
  54. package/dist/engine/core-ops.d.ts.map +1 -1
  55. package/dist/engine/core-ops.js +23 -8
  56. package/dist/engine/core-ops.js.map +1 -1
  57. package/dist/engine/module-manifest.d.ts.map +1 -1
  58. package/dist/engine/module-manifest.js +22 -2
  59. package/dist/engine/module-manifest.js.map +1 -1
  60. package/dist/engine/register-engine.d.ts.map +1 -1
  61. package/dist/engine/register-engine.js +26 -2
  62. package/dist/engine/register-engine.js.map +1 -1
  63. package/dist/errors/retry.d.ts.map +1 -1
  64. package/dist/errors/retry.js +2 -0
  65. package/dist/errors/retry.js.map +1 -1
  66. package/dist/facades/types.d.ts +1 -1
  67. package/dist/flows/chain-types.d.ts +18 -18
  68. package/dist/flows/gate-evaluator.d.ts.map +1 -1
  69. package/dist/flows/gate-evaluator.js +22 -0
  70. package/dist/flows/gate-evaluator.js.map +1 -1
  71. package/dist/flows/types.d.ts +157 -28
  72. package/dist/flows/types.d.ts.map +1 -1
  73. package/dist/flows/types.js +4 -0
  74. package/dist/flows/types.js.map +1 -1
  75. package/dist/index.d.ts +10 -2
  76. package/dist/index.d.ts.map +1 -1
  77. package/dist/index.js +9 -1
  78. package/dist/index.js.map +1 -1
  79. package/dist/intake/intake-pipeline.d.ts.map +1 -1
  80. package/dist/intake/intake-pipeline.js +1 -0
  81. package/dist/intake/intake-pipeline.js.map +1 -1
  82. package/dist/intake/text-ingester.d.ts.map +1 -1
  83. package/dist/intake/text-ingester.js +2 -0
  84. package/dist/intake/text-ingester.js.map +1 -1
  85. package/dist/llm/key-pool.d.ts +1 -1
  86. package/dist/llm/key-pool.d.ts.map +1 -1
  87. package/dist/llm/key-pool.js +3 -4
  88. package/dist/llm/key-pool.js.map +1 -1
  89. package/dist/llm/utils.d.ts.map +1 -1
  90. package/dist/llm/utils.js +2 -0
  91. package/dist/llm/utils.js.map +1 -1
  92. package/dist/migrations/migration-runner.test-helpers.d.ts +13 -0
  93. package/dist/migrations/migration-runner.test-helpers.d.ts.map +1 -0
  94. package/dist/migrations/migration-runner.test-helpers.js +47 -0
  95. package/dist/migrations/migration-runner.test-helpers.js.map +1 -0
  96. package/dist/operator/operator-profile.d.ts +44 -0
  97. package/dist/operator/operator-profile.d.ts.map +1 -0
  98. package/dist/operator/operator-profile.js +377 -0
  99. package/dist/operator/operator-profile.js.map +1 -0
  100. package/dist/operator/operator-signals.d.ts +45 -0
  101. package/dist/operator/operator-signals.d.ts.map +1 -0
  102. package/dist/operator/operator-signals.js +228 -0
  103. package/dist/operator/operator-signals.js.map +1 -0
  104. package/dist/operator/operator-types.d.ts +360 -0
  105. package/dist/operator/operator-types.d.ts.map +1 -0
  106. package/dist/operator/operator-types.js +24 -0
  107. package/dist/operator/operator-types.js.map +1 -0
  108. package/dist/packs/types.d.ts +27 -27
  109. package/dist/paths.d.ts +40 -0
  110. package/dist/paths.d.ts.map +1 -0
  111. package/dist/paths.js +98 -0
  112. package/dist/paths.js.map +1 -0
  113. package/dist/persistence/index.d.ts +1 -1
  114. package/dist/persistence/index.d.ts.map +1 -1
  115. package/dist/persistence/index.js +1 -1
  116. package/dist/persistence/index.js.map +1 -1
  117. package/dist/persistence/sqlite-provider.d.ts +2 -0
  118. package/dist/persistence/sqlite-provider.d.ts.map +1 -1
  119. package/dist/persistence/sqlite-provider.js +8 -5
  120. package/dist/persistence/sqlite-provider.js.map +1 -1
  121. package/dist/planning/evidence-collector.d.ts +13 -1
  122. package/dist/planning/evidence-collector.d.ts.map +1 -1
  123. package/dist/planning/evidence-collector.js +33 -0
  124. package/dist/planning/evidence-collector.js.map +1 -1
  125. package/dist/planning/gap-analysis.d.ts +5 -4
  126. package/dist/planning/gap-analysis.d.ts.map +1 -1
  127. package/dist/planning/gap-analysis.js +7 -341
  128. package/dist/planning/gap-analysis.js.map +1 -1
  129. package/dist/planning/gap-passes.d.ts +19 -0
  130. package/dist/planning/gap-passes.d.ts.map +1 -0
  131. package/dist/planning/gap-passes.js +157 -0
  132. package/dist/planning/gap-passes.js.map +1 -0
  133. package/dist/planning/gap-patterns.d.ts +29 -0
  134. package/dist/planning/gap-patterns.d.ts.map +1 -0
  135. package/dist/planning/gap-patterns.js +129 -0
  136. package/dist/planning/gap-patterns.js.map +1 -0
  137. package/dist/planning/gap-types.d.ts +1 -1
  138. package/dist/planning/gap-types.d.ts.map +1 -1
  139. package/dist/planning/gap-types.js +1 -0
  140. package/dist/planning/gap-types.js.map +1 -1
  141. package/dist/planning/github-projection.d.ts +122 -0
  142. package/dist/planning/github-projection.d.ts.map +1 -0
  143. package/dist/planning/github-projection.js +294 -0
  144. package/dist/planning/github-projection.js.map +1 -0
  145. package/dist/planning/impact-analyzer.d.ts +26 -0
  146. package/dist/planning/impact-analyzer.d.ts.map +1 -0
  147. package/dist/planning/impact-analyzer.js +199 -0
  148. package/dist/planning/impact-analyzer.js.map +1 -0
  149. package/dist/planning/plan-lifecycle.d.ts +136 -0
  150. package/dist/planning/plan-lifecycle.d.ts.map +1 -0
  151. package/dist/planning/plan-lifecycle.js +296 -0
  152. package/dist/planning/plan-lifecycle.js.map +1 -0
  153. package/dist/planning/planner-types.d.ts +202 -0
  154. package/dist/planning/planner-types.d.ts.map +1 -0
  155. package/dist/planning/planner-types.js +6 -0
  156. package/dist/planning/planner-types.js.map +1 -0
  157. package/dist/planning/planner.d.ts +31 -383
  158. package/dist/planning/planner.d.ts.map +1 -1
  159. package/dist/planning/planner.js +154 -878
  160. package/dist/planning/planner.js.map +1 -1
  161. package/dist/planning/rationalization-detector.d.ts +32 -0
  162. package/dist/planning/rationalization-detector.d.ts.map +1 -0
  163. package/dist/planning/rationalization-detector.js +89 -0
  164. package/dist/planning/rationalization-detector.js.map +1 -0
  165. package/dist/planning/reconciliation-engine.d.ts +47 -0
  166. package/dist/planning/reconciliation-engine.d.ts.map +1 -0
  167. package/dist/planning/reconciliation-engine.js +128 -0
  168. package/dist/planning/reconciliation-engine.js.map +1 -0
  169. package/dist/planning/task-verifier.d.ts +85 -0
  170. package/dist/planning/task-verifier.d.ts.map +1 -0
  171. package/dist/planning/task-verifier.js +227 -0
  172. package/dist/planning/task-verifier.js.map +1 -0
  173. package/dist/plugins/types.d.ts +4 -4
  174. package/dist/runtime/admin-ops.d.ts +2 -2
  175. package/dist/runtime/admin-ops.d.ts.map +1 -1
  176. package/dist/runtime/admin-ops.js +44 -17
  177. package/dist/runtime/admin-ops.js.map +1 -1
  178. package/dist/runtime/admin-setup-ops.d.ts.map +1 -1
  179. package/dist/runtime/admin-setup-ops.js +21 -46
  180. package/dist/runtime/admin-setup-ops.js.map +1 -1
  181. package/dist/runtime/archive-ops.d.ts +10 -0
  182. package/dist/runtime/archive-ops.d.ts.map +1 -0
  183. package/dist/runtime/archive-ops.js +310 -0
  184. package/dist/runtime/archive-ops.js.map +1 -0
  185. package/dist/runtime/capture-ops.d.ts.map +1 -1
  186. package/dist/runtime/capture-ops.js +42 -7
  187. package/dist/runtime/capture-ops.js.map +1 -1
  188. package/dist/runtime/claude-md-helpers.js +1 -1
  189. package/dist/runtime/claude-md-helpers.js.map +1 -1
  190. package/dist/runtime/context-health.d.ts +31 -0
  191. package/dist/runtime/context-health.d.ts.map +1 -0
  192. package/dist/runtime/context-health.js +57 -0
  193. package/dist/runtime/context-health.js.map +1 -0
  194. package/dist/runtime/facades/archive-facade.d.ts +10 -0
  195. package/dist/runtime/facades/archive-facade.d.ts.map +1 -0
  196. package/dist/runtime/facades/archive-facade.js +11 -0
  197. package/dist/runtime/facades/archive-facade.js.map +1 -0
  198. package/dist/runtime/facades/brain-facade.d.ts.map +1 -1
  199. package/dist/runtime/facades/brain-facade.js +2 -0
  200. package/dist/runtime/facades/brain-facade.js.map +1 -1
  201. package/dist/runtime/facades/chat-facade.d.ts +7 -0
  202. package/dist/runtime/facades/chat-facade.d.ts.map +1 -1
  203. package/dist/runtime/facades/chat-facade.js +15 -800
  204. package/dist/runtime/facades/chat-facade.js.map +1 -1
  205. package/dist/runtime/facades/chat-service-ops.d.ts +9 -0
  206. package/dist/runtime/facades/chat-service-ops.d.ts.map +1 -0
  207. package/dist/runtime/facades/chat-service-ops.js +330 -0
  208. package/dist/runtime/facades/chat-service-ops.js.map +1 -0
  209. package/dist/runtime/facades/chat-session-ops.d.ts +8 -0
  210. package/dist/runtime/facades/chat-session-ops.d.ts.map +1 -0
  211. package/dist/runtime/facades/chat-session-ops.js +136 -0
  212. package/dist/runtime/facades/chat-session-ops.js.map +1 -0
  213. package/dist/runtime/facades/chat-state.d.ts +31 -0
  214. package/dist/runtime/facades/chat-state.d.ts.map +1 -0
  215. package/dist/runtime/facades/chat-state.js +32 -0
  216. package/dist/runtime/facades/chat-state.js.map +1 -0
  217. package/dist/runtime/facades/chat-transport-ops.d.ts +9 -0
  218. package/dist/runtime/facades/chat-transport-ops.d.ts.map +1 -0
  219. package/dist/runtime/facades/chat-transport-ops.js +337 -0
  220. package/dist/runtime/facades/chat-transport-ops.js.map +1 -0
  221. package/dist/runtime/facades/control-facade.d.ts.map +1 -1
  222. package/dist/runtime/facades/control-facade.js +4 -1
  223. package/dist/runtime/facades/control-facade.js.map +1 -1
  224. package/dist/runtime/facades/index.d.ts.map +1 -1
  225. package/dist/runtime/facades/index.js +6 -0
  226. package/dist/runtime/facades/index.js.map +1 -1
  227. package/dist/runtime/facades/memory-facade.d.ts.map +1 -1
  228. package/dist/runtime/facades/memory-facade.js +75 -6
  229. package/dist/runtime/facades/memory-facade.js.map +1 -1
  230. package/dist/runtime/facades/operator-facade.d.ts +8 -0
  231. package/dist/runtime/facades/operator-facade.d.ts.map +1 -0
  232. package/dist/runtime/facades/operator-facade.js +220 -0
  233. package/dist/runtime/facades/operator-facade.js.map +1 -0
  234. package/dist/runtime/facades/orchestrate-facade.js +3 -3
  235. package/dist/runtime/facades/orchestrate-facade.js.map +1 -1
  236. package/dist/runtime/facades/plan-facade.d.ts.map +1 -1
  237. package/dist/runtime/facades/plan-facade.js +39 -6
  238. package/dist/runtime/facades/plan-facade.js.map +1 -1
  239. package/dist/runtime/facades/review-facade.d.ts +7 -0
  240. package/dist/runtime/facades/review-facade.d.ts.map +1 -0
  241. package/dist/runtime/facades/review-facade.js +8 -0
  242. package/dist/runtime/facades/review-facade.js.map +1 -0
  243. package/dist/runtime/facades/sync-facade.d.ts +7 -0
  244. package/dist/runtime/facades/sync-facade.d.ts.map +1 -0
  245. package/dist/runtime/facades/sync-facade.js +8 -0
  246. package/dist/runtime/facades/sync-facade.js.map +1 -0
  247. package/dist/runtime/facades/vault-facade.d.ts +4 -1
  248. package/dist/runtime/facades/vault-facade.d.ts.map +1 -1
  249. package/dist/runtime/facades/vault-facade.js +13 -66
  250. package/dist/runtime/facades/vault-facade.js.map +1 -1
  251. package/dist/runtime/github-integration.d.ts +49 -0
  252. package/dist/runtime/github-integration.d.ts.map +1 -0
  253. package/dist/runtime/github-integration.js +113 -0
  254. package/dist/runtime/github-integration.js.map +1 -0
  255. package/dist/runtime/grading-ops.js +1 -1
  256. package/dist/runtime/grading-ops.js.map +1 -1
  257. package/dist/runtime/memory-extra-ops.d.ts.map +1 -1
  258. package/dist/runtime/memory-extra-ops.js +6 -2
  259. package/dist/runtime/memory-extra-ops.js.map +1 -1
  260. package/dist/runtime/orchestrate-ops.d.ts.map +1 -1
  261. package/dist/runtime/orchestrate-ops.js +367 -40
  262. package/dist/runtime/orchestrate-ops.js.map +1 -1
  263. package/dist/runtime/planning-extra-ops.d.ts.map +1 -1
  264. package/dist/runtime/planning-extra-ops.js +69 -4
  265. package/dist/runtime/planning-extra-ops.js.map +1 -1
  266. package/dist/runtime/review-ops.d.ts +10 -0
  267. package/dist/runtime/review-ops.d.ts.map +1 -0
  268. package/dist/runtime/review-ops.js +97 -0
  269. package/dist/runtime/review-ops.js.map +1 -0
  270. package/dist/runtime/runtime.d.ts.map +1 -1
  271. package/dist/runtime/runtime.js +27 -12
  272. package/dist/runtime/runtime.js.map +1 -1
  273. package/dist/runtime/session-briefing.d.ts +3 -0
  274. package/dist/runtime/session-briefing.d.ts.map +1 -1
  275. package/dist/runtime/session-briefing.js +68 -1
  276. package/dist/runtime/session-briefing.js.map +1 -1
  277. package/dist/runtime/sync-ops.d.ts +12 -0
  278. package/dist/runtime/sync-ops.d.ts.map +1 -0
  279. package/dist/runtime/sync-ops.js +288 -0
  280. package/dist/runtime/sync-ops.js.map +1 -0
  281. package/dist/runtime/types.d.ts +10 -4
  282. package/dist/runtime/types.d.ts.map +1 -1
  283. package/dist/runtime/vault-extra-ops.d.ts +5 -4
  284. package/dist/runtime/vault-extra-ops.d.ts.map +1 -1
  285. package/dist/runtime/vault-extra-ops.js +5 -300
  286. package/dist/runtime/vault-extra-ops.js.map +1 -1
  287. package/dist/runtime/vault-sharing-ops.d.ts +4 -4
  288. package/dist/runtime/vault-sharing-ops.d.ts.map +1 -1
  289. package/dist/runtime/vault-sharing-ops.js +5 -300
  290. package/dist/runtime/vault-sharing-ops.js.map +1 -1
  291. package/dist/skills/sync-skills.d.ts +27 -0
  292. package/dist/skills/sync-skills.d.ts.map +1 -0
  293. package/dist/skills/sync-skills.js +81 -0
  294. package/dist/skills/sync-skills.js.map +1 -0
  295. package/dist/update-check.d.ts +14 -0
  296. package/dist/update-check.d.ts.map +1 -0
  297. package/dist/update-check.js +96 -0
  298. package/dist/update-check.js.map +1 -0
  299. package/dist/vault/linking.d.ts +10 -12
  300. package/dist/vault/linking.d.ts.map +1 -1
  301. package/dist/vault/linking.js +104 -161
  302. package/dist/vault/linking.js.map +1 -1
  303. package/dist/vault/vault-entries.d.ts +69 -0
  304. package/dist/vault/vault-entries.d.ts.map +1 -0
  305. package/dist/vault/vault-entries.js +257 -0
  306. package/dist/vault/vault-entries.js.map +1 -0
  307. package/dist/vault/vault-interfaces.d.ts +153 -0
  308. package/dist/vault/vault-interfaces.d.ts.map +1 -0
  309. package/dist/vault/vault-interfaces.js +2 -0
  310. package/dist/vault/vault-interfaces.js.map +1 -0
  311. package/dist/vault/vault-maintenance.d.ts +40 -0
  312. package/dist/vault/vault-maintenance.d.ts.map +1 -0
  313. package/dist/vault/vault-maintenance.js +142 -0
  314. package/dist/vault/vault-maintenance.js.map +1 -0
  315. package/dist/vault/vault-markdown-sync.d.ts +22 -0
  316. package/dist/vault/vault-markdown-sync.d.ts.map +1 -0
  317. package/dist/vault/vault-markdown-sync.js +143 -0
  318. package/dist/vault/vault-markdown-sync.js.map +1 -0
  319. package/dist/vault/vault-memories.d.ts +61 -0
  320. package/dist/vault/vault-memories.d.ts.map +1 -0
  321. package/dist/vault/vault-memories.js +240 -0
  322. package/dist/vault/vault-memories.js.map +1 -0
  323. package/dist/vault/vault-schema.d.ts +9 -0
  324. package/dist/vault/vault-schema.d.ts.map +1 -0
  325. package/dist/vault/vault-schema.js +179 -0
  326. package/dist/vault/vault-schema.js.map +1 -0
  327. package/dist/vault/vault.d.ts +29 -81
  328. package/dist/vault/vault.d.ts.map +1 -1
  329. package/dist/vault/vault.js +78 -931
  330. package/dist/vault/vault.js.map +1 -1
  331. package/package.json +1 -1
  332. package/src/agency/agency-manager.test.ts +600 -0
  333. package/src/agency/default-rules.test.ts +228 -0
  334. package/src/{__tests__ → brain}/brain-intelligence.test.ts +37 -14
  335. package/src/{__tests__ → brain}/brain.test.ts +1 -1
  336. package/src/brain/intelligence.ts +196 -15
  337. package/src/brain/learning-radar.ts +22 -1
  338. package/src/{__tests__ → brain}/second-brain-features.test.ts +4 -4
  339. package/src/{__tests__ → brain}/session-lifecycle.test.ts +2 -2
  340. package/src/brain/strength-scorer.ts +404 -0
  341. package/src/capabilities/chain-mapping.test.ts +66 -0
  342. package/src/capabilities/registry.test.ts +369 -0
  343. package/src/chat/agent-loop.test.ts +394 -0
  344. package/src/chat/agent-loop.ts +2 -0
  345. package/src/{__tests__ → chat}/chat-differentiators.test.ts +3 -3
  346. package/src/{__tests__ → chat}/chat-enhanced.test.ts +4 -4
  347. package/src/{__tests__ → chat}/chat-transport.test.ts +6 -6
  348. package/src/chat/mcp-bridge.test.ts +173 -0
  349. package/src/chat/notifications.ts +2 -0
  350. package/src/chat/output-compressor.test.ts +164 -0
  351. package/src/claudemd/compose.test.ts +178 -0
  352. package/src/claudemd/compose.ts +1 -1
  353. package/src/claudemd/inject.test.ts +211 -0
  354. package/src/context/context-engine.test.ts +461 -0
  355. package/src/control/identity-manager.test.ts +305 -0
  356. package/src/control/intent-router.test.ts +360 -0
  357. package/src/control/intent-router.ts +13 -4
  358. package/src/curator/classifier.test.ts +104 -0
  359. package/src/curator/contradiction-detector.test.ts +180 -0
  360. package/src/curator/contradiction-detector.ts +87 -0
  361. package/src/{__tests__ → curator}/curator-pipeline-e2e.test.ts +10 -10
  362. package/src/{__tests__ → curator}/curator.test.ts +77 -1
  363. package/src/curator/curator.ts +115 -777
  364. package/src/curator/duplicate-detector.test.ts +183 -0
  365. package/src/curator/duplicate-detector.ts +103 -0
  366. package/src/curator/health-audit.ts +126 -0
  367. package/src/curator/metadata-enricher.ts +84 -0
  368. package/src/curator/quality-gate.test.ts +135 -0
  369. package/src/curator/schema.ts +65 -0
  370. package/src/curator/tag-manager.test.ts +165 -0
  371. package/src/curator/tag-manager.ts +109 -0
  372. package/src/domain-packs/inject-rules.test.ts +117 -0
  373. package/src/domain-packs/knowledge-installer.test.ts +171 -0
  374. package/src/domain-packs/loader.test.ts +86 -0
  375. package/src/domain-packs/pack-runtime.test.ts +140 -0
  376. package/src/domain-packs/skills-installer.test.ts +135 -0
  377. package/src/domain-packs/token-resolver.test.ts +150 -0
  378. package/src/domain-packs/types.test.ts +130 -0
  379. package/src/enforcement/adapters/claude-code.test.ts +216 -0
  380. package/src/enforcement/registry.test.ts +264 -0
  381. package/src/engine/bin/soleri-engine.ts +28 -4
  382. package/src/engine/core-ops.test.ts +254 -0
  383. package/src/engine/core-ops.ts +25 -8
  384. package/src/engine/module-manifest.test.ts +124 -0
  385. package/src/engine/module-manifest.ts +22 -2
  386. package/src/engine/register-engine.test.ts +230 -0
  387. package/src/engine/register-engine.ts +26 -2
  388. package/src/errors/classify.test.ts +199 -0
  389. package/src/errors/retry.test.ts +156 -0
  390. package/src/errors/retry.ts +2 -0
  391. package/src/errors/types.test.ts +108 -0
  392. package/src/events/event-bus.test.ts +149 -0
  393. package/src/extensions/middleware.test.ts +234 -0
  394. package/src/facades/facade-factory.test.ts +424 -0
  395. package/src/flows/chain-runner.test.ts +273 -0
  396. package/src/flows/context-router.test.ts +52 -0
  397. package/src/flows/dispatch-registry.test.ts +128 -0
  398. package/src/flows/epilogue.test.ts +107 -0
  399. package/src/flows/executor.test.ts +263 -0
  400. package/src/flows/gate-evaluator.test.ts +194 -0
  401. package/src/flows/gate-evaluator.ts +25 -0
  402. package/src/flows/types.ts +4 -0
  403. package/src/governance/governance.test.ts +726 -0
  404. package/src/health/health-registry.test.ts +186 -0
  405. package/src/health/vault-integrity.test.ts +110 -0
  406. package/src/index.ts +92 -0
  407. package/src/intake/content-classifier.test.ts +209 -0
  408. package/src/intake/dedup-gate.test.ts +131 -0
  409. package/src/intake/intake-pipeline.test.ts +506 -0
  410. package/src/intake/intake-pipeline.ts +1 -0
  411. package/src/intake/text-ingester.test.ts +194 -0
  412. package/src/intake/text-ingester.ts +2 -0
  413. package/src/llm/key-pool.test.ts +236 -0
  414. package/src/llm/key-pool.ts +3 -4
  415. package/src/llm/llm-client.test.ts +345 -0
  416. package/src/llm/oauth-discovery.test.ts +180 -0
  417. package/src/llm/utils.test.ts +327 -0
  418. package/src/llm/utils.ts +2 -0
  419. package/src/{__tests__ → logging}/logger.test.ts +41 -62
  420. package/src/loop/loop-manager.test.ts +519 -0
  421. package/src/migrations/migration-runner.edge-cases.test.ts +319 -0
  422. package/src/migrations/migration-runner.test-helpers.ts +64 -0
  423. package/src/migrations/migration-runner.test.ts +385 -0
  424. package/src/operator/auto-signal-pipeline.test.ts +207 -0
  425. package/src/operator/operator-profile-extended.test.ts +320 -0
  426. package/src/operator/operator-profile.test.ts +314 -0
  427. package/src/operator/operator-profile.ts +469 -0
  428. package/src/operator/operator-signals-extended.test.ts +245 -0
  429. package/src/operator/operator-signals.test.ts +281 -0
  430. package/src/operator/operator-signals.ts +261 -0
  431. package/src/operator/operator-types.ts +444 -0
  432. package/src/operator/prompts/hook-precompact-operator-dispatch.md +94 -0
  433. package/src/operator/prompts/subagent-soft-signal-extractor.md +125 -0
  434. package/src/operator/prompts/subagent-synthesis-cognition.md +181 -0
  435. package/src/operator/prompts/subagent-synthesis-communication.md +140 -0
  436. package/src/operator/prompts/subagent-synthesis-technical.md +160 -0
  437. package/src/operator/prompts/subagent-synthesis-trust.md +143 -0
  438. package/src/{__tests__ → packs}/pack-lockfile.test.ts +3 -3
  439. package/src/{__tests__ → packs}/pack-system.test.ts +2 -2
  440. package/src/paths.ts +115 -0
  441. package/src/persistence/index.ts +1 -1
  442. package/src/persistence/sqlite-provider.test.ts +540 -0
  443. package/src/persistence/sqlite-provider.ts +8 -5
  444. package/src/persona/defaults.test.ts +59 -0
  445. package/src/persona/loader.test.ts +67 -0
  446. package/src/persona/prompt-generator.test.ts +127 -0
  447. package/src/planning/evidence-collector.test.ts +406 -0
  448. package/src/planning/evidence-collector.ts +50 -0
  449. package/src/planning/gap-analysis-alternatives.test.ts +169 -0
  450. package/src/planning/gap-analysis.ts +21 -636
  451. package/src/planning/gap-passes.test.ts +372 -0
  452. package/src/planning/gap-passes.ts +298 -0
  453. package/src/planning/gap-patterns.test.ts +320 -0
  454. package/src/planning/gap-patterns.ts +234 -0
  455. package/src/planning/gap-types.ts +4 -1
  456. package/src/planning/github-projection.test.ts +177 -0
  457. package/src/planning/github-projection.ts +425 -0
  458. package/src/planning/impact-analyzer.test.ts +180 -0
  459. package/src/planning/impact-analyzer.ts +264 -0
  460. package/src/planning/plan-lifecycle.test.ts +312 -0
  461. package/src/planning/plan-lifecycle.ts +346 -0
  462. package/src/planning/planner-types.ts +215 -0
  463. package/src/{__tests__ → planning}/planner.test.ts +169 -15
  464. package/src/planning/planner.ts +197 -1228
  465. package/src/planning/rationalization-detector.test.ts +171 -0
  466. package/src/planning/rationalization-detector.ts +138 -0
  467. package/src/planning/reconciliation-engine.test.ts +141 -0
  468. package/src/planning/reconciliation-engine.ts +162 -0
  469. package/src/planning/task-verifier.test.ts +235 -0
  470. package/src/planning/task-verifier.ts +303 -0
  471. package/src/planning/verification-protocol.test.ts +201 -0
  472. package/src/playbooks/generic/generic-playbooks.test.ts +438 -0
  473. package/src/playbooks/index.test.ts +77 -0
  474. package/src/playbooks/playbook-executor.test.ts +255 -0
  475. package/src/playbooks/playbook-registry.test.ts +232 -0
  476. package/src/playbooks/playbook-seeder.test.ts +153 -0
  477. package/src/plugins/plugin-loader.test.ts +212 -0
  478. package/src/plugins/plugin-registry.test.ts +272 -0
  479. package/src/project/project-registry.test.ts +428 -0
  480. package/src/prompts/parser.test.ts +100 -0
  481. package/src/prompts/template-manager.test.ts +109 -0
  482. package/src/{__tests__ → queue}/async-infrastructure.test.ts +3 -3
  483. package/src/queue/job-queue.test.ts +331 -0
  484. package/src/queue/pipeline-runner.test.ts +209 -0
  485. package/src/runtime/admin-extra-ops.test.ts +527 -0
  486. package/src/runtime/admin-ops.test.ts +257 -0
  487. package/src/runtime/admin-ops.ts +45 -17
  488. package/src/runtime/admin-setup-ops.test.ts +328 -0
  489. package/src/runtime/admin-setup-ops.ts +20 -43
  490. package/src/runtime/archive-ops.test.ts +269 -0
  491. package/src/runtime/archive-ops.ts +347 -0
  492. package/src/runtime/capture-ops.test.ts +433 -0
  493. package/src/runtime/capture-ops.ts +50 -8
  494. package/src/runtime/chain-ops.test.ts +149 -0
  495. package/src/runtime/claude-md-helpers.test.ts +191 -0
  496. package/src/runtime/claude-md-helpers.ts +1 -1
  497. package/src/runtime/context-health.test.ts +78 -0
  498. package/src/runtime/context-health.ts +85 -0
  499. package/src/runtime/curator-extra-ops.test.ts +202 -0
  500. package/src/runtime/deprecation.test.ts +98 -0
  501. package/src/runtime/domain-ops.test.ts +268 -0
  502. package/src/runtime/facades/admin-facade.test.ts +333 -0
  503. package/src/runtime/facades/agency-facade.test.ts +278 -0
  504. package/src/runtime/facades/archive-facade.test.ts +294 -0
  505. package/src/runtime/facades/archive-facade.ts +14 -0
  506. package/src/runtime/facades/brain-facade.test.ts +714 -0
  507. package/src/runtime/facades/brain-facade.ts +2 -0
  508. package/src/runtime/facades/chat-facade.test.ts +166 -0
  509. package/src/runtime/facades/chat-facade.ts +15 -906
  510. package/src/runtime/facades/chat-service-ops.test.ts +276 -0
  511. package/src/runtime/facades/chat-service-ops.ts +374 -0
  512. package/src/runtime/facades/chat-session-ops.test.ts +197 -0
  513. package/src/runtime/facades/chat-session-ops.ts +146 -0
  514. package/src/runtime/facades/chat-state.ts +60 -0
  515. package/src/runtime/facades/chat-transport-ops.test.ts +269 -0
  516. package/src/runtime/facades/chat-transport-ops.ts +380 -0
  517. package/src/runtime/facades/context-facade.test.ts +108 -0
  518. package/src/runtime/facades/control-facade.test.ts +436 -0
  519. package/src/runtime/facades/control-facade.ts +6 -1
  520. package/src/runtime/facades/curator-facade.test.ts +303 -0
  521. package/src/runtime/facades/index.ts +6 -0
  522. package/src/runtime/facades/loop-facade.test.ts +245 -0
  523. package/src/runtime/facades/memory-facade.test.ts +269 -0
  524. package/src/runtime/facades/memory-facade.ts +78 -6
  525. package/src/runtime/facades/operator-facade.test.ts +208 -0
  526. package/src/runtime/facades/operator-facade.ts +236 -0
  527. package/src/runtime/facades/orchestrate-facade.test.ts +185 -0
  528. package/src/runtime/facades/orchestrate-facade.ts +3 -3
  529. package/src/runtime/facades/plan-facade.test.ts +266 -0
  530. package/src/runtime/facades/plan-facade.ts +42 -6
  531. package/src/runtime/facades/review-facade.test.ts +82 -0
  532. package/src/runtime/facades/review-facade.ts +11 -0
  533. package/src/runtime/facades/sync-facade.test.ts +113 -0
  534. package/src/runtime/facades/sync-facade.ts +11 -0
  535. package/src/runtime/facades/vault-facade.test.ts +631 -0
  536. package/src/runtime/facades/vault-facade.ts +15 -70
  537. package/src/runtime/feature-flags.test.ts +140 -0
  538. package/src/runtime/github-integration.test.ts +89 -0
  539. package/src/runtime/github-integration.ts +159 -0
  540. package/src/runtime/grading-ops.test.ts +141 -0
  541. package/src/runtime/grading-ops.ts +1 -1
  542. package/src/runtime/intake-ops.test.ts +208 -0
  543. package/src/runtime/loop-ops.test.ts +238 -0
  544. package/src/runtime/memory-cross-project-ops.test.ts +177 -0
  545. package/src/runtime/memory-extra-ops.test.ts +453 -0
  546. package/src/runtime/memory-extra-ops.ts +6 -2
  547. package/src/runtime/orchestrate-ops.test.ts +302 -0
  548. package/src/runtime/orchestrate-ops.ts +435 -46
  549. package/src/runtime/pack-ops.test.ts +158 -0
  550. package/src/runtime/planning-extra-ops.test.ts +583 -0
  551. package/src/runtime/planning-extra-ops.ts +72 -4
  552. package/src/{__tests__ → runtime}/playbook-ops-execution.test.ts +3 -3
  553. package/src/runtime/playbook-ops.test.ts +262 -0
  554. package/src/runtime/plugin-ops.test.ts +201 -0
  555. package/src/runtime/project-ops.test.ts +235 -0
  556. package/src/runtime/review-ops.test.ts +142 -0
  557. package/src/runtime/review-ops.ts +99 -0
  558. package/src/runtime/runtime.test.ts +363 -0
  559. package/src/runtime/runtime.ts +39 -12
  560. package/src/runtime/session-briefing.test.ts +302 -0
  561. package/src/runtime/session-briefing.ts +80 -1
  562. package/src/runtime/sync-ops.test.ts +221 -0
  563. package/src/runtime/sync-ops.ts +325 -0
  564. package/src/runtime/telemetry-ops.test.ts +132 -0
  565. package/src/runtime/types.ts +10 -4
  566. package/src/runtime/vault-extra-ops.test.ts +246 -0
  567. package/src/runtime/vault-extra-ops.ts +5 -332
  568. package/src/runtime/vault-linking-ops.test.ts +237 -0
  569. package/src/runtime/vault-sharing-ops.test.ts +130 -0
  570. package/src/runtime/vault-sharing-ops.ts +5 -329
  571. package/src/skills/sync-skills.ts +108 -0
  572. package/src/streams/normalize.test.ts +95 -0
  573. package/src/streams/replayable-stream.test.ts +166 -0
  574. package/src/telemetry/telemetry.test.ts +143 -0
  575. package/src/transport/http-server.test.ts +394 -0
  576. package/src/transport/lsp-server.test.ts +458 -0
  577. package/src/transport/rate-limiter.test.ts +126 -0
  578. package/src/transport/session-manager.test.ts +133 -0
  579. package/src/transport/token-auth.test.ts +136 -0
  580. package/src/transport/ws-server.test.ts +294 -0
  581. package/src/update-check.ts +111 -0
  582. package/src/vault/__tests__/vault-characterization.test.ts +168 -0
  583. package/src/vault/content-hash.test.ts +78 -0
  584. package/src/vault/git-vault-sync.test.ts +234 -0
  585. package/src/vault/knowledge-review.test.ts +269 -0
  586. package/src/vault/linking.test.ts +358 -0
  587. package/src/vault/linking.ts +149 -183
  588. package/src/vault/obsidian-sync.test.ts +342 -0
  589. package/src/vault/playbook.test.ts +152 -0
  590. package/src/vault/scope-detector.test.ts +187 -0
  591. package/src/vault/vault-branching.test.ts +250 -0
  592. package/src/{__tests__ → vault}/vault-connect.test.ts +1 -1
  593. package/src/vault/vault-entries.ts +282 -0
  594. package/src/vault/vault-interfaces.ts +56 -0
  595. package/src/vault/vault-maintenance.ts +205 -0
  596. package/src/vault/vault-manager.test.ts +206 -0
  597. package/src/vault/vault-markdown-sync.test.ts +203 -0
  598. package/src/vault/vault-markdown-sync.ts +160 -0
  599. package/src/vault/vault-memories.ts +339 -0
  600. package/src/{__tests__ → vault}/vault-scaling.test.ts +1 -1
  601. package/src/vault/vault-schema.ts +181 -0
  602. package/src/{__tests__ → vault}/vault-sharing.test.ts +4 -4
  603. package/src/{__tests__ → vault}/vault.test.ts +2 -2
  604. package/src/vault/vault.ts +89 -1171
  605. package/dist/cognee/client.d.ts +0 -43
  606. package/dist/cognee/client.d.ts.map +0 -1
  607. package/dist/cognee/client.js +0 -375
  608. package/dist/cognee/client.js.map +0 -1
  609. package/dist/cognee/sync-manager.d.ts +0 -153
  610. package/dist/cognee/sync-manager.d.ts.map +0 -1
  611. package/dist/cognee/sync-manager.js +0 -390
  612. package/dist/cognee/sync-manager.js.map +0 -1
  613. package/dist/cognee/types.d.ts +0 -62
  614. package/dist/cognee/types.d.ts.map +0 -1
  615. package/dist/cognee/types.js +0 -3
  616. package/dist/cognee/types.js.map +0 -1
  617. package/dist/governance/index.d.ts +0 -3
  618. package/dist/governance/index.d.ts.map +0 -1
  619. package/dist/governance/index.js +0 -2
  620. package/dist/governance/index.js.map +0 -1
  621. package/dist/health/doctor-checks.d.ts +0 -15
  622. package/dist/health/doctor-checks.d.ts.map +0 -1
  623. package/dist/health/doctor-checks.js +0 -98
  624. package/dist/health/doctor-checks.js.map +0 -1
  625. package/dist/persistence/postgres-provider.d.ts +0 -81
  626. package/dist/persistence/postgres-provider.d.ts.map +0 -1
  627. package/dist/persistence/postgres-provider.js +0 -256
  628. package/dist/persistence/postgres-provider.js.map +0 -1
  629. package/dist/runtime/cognee-sync-ops.d.ts +0 -12
  630. package/dist/runtime/cognee-sync-ops.d.ts.map +0 -1
  631. package/dist/runtime/cognee-sync-ops.js +0 -93
  632. package/dist/runtime/cognee-sync-ops.js.map +0 -1
  633. package/dist/runtime/core-ops.d.ts +0 -23
  634. package/dist/runtime/core-ops.d.ts.map +0 -1
  635. package/dist/runtime/core-ops.js +0 -1296
  636. package/dist/runtime/core-ops.js.map +0 -1
  637. package/dist/runtime/facades/cognee-facade.d.ts +0 -8
  638. package/dist/runtime/facades/cognee-facade.d.ts.map +0 -1
  639. package/dist/runtime/facades/cognee-facade.js +0 -156
  640. package/dist/runtime/facades/cognee-facade.js.map +0 -1
  641. package/src/__tests__/admin-extra-ops.test.ts +0 -484
  642. package/src/__tests__/admin-ops.test.ts +0 -268
  643. package/src/__tests__/admin-setup-ops.test.ts +0 -355
  644. package/src/__tests__/agency-manager.test.ts +0 -374
  645. package/src/__tests__/agent-loop.test.ts +0 -256
  646. package/src/__tests__/capture-ops.test.ts +0 -784
  647. package/src/__tests__/claudemd.test.ts +0 -282
  648. package/src/__tests__/content-hash.test.ts +0 -60
  649. package/src/__tests__/context-engine.test.ts +0 -251
  650. package/src/__tests__/core-ops.test.ts +0 -550
  651. package/src/__tests__/curator-extra-ops.test.ts +0 -383
  652. package/src/__tests__/deprecation.test.ts +0 -78
  653. package/src/__tests__/domain-ops.test.ts +0 -226
  654. package/src/__tests__/domain-packs.test.ts +0 -421
  655. package/src/__tests__/enforcement.test.ts +0 -153
  656. package/src/__tests__/errors.test.ts +0 -388
  657. package/src/__tests__/extensions.test.ts +0 -233
  658. package/src/__tests__/facade-factory.test.ts +0 -271
  659. package/src/__tests__/feature-flags.test.ts +0 -137
  660. package/src/__tests__/flows.test.ts +0 -604
  661. package/src/__tests__/git-vault-sync.test.ts +0 -230
  662. package/src/__tests__/governance.test.ts +0 -522
  663. package/src/__tests__/grading-ops.test.ts +0 -361
  664. package/src/__tests__/health-registry.test.ts +0 -173
  665. package/src/__tests__/identity-manager.test.ts +0 -243
  666. package/src/__tests__/intake-pipeline.test.ts +0 -162
  667. package/src/__tests__/intent-router.test.ts +0 -222
  668. package/src/__tests__/knowledge-review.test.ts +0 -104
  669. package/src/__tests__/llm-client.test.ts +0 -69
  670. package/src/__tests__/llm.test.ts +0 -556
  671. package/src/__tests__/loader.test.ts +0 -176
  672. package/src/__tests__/loop-ops.test.ts +0 -469
  673. package/src/__tests__/lsp-transport.test.ts +0 -442
  674. package/src/__tests__/memory-cross-project-ops.test.ts +0 -248
  675. package/src/__tests__/memory-extra-ops.test.ts +0 -352
  676. package/src/__tests__/migration-runner.test.ts +0 -170
  677. package/src/__tests__/module-manifest-drift.test.ts +0 -59
  678. package/src/__tests__/normalize.test.ts +0 -85
  679. package/src/__tests__/obsidian-sync.test.ts +0 -354
  680. package/src/__tests__/orchestrate-ops.test.ts +0 -289
  681. package/src/__tests__/pack-ops.test.ts +0 -146
  682. package/src/__tests__/persistence.test.ts +0 -291
  683. package/src/__tests__/planning-extra-ops.test.ts +0 -706
  684. package/src/__tests__/playbook-executor.test.ts +0 -249
  685. package/src/__tests__/playbook-registry.test.ts +0 -326
  686. package/src/__tests__/playbook-seeder.test.ts +0 -163
  687. package/src/__tests__/playbook.test.ts +0 -389
  688. package/src/__tests__/plugin-ops.test.ts +0 -411
  689. package/src/__tests__/plugin-system.test.ts +0 -509
  690. package/src/__tests__/project-ops.test.ts +0 -381
  691. package/src/__tests__/replayable-stream.test.ts +0 -177
  692. package/src/__tests__/runtime.test.ts +0 -95
  693. package/src/__tests__/scope-detector.test.ts +0 -121
  694. package/src/__tests__/template-manager.test.ts +0 -222
  695. package/src/__tests__/token-resolver.test.ts +0 -79
  696. package/src/__tests__/transport.test.ts +0 -758
  697. package/src/__tests__/vault-branching.test.ts +0 -274
  698. package/src/__tests__/vault-extra-ops.test.ts +0 -482
  699. package/src/__tests__/vault-integrity.test.ts +0 -71
  700. package/src/__tests__/vault-manager.test.ts +0 -238
  701. package/src/__tests__/ws-transport.test.ts +0 -479
@@ -0,0 +1,269 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { Vault } from '../../vault/vault.js';
3
+ import { OperatorProfileStore } from '../../operator/operator-profile.js';
4
+ import { ProjectRegistry } from '../../project/project-registry.js';
5
+ import { createMemoryFacadeOps } from './memory-facade.js';
6
+ import { captureOps, executeOp } from '../../engine/test-helpers.js';
7
+ import type { CapturedOp } from '../../engine/test-helpers.js';
8
+ import type { AgentRuntime } from '../types.js';
9
+
10
+ // ─── Helpers ────────────────────────────────────────────────────────
11
+
12
+ function makeRuntime(vault: Vault): AgentRuntime {
13
+ const operatorProfile = new OperatorProfileStore(vault);
14
+ const projectRegistry = new ProjectRegistry(vault.getProvider());
15
+ return { vault, operatorProfile, projectRegistry } as unknown as AgentRuntime;
16
+ }
17
+
18
+ // ─── Tests ──────────────────────────────────────────────────────────
19
+
20
+ describe('memory-facade', () => {
21
+ let vault: Vault;
22
+ let ops: Map<string, CapturedOp>;
23
+
24
+ beforeEach(() => {
25
+ vault = new Vault(':memory:');
26
+ ops = captureOps(createMemoryFacadeOps(makeRuntime(vault)));
27
+ });
28
+
29
+ afterEach(() => {
30
+ vault.close();
31
+ });
32
+
33
+ it('registers base + extra + cross-project ops', () => {
34
+ // 4 base + 18 extra + 3 cross-project = 25
35
+ expect(ops.size).toBeGreaterThanOrEqual(25);
36
+ expect([...ops.keys()]).toContain('memory_search');
37
+ expect([...ops.keys()]).toContain('memory_capture');
38
+ expect([...ops.keys()]).toContain('memory_list');
39
+ expect([...ops.keys()]).toContain('session_capture');
40
+ expect([...ops.keys()]).toContain('memory_delete');
41
+ expect([...ops.keys()]).toContain('memory_promote_to_global');
42
+ });
43
+
44
+ it('has correct auth levels for base ops', () => {
45
+ expect(ops.get('memory_search')!.auth).toBe('read');
46
+ expect(ops.get('memory_capture')!.auth).toBe('write');
47
+ expect(ops.get('memory_list')!.auth).toBe('read');
48
+ expect(ops.get('session_capture')!.auth).toBe('write');
49
+ });
50
+
51
+ // ─── memory_capture ────────────────────────────────────────────
52
+
53
+ it('memory_capture stores a memory', async () => {
54
+ const result = await executeOp(ops, 'memory_capture', {
55
+ projectPath: '/test',
56
+ type: 'lesson',
57
+ context: 'learned about tokens',
58
+ summary: 'Token migration pattern',
59
+ topics: ['tokens'],
60
+ });
61
+ expect(result.success).toBe(true);
62
+ expect((result.data as Record<string, unknown>).captured).toBe(true);
63
+ });
64
+
65
+ // ─── memory_search ─────────────────────────────────────────────
66
+
67
+ it('memory_search returns empty for no matches', async () => {
68
+ const result = await executeOp(ops, 'memory_search', { query: 'nonexistent' });
69
+ expect(result.success).toBe(true);
70
+ expect((result.data as Record<string, unknown>).total).toBe(0);
71
+ });
72
+
73
+ it('memory_search finds captured memories', async () => {
74
+ await executeOp(ops, 'memory_capture', {
75
+ projectPath: '/test',
76
+ type: 'lesson',
77
+ context: 'context',
78
+ summary: 'Token migration best practices',
79
+ });
80
+ const result = await executeOp(ops, 'memory_search', { query: 'token migration' });
81
+ expect(result.success).toBe(true);
82
+ expect((result.data as Record<string, unknown>).total).toBeGreaterThanOrEqual(1);
83
+ });
84
+
85
+ it('memory_search returns summaries by default', async () => {
86
+ await executeOp(ops, 'memory_capture', {
87
+ projectPath: '/test',
88
+ type: 'lesson',
89
+ context: 'ctx',
90
+ summary: 'short summary',
91
+ });
92
+ const result = await executeOp(ops, 'memory_search', { query: 'short summary' });
93
+ expect(result.success).toBe(true);
94
+ const data = result.data as { results: Array<{ summary: string }> };
95
+ expect(data.results[0]).toHaveProperty('summary');
96
+ expect(data.results[0]).not.toHaveProperty('context');
97
+ });
98
+
99
+ it('memory_search returns full objects with verbose:true', async () => {
100
+ await executeOp(ops, 'memory_capture', {
101
+ projectPath: '/test',
102
+ type: 'lesson',
103
+ context: 'ctx',
104
+ summary: 'verbose test',
105
+ });
106
+ const result = await executeOp(ops, 'memory_search', { query: 'verbose test', verbose: true });
107
+ expect(result.success).toBe(true);
108
+ const data = result.data as { results: Array<Record<string, unknown>> };
109
+ expect(data.results[0]).toHaveProperty('context');
110
+ });
111
+
112
+ // ─── memory_list ───────────────────────────────────────────────
113
+
114
+ it('memory_list returns entries with stats', async () => {
115
+ await executeOp(ops, 'memory_capture', {
116
+ projectPath: '/test',
117
+ type: 'session',
118
+ context: 'ctx',
119
+ summary: 'session 1',
120
+ });
121
+ const result = await executeOp(ops, 'memory_list', {});
122
+ expect(result.success).toBe(true);
123
+ const data = result.data as { entries: unknown[]; total: number };
124
+ expect(data.total).toBeGreaterThanOrEqual(1);
125
+ expect(data.entries.length).toBeGreaterThanOrEqual(1);
126
+ });
127
+
128
+ it('memory_list filters by type', async () => {
129
+ await executeOp(ops, 'memory_capture', {
130
+ projectPath: '/test', type: 'lesson', context: 'c', summary: 'lesson',
131
+ });
132
+ await executeOp(ops, 'memory_capture', {
133
+ projectPath: '/test', type: 'preference', context: 'c', summary: 'pref',
134
+ });
135
+ const result = await executeOp(ops, 'memory_list', { type: 'lesson' });
136
+ expect(result.success).toBe(true);
137
+ const data = result.data as { entries: unknown[]; total: number };
138
+ expect(data.entries.length).toBe(1);
139
+ });
140
+
141
+ it('memory_list verbose returns full objects', async () => {
142
+ await executeOp(ops, 'memory_capture', {
143
+ projectPath: '/test', type: 'lesson', context: 'c', summary: 'verbose list',
144
+ });
145
+ const result = await executeOp(ops, 'memory_list', { verbose: true });
146
+ expect(result.success).toBe(true);
147
+ const data = result.data as { memories: Array<Record<string, unknown>> };
148
+ expect(data.memories[0]).toHaveProperty('context');
149
+ });
150
+
151
+ // ─── session_capture ───────────────────────────────────────────
152
+
153
+ it('session_capture stores with summary', async () => {
154
+ const result = await executeOp(ops, 'session_capture', {
155
+ summary: 'Built token migration feature',
156
+ topics: ['tokens'],
157
+ });
158
+ expect(result.success).toBe(true);
159
+ expect((result.data as Record<string, unknown>).captured).toBe(true);
160
+ });
161
+
162
+ it('session_capture accepts conversationContext alias', async () => {
163
+ const result = await executeOp(ops, 'session_capture', {
164
+ conversationContext: 'aliased summary',
165
+ });
166
+ expect(result.success).toBe(true);
167
+ expect((result.data as Record<string, unknown>).captured).toBe(true);
168
+ });
169
+
170
+ it('session_capture fails without summary or conversationContext', async () => {
171
+ const result = await executeOp(ops, 'session_capture', { topics: ['test'] });
172
+ expect(result.success).toBe(true);
173
+ expect((result.data as Record<string, unknown>).captured).toBe(false);
174
+ });
175
+
176
+ it('session_capture stores rich fields', async () => {
177
+ const result = await executeOp(ops, 'session_capture', {
178
+ summary: 'test session',
179
+ intent: 'BUILD',
180
+ decisions: ['used pattern X'],
181
+ currentState: 'half done',
182
+ nextSteps: ['finish Y'],
183
+ vaultEntriesReferenced: ['entry-1'],
184
+ filesModified: ['src/app.ts'],
185
+ toolsUsed: ['vault_search'],
186
+ });
187
+ expect(result.success).toBe(true);
188
+ expect((result.data as Record<string, unknown>).captured).toBe(true);
189
+ });
190
+
191
+ // ─── memory_delete ─────────────────────────────────────────────
192
+
193
+ it('memory_delete removes a memory', async () => {
194
+ const captureResult = await executeOp(ops, 'memory_capture', {
195
+ projectPath: '/test', type: 'lesson', context: 'c', summary: 'to delete',
196
+ });
197
+ const memoryId = ((captureResult.data as Record<string, unknown>).memory as Record<string, unknown>).id as string;
198
+ const result = await executeOp(ops, 'memory_delete', { memoryId });
199
+ expect(result.success).toBe(true);
200
+ expect((result.data as Record<string, unknown>).deleted).toBe(true);
201
+ });
202
+
203
+ it('memory_delete returns false for nonexistent memory', async () => {
204
+ const result = await executeOp(ops, 'memory_delete', { memoryId: 'nonexistent' });
205
+ expect(result.success).toBe(true);
206
+ expect((result.data as Record<string, unknown>).deleted).toBe(false);
207
+ });
208
+
209
+ it('memory_delete accepts id alias', async () => {
210
+ const result = await executeOp(ops, 'memory_delete', { id: 'nonexistent' });
211
+ expect(result.success).toBe(true);
212
+ expect((result.data as Record<string, unknown>).deleted).toBe(false);
213
+ });
214
+
215
+ it('memory_delete fails without any id param', async () => {
216
+ const result = await executeOp(ops, 'memory_delete', {});
217
+ expect(result.success).toBe(true);
218
+ expect((result.data as Record<string, unknown>).deleted).toBe(false);
219
+ expect((result.data as Record<string, unknown>).error).toContain('required');
220
+ });
221
+
222
+ // ─── memory_stats ──────────────────────────────────────────────
223
+
224
+ it('memory_stats returns statistics', async () => {
225
+ const result = await executeOp(ops, 'memory_stats', {});
226
+ expect(result.success).toBe(true);
227
+ expect(result.data).toHaveProperty('total');
228
+ });
229
+
230
+ // ─── memory_topics ─────────────────────────────────────────────
231
+
232
+ it('memory_topics returns empty initially', async () => {
233
+ const result = await executeOp(ops, 'memory_topics', {});
234
+ expect(result.success).toBe(true);
235
+ expect((result.data as Record<string, unknown>).count).toBe(0);
236
+ });
237
+
238
+ // ─── memory_deduplicate ────────────────────────────────────────
239
+
240
+ it('memory_deduplicate runs without error', async () => {
241
+ const result = await executeOp(ops, 'memory_deduplicate', {});
242
+ expect(result.success).toBe(true);
243
+ });
244
+
245
+ // ─── memory_promote_to_global ──────────────────────────────────
246
+
247
+ it('memory_promote_to_global fails on missing entry', async () => {
248
+ const result = await executeOp(ops, 'memory_promote_to_global', { entryId: 'missing' });
249
+ expect(result.success).toBe(true);
250
+ expect((result.data as Record<string, unknown>).promoted).toBe(false);
251
+ });
252
+
253
+ it('memory_promote_to_global adds _global tag', async () => {
254
+ vault.add({
255
+ id: 'test-entry',
256
+ type: 'pattern',
257
+ domain: 'general',
258
+ title: 'test',
259
+ description: 'test',
260
+ severity: 'suggestion',
261
+ tags: ['foo'],
262
+ });
263
+ const result = await executeOp(ops, 'memory_promote_to_global', { entryId: 'test-entry' });
264
+ expect(result.success).toBe(true);
265
+ const data = result.data as { promoted: boolean; tags: string[] };
266
+ expect(data.promoted).toBe(true);
267
+ expect(data.tags).toContain('_global');
268
+ });
269
+ });
@@ -8,6 +8,14 @@ import type { OpDefinition } from '../../facades/types.js';
8
8
  import type { AgentRuntime } from '../types.js';
9
9
  import { createMemoryExtraOps } from '../memory-extra-ops.js';
10
10
  import { createMemoryCrossProjectOps } from '../memory-cross-project-ops.js';
11
+ import { extractFromSession } from '../../operator/operator-signals.js';
12
+ import type { SessionCaptureData } from '../../operator/operator-signals.js';
13
+
14
+ /** Truncate text to maxLen chars, appending ellipsis when truncated. */
15
+ function truncateSummary(text: string, maxLen = 120): string {
16
+ if (text.length <= maxLen) return text;
17
+ return text.slice(0, maxLen) + '\u2026';
18
+ }
11
19
 
12
20
  export function createMemoryFacadeOps(runtime: AgentRuntime): OpDefinition[] {
13
21
  const { vault } = runtime;
@@ -16,20 +24,38 @@ export function createMemoryFacadeOps(runtime: AgentRuntime): OpDefinition[] {
16
24
  // ─── Memory (inline from core-ops.ts) ───────────────────────
17
25
  {
18
26
  name: 'memory_search',
19
- description: 'Search memories using full-text search.',
27
+ description:
28
+ 'Search memories using full-text search. Returns summaries by default; pass verbose: true for full objects.',
20
29
  auth: 'read',
21
30
  schema: z.object({
22
31
  query: z.string(),
23
32
  type: z.enum(['session', 'lesson', 'preference']).optional(),
24
33
  projectPath: z.string().optional(),
25
34
  limit: z.number().optional(),
35
+ verbose: z
36
+ .boolean()
37
+ .optional()
38
+ .default(false)
39
+ .describe('Return full memory objects instead of summaries'),
26
40
  }),
27
41
  handler: async (params) => {
28
- return vault.searchMemories(params.query as string, {
42
+ const memories = vault.searchMemories(params.query as string, {
29
43
  type: params.type as string | undefined,
30
44
  projectPath: params.projectPath as string | undefined,
31
45
  limit: (params.limit as number) ?? 10,
32
46
  });
47
+ if (params.verbose) {
48
+ return { results: memories, total: memories.length };
49
+ }
50
+ return {
51
+ results: memories.map((m) => ({
52
+ id: m.id,
53
+ summary: truncateSummary(m.summary || m.context),
54
+ score: null,
55
+ project: m.projectPath,
56
+ })),
57
+ total: memories.length,
58
+ };
33
59
  },
34
60
  },
35
61
  {
@@ -65,13 +91,19 @@ export function createMemoryFacadeOps(runtime: AgentRuntime): OpDefinition[] {
65
91
  },
66
92
  {
67
93
  name: 'memory_list',
68
- description: 'List memories with optional filters.',
94
+ description:
95
+ 'List memories with optional filters. Returns summaries by default; pass verbose: true for full objects.',
69
96
  auth: 'read',
70
97
  schema: z.object({
71
98
  type: z.enum(['session', 'lesson', 'preference']).optional(),
72
99
  projectPath: z.string().optional(),
73
100
  limit: z.number().optional(),
74
101
  offset: z.number().optional(),
102
+ verbose: z
103
+ .boolean()
104
+ .optional()
105
+ .default(false)
106
+ .describe('Return full memory objects instead of summaries'),
75
107
  }),
76
108
  handler: async (params) => {
77
109
  const memories = vault.listMemories({
@@ -81,7 +113,18 @@ export function createMemoryFacadeOps(runtime: AgentRuntime): OpDefinition[] {
81
113
  offset: (params.offset as number) ?? 0,
82
114
  });
83
115
  const stats = vault.memoryStats();
84
- return { memories, stats };
116
+ if (params.verbose) {
117
+ return { memories, stats };
118
+ }
119
+ return {
120
+ entries: memories.map((m) => ({
121
+ id: m.id,
122
+ summary: truncateSummary(m.summary || m.context),
123
+ project: m.projectPath,
124
+ createdAt: m.createdAt,
125
+ })),
126
+ total: stats.total,
127
+ };
85
128
  },
86
129
  },
87
130
  {
@@ -91,7 +134,11 @@ export function createMemoryFacadeOps(runtime: AgentRuntime): OpDefinition[] {
91
134
  auth: 'write',
92
135
  schema: z.object({
93
136
  projectPath: z.string().optional().default('.'),
94
- summary: z.string().describe('Brief summary of what was accomplished'),
137
+ summary: z.string().optional().describe('Brief summary of what was accomplished'),
138
+ conversationContext: z
139
+ .string()
140
+ .optional()
141
+ .describe('Alias for summary — brief summary of what was accomplished'),
95
142
  topics: z.array(z.string()).optional().default([]),
96
143
  filesModified: z.array(z.string()).optional().default([]),
97
144
  toolsUsed: z.array(z.string()).optional().default([]),
@@ -107,11 +154,15 @@ export function createMemoryFacadeOps(runtime: AgentRuntime): OpDefinition[] {
107
154
  handler: async (params) => {
108
155
  const { resolve } = await import('node:path');
109
156
  const projectPath = resolve((params.projectPath as string) ?? '.');
157
+ const summary = (params.summary ?? params.conversationContext) as string;
158
+ if (!summary) {
159
+ return { captured: false, error: 'Either summary or conversationContext is required.' };
160
+ }
110
161
  const memory = vault.captureMemory({
111
162
  projectPath,
112
163
  type: 'session',
113
164
  context: 'Auto-captured before context compaction',
114
- summary: params.summary as string,
165
+ summary,
115
166
  topics: (params.topics as string[]) ?? [],
116
167
  filesModified: (params.filesModified as string[]) ?? [],
117
168
  toolsUsed: (params.toolsUsed as string[]) ?? [],
@@ -121,6 +172,27 @@ export function createMemoryFacadeOps(runtime: AgentRuntime): OpDefinition[] {
121
172
  nextSteps: (params.nextSteps as string[]) ?? [],
122
173
  vaultEntriesReferenced: (params.vaultEntriesReferenced as string[]) ?? [],
123
174
  });
175
+ // ─── Auto-signal extraction (never breaks session_capture) ───
176
+ try {
177
+ if (runtime.operatorProfile) {
178
+ const sessionData: SessionCaptureData = {
179
+ sessionId: memory.id ?? `session-${Date.now()}`,
180
+ intent: (params.intent as string) ?? null,
181
+ capturedAt: new Date().toISOString(),
182
+ toolsUsed: (params.toolsUsed as string[]) ?? null,
183
+ filesModified: (params.filesModified as string[]) ?? null,
184
+ decisions: (params.decisions as string[]) ?? null,
185
+ summary: summary ?? null,
186
+ };
187
+ const signals = extractFromSession(sessionData);
188
+ if (signals.length > 0) {
189
+ runtime.operatorProfile.accumulateSignals(signals);
190
+ }
191
+ }
192
+ } catch {
193
+ // Signal extraction must never break session_capture
194
+ }
195
+
124
196
  return { captured: true, memory, message: 'Session summary saved to memory.' };
125
197
  },
126
198
  },
@@ -0,0 +1,208 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { Vault } from '../../vault/vault.js';
3
+ import { OperatorProfileStore } from '../../operator/operator-profile.js';
4
+ import { SignalType } from '../../operator/operator-types.js';
5
+ import { createOperatorFacadeOps } from './operator-facade.js';
6
+ import { captureOps, executeOp } from '../../engine/test-helpers.js';
7
+ import type { CapturedOp } from '../../engine/test-helpers.js';
8
+ import type { AgentRuntime } from '../types.js';
9
+
10
+ // ─── Helpers ────────────────────────────────────────────────────────
11
+
12
+ function makeRuntime(vault: Vault, store: OperatorProfileStore): AgentRuntime {
13
+ return { operatorProfile: store, vault } as unknown as AgentRuntime;
14
+ }
15
+
16
+ function makeSignalPayload(type: SignalType = SignalType.CommandStyle) {
17
+ return {
18
+ id: `sig-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
19
+ signalType: type,
20
+ data: { style: 'terse', snippet: 'test' },
21
+ timestamp: new Date().toISOString(),
22
+ sessionId: 'test-session',
23
+ confidence: 0.8,
24
+ };
25
+ }
26
+
27
+ // ─── Tests ──────────────────────────────────────────────────────────
28
+
29
+ describe('operator-facade (colocated)', () => {
30
+ let vault: Vault;
31
+ let store: OperatorProfileStore;
32
+ let ops: Map<string, CapturedOp>;
33
+
34
+ beforeEach(() => {
35
+ vault = new Vault(':memory:');
36
+ store = new OperatorProfileStore(vault);
37
+ ops = captureOps(createOperatorFacadeOps(makeRuntime(vault, store)));
38
+ });
39
+
40
+ afterEach(() => {
41
+ vault.close();
42
+ });
43
+
44
+ it('registers all 10 ops', () => {
45
+ expect(ops.size).toBe(10);
46
+ expect([...ops.keys()]).toEqual(
47
+ expect.arrayContaining([
48
+ 'profile_get', 'profile_update_section', 'profile_correct',
49
+ 'profile_delete', 'profile_export', 'signal_accumulate',
50
+ 'signal_list', 'signal_stats', 'synthesis_check', 'profile_snapshot',
51
+ ]),
52
+ );
53
+ });
54
+
55
+ it('has correct auth levels', () => {
56
+ expect(ops.get('profile_get')!.auth).toBe('read');
57
+ expect(ops.get('profile_update_section')!.auth).toBe('write');
58
+ expect(ops.get('profile_correct')!.auth).toBe('write');
59
+ expect(ops.get('profile_delete')!.auth).toBe('admin');
60
+ expect(ops.get('profile_export')!.auth).toBe('read');
61
+ expect(ops.get('signal_accumulate')!.auth).toBe('write');
62
+ expect(ops.get('signal_list')!.auth).toBe('read');
63
+ expect(ops.get('signal_stats')!.auth).toBe('read');
64
+ expect(ops.get('synthesis_check')!.auth).toBe('read');
65
+ expect(ops.get('profile_snapshot')!.auth).toBe('write');
66
+ });
67
+
68
+ // ─── profile_get ───────────────────────────────────────────────
69
+
70
+ it('profile_get returns null when no profile', async () => {
71
+ const result = await executeOp(ops, 'profile_get', {});
72
+ expect(result.success).toBe(true);
73
+ expect((result.data as { profile: null }).profile).toBeNull();
74
+ });
75
+
76
+ it('profile_get returns specific section', async () => {
77
+ store.accumulateSignals([makeSignalPayload() as never]);
78
+ const result = await executeOp(ops, 'profile_get', { section: 'communication' });
79
+ expect(result.success).toBe(true);
80
+ expect((result.data as { section: string }).section).toBe('communication');
81
+ });
82
+
83
+ // ─── profile_update_section ────────────────────────────────────
84
+
85
+ it('profile_update_section updates section', async () => {
86
+ const result = await executeOp(ops, 'profile_update_section', {
87
+ section: 'communication',
88
+ data: { style: 'concise', signalWords: ['yo'], formality: 0.3, patience: 0.9, adaptationRules: [] },
89
+ });
90
+ expect(result.success).toBe(true);
91
+ expect((result.data as Record<string, unknown>).updated).toBe(true);
92
+ });
93
+
94
+ // ─── profile_correct ──────────────────────────────────────────
95
+
96
+ it('profile_correct takes snapshot before correcting', async () => {
97
+ store.accumulateSignals([makeSignalPayload() as never]);
98
+ const result = await executeOp(ops, 'profile_correct', {
99
+ section: 'identity',
100
+ data: { background: 'engineer', role: 'lead', philosophy: 'pragmatism', evidence: [] },
101
+ reason: 'User correction',
102
+ });
103
+ expect(result.success).toBe(true);
104
+ expect((result.data as Record<string, unknown>).corrected).toBe(true);
105
+ });
106
+
107
+ // ─── profile_delete ────────────────────────────────────────────
108
+
109
+ it('profile_delete removes profile', async () => {
110
+ store.accumulateSignals([makeSignalPayload() as never]);
111
+ const result = await executeOp(ops, 'profile_delete', {});
112
+ expect(result.success).toBe(true);
113
+ expect((result.data as Record<string, unknown>).deleted).toBe(true);
114
+ expect(store.getProfile()).toBeNull();
115
+ });
116
+
117
+ it('profile_delete returns false when no profile', async () => {
118
+ const result = await executeOp(ops, 'profile_delete', {});
119
+ expect(result.success).toBe(true);
120
+ expect((result.data as Record<string, unknown>).deleted).toBe(false);
121
+ });
122
+
123
+ // ─── profile_export ────────────────────────────────────────────
124
+
125
+ it('profile_export returns JSON by default', async () => {
126
+ store.accumulateSignals([makeSignalPayload() as never]);
127
+ const result = await executeOp(ops, 'profile_export', {});
128
+ expect(result.success).toBe(true);
129
+ const data = result.data as { exported: boolean; format: string; content: string };
130
+ expect(data.exported).toBe(true);
131
+ expect(data.format).toBe('json');
132
+ expect(() => JSON.parse(data.content)).not.toThrow();
133
+ });
134
+
135
+ it('profile_export returns markdown', async () => {
136
+ store.accumulateSignals([makeSignalPayload() as never]);
137
+ const result = await executeOp(ops, 'profile_export', { format: 'markdown' });
138
+ expect(result.success).toBe(true);
139
+ expect((result.data as { content: string }).content).toContain('# Operator Profile');
140
+ });
141
+
142
+ it('profile_export handles missing profile', async () => {
143
+ const result = await executeOp(ops, 'profile_export', {});
144
+ expect(result.success).toBe(true);
145
+ expect((result.data as Record<string, unknown>).exported).toBe(false);
146
+ });
147
+
148
+ // ─── signal_accumulate ─────────────────────────────────────────
149
+
150
+ it('signal_accumulate stores signals', async () => {
151
+ const signals = [makeSignalPayload(), makeSignalPayload(SignalType.Frustration)];
152
+ signals[1].data = { level: 'mild', trigger: 'slow', context: 'test' };
153
+ const result = await executeOp(ops, 'signal_accumulate', { signals });
154
+ expect(result.success).toBe(true);
155
+ expect((result.data as Record<string, unknown>).stored).toBe(2);
156
+ });
157
+
158
+ // ─── signal_list ───────────────────────────────────────────────
159
+
160
+ it('signal_list returns stored signals', async () => {
161
+ store.accumulateSignals([makeSignalPayload() as never]);
162
+ const result = await executeOp(ops, 'signal_list', {});
163
+ expect(result.success).toBe(true);
164
+ expect((result.data as Record<string, unknown>).count).toBe(1);
165
+ });
166
+
167
+ it('signal_list filters by type', async () => {
168
+ store.accumulateSignals([makeSignalPayload(SignalType.CommandStyle) as never]);
169
+ store.accumulateSignals([makeSignalPayload(SignalType.Frustration) as never]);
170
+ const result = await executeOp(ops, 'signal_list', { types: ['command_style'] });
171
+ expect(result.success).toBe(true);
172
+ expect((result.data as Record<string, unknown>).count).toBe(1);
173
+ });
174
+
175
+ // ─── signal_stats ──────────────────────────────────────────────
176
+
177
+ it('signal_stats returns breakdown', async () => {
178
+ store.accumulateSignals([makeSignalPayload() as never, makeSignalPayload() as never]);
179
+ const result = await executeOp(ops, 'signal_stats', {});
180
+ expect(result.success).toBe(true);
181
+ const data = result.data as { byType: Record<string, number>; totalUnprocessed: number };
182
+ expect(data.totalUnprocessed).toBe(2);
183
+ });
184
+
185
+ // ─── synthesis_check ───────────────────────────────────────────
186
+
187
+ it('synthesis_check reports not due with few signals', async () => {
188
+ store.accumulateSignals([makeSignalPayload() as never]);
189
+ const result = await executeOp(ops, 'synthesis_check', {});
190
+ expect(result.success).toBe(true);
191
+ expect((result.data as Record<string, unknown>).due).toBe(false);
192
+ });
193
+
194
+ // ─── profile_snapshot ──────────────────────────────────────────
195
+
196
+ it('profile_snapshot creates version', async () => {
197
+ store.accumulateSignals([makeSignalPayload() as never]);
198
+ const result = await executeOp(ops, 'profile_snapshot', { trigger: 'manual' });
199
+ expect(result.success).toBe(true);
200
+ expect((result.data as Record<string, unknown>).snapshotted).toBe(true);
201
+ });
202
+
203
+ it('profile_snapshot returns false when no profile', async () => {
204
+ const result = await executeOp(ops, 'profile_snapshot', { trigger: 'test' });
205
+ expect(result.success).toBe(true);
206
+ expect((result.data as Record<string, unknown>).snapshotted).toBe(false);
207
+ });
208
+ });