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 })