/ src / lib / server / tool-capability-policy.test.ts
tool-capability-policy.test.ts
 1  import assert from 'node:assert/strict'
 2  import { test } from 'node:test'
 3  import {
 4    resolveConcreteToolPolicyBlock,
 5    resolveSessionToolPolicy,
 6  } from './tool-capability-policy'
 7  
 8  test('capability policy permissive mode allows non-blocked tools', () => {
 9    const decision = resolveSessionToolPolicy(['shell', 'web_search'], { capabilityPolicyMode: 'permissive' })
10    assert.deepEqual(decision.enabledExtensions, ['shell', 'web_search'])
11    assert.equal(decision.blockedExtensions.length, 0)
12  })
13  
14  test('capability policy balanced mode blocks destructive delete_file', () => {
15    const decision = resolveSessionToolPolicy(['files', 'delete_file'], { capabilityPolicyMode: 'balanced' })
16    assert.deepEqual(decision.enabledExtensions, ['files'])
17    assert.equal(decision.blockedExtensions.length, 1)
18    assert.equal(decision.blockedExtensions[0].tool, 'delete_file')
19  })
20  
21  test('capability policy strict mode blocks execution/platform families', () => {
22    const decision = resolveSessionToolPolicy(
23      ['shell', 'execute', 'manage_tasks', 'web_search', 'memory'],
24      { capabilityPolicyMode: 'strict' },
25    )
26    assert.deepEqual(decision.enabledExtensions, ['web_search', 'memory'])
27    assert.equal(decision.blockedExtensions.some((entry) => entry.tool === 'shell'), true)
28    assert.equal(decision.blockedExtensions.some((entry) => entry.tool === 'execute'), true)
29    assert.equal(decision.blockedExtensions.some((entry) => entry.tool === 'manage_tasks'), true)
30  })
31  
32  test('capability policy respects explicit allow overrides', () => {
33    const decision = resolveSessionToolPolicy(
34      ['shell', 'web_search'],
35      {
36        capabilityPolicyMode: 'strict',
37        capabilityAllowedTools: ['shell'],
38      },
39    )
40    assert.deepEqual(decision.enabledExtensions, ['shell', 'web_search'])
41  })
42  
43  test('concrete tool checks inherit blocked family rules', () => {
44    const decision = resolveSessionToolPolicy(
45      ['claude_code', 'codex_cli'],
46      {
47        safetyBlockedTools: ['delegate_to_codex_cli'],
48      },
49    )
50  
51    assert.equal(
52      resolveConcreteToolPolicyBlock('delegate_to_codex_cli', decision, { safetyBlockedTools: ['delegate_to_codex_cli'] }),
53      'blocked by safety policy',
54    )
55    assert.equal(
56      resolveConcreteToolPolicyBlock('delegate_to_claude_code', decision, { safetyBlockedTools: ['delegate_to_codex_cli'] }),
57      null,
58    )
59  })
60  
61  test('task and project management can be disabled from app settings', () => {
62    const decision = resolveSessionToolPolicy(
63      ['manage_platform', 'manage_tasks', 'manage_projects'],
64      {
65        taskManagementEnabled: false,
66        projectManagementEnabled: false,
67      },
68    )
69  
70    assert.deepEqual(decision.enabledExtensions, ['manage_platform'])
71    assert.equal(
72      decision.blockedExtensions.some((entry) => entry.tool === 'manage_tasks' && /disabled in app settings/.test(entry.reason)),
73      true,
74    )
75    assert.equal(
76      decision.blockedExtensions.some((entry) => entry.tool === 'manage_projects' && /disabled in app settings/.test(entry.reason)),
77      true,
78    )
79    assert.match(
80      resolveConcreteToolPolicyBlock('manage_tasks', decision, { taskManagementEnabled: false })!,
81      /task management is disabled/i,
82    )
83  })