/** * A5+A4 regression: ToolRegistry permission fixes * A5: ACTION_BRANCHES was module-level const — `this` was undefined in read_only/sandbox. * Fix: moved to instance method execute_branch(). * A4: build_permission_context passed undefined for task_scope/permission_profile. * Fix: passes context.task_scope and context.permission_profile. */ import { describe, it, expect } from 'bun:test' import { readFileSync } from 'fs' import { join } from 'path' describe('A5+A4: ToolRegistry permission fixes', () => { const src = readFileSync( join(import.meta.dir, '..', '..', 'src', 'tools', 'ToolRegistry.ts'), 'utf-8' ) it('does not have module-level ACTION_BRANCHES constant', () => { expect(src).not.toMatch(/^const ACTION_BRANCHES/m) }) it('has execute_branch as instance method', () => { expect(src).toMatch(/execute_branch\s*\(/) }) it('ToolExecutionContext includes task_scope field', () => { const ctx_match = src.match(/interface ToolExecutionContext[^}]+}/s) expect(ctx_match).not.toBeNull() expect(ctx_match![0]).toContain('task_scope') }) it('ToolExecutionContext includes permission_profile field', () => { const ctx_match = src.match(/interface ToolExecutionContext[^}]+}/s) expect(ctx_match).not.toBeNull() expect(ctx_match![0]).toContain('permission_profile') }) it('build_permission_context passes context.task_scope instead of undefined', () => { const build_match = src.match(/private build_permission_context[^{]+\{[^}]+}/s) expect(build_match).not.toBeNull() expect(build_match![0]).toContain('context.task_scope') expect(build_match![0]).not.toMatch(/task_scope:\s*undefined/) }) it('build_permission_context passes context.permission_profile instead of undefined', () => { const build_match = src.match(/private build_permission_context[^{]+\{[^}]+}/s) expect(build_match).not.toBeNull() expect(build_match![0]).toContain('context.permission_profile') expect(build_match![0]).not.toMatch(/permission_profile:\s*undefined/) }) it('permission branches preserve original call_id', () => { expect(src).toContain('permission.prompt.requested') expect(src).toContain('request_ref: { call_id: call.call_id') expect(src).toContain("create_error_result(call.call_id, 'permission_denied'") expect(src).not.toContain("create_error_result('', 'user_prompt_required'") expect(src).not.toContain("create_error_result('', 'permission_denied'") }) })