diff --git a/packages/cli/src/config/config.test.ts b/packages/cli/src/config/config.test.ts index a568b1e93e..c28bc33757 100644 --- a/packages/cli/src/config/config.test.ts +++ b/packages/cli/src/config/config.test.ts @@ -3199,7 +3199,6 @@ describe('Policy Engine Integration in loadCliConfig', () => { }), expect.anything(), undefined, - undefined, ); }); @@ -3222,7 +3221,6 @@ describe('Policy Engine Integration in loadCliConfig', () => { }), expect.anything(), undefined, - undefined, ); }); @@ -3244,7 +3242,6 @@ describe('Policy Engine Integration in loadCliConfig', () => { }), expect.anything(), undefined, - undefined, ); }); }); diff --git a/packages/cli/src/config/policy.ts b/packages/cli/src/config/policy.ts index 5d48271ede..2caa8d71e0 100644 --- a/packages/cli/src/config/policy.ts +++ b/packages/cli/src/config/policy.ts @@ -27,14 +27,10 @@ export async function createPolicyEngineConfig( tools: settings.tools, mcpServers: settings.mcpServers, policyPaths: settings.policyPaths, + workspacePoliciesDir, }; - return createCorePolicyEngineConfig( - policySettings, - approvalMode, - undefined, - workspacePoliciesDir, - ); + return createCorePolicyEngineConfig(policySettings, approvalMode); } export function createPolicyUpdater( diff --git a/packages/cli/src/config/workspace-policy-cli.test.ts b/packages/cli/src/config/workspace-policy-cli.test.ts index e6ad5bfc4c..630c7245b8 100644 --- a/packages/cli/src/config/workspace-policy-cli.test.ts +++ b/packages/cli/src/config/workspace-policy-cli.test.ts @@ -81,10 +81,13 @@ describe('Workspace-Level Policy CLI Integration', () => { await loadCliConfig(settings, 'test-session', argv, { cwd: MOCK_CWD }); expect(ServerConfig.createPolicyEngineConfig).toHaveBeenCalledWith( - expect.anything(), + expect.objectContaining({ + workspacePoliciesDir: expect.stringContaining( + path.join('.gemini', 'policies'), + ), + }), expect.anything(), undefined, - expect.stringContaining(path.join('.gemini', 'policies')), ); }); @@ -100,9 +103,10 @@ describe('Workspace-Level Policy CLI Integration', () => { await loadCliConfig(settings, 'test-session', argv, { cwd: MOCK_CWD }); expect(ServerConfig.createPolicyEngineConfig).toHaveBeenCalledWith( + expect.objectContaining({ + workspacePoliciesDir: undefined, + }), expect.anything(), - expect.anything(), - undefined, undefined, ); }); @@ -124,9 +128,10 @@ describe('Workspace-Level Policy CLI Integration', () => { await loadCliConfig(settings, 'test-session', argv, { cwd: MOCK_CWD }); expect(ServerConfig.createPolicyEngineConfig).toHaveBeenCalledWith( + expect.objectContaining({ + workspacePoliciesDir: undefined, + }), expect.anything(), - expect.anything(), - undefined, undefined, ); }); @@ -152,9 +157,10 @@ describe('Workspace-Level Policy CLI Integration', () => { expect.stringContaining('Workspace policies changed or are new'), ); expect(ServerConfig.createPolicyEngineConfig).toHaveBeenCalledWith( + expect.objectContaining({ + workspacePoliciesDir: undefined, + }), expect.anything(), - expect.anything(), - undefined, undefined, // Should NOT load policies ); }); @@ -181,10 +187,13 @@ describe('Workspace-Level Policy CLI Integration', () => { 'new-hash', ); expect(ServerConfig.createPolicyEngineConfig).toHaveBeenCalledWith( - expect.anything(), + expect.objectContaining({ + workspacePoliciesDir: expect.stringContaining( + path.join('.gemini', 'policies'), + ), + }), expect.anything(), undefined, - expect.stringContaining(path.join('.gemini', 'policies')), ); }); @@ -220,9 +229,10 @@ describe('Workspace-Level Policy CLI Integration', () => { // so it currently DOES NOT pass the directory to createPolicyEngineConfig yet. // The UI will handle the confirmation and reload/update. expect(ServerConfig.createPolicyEngineConfig).toHaveBeenCalledWith( + expect.objectContaining({ + workspacePoliciesDir: undefined, + }), expect.anything(), - expect.anything(), - undefined, undefined, ); }); @@ -254,9 +264,10 @@ describe('Workspace-Level Policy CLI Integration', () => { }); expect(ServerConfig.createPolicyEngineConfig).toHaveBeenCalledWith( + expect.objectContaining({ + workspacePoliciesDir: undefined, + }), expect.anything(), - expect.anything(), - undefined, undefined, ); }); diff --git a/packages/core/src/policy/config.ts b/packages/core/src/policy/config.ts index 413ef81ae7..4db5533c80 100644 --- a/packages/core/src/policy/config.ts +++ b/packages/core/src/policy/config.ts @@ -167,12 +167,11 @@ export async function createPolicyEngineConfig( settings: PolicySettings, approvalMode: ApprovalMode, defaultPoliciesDir?: string, - workspacePoliciesDir?: string, ): Promise { const policyDirs = getPolicyDirectories( defaultPoliciesDir, settings.policyPaths, - workspacePoliciesDir, + settings.workspacePoliciesDir, ); const securePolicyDirs = await filterSecurePolicyDirectories(policyDirs); @@ -186,7 +185,11 @@ export async function createPolicyEngineConfig( checkers: tomlCheckers, errors, } = await loadPoliciesFromToml(securePolicyDirs, (p) => { - const tier = getPolicyTier(p, defaultPoliciesDir, workspacePoliciesDir); + const tier = getPolicyTier( + p, + defaultPoliciesDir, + settings.workspacePoliciesDir, + ); // If it's a user-provided path that isn't already categorized as ADMIN, // treat it as USER tier. diff --git a/packages/core/src/policy/types.ts b/packages/core/src/policy/types.ts index 2e672fff26..17ae6003a1 100644 --- a/packages/core/src/policy/types.ts +++ b/packages/core/src/policy/types.ts @@ -272,7 +272,9 @@ export interface PolicySettings { allowed?: string[]; }; mcpServers?: Record; + // User provided policies that will replace the USER level policies in ~/.gemini/policies policyPaths?: string[]; + workspacePoliciesDir?: string; } export interface CheckResult { diff --git a/packages/core/src/policy/workspace-policy.test.ts b/packages/core/src/policy/workspace-policy.test.ts index fea2ee39db..999dae6f0d 100644 --- a/packages/core/src/policy/workspace-policy.test.ts +++ b/packages/core/src/policy/workspace-policy.test.ts @@ -134,10 +134,9 @@ priority = 10 // Test 1: Workspace vs User (User should win) const config = await createPolicyEngineConfig( - {}, + { workspacePoliciesDir }, ApprovalMode.DEFAULT, defaultPoliciesDir, - workspacePoliciesDir, ); const rules = config.rules?.filter((r) => r.toolName === 'test_tool'); @@ -214,10 +213,9 @@ priority=10`, const { createPolicyEngineConfig } = await import('./config.js'); const config = await createPolicyEngineConfig( - {}, + { workspacePoliciesDir: undefined }, ApprovalMode.DEFAULT, defaultPoliciesDir, - undefined, // No workspace dir ); // Should only have default tier rule (1.01) @@ -280,10 +278,8 @@ priority=500`, const { createPolicyEngineConfig } = await import('./config.js'); const config = await createPolicyEngineConfig( - {}, + { workspacePoliciesDir }, ApprovalMode.DEFAULT, - undefined, - workspacePoliciesDir, ); const rule = config.rules?.find((r) => r.toolName === 'p_tool');