@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.
- 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 +2 -0
- package/dist/engine/module-manifest.d.ts.map +1 -1
- package/dist/engine/module-manifest.js +136 -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/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.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-complexity-assessor.d.ts +42 -0
- package/dist/planning/task-complexity-assessor.d.ts.map +1 -0
- package/dist/planning/task-complexity-assessor.js +132 -0
- package/dist/planning/task-complexity-assessor.js.map +1 -0
- 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-ops.d.ts.map +1 -1
- package/dist/runtime/admin-ops.js +18 -0
- package/dist/runtime/admin-ops.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 +75 -42
- 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 +48 -4
- package/src/engine/module-manifest.ts +138 -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/index.ts +8 -0
- 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-complexity-assessor.test.ts +298 -0
- package/src/planning/task-complexity-assessor.ts +183 -0
- 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 +22 -1
- package/src/runtime/admin-ops.ts +19 -0
- 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.test.ts +204 -0
- package/src/runtime/orchestrate-ops.ts +103 -65
- 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-scaling.test.ts +5 -5
- 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
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Colocated contract tests for branching-ops.ts.
|
|
3
|
+
* Tests the 5 vault branching ops extracted from vault-facade.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
7
|
+
import { createBranchingOps } from './branching-ops.js';
|
|
8
|
+
import { captureOps, executeOp } from '../engine/test-helpers.js';
|
|
9
|
+
import type { CapturedOp } from '../engine/test-helpers.js';
|
|
10
|
+
import type { AgentRuntime } from './types.js';
|
|
11
|
+
|
|
12
|
+
function makeMockVaultBranching() {
|
|
13
|
+
return {
|
|
14
|
+
branch: vi.fn(),
|
|
15
|
+
addOperation: vi.fn(),
|
|
16
|
+
listBranches: vi.fn().mockReturnValue([{ name: 'experiment', ops: 3 }]),
|
|
17
|
+
merge: vi.fn().mockReturnValue({ merged: true, applied: 3 }),
|
|
18
|
+
deleteBranch: vi.fn().mockReturnValue(true),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function makeRuntime(): AgentRuntime {
|
|
23
|
+
return {
|
|
24
|
+
vaultBranching: makeMockVaultBranching(),
|
|
25
|
+
config: { agentId: 'test-agent' },
|
|
26
|
+
} as unknown as AgentRuntime;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
describe('branching-ops', () => {
|
|
30
|
+
let runtime: AgentRuntime;
|
|
31
|
+
let ops: Map<string, CapturedOp>;
|
|
32
|
+
|
|
33
|
+
beforeEach(() => {
|
|
34
|
+
runtime = makeRuntime();
|
|
35
|
+
ops = captureOps(createBranchingOps(runtime));
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('registers all 5 branching ops', () => {
|
|
39
|
+
expect(ops.size).toBe(5);
|
|
40
|
+
expect(ops.has('vault_branch')).toBe(true);
|
|
41
|
+
expect(ops.has('vault_branch_add')).toBe(true);
|
|
42
|
+
expect(ops.has('vault_branch_list')).toBe(true);
|
|
43
|
+
expect(ops.has('vault_merge_branch')).toBe(true);
|
|
44
|
+
expect(ops.has('vault_delete_branch')).toBe(true);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('has correct auth levels', () => {
|
|
48
|
+
expect(ops.get('vault_branch')!.auth).toBe('write');
|
|
49
|
+
expect(ops.get('vault_branch_add')!.auth).toBe('write');
|
|
50
|
+
expect(ops.get('vault_branch_list')!.auth).toBe('read');
|
|
51
|
+
expect(ops.get('vault_merge_branch')!.auth).toBe('admin');
|
|
52
|
+
expect(ops.get('vault_delete_branch')!.auth).toBe('admin');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
describe('vault_branch', () => {
|
|
56
|
+
it('creates a branch', async () => {
|
|
57
|
+
const result = await executeOp(ops, 'vault_branch', { name: 'experiment' });
|
|
58
|
+
expect(result.success).toBe(true);
|
|
59
|
+
const data = result.data as { created: boolean; name: string };
|
|
60
|
+
expect(data.created).toBe(true);
|
|
61
|
+
expect(data.name).toBe('experiment');
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('returns error on duplicate branch', async () => {
|
|
65
|
+
const vb = runtime.vaultBranching as ReturnType<typeof makeMockVaultBranching>;
|
|
66
|
+
vb.branch.mockImplementation(() => {
|
|
67
|
+
throw new Error('Branch already exists');
|
|
68
|
+
});
|
|
69
|
+
const result = await executeOp(ops, 'vault_branch', { name: 'dup' });
|
|
70
|
+
expect(result.success).toBe(true);
|
|
71
|
+
const data = result.data as { error: string };
|
|
72
|
+
expect(data.error).toBe('Branch already exists');
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
describe('vault_branch_add', () => {
|
|
77
|
+
it('adds an operation to a branch', async () => {
|
|
78
|
+
const result = await executeOp(ops, 'vault_branch_add', {
|
|
79
|
+
branchName: 'exp',
|
|
80
|
+
entryId: 'e1',
|
|
81
|
+
action: 'add',
|
|
82
|
+
entryData: { id: 'e1', title: 'New', type: 'pattern', domain: 'test' },
|
|
83
|
+
});
|
|
84
|
+
expect(result.success).toBe(true);
|
|
85
|
+
const data = result.data as { added: boolean; action: string };
|
|
86
|
+
expect(data.added).toBe(true);
|
|
87
|
+
expect(data.action).toBe('add');
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('returns error on invalid branch', async () => {
|
|
91
|
+
const vb = runtime.vaultBranching as ReturnType<typeof makeMockVaultBranching>;
|
|
92
|
+
vb.addOperation.mockImplementation(() => {
|
|
93
|
+
throw new Error('Branch not found');
|
|
94
|
+
});
|
|
95
|
+
const result = await executeOp(ops, 'vault_branch_add', {
|
|
96
|
+
branchName: 'missing',
|
|
97
|
+
entryId: 'e1',
|
|
98
|
+
action: 'remove',
|
|
99
|
+
});
|
|
100
|
+
expect(result.success).toBe(true);
|
|
101
|
+
expect((result.data as { error: string }).error).toBe('Branch not found');
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
describe('vault_branch_list', () => {
|
|
106
|
+
it('lists all branches', async () => {
|
|
107
|
+
const result = await executeOp(ops, 'vault_branch_list', {});
|
|
108
|
+
expect(result.success).toBe(true);
|
|
109
|
+
const data = result.data as { branches: Array<{ name: string }> };
|
|
110
|
+
expect(data.branches).toHaveLength(1);
|
|
111
|
+
expect(data.branches[0].name).toBe('experiment');
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
describe('vault_merge_branch', () => {
|
|
116
|
+
it('merges a branch', async () => {
|
|
117
|
+
const result = await executeOp(ops, 'vault_merge_branch', { branchName: 'experiment' });
|
|
118
|
+
expect(result.success).toBe(true);
|
|
119
|
+
const data = result.data as { merged: boolean; applied: number };
|
|
120
|
+
expect(data.merged).toBe(true);
|
|
121
|
+
expect(data.applied).toBe(3);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('returns error on merge failure', async () => {
|
|
125
|
+
const vb = runtime.vaultBranching as ReturnType<typeof makeMockVaultBranching>;
|
|
126
|
+
vb.merge.mockImplementation(() => {
|
|
127
|
+
throw new Error('Conflict detected');
|
|
128
|
+
});
|
|
129
|
+
const result = await executeOp(ops, 'vault_merge_branch', { branchName: 'conflict' });
|
|
130
|
+
expect(result.success).toBe(true);
|
|
131
|
+
expect((result.data as { error: string }).error).toBe('Conflict detected');
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
describe('vault_delete_branch', () => {
|
|
136
|
+
it('deletes a branch', async () => {
|
|
137
|
+
const result = await executeOp(ops, 'vault_delete_branch', { branchName: 'experiment' });
|
|
138
|
+
expect(result.success).toBe(true);
|
|
139
|
+
const data = result.data as { deleted: boolean; branchName: string };
|
|
140
|
+
expect(data.deleted).toBe(true);
|
|
141
|
+
expect(data.branchName).toBe('experiment');
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
});
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Branching Ops — vault branch lifecycle operations.
|
|
3
|
+
*
|
|
4
|
+
* Covers:
|
|
5
|
+
* - Create named branches for experimentation
|
|
6
|
+
* - Add operations (add/modify/remove) to branches
|
|
7
|
+
* - List, merge, and delete branches
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
import type { OpDefinition } from '../facades/types.js';
|
|
12
|
+
import type { IntelligenceEntry } from '../intelligence/types.js';
|
|
13
|
+
import type { AgentRuntime } from './types.js';
|
|
14
|
+
|
|
15
|
+
export function createBranchingOps(runtime: AgentRuntime): OpDefinition[] {
|
|
16
|
+
return [
|
|
17
|
+
{
|
|
18
|
+
name: 'vault_branch',
|
|
19
|
+
description:
|
|
20
|
+
'Create a named vault branch for experimentation. Changes can be reviewed and merged later.',
|
|
21
|
+
auth: 'write',
|
|
22
|
+
schema: z.object({
|
|
23
|
+
name: z.string().describe('Unique branch name'),
|
|
24
|
+
}),
|
|
25
|
+
handler: async (params) => {
|
|
26
|
+
const { vaultBranching } = runtime;
|
|
27
|
+
try {
|
|
28
|
+
vaultBranching.branch(params.name as string);
|
|
29
|
+
return { created: true, name: params.name };
|
|
30
|
+
} catch (err) {
|
|
31
|
+
return { error: (err as Error).message };
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'vault_branch_add',
|
|
37
|
+
description: 'Add an operation (add/modify/remove) to a vault branch.',
|
|
38
|
+
auth: 'write',
|
|
39
|
+
schema: z.object({
|
|
40
|
+
branchName: z.string().describe('Branch to add the operation to'),
|
|
41
|
+
entryId: z.string().describe('Entry ID'),
|
|
42
|
+
action: z.enum(['add', 'modify', 'remove']).describe('Operation type'),
|
|
43
|
+
entryData: z
|
|
44
|
+
.record(z.unknown())
|
|
45
|
+
.optional()
|
|
46
|
+
.describe('Full entry data (required for add/modify)'),
|
|
47
|
+
}),
|
|
48
|
+
handler: async (params) => {
|
|
49
|
+
const { vaultBranching } = runtime;
|
|
50
|
+
try {
|
|
51
|
+
vaultBranching.addOperation(
|
|
52
|
+
params.branchName as string,
|
|
53
|
+
params.entryId as string,
|
|
54
|
+
params.action as 'add' | 'modify' | 'remove',
|
|
55
|
+
params.entryData as IntelligenceEntry | undefined,
|
|
56
|
+
);
|
|
57
|
+
return {
|
|
58
|
+
added: true,
|
|
59
|
+
branchName: params.branchName,
|
|
60
|
+
entryId: params.entryId,
|
|
61
|
+
action: params.action,
|
|
62
|
+
};
|
|
63
|
+
} catch (err) {
|
|
64
|
+
return { error: (err as Error).message };
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: 'vault_branch_list',
|
|
70
|
+
description: 'List all vault branches with entry counts and merge status.',
|
|
71
|
+
auth: 'read',
|
|
72
|
+
handler: async () => {
|
|
73
|
+
const { vaultBranching } = runtime;
|
|
74
|
+
return { branches: vaultBranching.listBranches() };
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'vault_merge_branch',
|
|
79
|
+
description: 'Merge a branch into the main vault. Branch entries win on conflict.',
|
|
80
|
+
auth: 'admin',
|
|
81
|
+
schema: z.object({
|
|
82
|
+
branchName: z.string().describe('Branch to merge'),
|
|
83
|
+
}),
|
|
84
|
+
handler: async (params) => {
|
|
85
|
+
const { vaultBranching } = runtime;
|
|
86
|
+
try {
|
|
87
|
+
return vaultBranching.merge(params.branchName as string);
|
|
88
|
+
} catch (err) {
|
|
89
|
+
return { error: (err as Error).message };
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: 'vault_delete_branch',
|
|
95
|
+
description: 'Delete a vault branch and all its operations.',
|
|
96
|
+
auth: 'admin',
|
|
97
|
+
schema: z.object({
|
|
98
|
+
branchName: z.string().describe('Branch to delete'),
|
|
99
|
+
}),
|
|
100
|
+
handler: async (params) => {
|
|
101
|
+
const { vaultBranching } = runtime;
|
|
102
|
+
const deleted = vaultBranching.deleteBranch(params.branchName as string);
|
|
103
|
+
return { deleted, branchName: params.branchName };
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
];
|
|
107
|
+
}
|
|
@@ -36,9 +36,7 @@ function createMockRuntime(): AgentRuntime {
|
|
|
36
36
|
blocked: false,
|
|
37
37
|
entry: { id: 'captured-1' },
|
|
38
38
|
})),
|
|
39
|
-
intelligentSearch: vi.fn(async () => [
|
|
40
|
-
{ id: 'r1', title: 'Result 1', score: 0.8 },
|
|
41
|
-
]),
|
|
39
|
+
intelligentSearch: vi.fn(async () => [{ id: 'r1', title: 'Result 1', score: 0.8 }]),
|
|
42
40
|
recordFeedback: vi.fn(),
|
|
43
41
|
},
|
|
44
42
|
governance: {
|
|
@@ -113,9 +111,7 @@ describe('createCaptureOps', () => {
|
|
|
113
111
|
it('uses manual tier override when provided', async () => {
|
|
114
112
|
const result = (await findOp(ops, 'capture_knowledge').handler({
|
|
115
113
|
tier: 'team',
|
|
116
|
-
entries: [
|
|
117
|
-
{ type: 'pattern', domain: 'a', title: 'A', description: 'a', tags: [] },
|
|
118
|
-
],
|
|
114
|
+
entries: [{ type: 'pattern', domain: 'a', title: 'A', description: 'a', tags: [] }],
|
|
119
115
|
})) as Record<string, unknown>;
|
|
120
116
|
expect(result.captured).toBe(1);
|
|
121
117
|
const results = result.results as Array<Record<string, unknown>>;
|
|
@@ -129,9 +125,7 @@ describe('createCaptureOps', () => {
|
|
|
129
125
|
reason: 'Requires review',
|
|
130
126
|
} as unknown);
|
|
131
127
|
const result = (await findOp(ops, 'capture_knowledge').handler({
|
|
132
|
-
entries: [
|
|
133
|
-
{ type: 'pattern', domain: 'a', title: 'A', description: 'a', tags: [] },
|
|
134
|
-
],
|
|
128
|
+
entries: [{ type: 'pattern', domain: 'a', title: 'A', description: 'a', tags: [] }],
|
|
135
129
|
})) as Record<string, unknown>;
|
|
136
130
|
expect(result.proposed).toBe(1);
|
|
137
131
|
expect(result.captured).toBe(0);
|
|
@@ -144,9 +138,7 @@ describe('createCaptureOps', () => {
|
|
|
144
138
|
reason: 'Not allowed',
|
|
145
139
|
} as unknown);
|
|
146
140
|
const result = (await findOp(ops, 'capture_knowledge').handler({
|
|
147
|
-
entries: [
|
|
148
|
-
{ type: 'pattern', domain: 'a', title: 'A', description: 'a', tags: [] },
|
|
149
|
-
],
|
|
141
|
+
entries: [{ type: 'pattern', domain: 'a', title: 'A', description: 'a', tags: [] }],
|
|
150
142
|
})) as Record<string, unknown>;
|
|
151
143
|
expect(result.rejected).toBe(1);
|
|
152
144
|
});
|
|
@@ -157,9 +149,7 @@ describe('createCaptureOps', () => {
|
|
|
157
149
|
duplicate: { id: 'existing-1' },
|
|
158
150
|
} as unknown);
|
|
159
151
|
const result = (await findOp(ops, 'capture_knowledge').handler({
|
|
160
|
-
entries: [
|
|
161
|
-
{ type: 'pattern', domain: 'a', title: 'A', description: 'a', tags: [] },
|
|
162
|
-
],
|
|
152
|
+
entries: [{ type: 'pattern', domain: 'a', title: 'A', description: 'a', tags: [] }],
|
|
163
153
|
})) as Record<string, unknown>;
|
|
164
154
|
expect(result.duplicated).toBe(1);
|
|
165
155
|
expect(result.captured).toBe(0);
|
|
@@ -170,9 +160,7 @@ describe('createCaptureOps', () => {
|
|
|
170
160
|
throw new Error('Capture failed');
|
|
171
161
|
});
|
|
172
162
|
const result = (await findOp(ops, 'capture_knowledge').handler({
|
|
173
|
-
entries: [
|
|
174
|
-
{ type: 'pattern', domain: 'a', title: 'A', description: 'a', tags: [] },
|
|
175
|
-
],
|
|
163
|
+
entries: [{ type: 'pattern', domain: 'a', title: 'A', description: 'a', tags: [] }],
|
|
176
164
|
})) as Record<string, unknown>;
|
|
177
165
|
expect(result.rejected).toBe(1);
|
|
178
166
|
const results = result.results as Array<Record<string, unknown>>;
|
|
@@ -185,9 +173,7 @@ describe('createCaptureOps', () => {
|
|
|
185
173
|
{ entryId: 'related-1', title: 'Related', suggestedType: 'related', score: 0.9 },
|
|
186
174
|
]);
|
|
187
175
|
const result = (await findOp(ops, 'capture_knowledge').handler({
|
|
188
|
-
entries: [
|
|
189
|
-
{ type: 'pattern', domain: 'a', title: 'A', description: 'a', tags: [] },
|
|
190
|
-
],
|
|
176
|
+
entries: [{ type: 'pattern', domain: 'a', title: 'A', description: 'a', tags: [] }],
|
|
191
177
|
})) as Record<string, unknown>;
|
|
192
178
|
expect(result.autoLinkedCount).toBe(1);
|
|
193
179
|
expect(result.suggestedLinks).toBeDefined();
|
|
@@ -95,7 +95,11 @@ describe('createChainOps', () => {
|
|
|
95
95
|
const rt = mockRuntime();
|
|
96
96
|
const ops = captureOps(createChainOps(rt));
|
|
97
97
|
await ops.get('chain_resume')!.handler({ instanceId: 'inst-1', chain: VALID_CHAIN });
|
|
98
|
-
expect(rt.chainRunner.resume).toHaveBeenCalledWith(
|
|
98
|
+
expect(rt.chainRunner.resume).toHaveBeenCalledWith(
|
|
99
|
+
'inst-1',
|
|
100
|
+
VALID_CHAIN,
|
|
101
|
+
expect.any(Function),
|
|
102
|
+
);
|
|
99
103
|
});
|
|
100
104
|
});
|
|
101
105
|
|
|
@@ -113,7 +117,11 @@ describe('createChainOps', () => {
|
|
|
113
117
|
const rt = mockRuntime();
|
|
114
118
|
const ops = captureOps(createChainOps(rt));
|
|
115
119
|
await ops.get('chain_step_approve')!.handler({ instanceId: 'inst-1', chain: VALID_CHAIN });
|
|
116
|
-
expect(rt.chainRunner.approve).toHaveBeenCalledWith(
|
|
120
|
+
expect(rt.chainRunner.approve).toHaveBeenCalledWith(
|
|
121
|
+
'inst-1',
|
|
122
|
+
VALID_CHAIN,
|
|
123
|
+
expect.any(Function),
|
|
124
|
+
);
|
|
117
125
|
});
|
|
118
126
|
});
|
|
119
127
|
|
|
@@ -138,10 +146,12 @@ describe('createChainOps', () => {
|
|
|
138
146
|
(ops as typeof ops & { _setAllOps: (o: typeof fakeOps) => void })._setAllOps(fakeOps);
|
|
139
147
|
|
|
140
148
|
// Execute chain — the dispatch should be able to find 'some_op'
|
|
141
|
-
await ops
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
149
|
+
await ops
|
|
150
|
+
.find((o) => o.name === 'chain_execute')!
|
|
151
|
+
.handler({
|
|
152
|
+
chain: VALID_CHAIN,
|
|
153
|
+
input: {},
|
|
154
|
+
});
|
|
145
155
|
// The dispatch function was passed to chainRunner.execute; verify it was called
|
|
146
156
|
expect(rt.chainRunner.execute).toHaveBeenCalledOnce();
|
|
147
157
|
});
|
|
@@ -124,9 +124,7 @@ describe('composeIntegrationSection', () => {
|
|
|
124
124
|
});
|
|
125
125
|
|
|
126
126
|
it('renders provided facades with up to 5 ops', () => {
|
|
127
|
-
const facades = [
|
|
128
|
-
{ name: 'mybot_custom', ops: ['a', 'b', 'c', 'd', 'e', 'f'] },
|
|
129
|
-
];
|
|
127
|
+
const facades = [{ name: 'mybot_custom', ops: ['a', 'b', 'c', 'd', 'e', 'f'] }];
|
|
130
128
|
const result = composeIntegrationSection(CONFIG, facades);
|
|
131
129
|
expect(result).toContain('`mybot_custom`');
|
|
132
130
|
expect(result).toContain('`a`');
|
|
@@ -43,9 +43,7 @@ describe('ContextHealthMonitor', () => {
|
|
|
43
43
|
expect(status.level).toBe('red');
|
|
44
44
|
expect(status.estimatedFill).toBeGreaterThanOrEqual(0.6);
|
|
45
45
|
expect(status.toolCallCount).toBe(200);
|
|
46
|
-
expect(status.recommendation).toBe(
|
|
47
|
-
'Session capture recommended before context degradation.',
|
|
48
|
-
);
|
|
46
|
+
expect(status.recommendation).toBe('Session capture recommended before context degradation.');
|
|
49
47
|
});
|
|
50
48
|
|
|
51
49
|
it('should reset all tracking', () => {
|
|
@@ -56,9 +56,7 @@ export class ContextHealthMonitor {
|
|
|
56
56
|
|
|
57
57
|
/** Check current context health status. */
|
|
58
58
|
check(): ContextHealthStatus {
|
|
59
|
-
const estimatedTokens = Math.round(
|
|
60
|
-
this.totalPayloadSize * OVERHEAD_FACTOR,
|
|
61
|
-
);
|
|
59
|
+
const estimatedTokens = Math.round(this.totalPayloadSize * OVERHEAD_FACTOR);
|
|
62
60
|
const estimatedFill = Math.min(estimatedTokens / CONTEXT_WINDOW, 1.0);
|
|
63
61
|
const level = this.classifyLevel(estimatedFill);
|
|
64
62
|
|
|
@@ -14,7 +14,9 @@ function mockRuntime() {
|
|
|
14
14
|
recordSnapshot: vi.fn().mockReturnValue({ recorded: true, historyId: 42 }),
|
|
15
15
|
getQueueStats: vi.fn().mockReturnValue({ totalEntries: 5, groomedEntries: 3 }),
|
|
16
16
|
enrichMetadata: vi.fn().mockReturnValue({ enriched: false, changes: [] }),
|
|
17
|
-
detectContradictionsHybrid: vi
|
|
17
|
+
detectContradictionsHybrid: vi
|
|
18
|
+
.fn()
|
|
19
|
+
.mockResolvedValue({ contradictions: [], method: 'tfidf-only' }),
|
|
18
20
|
consolidate: vi.fn(),
|
|
19
21
|
},
|
|
20
22
|
jobQueue: {
|
|
@@ -94,13 +94,13 @@ describe('createDomainFacade', () => {
|
|
|
94
94
|
it('falls back to vault FTS when brain returns empty', async () => {
|
|
95
95
|
const rt = mockRuntime();
|
|
96
96
|
(rt.brain.intelligentSearch as ReturnType<typeof vi.fn>).mockResolvedValue([]);
|
|
97
|
-
(rt.vault.search as ReturnType<typeof vi.fn>).mockReturnValue([
|
|
98
|
-
{ entry: { id: 'e1' } },
|
|
99
|
-
]);
|
|
97
|
+
(rt.vault.search as ReturnType<typeof vi.fn>).mockReturnValue([{ entry: { id: 'e1' } }]);
|
|
100
98
|
const facade = createDomainFacade(rt, 'a', 'security');
|
|
101
|
-
const results = (await facade.ops
|
|
102
|
-
|
|
103
|
-
|
|
99
|
+
const results = (await facade.ops
|
|
100
|
+
.find((o) => o.name === 'search')!
|
|
101
|
+
.handler({
|
|
102
|
+
query: 'test',
|
|
103
|
+
})) as unknown[];
|
|
104
104
|
expect(rt.vault.search).toHaveBeenCalledWith('test', { domain: 'security', limit: 10 });
|
|
105
105
|
expect(results).toHaveLength(1);
|
|
106
106
|
});
|
|
@@ -118,9 +118,11 @@ describe('createDomainFacade', () => {
|
|
|
118
118
|
it('returns error object for missing entry', async () => {
|
|
119
119
|
const rt = mockRuntime();
|
|
120
120
|
const facade = createDomainFacade(rt, 'a', 'testing');
|
|
121
|
-
const result = (await facade.ops
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
const result = (await facade.ops
|
|
122
|
+
.find((o) => o.name === 'get_entry')!
|
|
123
|
+
.handler({
|
|
124
|
+
id: 'missing',
|
|
125
|
+
})) as { error: string };
|
|
124
126
|
expect(result.error).toContain('missing');
|
|
125
127
|
});
|
|
126
128
|
});
|
|
@@ -129,14 +131,16 @@ describe('createDomainFacade', () => {
|
|
|
129
131
|
it('calls brain.enrichAndCapture when governance allows', async () => {
|
|
130
132
|
const rt = mockRuntime();
|
|
131
133
|
const facade = createDomainFacade(rt, 'a', 'security');
|
|
132
|
-
const result = (await facade.ops
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
134
|
+
const result = (await facade.ops
|
|
135
|
+
.find((o) => o.name === 'capture')!
|
|
136
|
+
.handler({
|
|
137
|
+
id: 'new-1',
|
|
138
|
+
type: 'pattern',
|
|
139
|
+
title: 'Test',
|
|
140
|
+
severity: 'warning',
|
|
141
|
+
description: 'desc',
|
|
142
|
+
tags: ['x'],
|
|
143
|
+
})) as { captured: boolean; governance: { action: string } };
|
|
140
144
|
expect(rt.brain.enrichAndCapture).toHaveBeenCalledOnce();
|
|
141
145
|
expect(result.governance.action).toBe('capture');
|
|
142
146
|
});
|
|
@@ -148,14 +152,16 @@ describe('createDomainFacade', () => {
|
|
|
148
152
|
reason: 'needs review',
|
|
149
153
|
});
|
|
150
154
|
const facade = createDomainFacade(rt, 'a', 'security');
|
|
151
|
-
const result = (await facade.ops
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
155
|
+
const result = (await facade.ops
|
|
156
|
+
.find((o) => o.name === 'capture')!
|
|
157
|
+
.handler({
|
|
158
|
+
id: 'p1',
|
|
159
|
+
type: 'pattern',
|
|
160
|
+
title: 'Proposed',
|
|
161
|
+
severity: 'warning',
|
|
162
|
+
description: 'desc',
|
|
163
|
+
tags: [],
|
|
164
|
+
})) as { captured: boolean; governance: { action: string; proposalId: number } };
|
|
159
165
|
expect(result.captured).toBe(false);
|
|
160
166
|
expect(result.governance.action).toBe('propose');
|
|
161
167
|
expect(result.governance.proposalId).toBe(1);
|
|
@@ -168,14 +174,16 @@ describe('createDomainFacade', () => {
|
|
|
168
174
|
reason: 'quota exceeded',
|
|
169
175
|
});
|
|
170
176
|
const facade = createDomainFacade(rt, 'a', 'security');
|
|
171
|
-
const result = (await facade.ops
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
177
|
+
const result = (await facade.ops
|
|
178
|
+
.find((o) => o.name === 'capture')!
|
|
179
|
+
.handler({
|
|
180
|
+
id: 'r1',
|
|
181
|
+
type: 'rule',
|
|
182
|
+
title: 'Rejected',
|
|
183
|
+
severity: 'warning',
|
|
184
|
+
description: 'desc',
|
|
185
|
+
tags: [],
|
|
186
|
+
})) as { captured: boolean; governance: { action: string; reason: string } };
|
|
179
187
|
expect(result.captured).toBe(false);
|
|
180
188
|
expect(result.governance.action).toBe('reject');
|
|
181
189
|
expect(result.governance.reason).toBe('quota exceeded');
|
|
@@ -186,9 +194,11 @@ describe('createDomainFacade', () => {
|
|
|
186
194
|
it('returns removed status', async () => {
|
|
187
195
|
const rt = mockRuntime();
|
|
188
196
|
const facade = createDomainFacade(rt, 'a', 'testing');
|
|
189
|
-
const result = (await facade.ops
|
|
190
|
-
|
|
191
|
-
|
|
197
|
+
const result = (await facade.ops
|
|
198
|
+
.find((o) => o.name === 'remove')!
|
|
199
|
+
.handler({
|
|
200
|
+
id: 'del-1',
|
|
201
|
+
})) as { removed: boolean; id: string };
|
|
192
202
|
expect(result.removed).toBe(true);
|
|
193
203
|
expect(result.id).toBe('del-1');
|
|
194
204
|
});
|
|
@@ -244,10 +244,7 @@ describe('createAdminFacadeOps', () => {
|
|
|
244
244
|
|
|
245
245
|
describe('admin_vault_size (from satellite)', () => {
|
|
246
246
|
it('returns in-memory for :memory: vault', async () => {
|
|
247
|
-
const result = (await findOp(ops, 'admin_vault_size').handler({})) as Record<
|
|
248
|
-
string,
|
|
249
|
-
unknown
|
|
250
|
-
>;
|
|
247
|
+
const result = (await findOp(ops, 'admin_vault_size').handler({})) as Record<string, unknown>;
|
|
251
248
|
expect(result.path).toBe(':memory:');
|
|
252
249
|
expect(result.sizeHuman).toBe('in-memory');
|
|
253
250
|
});
|
|
@@ -90,9 +90,18 @@ describe('archive-facade', () => {
|
|
|
90
90
|
|
|
91
91
|
it('includes all expected op names', () => {
|
|
92
92
|
const expected = [
|
|
93
|
-
'vault_archive',
|
|
94
|
-
'
|
|
95
|
-
'
|
|
93
|
+
'vault_archive',
|
|
94
|
+
'vault_restore',
|
|
95
|
+
'vault_optimize',
|
|
96
|
+
'vault_backup',
|
|
97
|
+
'vault_age_report',
|
|
98
|
+
'vault_set_temporal',
|
|
99
|
+
'vault_find_expiring',
|
|
100
|
+
'vault_find_expired',
|
|
101
|
+
'knowledge_audit',
|
|
102
|
+
'knowledge_health',
|
|
103
|
+
'knowledge_merge',
|
|
104
|
+
'knowledge_reorganize',
|
|
96
105
|
];
|
|
97
106
|
for (const name of expected) {
|
|
98
107
|
expect(ops.has(name), `missing op: ${name}`).toBe(true);
|
|
@@ -121,7 +130,8 @@ describe('archive-facade', () => {
|
|
|
121
130
|
describe('vault_archive', () => {
|
|
122
131
|
it('archives old entries', async () => {
|
|
123
132
|
const result = await executeOp(ops, 'vault_archive', {
|
|
124
|
-
olderThanDays: 90,
|
|
133
|
+
olderThanDays: 90,
|
|
134
|
+
reason: 'cleanup',
|
|
125
135
|
});
|
|
126
136
|
expect(result.success).toBe(true);
|
|
127
137
|
const vault = runtime.vault as ReturnType<typeof makeMockVault>;
|
|
@@ -178,7 +188,9 @@ describe('archive-facade', () => {
|
|
|
178
188
|
describe('vault_set_temporal', () => {
|
|
179
189
|
it('sets temporal fields', async () => {
|
|
180
190
|
const result = await executeOp(ops, 'vault_set_temporal', {
|
|
181
|
-
id: 'entry-1',
|
|
191
|
+
id: 'entry-1',
|
|
192
|
+
validFrom: 1000,
|
|
193
|
+
validUntil: 2000,
|
|
182
194
|
});
|
|
183
195
|
expect(result.success).toBe(true);
|
|
184
196
|
const data = result.data as { updated: boolean };
|
|
@@ -251,7 +263,8 @@ describe('archive-facade', () => {
|
|
|
251
263
|
.mockReturnValueOnce(makeEntry({ id: 'remove', tags: ['b'] }));
|
|
252
264
|
|
|
253
265
|
const result = await executeOp(ops, 'knowledge_merge', {
|
|
254
|
-
keepId: 'keep',
|
|
266
|
+
keepId: 'keep',
|
|
267
|
+
removeId: 'remove',
|
|
255
268
|
});
|
|
256
269
|
expect(result.success).toBe(true);
|
|
257
270
|
const data = result.data as { merged: boolean; keptId: string };
|
|
@@ -263,7 +276,8 @@ describe('archive-facade', () => {
|
|
|
263
276
|
const vault = runtime.vault as ReturnType<typeof makeMockVault>;
|
|
264
277
|
vault.get.mockReturnValue(null);
|
|
265
278
|
const result = await executeOp(ops, 'knowledge_merge', {
|
|
266
|
-
keepId: 'x',
|
|
279
|
+
keepId: 'x',
|
|
280
|
+
removeId: 'y',
|
|
267
281
|
});
|
|
268
282
|
expect(result.success).toBe(true);
|
|
269
283
|
const data = result.data as { error: string };
|