@soleri/core 9.2.0 → 9.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/flows/build.flow.yaml +8 -9
- package/data/flows/deliver.flow.yaml +9 -10
- package/data/flows/design.flow.yaml +3 -4
- package/data/flows/enhance.flow.yaml +5 -6
- package/data/flows/explore.flow.yaml +3 -4
- package/data/flows/fix.flow.yaml +5 -6
- package/data/flows/plan.flow.yaml +4 -5
- package/data/flows/review.flow.yaml +3 -4
- package/dist/curator/curator.d.ts.map +1 -1
- package/dist/curator/curator.js +98 -22
- package/dist/curator/curator.js.map +1 -1
- package/dist/engine/bin/soleri-engine.js.map +1 -1
- package/dist/engine/module-manifest.d.ts.map +1 -1
- package/dist/engine/module-manifest.js +21 -1
- package/dist/engine/module-manifest.js.map +1 -1
- package/dist/engine/register-engine.d.ts.map +1 -1
- package/dist/engine/register-engine.js +25 -1
- package/dist/engine/register-engine.js.map +1 -1
- package/dist/flows/gate-evaluator.js.map +1 -1
- package/dist/operator/operator-profile.d.ts.map +1 -1
- package/dist/operator/operator-profile.js +11 -5
- package/dist/operator/operator-profile.js.map +1 -1
- package/dist/operator/operator-signals.d.ts.map +1 -1
- package/dist/operator/operator-signals.js.map +1 -1
- package/dist/planning/evidence-collector.js.map +1 -1
- package/dist/planning/gap-passes.d.ts.map +1 -1
- package/dist/planning/gap-passes.js +23 -6
- package/dist/planning/gap-passes.js.map +1 -1
- package/dist/planning/gap-patterns.d.ts.map +1 -1
- package/dist/planning/gap-patterns.js +57 -11
- package/dist/planning/gap-patterns.js.map +1 -1
- package/dist/planning/github-projection.d.ts.map +1 -1
- package/dist/planning/github-projection.js +39 -20
- package/dist/planning/github-projection.js.map +1 -1
- package/dist/planning/impact-analyzer.d.ts.map +1 -1
- package/dist/planning/impact-analyzer.js +20 -18
- package/dist/planning/impact-analyzer.js.map +1 -1
- package/dist/planning/plan-lifecycle.d.ts.map +1 -1
- package/dist/planning/plan-lifecycle.js +22 -9
- package/dist/planning/plan-lifecycle.js.map +1 -1
- package/dist/planning/planner.d.ts.map +1 -1
- package/dist/planning/planner.js +60 -17
- package/dist/planning/planner.js.map +1 -1
- package/dist/planning/rationalization-detector.d.ts.map +1 -1
- package/dist/planning/rationalization-detector.js.map +1 -1
- package/dist/planning/reconciliation-engine.d.ts.map +1 -1
- package/dist/planning/reconciliation-engine.js.map +1 -1
- package/dist/planning/task-verifier.d.ts.map +1 -1
- package/dist/planning/task-verifier.js +14 -6
- package/dist/planning/task-verifier.js.map +1 -1
- package/dist/runtime/admin-setup-ops.d.ts.map +1 -1
- package/dist/runtime/admin-setup-ops.js +2 -1
- package/dist/runtime/admin-setup-ops.js.map +1 -1
- package/dist/runtime/branching-ops.d.ts +12 -0
- package/dist/runtime/branching-ops.d.ts.map +1 -0
- package/dist/runtime/branching-ops.js +100 -0
- package/dist/runtime/branching-ops.js.map +1 -0
- package/dist/runtime/context-health.d.ts.map +1 -1
- package/dist/runtime/context-health.js.map +1 -1
- package/dist/runtime/facades/branching-facade.d.ts +7 -0
- package/dist/runtime/facades/branching-facade.d.ts.map +1 -0
- package/dist/runtime/facades/branching-facade.js +8 -0
- package/dist/runtime/facades/branching-facade.js.map +1 -0
- package/dist/runtime/facades/chat-service-ops.d.ts.map +1 -1
- package/dist/runtime/facades/chat-service-ops.js +3 -1
- package/dist/runtime/facades/chat-service-ops.js.map +1 -1
- package/dist/runtime/facades/chat-transport-ops.d.ts.map +1 -1
- package/dist/runtime/facades/chat-transport-ops.js.map +1 -1
- package/dist/runtime/facades/index.d.ts.map +1 -1
- package/dist/runtime/facades/index.js +42 -0
- package/dist/runtime/facades/index.js.map +1 -1
- package/dist/runtime/facades/intake-facade.d.ts +9 -0
- package/dist/runtime/facades/intake-facade.d.ts.map +1 -0
- package/dist/runtime/facades/intake-facade.js +11 -0
- package/dist/runtime/facades/intake-facade.js.map +1 -0
- package/dist/runtime/facades/links-facade.d.ts +9 -0
- package/dist/runtime/facades/links-facade.d.ts.map +1 -0
- package/dist/runtime/facades/links-facade.js +10 -0
- package/dist/runtime/facades/links-facade.js.map +1 -0
- package/dist/runtime/facades/operator-facade.d.ts.map +1 -1
- package/dist/runtime/facades/operator-facade.js.map +1 -1
- package/dist/runtime/facades/plan-facade.d.ts.map +1 -1
- package/dist/runtime/facades/plan-facade.js +4 -1
- package/dist/runtime/facades/plan-facade.js.map +1 -1
- package/dist/runtime/facades/tier-facade.d.ts +7 -0
- package/dist/runtime/facades/tier-facade.d.ts.map +1 -0
- package/dist/runtime/facades/tier-facade.js +8 -0
- package/dist/runtime/facades/tier-facade.js.map +1 -0
- package/dist/runtime/facades/vault-facade.d.ts +9 -1
- package/dist/runtime/facades/vault-facade.d.ts.map +1 -1
- package/dist/runtime/facades/vault-facade.js +44 -187
- package/dist/runtime/facades/vault-facade.js.map +1 -1
- package/dist/runtime/github-integration.d.ts.map +1 -1
- package/dist/runtime/github-integration.js +11 -4
- package/dist/runtime/github-integration.js.map +1 -1
- package/dist/runtime/orchestrate-ops.d.ts.map +1 -1
- package/dist/runtime/orchestrate-ops.js +32 -10
- package/dist/runtime/orchestrate-ops.js.map +1 -1
- package/dist/runtime/planning-extra-ops.d.ts.map +1 -1
- package/dist/runtime/planning-extra-ops.js.map +1 -1
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +3 -1
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/runtime/session-briefing.d.ts.map +1 -1
- package/dist/runtime/session-briefing.js +5 -1
- package/dist/runtime/session-briefing.js.map +1 -1
- package/dist/runtime/tier-ops.d.ts +13 -0
- package/dist/runtime/tier-ops.d.ts.map +1 -0
- package/dist/runtime/tier-ops.js +110 -0
- package/dist/runtime/tier-ops.js.map +1 -0
- package/dist/skills/sync-skills.d.ts.map +1 -1
- package/dist/skills/sync-skills.js +1 -1
- package/dist/skills/sync-skills.js.map +1 -1
- package/dist/vault/linking.d.ts.map +1 -1
- package/dist/vault/linking.js +41 -5
- package/dist/vault/linking.js.map +1 -1
- package/dist/vault/vault-entries.d.ts.map +1 -1
- package/dist/vault/vault-entries.js +68 -26
- package/dist/vault/vault-entries.js.map +1 -1
- package/dist/vault/vault-maintenance.d.ts.map +1 -1
- package/dist/vault/vault-maintenance.js +6 -2
- package/dist/vault/vault-maintenance.js.map +1 -1
- package/dist/vault/vault-markdown-sync.d.ts.map +1 -1
- package/dist/vault/vault-markdown-sync.js.map +1 -1
- package/dist/vault/vault-memories.d.ts.map +1 -1
- package/dist/vault/vault-memories.js +3 -1
- package/dist/vault/vault-memories.js.map +1 -1
- package/dist/vault/vault-schema.js +36 -10
- package/dist/vault/vault-schema.js.map +1 -1
- package/dist/vault/vault.d.ts.map +1 -1
- package/dist/vault/vault.js +5 -1
- package/dist/vault/vault.js.map +1 -1
- package/package.json +7 -7
- package/src/agency/agency-manager.test.ts +60 -40
- package/src/agency/default-rules.test.ts +17 -9
- package/src/capabilities/registry.test.ts +2 -12
- package/src/chat/agent-loop.test.ts +33 -43
- package/src/chat/mcp-bridge.test.ts +7 -2
- package/src/claudemd/inject.test.ts +2 -12
- package/src/context/context-engine.test.ts +96 -51
- package/src/control/intent-router.test.ts +3 -3
- package/src/curator/classifier.test.ts +14 -8
- package/src/curator/contradiction-detector.test.ts +30 -5
- package/src/curator/curator.ts +278 -56
- package/src/curator/duplicate-detector.test.ts +77 -15
- package/src/curator/quality-gate.test.ts +71 -31
- package/src/curator/tag-manager.test.ts +12 -4
- package/src/domain-packs/knowledge-installer.test.ts +2 -10
- package/src/domain-packs/token-resolver.test.ts +1 -3
- package/src/domain-packs/types.test.ts +16 -2
- package/src/enforcement/registry.test.ts +2 -8
- package/src/engine/bin/soleri-engine.ts +3 -1
- package/src/engine/module-manifest.test.ts +5 -4
- package/src/engine/module-manifest.ts +21 -1
- package/src/engine/register-engine.test.ts +6 -1
- package/src/engine/register-engine.ts +26 -3
- package/src/errors/classify.test.ts +6 -2
- package/src/errors/retry.test.ts +1 -4
- package/src/facades/facade-factory.test.ts +110 -64
- package/src/flows/epilogue.test.ts +16 -10
- package/src/flows/gate-evaluator.test.ts +12 -6
- package/src/flows/gate-evaluator.ts +1 -3
- package/src/governance/governance.test.ts +137 -21
- package/src/health/health-registry.test.ts +8 -1
- package/src/intake/content-classifier.test.ts +121 -51
- package/src/intake/dedup-gate.test.ts +38 -22
- package/src/intake/intake-pipeline.test.ts +5 -3
- package/src/intake/text-ingester.test.ts +26 -20
- package/src/llm/key-pool.test.ts +1 -3
- package/src/llm/llm-client.test.ts +1 -4
- package/src/llm/oauth-discovery.test.ts +16 -16
- package/src/llm/utils.test.ts +62 -18
- package/src/logging/logger.test.ts +4 -1
- package/src/loop/loop-manager.test.ts +2 -6
- package/src/migrations/migration-runner.edge-cases.test.ts +2 -7
- package/src/operator/operator-profile-extended.test.ts +15 -5
- package/src/operator/operator-profile.test.ts +26 -8
- package/src/operator/operator-profile.ts +38 -22
- package/src/operator/operator-signals-extended.test.ts +35 -23
- package/src/operator/operator-signals.test.ts +6 -10
- package/src/operator/operator-signals.ts +2 -1
- package/src/operator/prompts/hook-precompact-operator-dispatch.md +10 -6
- package/src/operator/prompts/subagent-soft-signal-extractor.md +5 -0
- package/src/operator/prompts/subagent-synthesis-cognition.md +19 -10
- package/src/operator/prompts/subagent-synthesis-communication.md +13 -7
- package/src/operator/prompts/subagent-synthesis-technical.md +19 -9
- package/src/operator/prompts/subagent-synthesis-trust.md +27 -21
- package/src/persona/defaults.test.ts +1 -5
- package/src/planning/evidence-collector.test.ts +147 -38
- package/src/planning/evidence-collector.ts +1 -4
- package/src/planning/gap-analysis-alternatives.test.ts +41 -11
- package/src/planning/gap-passes.test.ts +215 -33
- package/src/planning/gap-passes.ts +115 -46
- package/src/planning/gap-patterns.test.ts +87 -13
- package/src/planning/gap-patterns.ts +114 -31
- package/src/planning/github-projection.test.ts +6 -1
- package/src/planning/github-projection.ts +41 -20
- package/src/planning/impact-analyzer.test.ts +10 -23
- package/src/planning/impact-analyzer.ts +33 -46
- package/src/planning/plan-lifecycle.test.ts +103 -36
- package/src/planning/plan-lifecycle.ts +49 -18
- package/src/planning/planner.test.ts +12 -2
- package/src/planning/planner.ts +198 -58
- package/src/planning/rationalization-detector.test.ts +5 -20
- package/src/planning/rationalization-detector.ts +14 -16
- package/src/planning/reconciliation-engine.test.ts +20 -3
- package/src/planning/reconciliation-engine.ts +1 -2
- package/src/planning/task-verifier.test.ts +59 -27
- package/src/planning/task-verifier.ts +15 -9
- package/src/playbooks/playbook-executor.test.ts +1 -3
- package/src/plugins/plugin-loader.test.ts +19 -14
- package/src/plugins/plugin-registry.test.ts +45 -33
- package/src/project/project-registry.test.ts +23 -12
- package/src/prompts/template-manager.test.ts +4 -1
- package/src/queue/job-queue.test.ts +10 -14
- package/src/runtime/admin-extra-ops.test.ts +5 -19
- package/src/runtime/admin-ops.test.ts +1 -3
- package/src/runtime/admin-setup-ops.test.ts +3 -4
- package/src/runtime/admin-setup-ops.ts +9 -2
- package/src/runtime/archive-ops.test.ts +4 -1
- package/src/runtime/branching-ops.test.ts +144 -0
- package/src/runtime/branching-ops.ts +107 -0
- package/src/runtime/capture-ops.test.ts +7 -21
- package/src/runtime/chain-ops.test.ts +16 -6
- package/src/runtime/claude-md-helpers.test.ts +1 -3
- package/src/runtime/context-health.test.ts +1 -3
- package/src/runtime/context-health.ts +1 -3
- package/src/runtime/curator-extra-ops.test.ts +3 -1
- package/src/runtime/domain-ops.test.ts +46 -36
- package/src/runtime/facades/admin-facade.test.ts +1 -4
- package/src/runtime/facades/archive-facade.test.ts +21 -7
- package/src/runtime/facades/brain-facade.test.ts +176 -72
- package/src/runtime/facades/branching-facade.test.ts +43 -0
- package/src/runtime/facades/branching-facade.ts +11 -0
- package/src/runtime/facades/chat-facade.test.ts +81 -28
- package/src/runtime/facades/chat-service-ops.test.ts +178 -73
- package/src/runtime/facades/chat-service-ops.ts +3 -1
- package/src/runtime/facades/chat-session-ops.test.ts +25 -10
- package/src/runtime/facades/chat-transport-ops.test.ts +101 -34
- package/src/runtime/facades/chat-transport-ops.ts +0 -1
- package/src/runtime/facades/context-facade.test.ts +19 -4
- package/src/runtime/facades/control-facade.test.ts +3 -3
- package/src/runtime/facades/index.ts +42 -0
- package/src/runtime/facades/intake-facade.test.ts +215 -0
- package/src/runtime/facades/intake-facade.ts +14 -0
- package/src/runtime/facades/links-facade.test.ts +203 -0
- package/src/runtime/facades/links-facade.ts +13 -0
- package/src/runtime/facades/loop-facade.test.ts +22 -5
- package/src/runtime/facades/memory-facade.test.ts +19 -5
- package/src/runtime/facades/operator-facade.test.ts +17 -4
- package/src/runtime/facades/operator-facade.ts +11 -3
- package/src/runtime/facades/orchestrate-facade.test.ts +7 -1
- package/src/runtime/facades/plan-facade.test.ts +29 -12
- package/src/runtime/facades/plan-facade.ts +7 -2
- package/src/runtime/facades/tier-facade.test.ts +47 -0
- package/src/runtime/facades/tier-facade.ts +11 -0
- package/src/runtime/facades/vault-facade.test.ts +174 -242
- package/src/runtime/facades/vault-facade.ts +55 -199
- package/src/runtime/github-integration.ts +11 -8
- package/src/runtime/grading-ops.test.ts +39 -8
- package/src/runtime/intake-ops.test.ts +69 -16
- package/src/runtime/loop-ops.test.ts +16 -6
- package/src/runtime/memory-cross-project-ops.test.ts +25 -14
- package/src/runtime/orchestrate-ops.ts +54 -27
- package/src/runtime/pack-ops.test.ts +23 -6
- package/src/runtime/planning-extra-ops.test.ts +17 -7
- package/src/runtime/planning-extra-ops.ts +3 -1
- package/src/runtime/playbook-ops.test.ts +26 -3
- package/src/runtime/plugin-ops.test.ts +83 -25
- package/src/runtime/project-ops.test.ts +26 -6
- package/src/runtime/runtime.ts +3 -1
- package/src/runtime/session-briefing.test.ts +183 -54
- package/src/runtime/session-briefing.ts +8 -2
- package/src/runtime/sync-ops.test.ts +3 -12
- package/src/runtime/telemetry-ops.test.ts +31 -6
- package/src/runtime/tier-ops.test.ts +159 -0
- package/src/runtime/tier-ops.ts +119 -0
- package/src/runtime/vault-extra-ops.test.ts +32 -8
- package/src/runtime/vault-sharing-ops.test.ts +1 -4
- package/src/skills/sync-skills.ts +2 -12
- package/src/transport/ws-server.test.ts +7 -4
- package/src/vault/__tests__/vault-characterization.test.ts +492 -81
- package/src/vault/linking.test.ts +50 -17
- package/src/vault/linking.ts +48 -7
- package/src/vault/obsidian-sync.test.ts +6 -3
- package/src/vault/scope-detector.test.ts +1 -3
- package/src/vault/vault-branching.test.ts +9 -7
- package/src/vault/vault-entries.ts +209 -65
- package/src/vault/vault-maintenance.ts +7 -12
- package/src/vault/vault-manager.test.ts +10 -10
- package/src/vault/vault-markdown-sync.ts +4 -1
- package/src/vault/vault-memories.ts +7 -7
- package/src/vault/vault-schema.ts +72 -15
- package/src/vault/vault.ts +55 -9
- package/src/brain/strength-scorer.ts +0 -404
- package/src/engine/index.ts +0 -21
- package/src/persona/index.ts +0 -9
- package/src/vault/vault-interfaces.ts +0 -56
|
@@ -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
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
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
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
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
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
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) => {
|
|
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) => {
|
|
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) => {
|
|
305
|
+
tool: (name: string) => {
|
|
306
|
+
registered.push(name);
|
|
307
|
+
},
|
|
288
308
|
};
|
|
289
309
|
|
|
290
310
|
const facade = createFacade({
|
|
291
311
|
ops: [
|
|
292
|
-
{
|
|
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) => {
|
|
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) => {
|
|
350
|
+
tool: (name: string) => {
|
|
351
|
+
registered.push(name);
|
|
352
|
+
},
|
|
323
353
|
};
|
|
324
354
|
|
|
325
355
|
const facade = createFacade({
|
|
326
356
|
ops: [
|
|
327
|
-
{
|
|
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
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
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 {
|
|
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
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
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
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
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(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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(
|
|
56
|
-
|
|
57
|
-
|
|
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(
|
|
133
|
-
|
|
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(
|
|
148
|
-
|
|
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<
|
|
69
|
-
|
|
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(
|
|
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<
|
|
85
|
-
|
|
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(
|
|
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
|
-
{
|
|
155
|
-
|
|
156
|
-
|
|
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
|
-
{
|
|
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
|
-
{
|
|
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
|
-
{
|
|
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
|
-
{
|
|
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
|
-
{
|
|
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(
|
|
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', {
|
|
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
|
-
{
|
|
649
|
-
|
|
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<
|
|
706
|
-
|
|
707
|
-
|
|
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(
|
|
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');
|