diff --git a/cli/src/codex/utils/appServerConfig.test.ts b/cli/src/codex/utils/appServerConfig.test.ts index 32224112..f135a1ba 100644 --- a/cli/src/codex/utils/appServerConfig.test.ts +++ b/cli/src/codex/utils/appServerConfig.test.ts @@ -27,6 +27,17 @@ describe('appServerConfig', () => { }); }); + it('uses on-request approvals for default Codex threads', () => { + const params = buildThreadStartParams({ + cwd: '/workspace/project', + mode: { permissionMode: 'default', collaborationMode: 'default' }, + mcpServers + }); + + expect(params.sandbox).toBe('workspace-write'); + expect(params.approvalPolicy).toBe('on-request'); + }); + it('ignores CLI overrides when permission mode is not default', () => { const params = buildThreadStartParams({ cwd: '/workspace/project', diff --git a/cli/src/codex/utils/permissionModeConfig.test.ts b/cli/src/codex/utils/permissionModeConfig.test.ts new file mode 100644 index 00000000..927308f3 --- /dev/null +++ b/cli/src/codex/utils/permissionModeConfig.test.ts @@ -0,0 +1,20 @@ +import { describe, expect, it } from 'vitest'; +import { resolveCodexPermissionModeConfig } from './permissionModeConfig'; + +describe('resolveCodexPermissionModeConfig', () => { + it('uses on-request approvals for default mode', () => { + expect(resolveCodexPermissionModeConfig('default')).toEqual({ + approvalPolicy: 'on-request', + sandbox: 'workspace-write', + sandboxPolicy: { type: 'workspaceWrite' } + }); + }); + + it('keeps safe-yolo escalation on failure', () => { + expect(resolveCodexPermissionModeConfig('safe-yolo')).toEqual({ + approvalPolicy: 'on-failure', + sandbox: 'workspace-write', + sandboxPolicy: { type: 'workspaceWrite' } + }); + }); +}); diff --git a/cli/src/codex/utils/permissionModeConfig.ts b/cli/src/codex/utils/permissionModeConfig.ts index 30089409..e0838834 100644 --- a/cli/src/codex/utils/permissionModeConfig.ts +++ b/cli/src/codex/utils/permissionModeConfig.ts @@ -11,7 +11,10 @@ export function resolveCodexPermissionModeConfig(mode: CodexPermissionMode): Cod switch (mode) { case 'default': return { - approvalPolicy: 'untrusted', + // Remote Codex sessions rely on HAPI's approval UI for sandbox escalation. + // `on-request` keeps workspace-write sandboxing while still surfacing a + // user-approvable elevation request when the model needs it. + approvalPolicy: 'on-request', sandbox: 'workspace-write', sandboxPolicy: { type: 'workspaceWrite' } };