@soleri/core 9.2.0 → 9.3.1

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 (316) 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/curator/curator.d.ts.map +1 -1
  10. package/dist/curator/curator.js +98 -22
  11. package/dist/curator/curator.js.map +1 -1
  12. package/dist/engine/bin/soleri-engine.js.map +1 -1
  13. package/dist/engine/module-manifest.d.ts +2 -0
  14. package/dist/engine/module-manifest.d.ts.map +1 -1
  15. package/dist/engine/module-manifest.js +136 -1
  16. package/dist/engine/module-manifest.js.map +1 -1
  17. package/dist/engine/register-engine.d.ts.map +1 -1
  18. package/dist/engine/register-engine.js +25 -1
  19. package/dist/engine/register-engine.js.map +1 -1
  20. package/dist/flows/gate-evaluator.js.map +1 -1
  21. package/dist/index.d.ts +2 -0
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +2 -0
  24. package/dist/index.js.map +1 -1
  25. package/dist/operator/operator-profile.d.ts.map +1 -1
  26. package/dist/operator/operator-profile.js +11 -5
  27. package/dist/operator/operator-profile.js.map +1 -1
  28. package/dist/operator/operator-signals.d.ts.map +1 -1
  29. package/dist/operator/operator-signals.js.map +1 -1
  30. package/dist/planning/evidence-collector.js.map +1 -1
  31. package/dist/planning/gap-passes.d.ts.map +1 -1
  32. package/dist/planning/gap-passes.js +23 -6
  33. package/dist/planning/gap-passes.js.map +1 -1
  34. package/dist/planning/gap-patterns.d.ts.map +1 -1
  35. package/dist/planning/gap-patterns.js +57 -11
  36. package/dist/planning/gap-patterns.js.map +1 -1
  37. package/dist/planning/github-projection.d.ts.map +1 -1
  38. package/dist/planning/github-projection.js +39 -20
  39. package/dist/planning/github-projection.js.map +1 -1
  40. package/dist/planning/impact-analyzer.d.ts.map +1 -1
  41. package/dist/planning/impact-analyzer.js +20 -18
  42. package/dist/planning/impact-analyzer.js.map +1 -1
  43. package/dist/planning/plan-lifecycle.d.ts.map +1 -1
  44. package/dist/planning/plan-lifecycle.js +22 -9
  45. package/dist/planning/plan-lifecycle.js.map +1 -1
  46. package/dist/planning/planner.d.ts.map +1 -1
  47. package/dist/planning/planner.js +60 -17
  48. package/dist/planning/planner.js.map +1 -1
  49. package/dist/planning/rationalization-detector.d.ts.map +1 -1
  50. package/dist/planning/rationalization-detector.js.map +1 -1
  51. package/dist/planning/reconciliation-engine.d.ts.map +1 -1
  52. package/dist/planning/reconciliation-engine.js.map +1 -1
  53. package/dist/planning/task-complexity-assessor.d.ts +42 -0
  54. package/dist/planning/task-complexity-assessor.d.ts.map +1 -0
  55. package/dist/planning/task-complexity-assessor.js +132 -0
  56. package/dist/planning/task-complexity-assessor.js.map +1 -0
  57. package/dist/planning/task-verifier.d.ts.map +1 -1
  58. package/dist/planning/task-verifier.js +14 -6
  59. package/dist/planning/task-verifier.js.map +1 -1
  60. package/dist/runtime/admin-ops.d.ts.map +1 -1
  61. package/dist/runtime/admin-ops.js +18 -0
  62. package/dist/runtime/admin-ops.js.map +1 -1
  63. package/dist/runtime/admin-setup-ops.d.ts.map +1 -1
  64. package/dist/runtime/admin-setup-ops.js +2 -1
  65. package/dist/runtime/admin-setup-ops.js.map +1 -1
  66. package/dist/runtime/branching-ops.d.ts +12 -0
  67. package/dist/runtime/branching-ops.d.ts.map +1 -0
  68. package/dist/runtime/branching-ops.js +100 -0
  69. package/dist/runtime/branching-ops.js.map +1 -0
  70. package/dist/runtime/context-health.d.ts.map +1 -1
  71. package/dist/runtime/context-health.js.map +1 -1
  72. package/dist/runtime/facades/branching-facade.d.ts +7 -0
  73. package/dist/runtime/facades/branching-facade.d.ts.map +1 -0
  74. package/dist/runtime/facades/branching-facade.js +8 -0
  75. package/dist/runtime/facades/branching-facade.js.map +1 -0
  76. package/dist/runtime/facades/chat-service-ops.d.ts.map +1 -1
  77. package/dist/runtime/facades/chat-service-ops.js +3 -1
  78. package/dist/runtime/facades/chat-service-ops.js.map +1 -1
  79. package/dist/runtime/facades/chat-transport-ops.d.ts.map +1 -1
  80. package/dist/runtime/facades/chat-transport-ops.js.map +1 -1
  81. package/dist/runtime/facades/index.d.ts.map +1 -1
  82. package/dist/runtime/facades/index.js +42 -0
  83. package/dist/runtime/facades/index.js.map +1 -1
  84. package/dist/runtime/facades/intake-facade.d.ts +9 -0
  85. package/dist/runtime/facades/intake-facade.d.ts.map +1 -0
  86. package/dist/runtime/facades/intake-facade.js +11 -0
  87. package/dist/runtime/facades/intake-facade.js.map +1 -0
  88. package/dist/runtime/facades/links-facade.d.ts +9 -0
  89. package/dist/runtime/facades/links-facade.d.ts.map +1 -0
  90. package/dist/runtime/facades/links-facade.js +10 -0
  91. package/dist/runtime/facades/links-facade.js.map +1 -0
  92. package/dist/runtime/facades/operator-facade.d.ts.map +1 -1
  93. package/dist/runtime/facades/operator-facade.js.map +1 -1
  94. package/dist/runtime/facades/plan-facade.d.ts.map +1 -1
  95. package/dist/runtime/facades/plan-facade.js +4 -1
  96. package/dist/runtime/facades/plan-facade.js.map +1 -1
  97. package/dist/runtime/facades/tier-facade.d.ts +7 -0
  98. package/dist/runtime/facades/tier-facade.d.ts.map +1 -0
  99. package/dist/runtime/facades/tier-facade.js +8 -0
  100. package/dist/runtime/facades/tier-facade.js.map +1 -0
  101. package/dist/runtime/facades/vault-facade.d.ts +9 -1
  102. package/dist/runtime/facades/vault-facade.d.ts.map +1 -1
  103. package/dist/runtime/facades/vault-facade.js +44 -187
  104. package/dist/runtime/facades/vault-facade.js.map +1 -1
  105. package/dist/runtime/github-integration.d.ts.map +1 -1
  106. package/dist/runtime/github-integration.js +11 -4
  107. package/dist/runtime/github-integration.js.map +1 -1
  108. package/dist/runtime/orchestrate-ops.d.ts.map +1 -1
  109. package/dist/runtime/orchestrate-ops.js +75 -42
  110. package/dist/runtime/orchestrate-ops.js.map +1 -1
  111. package/dist/runtime/planning-extra-ops.d.ts.map +1 -1
  112. package/dist/runtime/planning-extra-ops.js.map +1 -1
  113. package/dist/runtime/runtime.d.ts.map +1 -1
  114. package/dist/runtime/runtime.js +3 -1
  115. package/dist/runtime/runtime.js.map +1 -1
  116. package/dist/runtime/session-briefing.d.ts.map +1 -1
  117. package/dist/runtime/session-briefing.js +5 -1
  118. package/dist/runtime/session-briefing.js.map +1 -1
  119. package/dist/runtime/tier-ops.d.ts +13 -0
  120. package/dist/runtime/tier-ops.d.ts.map +1 -0
  121. package/dist/runtime/tier-ops.js +110 -0
  122. package/dist/runtime/tier-ops.js.map +1 -0
  123. package/dist/skills/sync-skills.d.ts.map +1 -1
  124. package/dist/skills/sync-skills.js +1 -1
  125. package/dist/skills/sync-skills.js.map +1 -1
  126. package/dist/vault/linking.d.ts.map +1 -1
  127. package/dist/vault/linking.js +41 -5
  128. package/dist/vault/linking.js.map +1 -1
  129. package/dist/vault/vault-entries.d.ts.map +1 -1
  130. package/dist/vault/vault-entries.js +68 -26
  131. package/dist/vault/vault-entries.js.map +1 -1
  132. package/dist/vault/vault-maintenance.d.ts.map +1 -1
  133. package/dist/vault/vault-maintenance.js +6 -2
  134. package/dist/vault/vault-maintenance.js.map +1 -1
  135. package/dist/vault/vault-markdown-sync.d.ts.map +1 -1
  136. package/dist/vault/vault-markdown-sync.js.map +1 -1
  137. package/dist/vault/vault-memories.d.ts.map +1 -1
  138. package/dist/vault/vault-memories.js +3 -1
  139. package/dist/vault/vault-memories.js.map +1 -1
  140. package/dist/vault/vault-schema.js +36 -10
  141. package/dist/vault/vault-schema.js.map +1 -1
  142. package/dist/vault/vault.d.ts.map +1 -1
  143. package/dist/vault/vault.js +5 -1
  144. package/dist/vault/vault.js.map +1 -1
  145. package/package.json +7 -7
  146. package/src/agency/agency-manager.test.ts +60 -40
  147. package/src/agency/default-rules.test.ts +17 -9
  148. package/src/capabilities/registry.test.ts +2 -12
  149. package/src/chat/agent-loop.test.ts +33 -43
  150. package/src/chat/mcp-bridge.test.ts +7 -2
  151. package/src/claudemd/inject.test.ts +2 -12
  152. package/src/context/context-engine.test.ts +96 -51
  153. package/src/control/intent-router.test.ts +3 -3
  154. package/src/curator/classifier.test.ts +14 -8
  155. package/src/curator/contradiction-detector.test.ts +30 -5
  156. package/src/curator/curator.ts +278 -56
  157. package/src/curator/duplicate-detector.test.ts +77 -15
  158. package/src/curator/quality-gate.test.ts +71 -31
  159. package/src/curator/tag-manager.test.ts +12 -4
  160. package/src/domain-packs/knowledge-installer.test.ts +2 -10
  161. package/src/domain-packs/token-resolver.test.ts +1 -3
  162. package/src/domain-packs/types.test.ts +16 -2
  163. package/src/enforcement/registry.test.ts +2 -8
  164. package/src/engine/bin/soleri-engine.ts +3 -1
  165. package/src/engine/module-manifest.test.ts +48 -4
  166. package/src/engine/module-manifest.ts +138 -1
  167. package/src/engine/register-engine.test.ts +6 -1
  168. package/src/engine/register-engine.ts +26 -3
  169. package/src/errors/classify.test.ts +6 -2
  170. package/src/errors/retry.test.ts +1 -4
  171. package/src/facades/facade-factory.test.ts +110 -64
  172. package/src/flows/epilogue.test.ts +16 -10
  173. package/src/flows/gate-evaluator.test.ts +12 -6
  174. package/src/flows/gate-evaluator.ts +1 -3
  175. package/src/governance/governance.test.ts +137 -21
  176. package/src/health/health-registry.test.ts +8 -1
  177. package/src/index.ts +8 -0
  178. package/src/intake/content-classifier.test.ts +121 -51
  179. package/src/intake/dedup-gate.test.ts +38 -22
  180. package/src/intake/intake-pipeline.test.ts +5 -3
  181. package/src/intake/text-ingester.test.ts +26 -20
  182. package/src/llm/key-pool.test.ts +1 -3
  183. package/src/llm/llm-client.test.ts +1 -4
  184. package/src/llm/oauth-discovery.test.ts +16 -16
  185. package/src/llm/utils.test.ts +62 -18
  186. package/src/logging/logger.test.ts +4 -1
  187. package/src/loop/loop-manager.test.ts +2 -6
  188. package/src/migrations/migration-runner.edge-cases.test.ts +2 -7
  189. package/src/operator/operator-profile-extended.test.ts +15 -5
  190. package/src/operator/operator-profile.test.ts +26 -8
  191. package/src/operator/operator-profile.ts +38 -22
  192. package/src/operator/operator-signals-extended.test.ts +35 -23
  193. package/src/operator/operator-signals.test.ts +6 -10
  194. package/src/operator/operator-signals.ts +2 -1
  195. package/src/operator/prompts/hook-precompact-operator-dispatch.md +10 -6
  196. package/src/operator/prompts/subagent-soft-signal-extractor.md +5 -0
  197. package/src/operator/prompts/subagent-synthesis-cognition.md +19 -10
  198. package/src/operator/prompts/subagent-synthesis-communication.md +13 -7
  199. package/src/operator/prompts/subagent-synthesis-technical.md +19 -9
  200. package/src/operator/prompts/subagent-synthesis-trust.md +27 -21
  201. package/src/persona/defaults.test.ts +1 -5
  202. package/src/planning/evidence-collector.test.ts +147 -38
  203. package/src/planning/evidence-collector.ts +1 -4
  204. package/src/planning/gap-analysis-alternatives.test.ts +41 -11
  205. package/src/planning/gap-passes.test.ts +215 -33
  206. package/src/planning/gap-passes.ts +115 -46
  207. package/src/planning/gap-patterns.test.ts +87 -13
  208. package/src/planning/gap-patterns.ts +114 -31
  209. package/src/planning/github-projection.test.ts +6 -1
  210. package/src/planning/github-projection.ts +41 -20
  211. package/src/planning/impact-analyzer.test.ts +10 -23
  212. package/src/planning/impact-analyzer.ts +33 -46
  213. package/src/planning/plan-lifecycle.test.ts +103 -36
  214. package/src/planning/plan-lifecycle.ts +49 -18
  215. package/src/planning/planner.test.ts +12 -2
  216. package/src/planning/planner.ts +198 -58
  217. package/src/planning/rationalization-detector.test.ts +5 -20
  218. package/src/planning/rationalization-detector.ts +14 -16
  219. package/src/planning/reconciliation-engine.test.ts +20 -3
  220. package/src/planning/reconciliation-engine.ts +1 -2
  221. package/src/planning/task-complexity-assessor.test.ts +298 -0
  222. package/src/planning/task-complexity-assessor.ts +183 -0
  223. package/src/planning/task-verifier.test.ts +59 -27
  224. package/src/planning/task-verifier.ts +15 -9
  225. package/src/playbooks/playbook-executor.test.ts +1 -3
  226. package/src/plugins/plugin-loader.test.ts +19 -14
  227. package/src/plugins/plugin-registry.test.ts +45 -33
  228. package/src/project/project-registry.test.ts +23 -12
  229. package/src/prompts/template-manager.test.ts +4 -1
  230. package/src/queue/job-queue.test.ts +10 -14
  231. package/src/runtime/admin-extra-ops.test.ts +5 -19
  232. package/src/runtime/admin-ops.test.ts +22 -1
  233. package/src/runtime/admin-ops.ts +19 -0
  234. package/src/runtime/admin-setup-ops.test.ts +3 -4
  235. package/src/runtime/admin-setup-ops.ts +9 -2
  236. package/src/runtime/archive-ops.test.ts +4 -1
  237. package/src/runtime/branching-ops.test.ts +144 -0
  238. package/src/runtime/branching-ops.ts +107 -0
  239. package/src/runtime/capture-ops.test.ts +7 -21
  240. package/src/runtime/chain-ops.test.ts +16 -6
  241. package/src/runtime/claude-md-helpers.test.ts +1 -3
  242. package/src/runtime/context-health.test.ts +1 -3
  243. package/src/runtime/context-health.ts +1 -3
  244. package/src/runtime/curator-extra-ops.test.ts +3 -1
  245. package/src/runtime/domain-ops.test.ts +46 -36
  246. package/src/runtime/facades/admin-facade.test.ts +1 -4
  247. package/src/runtime/facades/archive-facade.test.ts +21 -7
  248. package/src/runtime/facades/brain-facade.test.ts +176 -72
  249. package/src/runtime/facades/branching-facade.test.ts +43 -0
  250. package/src/runtime/facades/branching-facade.ts +11 -0
  251. package/src/runtime/facades/chat-facade.test.ts +81 -28
  252. package/src/runtime/facades/chat-service-ops.test.ts +178 -73
  253. package/src/runtime/facades/chat-service-ops.ts +3 -1
  254. package/src/runtime/facades/chat-session-ops.test.ts +25 -10
  255. package/src/runtime/facades/chat-transport-ops.test.ts +101 -34
  256. package/src/runtime/facades/chat-transport-ops.ts +0 -1
  257. package/src/runtime/facades/context-facade.test.ts +19 -4
  258. package/src/runtime/facades/control-facade.test.ts +3 -3
  259. package/src/runtime/facades/index.ts +42 -0
  260. package/src/runtime/facades/intake-facade.test.ts +215 -0
  261. package/src/runtime/facades/intake-facade.ts +14 -0
  262. package/src/runtime/facades/links-facade.test.ts +203 -0
  263. package/src/runtime/facades/links-facade.ts +13 -0
  264. package/src/runtime/facades/loop-facade.test.ts +22 -5
  265. package/src/runtime/facades/memory-facade.test.ts +19 -5
  266. package/src/runtime/facades/operator-facade.test.ts +17 -4
  267. package/src/runtime/facades/operator-facade.ts +11 -3
  268. package/src/runtime/facades/orchestrate-facade.test.ts +7 -1
  269. package/src/runtime/facades/plan-facade.test.ts +29 -12
  270. package/src/runtime/facades/plan-facade.ts +7 -2
  271. package/src/runtime/facades/tier-facade.test.ts +47 -0
  272. package/src/runtime/facades/tier-facade.ts +11 -0
  273. package/src/runtime/facades/vault-facade.test.ts +174 -242
  274. package/src/runtime/facades/vault-facade.ts +55 -199
  275. package/src/runtime/github-integration.ts +11 -8
  276. package/src/runtime/grading-ops.test.ts +39 -8
  277. package/src/runtime/intake-ops.test.ts +69 -16
  278. package/src/runtime/loop-ops.test.ts +16 -6
  279. package/src/runtime/memory-cross-project-ops.test.ts +25 -14
  280. package/src/runtime/orchestrate-ops.test.ts +204 -0
  281. package/src/runtime/orchestrate-ops.ts +103 -65
  282. package/src/runtime/pack-ops.test.ts +23 -6
  283. package/src/runtime/planning-extra-ops.test.ts +17 -7
  284. package/src/runtime/planning-extra-ops.ts +3 -1
  285. package/src/runtime/playbook-ops.test.ts +26 -3
  286. package/src/runtime/plugin-ops.test.ts +83 -25
  287. package/src/runtime/project-ops.test.ts +26 -6
  288. package/src/runtime/runtime.ts +3 -1
  289. package/src/runtime/session-briefing.test.ts +183 -54
  290. package/src/runtime/session-briefing.ts +8 -2
  291. package/src/runtime/sync-ops.test.ts +3 -12
  292. package/src/runtime/telemetry-ops.test.ts +31 -6
  293. package/src/runtime/tier-ops.test.ts +159 -0
  294. package/src/runtime/tier-ops.ts +119 -0
  295. package/src/runtime/vault-extra-ops.test.ts +32 -8
  296. package/src/runtime/vault-sharing-ops.test.ts +1 -4
  297. package/src/skills/sync-skills.ts +2 -12
  298. package/src/transport/ws-server.test.ts +7 -4
  299. package/src/vault/__tests__/vault-characterization.test.ts +492 -81
  300. package/src/vault/linking.test.ts +50 -17
  301. package/src/vault/linking.ts +48 -7
  302. package/src/vault/obsidian-sync.test.ts +6 -3
  303. package/src/vault/scope-detector.test.ts +1 -3
  304. package/src/vault/vault-branching.test.ts +9 -7
  305. package/src/vault/vault-entries.ts +209 -65
  306. package/src/vault/vault-maintenance.ts +7 -12
  307. package/src/vault/vault-manager.test.ts +10 -10
  308. package/src/vault/vault-markdown-sync.ts +4 -1
  309. package/src/vault/vault-memories.ts +7 -7
  310. package/src/vault/vault-scaling.test.ts +5 -5
  311. package/src/vault/vault-schema.ts +72 -15
  312. package/src/vault/vault.ts +55 -9
  313. package/src/brain/strength-scorer.ts +0 -404
  314. package/src/engine/index.ts +0 -21
  315. package/src/persona/index.ts +0 -9
  316. package/src/vault/vault-interfaces.ts +0 -56
@@ -95,7 +95,9 @@ describe('classifyError', () => {
95
95
 
96
96
  describe('message pattern classification', () => {
97
97
  it('should classify "overloaded" as LLM_OVERLOAD', () => {
98
- expect(classifyError(new Error('server is overloaded')).code).toBe(SoleriErrorCode.LLM_OVERLOAD);
98
+ expect(classifyError(new Error('server is overloaded')).code).toBe(
99
+ SoleriErrorCode.LLM_OVERLOAD,
100
+ );
99
101
  });
100
102
 
101
103
  it('should classify "model busy" as LLM_OVERLOAD', () => {
@@ -123,7 +125,9 @@ describe('classifyError', () => {
123
125
  });
124
126
 
125
127
  it('should classify "not found" as RESOURCE_NOT_FOUND', () => {
126
- expect(classifyError(new Error('resource not found')).code).toBe(SoleriErrorCode.RESOURCE_NOT_FOUND);
128
+ expect(classifyError(new Error('resource not found')).code).toBe(
129
+ SoleriErrorCode.RESOURCE_NOT_FOUND,
130
+ );
127
131
  });
128
132
 
129
133
  it('should classify "rate limit" as RATE_LIMIT', () => {
@@ -118,10 +118,7 @@ describe('retryWithPreset', () => {
118
118
 
119
119
  it('should call onRetry callback on each retry', async () => {
120
120
  const onRetry = vi.fn();
121
- const fn = vi
122
- .fn()
123
- .mockRejectedValueOnce(new Error('network fail'))
124
- .mockResolvedValue('ok');
121
+ const fn = vi.fn().mockRejectedValueOnce(new Error('network fail')).mockResolvedValue('ok');
125
122
 
126
123
  const resultPromise = retryWithPreset(fn, 'fast', { onRetry });
127
124
  await vi.advanceTimersByTimeAsync(20_000);
@@ -88,12 +88,16 @@ describe('facade-factory dispatchOp — colocated', () => {
88
88
 
89
89
  it('catches handler exceptions and returns error response', async () => {
90
90
  const facade = createFacade({
91
- ops: [{
92
- name: 'failing_op',
93
- description: 'Fails',
94
- auth: 'read',
95
- handler: async () => { throw new Error('Handler exploded'); },
96
- }],
91
+ ops: [
92
+ {
93
+ name: 'failing_op',
94
+ description: 'Fails',
95
+ auth: 'read',
96
+ handler: async () => {
97
+ throw new Error('Handler exploded');
98
+ },
99
+ },
100
+ ],
97
101
  });
98
102
  const handler = captureHandler(facade);
99
103
 
@@ -105,12 +109,16 @@ describe('facade-factory dispatchOp — colocated', () => {
105
109
 
106
110
  it('catches non-Error throws and converts to string', async () => {
107
111
  const facade = createFacade({
108
- ops: [{
109
- name: 'string_throw',
110
- description: 'Throws string',
111
- auth: 'read',
112
- handler: async () => { throw 'raw string error'; },
113
- }],
112
+ ops: [
113
+ {
114
+ name: 'string_throw',
115
+ description: 'Throws string',
116
+ auth: 'read',
117
+ handler: async () => {
118
+ throw 'raw string error';
119
+ },
120
+ },
121
+ ],
114
122
  });
115
123
  const handler = captureHandler(facade);
116
124
 
@@ -128,13 +136,15 @@ describe('facade-factory dispatchOp — colocated', () => {
128
136
  describe('facade-factory schema validation — colocated', () => {
129
137
  it('validates params against op schema and rejects invalid', async () => {
130
138
  const facade = createFacade({
131
- ops: [{
132
- name: 'validated_op',
133
- description: 'Has schema',
134
- auth: 'read',
135
- schema: z.object({ query: z.string(), limit: z.number() }),
136
- handler: async (params) => ({ echo: params }),
137
- }],
139
+ ops: [
140
+ {
141
+ name: 'validated_op',
142
+ description: 'Has schema',
143
+ auth: 'read',
144
+ schema: z.object({ query: z.string(), limit: z.number() }),
145
+ handler: async (params) => ({ echo: params }),
146
+ },
147
+ ],
138
148
  });
139
149
  const handler = captureHandler(facade);
140
150
 
@@ -146,13 +156,15 @@ describe('facade-factory schema validation — colocated', () => {
146
156
 
147
157
  it('passes validated params to handler', async () => {
148
158
  const facade = createFacade({
149
- ops: [{
150
- name: 'validated_op',
151
- description: 'Has schema',
152
- auth: 'read',
153
- schema: z.object({ query: z.string(), limit: z.number().optional() }),
154
- handler: async (params) => ({ echo: params }),
155
- }],
159
+ ops: [
160
+ {
161
+ name: 'validated_op',
162
+ description: 'Has schema',
163
+ auth: 'read',
164
+ schema: z.object({ query: z.string(), limit: z.number().optional() }),
165
+ handler: async (params) => ({ echo: params }),
166
+ },
167
+ ],
156
168
  });
157
169
  const handler = captureHandler(facade);
158
170
 
@@ -164,12 +176,14 @@ describe('facade-factory schema validation — colocated', () => {
164
176
 
165
177
  it('passes raw params when no schema defined', async () => {
166
178
  const facade = createFacade({
167
- ops: [{
168
- name: 'no_schema',
169
- description: 'No schema',
170
- auth: 'read',
171
- handler: async (params) => ({ echo: params }),
172
- }],
179
+ ops: [
180
+ {
181
+ name: 'no_schema',
182
+ description: 'No schema',
183
+ auth: 'read',
184
+ handler: async (params) => ({ echo: params }),
185
+ },
186
+ ],
173
187
  });
174
188
  const handler = captureHandler(facade);
175
189
 
@@ -255,7 +269,9 @@ describe('registerAllFacades — colocated', () => {
255
269
  it('registers all facades on the server', () => {
256
270
  const registered: string[] = [];
257
271
  const mockServer = {
258
- tool: (name: string) => { registered.push(name); },
272
+ tool: (name: string) => {
273
+ registered.push(name);
274
+ },
259
275
  };
260
276
 
261
277
  registerAllFacades(mockServer as never, [
@@ -270,7 +286,9 @@ describe('registerAllFacades — colocated', () => {
270
286
  it('accepts legacy function auth policy', () => {
271
287
  const registered: string[] = [];
272
288
  const mockServer = {
273
- tool: (name: string) => { registered.push(name); },
289
+ tool: (name: string) => {
290
+ registered.push(name);
291
+ },
274
292
  };
275
293
 
276
294
  registerAllFacades(mockServer as never, [createFacade()], () => ({
@@ -284,12 +302,20 @@ describe('registerAllFacades — colocated', () => {
284
302
  it('promotes hot ops to standalone tools with agentId prefix', () => {
285
303
  const registered: string[] = [];
286
304
  const mockServer = {
287
- tool: (name: string) => { registered.push(name); },
305
+ tool: (name: string) => {
306
+ registered.push(name);
307
+ },
288
308
  };
289
309
 
290
310
  const facade = createFacade({
291
311
  ops: [
292
- { name: 'search', description: 'Search', auth: 'read', hot: true, handler: async () => ({}) },
312
+ {
313
+ name: 'search',
314
+ description: 'Search',
315
+ auth: 'read',
316
+ hot: true,
317
+ handler: async () => ({}),
318
+ },
293
319
  { name: 'delete', description: 'Delete', auth: 'admin', handler: async () => ({}) },
294
320
  ],
295
321
  });
@@ -304,7 +330,9 @@ describe('registerAllFacades — colocated', () => {
304
330
  it('promotes ops listed in hotOps option', () => {
305
331
  const registered: string[] = [];
306
332
  const mockServer = {
307
- tool: (name: string) => { registered.push(name); },
333
+ tool: (name: string) => {
334
+ registered.push(name);
335
+ },
308
336
  };
309
337
 
310
338
  registerAllFacades(mockServer as never, [createFacade()], {
@@ -319,12 +347,20 @@ describe('registerAllFacades — colocated', () => {
319
347
  it('does not promote hot ops without agentId', () => {
320
348
  const registered: string[] = [];
321
349
  const mockServer = {
322
- tool: (name: string) => { registered.push(name); },
350
+ tool: (name: string) => {
351
+ registered.push(name);
352
+ },
323
353
  };
324
354
 
325
355
  const facade = createFacade({
326
356
  ops: [
327
- { name: 'search', description: 'Search', auth: 'read', hot: true, handler: async () => ({}) },
357
+ {
358
+ name: 'search',
359
+ description: 'Search',
360
+ auth: 'read',
361
+ hot: true,
362
+ handler: async () => ({}),
363
+ },
328
364
  ],
329
365
  });
330
366
 
@@ -344,20 +380,24 @@ describe('registerAllFacades — colocated', () => {
344
380
  };
345
381
 
346
382
  const facade = createFacade({
347
- ops: [{
348
- name: 'search',
349
- description: 'Search',
350
- auth: 'read',
351
- hot: true,
352
- schema: z.object({ query: z.string() }),
353
- handler: async (params) => ({ results: [], query: (params as { query: string }).query }),
354
- }],
383
+ ops: [
384
+ {
385
+ name: 'search',
386
+ description: 'Search',
387
+ auth: 'read',
388
+ hot: true,
389
+ schema: z.object({ query: z.string() }),
390
+ handler: async (params) => ({ results: [], query: (params as { query: string }).query }),
391
+ },
392
+ ],
355
393
  });
356
394
 
357
395
  registerAllFacades(mockServer as never, [facade], { agentId: 'agent' });
358
396
 
359
397
  expect(capturedHandler).not.toBeNull();
360
- const result = await capturedHandler!({ query: 'hello' }) as { content: Array<{ text: string }> };
398
+ const result = (await capturedHandler!({ query: 'hello' })) as {
399
+ content: Array<{ text: string }>;
400
+ };
361
401
  const parsed = JSON.parse(result.content[0].text);
362
402
  expect(parsed.success).toBe(true);
363
403
  expect(parsed.data.query).toBe('hello');
@@ -374,18 +414,22 @@ describe('registerAllFacades — colocated', () => {
374
414
  };
375
415
 
376
416
  const facade = createFacade({
377
- ops: [{
378
- name: 'boom',
379
- description: 'Explodes',
380
- auth: 'read',
381
- hot: true,
382
- handler: async () => { throw new Error('Kaboom'); },
383
- }],
417
+ ops: [
418
+ {
419
+ name: 'boom',
420
+ description: 'Explodes',
421
+ auth: 'read',
422
+ hot: true,
423
+ handler: async () => {
424
+ throw new Error('Kaboom');
425
+ },
426
+ },
427
+ ],
384
428
  });
385
429
 
386
430
  registerAllFacades(mockServer as never, [facade], { agentId: 'agent' });
387
431
 
388
- const result = await capturedHandler!({}) as { content: Array<{ text: string }> };
432
+ const result = (await capturedHandler!({})) as { content: Array<{ text: string }> };
389
433
  const parsed = JSON.parse(result.content[0].text);
390
434
  expect(parsed.success).toBe(false);
391
435
  expect(parsed.error).toBe('Kaboom');
@@ -402,13 +446,15 @@ describe('registerAllFacades — colocated', () => {
402
446
  };
403
447
 
404
448
  const facade = createFacade({
405
- ops: [{
406
- name: 'admin_op',
407
- description: 'Admin',
408
- auth: 'admin',
409
- hot: true,
410
- handler: async () => ({ ok: true }),
411
- }],
449
+ ops: [
450
+ {
451
+ name: 'admin_op',
452
+ description: 'Admin',
453
+ auth: 'admin',
454
+ hot: true,
455
+ handler: async () => ({ ok: true }),
456
+ },
457
+ ],
412
458
  });
413
459
 
414
460
  registerAllFacades(mockServer as never, [facade], {
@@ -416,7 +462,7 @@ describe('registerAllFacades — colocated', () => {
416
462
  authPolicy: () => ({ mode: 'enforce', callerLevel: 'read' }),
417
463
  });
418
464
 
419
- const result = await capturedHandler!({}) as { content: Array<{ text: string }> };
465
+ const result = (await capturedHandler!({})) as { content: Array<{ text: string }> };
420
466
  const parsed = JSON.parse(result.content[0].text);
421
467
  expect(parsed.success).toBe(false);
422
468
  expect(parsed.error).toContain('requires admin');
@@ -30,12 +30,15 @@ describe('runEpilogue', () => {
30
30
  const dispatch = vi.fn(async () => ({ tool: 'capture_knowledge', status: 'ok', data: {} }));
31
31
  const result = await runEpilogue(dispatch, probes({ vault: true }), '/project', 'summary');
32
32
 
33
- expect(dispatch).toHaveBeenCalledWith('capture_knowledge', expect.objectContaining({
34
- title: 'Flow execution summary',
35
- content: 'summary',
36
- type: 'workflow',
37
- projectPath: '/project',
38
- }));
33
+ expect(dispatch).toHaveBeenCalledWith(
34
+ 'capture_knowledge',
35
+ expect.objectContaining({
36
+ title: 'Flow execution summary',
37
+ content: 'summary',
38
+ type: 'workflow',
39
+ projectPath: '/project',
40
+ }),
41
+ );
39
42
  expect(result.captured).toBe(true);
40
43
  });
41
44
 
@@ -52,10 +55,13 @@ describe('runEpilogue', () => {
52
55
  'summary',
53
56
  );
54
57
 
55
- expect(dispatch).toHaveBeenCalledWith('session_capture', expect.objectContaining({
56
- summary: 'summary',
57
- projectPath: '/project',
58
- }));
58
+ expect(dispatch).toHaveBeenCalledWith(
59
+ 'session_capture',
60
+ expect.objectContaining({
61
+ summary: 'summary',
62
+ projectPath: '/project',
63
+ }),
64
+ );
59
65
  expect(result.captured).toBe(true);
60
66
  expect(result.sessionId).toBe('sess-123');
61
67
  });
@@ -129,9 +129,12 @@ describe('evaluateGate', () => {
129
129
 
130
130
  describe('VERIFY type', () => {
131
131
  it('passes with verified findings', () => {
132
- const verdict = evaluateGate({ type: 'VERIFY' }, {
133
- verification: { findings: [{ proven: true }] },
134
- });
132
+ const verdict = evaluateGate(
133
+ { type: 'VERIFY' },
134
+ {
135
+ verification: { findings: [{ proven: true }] },
136
+ },
137
+ );
135
138
  expect(verdict.passed).toBe(true);
136
139
  expect(verdict.action).toBe('CONTINUE');
137
140
  });
@@ -144,9 +147,12 @@ describe('evaluateGate', () => {
144
147
  });
145
148
 
146
149
  it('returns advisory when findings exist but none proven', () => {
147
- const verdict = evaluateGate({ type: 'VERIFY' }, {
148
- verification: { findings: [{ proven: false }] },
149
- });
150
+ const verdict = evaluateGate(
151
+ { type: 'VERIFY' },
152
+ {
153
+ verification: { findings: [{ proven: false }] },
154
+ },
155
+ );
150
156
  expect(verdict.passed).toBe(true);
151
157
  expect(verdict.message).toContain('Advisory');
152
158
  });
@@ -175,9 +175,7 @@ export function resolvePath(obj: Record<string, unknown>, path: string): unknown
175
175
  * Looks for a verification object with at least one proven finding.
176
176
  */
177
177
  function evaluateVerifyGate(data: Record<string, unknown>): boolean {
178
- const verification = data.verification as
179
- | { findings?: Array<{ proven?: boolean }> }
180
- | undefined;
178
+ const verification = data.verification as { findings?: Array<{ proven?: boolean }> } | undefined;
181
179
  if (!verification?.findings?.length) return false;
182
180
  return verification.findings.some((f) => f.proven === true);
183
181
  }
@@ -65,14 +65,25 @@ describe('Governance (colocated)', () => {
65
65
 
66
66
  describe('setPolicy', () => {
67
67
  it('upserts on repeated calls for same project+type', () => {
68
- runtime.governance.setPolicy('/p', 'quota', { maxEntriesTotal: 100 } as Record<string, unknown>);
69
- runtime.governance.setPolicy('/p', 'quota', { maxEntriesTotal: 200 } as Record<string, unknown>);
68
+ runtime.governance.setPolicy('/p', 'quota', { maxEntriesTotal: 100 } as Record<
69
+ string,
70
+ unknown
71
+ >);
72
+ runtime.governance.setPolicy('/p', 'quota', { maxEntriesTotal: 200 } as Record<
73
+ string,
74
+ unknown
75
+ >);
70
76
  const policy = runtime.governance.getPolicy('/p');
71
77
  expect(policy.quotas.maxEntriesTotal).toBe(200);
72
78
  });
73
79
 
74
80
  it('records audit trail with changedBy', () => {
75
- runtime.governance.setPolicy('/p', 'retention', { archiveAfterDays: 7 } as Record<string, unknown>, 'admin');
81
+ runtime.governance.setPolicy(
82
+ '/p',
83
+ 'retention',
84
+ { archiveAfterDays: 7 } as Record<string, unknown>,
85
+ 'admin',
86
+ );
76
87
  const trail = runtime.governance.getAuditTrail('/p');
77
88
  expect(trail).toHaveLength(1);
78
89
  expect(trail[0].changedBy).toBe('admin');
@@ -81,8 +92,14 @@ describe('Governance (colocated)', () => {
81
92
  });
82
93
 
83
94
  it('captures old config on update', () => {
84
- runtime.governance.setPolicy('/p', 'quota', { maxEntriesTotal: 50 } as Record<string, unknown>);
85
- runtime.governance.setPolicy('/p', 'quota', { maxEntriesTotal: 100 } as Record<string, unknown>);
95
+ runtime.governance.setPolicy('/p', 'quota', { maxEntriesTotal: 50 } as Record<
96
+ string,
97
+ unknown
98
+ >);
99
+ runtime.governance.setPolicy('/p', 'quota', { maxEntriesTotal: 100 } as Record<
100
+ string,
101
+ unknown
102
+ >);
86
103
  const trail = runtime.governance.getAuditTrail('/p');
87
104
  const update = trail.find((t) => t.oldConfig !== null);
88
105
  expect(update).toBeDefined();
@@ -124,7 +141,9 @@ describe('Governance (colocated)', () => {
124
141
  });
125
142
 
126
143
  it('throws on unknown preset', () => {
127
- expect(() => runtime.governance.applyPreset('/p', 'nonexistent' as never)).toThrow('Unknown preset');
144
+ expect(() => runtime.governance.applyPreset('/p', 'nonexistent' as never)).toThrow(
145
+ 'Unknown preset',
146
+ );
128
147
  });
129
148
 
130
149
  it('creates audit trail entries for all 3 policy types', () => {
@@ -151,9 +170,33 @@ describe('Governance (colocated)', () => {
151
170
 
152
171
  it('counts entries by category and type', () => {
153
172
  runtime.vault.seed([
154
- { id: 'e1', type: 'pattern', domain: 'testing', title: 'T1', severity: 'warning', description: 'D1', tags: [] },
155
- { id: 'e2', type: 'rule', domain: 'testing', title: 'T2', severity: 'warning', description: 'D2', tags: [] },
156
- { id: 'e3', type: 'pattern', domain: 'styling', title: 'T3', severity: 'warning', description: 'D3', tags: [] },
173
+ {
174
+ id: 'e1',
175
+ type: 'pattern',
176
+ domain: 'testing',
177
+ title: 'T1',
178
+ severity: 'warning',
179
+ description: 'D1',
180
+ tags: [],
181
+ },
182
+ {
183
+ id: 'e2',
184
+ type: 'rule',
185
+ domain: 'testing',
186
+ title: 'T2',
187
+ severity: 'warning',
188
+ description: 'D2',
189
+ tags: [],
190
+ },
191
+ {
192
+ id: 'e3',
193
+ type: 'pattern',
194
+ domain: 'styling',
195
+ title: 'T3',
196
+ severity: 'warning',
197
+ description: 'D3',
198
+ tags: [],
199
+ },
157
200
  ]);
158
201
  const status = runtime.governance.getQuotaStatus('/p');
159
202
  expect(status.total).toBe(3);
@@ -193,7 +236,15 @@ describe('Governance (colocated)', () => {
193
236
  warnAtPercent: 80,
194
237
  });
195
238
  runtime.vault.seed([
196
- { id: 'x1', type: 'pattern', domain: 'a', title: 'T', severity: 'warning', description: 'D', tags: [] },
239
+ {
240
+ id: 'x1',
241
+ type: 'pattern',
242
+ domain: 'a',
243
+ title: 'T',
244
+ severity: 'warning',
245
+ description: 'D',
246
+ tags: [],
247
+ },
197
248
  ]);
198
249
  const status = runtime.governance.getQuotaStatus('/p');
199
250
  expect(status.isWarning).toBe(false);
@@ -289,7 +340,15 @@ describe('Governance (colocated)', () => {
289
340
  warnAtPercent: 80,
290
341
  });
291
342
  runtime.vault.seed([
292
- { id: 'full1', type: 'pattern', domain: 'a', title: 'T', severity: 'warning', description: 'D', tags: [] },
343
+ {
344
+ id: 'full1',
345
+ type: 'pattern',
346
+ domain: 'a',
347
+ title: 'T',
348
+ severity: 'warning',
349
+ description: 'D',
350
+ tags: [],
351
+ },
293
352
  ]);
294
353
  const decision = runtime.governance.evaluateCapture('/p', { type: 'pattern', category: 'a' });
295
354
  expect(decision.allowed).toBe(false);
@@ -305,7 +364,15 @@ describe('Governance (colocated)', () => {
305
364
  warnAtPercent: 80,
306
365
  });
307
366
  runtime.vault.seed([
308
- { id: 'cat1', type: 'pattern', domain: 'a', title: 'T', severity: 'warning', description: 'D', tags: [] },
367
+ {
368
+ id: 'cat1',
369
+ type: 'pattern',
370
+ domain: 'a',
371
+ title: 'T',
372
+ severity: 'warning',
373
+ description: 'D',
374
+ tags: [],
375
+ },
309
376
  ]);
310
377
  const decision = runtime.governance.evaluateCapture('/p', { type: 'pattern', category: 'a' });
311
378
  expect(decision.allowed).toBe(false);
@@ -321,7 +388,15 @@ describe('Governance (colocated)', () => {
321
388
  warnAtPercent: 80,
322
389
  });
323
390
  runtime.vault.seed([
324
- { id: 'typ1', type: 'pattern', domain: 'a', title: 'T', severity: 'warning', description: 'D', tags: [] },
391
+ {
392
+ id: 'typ1',
393
+ type: 'pattern',
394
+ domain: 'a',
395
+ title: 'T',
396
+ severity: 'warning',
397
+ description: 'D',
398
+ tags: [],
399
+ },
325
400
  ]);
326
401
  const decision = runtime.governance.evaluateCapture('/p', { type: 'pattern', category: 'b' });
327
402
  expect(decision.allowed).toBe(false);
@@ -354,7 +429,15 @@ describe('Governance (colocated)', () => {
354
429
  warnAtPercent: 80,
355
430
  });
356
431
  runtime.vault.seed([
357
- { id: 'mx1', type: 'pattern', domain: 'a', title: 'T', severity: 'warning', description: 'D', tags: [] },
432
+ {
433
+ id: 'mx1',
434
+ type: 'pattern',
435
+ domain: 'a',
436
+ title: 'T',
437
+ severity: 'warning',
438
+ description: 'D',
439
+ tags: [],
440
+ },
358
441
  ]);
359
442
  const results = runtime.governance.evaluateBatch('/p', [
360
443
  { type: 'pattern', category: 'a' },
@@ -478,7 +561,11 @@ describe('Governance (colocated)', () => {
478
561
  category: 'a',
479
562
  data: { description: 'Original', severity: 'warning' },
480
563
  });
481
- const result = runtime.governance.modifyProposal(id, { description: 'Updated', extra: true }, 'editor');
564
+ const result = runtime.governance.modifyProposal(
565
+ id,
566
+ { description: 'Updated', extra: true },
567
+ 'editor',
568
+ );
482
569
  expect(result).not.toBeNull();
483
570
  expect(result!.status).toBe('modified');
484
571
  expect(result!.proposedData.description).toBe('Updated');
@@ -578,7 +665,11 @@ describe('Governance (colocated)', () => {
578
665
  });
579
666
 
580
667
  it('computes byCategory breakdown', () => {
581
- const id1 = runtime.governance.propose('/p', { title: 'P1', type: 'pattern', category: 'arch' });
668
+ const id1 = runtime.governance.propose('/p', {
669
+ title: 'P1',
670
+ type: 'pattern',
671
+ category: 'arch',
672
+ });
582
673
  const id2 = runtime.governance.propose('/p', { title: 'P2', type: 'rule', category: 'arch' });
583
674
  runtime.governance.approveProposal(id1);
584
675
  runtime.governance.rejectProposal(id2);
@@ -645,8 +736,24 @@ describe('Governance (colocated)', () => {
645
736
  warnAtPercent: 80,
646
737
  });
647
738
  runtime.vault.seed([
648
- { id: 'd1', type: 'pattern', domain: 'd', title: 'T', severity: 'warning', description: 'D', tags: [] },
649
- { id: 'd2', type: 'rule', domain: 'd', title: 'T', severity: 'warning', description: 'D', tags: [] },
739
+ {
740
+ id: 'd1',
741
+ type: 'pattern',
742
+ domain: 'd',
743
+ title: 'T',
744
+ severity: 'warning',
745
+ description: 'D',
746
+ tags: [],
747
+ },
748
+ {
749
+ id: 'd2',
750
+ type: 'rule',
751
+ domain: 'd',
752
+ title: 'T',
753
+ severity: 'warning',
754
+ description: 'D',
755
+ tags: [],
756
+ },
650
757
  ]);
651
758
  const dashboard = runtime.governance.getDashboard('/p');
652
759
  expect(dashboard.vaultSize).toBe(2);
@@ -702,9 +809,18 @@ describe('Governance (colocated)', () => {
702
809
  });
703
810
 
704
811
  it('setPolicy handles all three policy types independently', () => {
705
- runtime.governance.setPolicy('/p', 'quota', { maxEntriesTotal: 42 } as Record<string, unknown>);
706
- runtime.governance.setPolicy('/p', 'retention', { archiveAfterDays: 7 } as Record<string, unknown>);
707
- runtime.governance.setPolicy('/p', 'auto-capture', { enabled: false } as Record<string, unknown>);
812
+ runtime.governance.setPolicy('/p', 'quota', { maxEntriesTotal: 42 } as Record<
813
+ string,
814
+ unknown
815
+ >);
816
+ runtime.governance.setPolicy('/p', 'retention', { archiveAfterDays: 7 } as Record<
817
+ string,
818
+ unknown
819
+ >);
820
+ runtime.governance.setPolicy('/p', 'auto-capture', { enabled: false } as Record<
821
+ string,
822
+ unknown
823
+ >);
708
824
 
709
825
  const policy = runtime.governance.getPolicy('/p');
710
826
  expect(policy.quotas.maxEntriesTotal).toBe(42);
@@ -161,7 +161,14 @@ describe('withDegradation', () => {
161
161
  reg.register('test');
162
162
 
163
163
  const fail = () =>
164
- withDegradation(reg, 'test', async () => { throw new Error('fail'); }, null);
164
+ withDegradation(
165
+ reg,
166
+ 'test',
167
+ async () => {
168
+ throw new Error('fail');
169
+ },
170
+ null,
171
+ );
165
172
 
166
173
  await fail();
167
174
  expect(reg.get('test')!.status).toBe('degraded');