Skip to content

Fix/pending tools and trust overrides#27854

Merged
galz10 merged 7 commits into
google-gemini:mainfrom
jvargassanchez-dot:fix/pending-tools-and-trust-overrides
Jun 15, 2026
Merged

Fix/pending tools and trust overrides#27854
galz10 merged 7 commits into
google-gemini:mainfrom
jvargassanchez-dot:fix/pending-tools-and-trust-overrides

Conversation

@jvargassanchez-dot

@jvargassanchez-dot jvargassanchez-dot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR improves the agent's execution stability by preventing premature state progression when the agent is waiting for user tool approvals. It also eliminates race conditions during file modifications by forcing file writes to execute sequentially, and fixes a configuration bug to ensure environment variables correctly override workspace trust settings.

Details

  • Execution State: Added hasPendingTools() and getPendingToolsCount() to the Task class. The CoderAgentExecutor now uses these to safely pause its execution loop and yield the turn to the user when tool confirmations are pending.
  • Sequential File Writes: Updated _isParallelizable in the scheduler to treat WRITE_FILE_TOOL_NAME as non-parallelizable. This ensures multiple file edits requested in a single LLM batch do not conflict with each other.
  • Trust Configuration: Extracted the trust resolution into a new setIsTrusted helper, allowing the GEMINI_FOLDER_TRUST environment variable to take precedence over internal agent settings.
  • Testing: Added comprehensive unit and integration tests across the agent, configuration, and scheduler modules to guarantee these behaviors.

Related Issues

Fixes b/521342062 # 400 error when using the write file tool
Fixes b/522312717 # The "Untrusted Folder" message appears in chat even when working within a trusted folder.

How to Validate

  1. Run unit tests for the A2A server:
    npm test -w @google/gemini-cli-a2a-server
  2. Verify that all 140 tests pass.
  3. Run unit test for core:
    yarn workspace @google/gemini-cli-core build
    yarn test -w @google/gemini-cli-core
  4. Verify that all tests modified in this PR pass.

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
  • Validated on required platforms/methods:
    • MacOS
      • npm run
      • npx
      • Docker
      • Podman
      • Seatbelt
    • Windows
      • npm run
      • npx
      • Docker
    • [ x] Linux
      • [ x] npm run
      • npx
      • Docker

- task/executor: Add  check to safely yield the agent turn when waiting for tool approvals, preventing premature state progression.
- config: Extract  logic to allow  environment variables to properly override workspace trust settings.
- scheduler: Enforce sequential execution for  to prevent parallel modification race conditions.
- : Add unit tests for  verifying environment variable overrides.
- : Add unit tests for  and  state tracking.
-  : Add integration test to verify  is strictly executed sequentially within batches.
- : Update mock implementations and add coverage for the new execution yielding logic.
@jvargassanchez-dot jvargassanchez-dot requested a review from a team as a code owner June 11, 2026 21:42
@github-actions github-actions Bot added the size/m A medium sized PR label Jun 11, 2026
@github-actions

github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown

📊 PR Size: size/L

  • Lines changed: 285
  • Additions: +248
  • Deletions: -37
  • Files changed: 8

@gemini-cli gemini-cli Bot added the status/need-issue Pull requests that need to have an associated issue. label Jun 11, 2026
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the robustness of the agent's execution environment by addressing critical race conditions and state management issues. By enforcing sequential execution for file writes and implementing a proper waiting mechanism for pending tool approvals, the agent now handles complex task sequences more reliably. Additionally, the configuration logic has been improved to provide better control over workspace trust settings via environment variables.

Highlights

  • Execution Stability: Introduced pending tool tracking in the Task class to prevent premature state progression, ensuring the agent yields to the user when tool approvals are required.
  • Sequential File Operations: Updated the scheduler to treat file write operations as non-parallelizable, preventing race conditions during concurrent file modifications.
  • Trust Configuration: Added a centralized trust resolution helper that allows the GEMINI_FOLDER_TRUST environment variable to override internal workspace trust settings.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces several updates to the agent execution and scheduling logic. Specifically, it adds a new setIsTrusted utility in config.ts to determine folder trust based on the GEMINI_FOLDER_TRUST environment variable or agent settings, and integrates it into the CoderAgentExecutor. It also implements checks for pending tools in the executor loop to yield control back to the user when tools are awaiting approval. Additionally, the scheduler has been updated to force sequential execution of the write_file tool, preventing parallel writes. Unit tests have been added to cover these new behaviors. As there are no review comments provided, I have no additional feedback to offer.

@galz10 galz10 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

Intent Summary: This PR prevents the agent from advancing while tool confirmations are pending, serializes file writes to avoid race conditions, and attempts to allow the GEMINI_FOLDER_TRUST environment variable to override workspace trust settings.

🚨 Critical Concerns (P0/P1)

Action required before merging.

  • Security Flaw / Fail-Open Behavior (packages/a2a-server/src/config/config.ts:185): The trust override logic is additive (||), not an override. If a user or CI pipeline explicitly sets GEMINI_FOLDER_TRUST=false to enforce a strict security boundary, this function ignores it if agentSettings?.isTrusted is true. Environment variables should act as an authoritative system-level override. The current implementation only allows the environment variable to escalate privileges (grant trust), but fails to let it revoke privileges (enforce distrust).

    // Suggested fix:
    export function setIsTrusted(
      agentSettings: AgentSettings | undefined,
    ): boolean {
      if (process.env['GEMINI_FOLDER_TRUST'] !== undefined) {
        return process.env['GEMINI_FOLDER_TRUST'] === 'true';
      }
      return !!agentSettings?.isTrusted;
    }

    (Note: You must also update the corresponding tests in config.test.ts which currently encode this flawed fallback behavior).

  • Incomplete Race Condition Fix (packages/core/src/scheduler/scheduler.ts:554): Serializing WRITE_FILE_TOOL_NAME to prevent file modification race conditions is incomplete because it omits EDIT_TOOL_NAME (the replace tool). Concurrent replace calls or a mix of replace and write_file on the same file will still race and corrupt data. Add EDIT_TOOL_NAME to the non-parallelizable list.

  • Missing Test Coverage (packages/a2a-server/src/agent/executor.ts:549): Added a new control flow branch for currentTask.hasPendingTools(), but packages/a2a-server/src/agent/executor.test.ts only mocks this to return false. There are no test cases verifying that the executor properly yields the turn when tools are pending. This is a P0 test coverage violation.

🧹 Refactoring & Nits (P2/P3)

Recommended improvements.

  • packages/a2a-server/src/agent/task.ts:140: Replace hasPendingTools() and getPendingToolsCount() with TypeScript getters (e.g., get hasPendingTools()) to adhere to standard class property access conventions, rather than creating distinct getter methods.

📝 Metadata Review

  • The PR description is clear, but the "Trust Configuration" bullet incorrectly claims the environment variable takes "precedence" over internal settings. The implementation only allows the env var to elevate trust, not revoke it. Fix the code to match the PR description's intent.

…overage

- Include the  tool constant to ensure it is not parallelizable.
- - Refactor  and  in the  class into TypeScript getters ( and ) to adhere to standard property access conventions.

- Add missing test coverage in executor.test.ts to verify the executor correctly yields the turn and transitions to input-required when tools are pending.
- Improve the validation of environment variables within the  function's logic.
- - Expand test coverage in  to fully verify the environment variable precedence logic in .

- Add integration tests to validate the new  constant in parallelizable validation.
@github-actions github-actions Bot added the size/l A large sized PR label Jun 12, 2026
@jvargassanchez-dot

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements sequential execution for file-writing and editing tools, adds a mechanism to yield the agent's turn when tools are pending user approval, and introduces a setIsTrusted helper to determine workspace trust. A critical security vulnerability was identified where workspace-level .env files can pollute global environment variables and bypass the folder trust mechanism, potentially leading to Remote Code Execution (RCE).

Comment on lines +185 to +192
export function setIsTrusted(
agentSettings: AgentSettings | undefined,
): boolean {
if (process.env['GEMINI_FOLDER_TRUST'] !== undefined) {
return process.env['GEMINI_FOLDER_TRUST'] === 'true';
}
return !!agentSettings?.isTrusted;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-critical critical

Folder Trust Bypass via Workspace .env Environment Pollution

Severity: critical
Sub-category: Broken Access Control / Environment Pollution

Description:
The setIsTrusted function determines if a workspace folder is trusted by checking process.env['GEMINI_FOLDER_TRUST'] and falling back to agentSettings.isTrusted.
However, in CoderAgentExecutor.getConfig (in packages/a2a-server/src/agent/executor.ts), loadEnvironment() is called immediately after setIsTrusted. loadEnvironment() loads environment variables from the workspace's .env file and overrides process.env globally using dotenv.config({ override: true }).
If an untrusted workspace contains a .env file with GEMINI_FOLDER_TRUST=true, this value will be loaded into process.env globally. On any subsequent task execution or configuration resolution, setIsTrusted will read this polluted environment variable and return true, completely bypassing the folder trust security mechanism.
Since trusted folders allow the agent to execute powerful tools (such as running arbitrary shell commands) without user confirmation, this bypass directly enables Remote Code Execution (RCE) when an untrusted folder is opened.

Remediation:
Do not allow workspace-level .env files to override system-level security environment variables like GEMINI_FOLDER_TRUST. Alternatively, resolve the folder trust status using only the system's initial environment variables or the explicit agentSettings.isTrusted passed by the client, and prevent loadEnvironment() from overriding security-critical environment variables.

const INITIAL_FOLDER_TRUST = process.env['GEMINI_FOLDER_TRUST'];

export function setIsTrusted(
  agentSettings: AgentSettings | undefined,
): boolean {
  if (INITIAL_FOLDER_TRUST !== undefined) {
    return INITIAL_FOLDER_TRUST === 'true';
  }
  return !!agentSettings?.isTrusted;
}
References
  1. Workspace-level configurations should be treated as untrusted by default. Security-sensitive settings, such as policy paths, must be loaded from trusted user-level configuration and should not be overridable by workspace settings unless trust is explicitly granted by the hosting environment.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix this.

…_TRUST in config.ts to evaluate it once upon initialization and Update config.test.ts to use vi.resetModules() and dynamic imports to properly mock module-level environment variables.
@jvargassanchez-dot

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces tracking for pending tools to yield the agent's turn when awaiting approval, adds a helper to determine workspace trust, and forces sequential execution for file-modifying tools (WRITE_FILE_TOOL_NAME and EDIT_TOOL_NAME) in the scheduler. Feedback highlights a critical security vulnerability in setIsTrusted where client-controlled metadata can bypass trust checks and potentially lead to Remote Code Execution (RCE); this should be restricted to server-side configuration. Additionally, the scheduler should import and use the EDIT_TOOL_NAMES set rather than hardcoding individual file-modifying tool names to ensure robust sequential execution.

Comment on lines +187 to +194
export function setIsTrusted(
agentSettings: AgentSettings | undefined,
): boolean {
if (INITIAL_FOLDER_TRUST !== undefined) {
return INITIAL_FOLDER_TRUST === 'true';
}
return !!agentSettings?.isTrusted;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

The setIsTrusted function is vulnerable to Remote Code Execution (RCE). An untrusted client can self-certify their workspace as trusted by sending isTrusted: true in userMessage.metadata, which is supplied by the client and is fully user-controlled. This bypasses security restrictions, allowing an attacker to execute arbitrary tools and potentially achieve RCE on the server. To remediate this, the trust status must be determined solely by server-side configuration, such as a strict allowlist of trusted paths, or by requiring the GEMINI_FOLDER_TRUST environment variable to be explicitly set on the server, and not be controlled by the client.

Suggested change
export function setIsTrusted(
agentSettings: AgentSettings | undefined,
): boolean {
if (INITIAL_FOLDER_TRUST !== undefined) {
return INITIAL_FOLDER_TRUST === 'true';
}
return !!agentSettings?.isTrusted;
}
export function setIsTrusted(
agentSettings: AgentSettings | undefined,
): boolean {
if (INITIAL_FOLDER_TRUST !== undefined) {
return INITIAL_FOLDER_TRUST === 'true';
}
return false;
}
References
  1. Workspace-level configurations should be treated as untrusted by default. Security-sensitive settings, such as policy paths, must be loaded from trusted user-level configuration and should not be overridable by workspace settings unless trust is explicitly granted by the hosting environment.

Comment on lines +29 to +33
import {
EDIT_TOOL_NAME,
UPDATE_TOPIC_TOOL_NAME,
WRITE_FILE_TOOL_NAME,
} from '../tools/tool-names.js';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Import EDIT_TOOL_NAMES instead of hardcoding individual file-modifying tool names to ensure all file-modifying tools are executed sequentially.

import {
  EDIT_TOOL_NAMES,
  UPDATE_TOPIC_TOOL_NAME,
} from '../tools/tool-names.js';

Comment on lines +555 to 561
if (
request.name === UPDATE_TOPIC_TOOL_NAME ||
request.name === WRITE_FILE_TOOL_NAME ||
request.name === EDIT_TOOL_NAME
) {
return false;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Instead of hardcoding specific file-modifying tool names like WRITE_FILE_TOOL_NAME and EDIT_TOOL_NAME, we should use the EDIT_TOOL_NAMES set (which contains all file-modifying/restorable tools, such as replace or others). This ensures that any new or existing file-modifying tools are automatically executed sequentially, preventing race conditions and potential file corruption.

    if (
      request.name === UPDATE_TOPIC_TOOL_NAME ||
      EDIT_TOOL_NAMES.has(request.name)
    ) {
      return false;
    }

…AME modifier tools using the EDIT_TOOL_NAMES array constant, which now includes both and supports future tool names, updated the scheduler_parallel.test to support the last scheduler modifications
@jvargassanchez-dot

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a mechanism to yield the agent turn when tools are pending, adds a setIsTrusted helper to determine workspace trust based on the GEMINI_FOLDER_TRUST environment variable, and forces sequential execution for file write and edit tools in the scheduler. Feedback highlights a security vulnerability where loading workspace environment variables via loadEnvironment() before establishing trust could allow an untrusted workspace to override critical process-level environment variables.

Comment thread packages/a2a-server/src/agent/executor.ts Outdated
@wissamblue69-dotcom

Copy link
Copy Markdown

Summary

This PR improves the agent's execution stability by preventing premature state progression when the agent is waiting for user tool approvals. It also eliminates race conditions during file modifications by forcing file writes to execute sequentially, and fixes a configuration bug to ensure environment variables correctly override workspace trust settings.

Details

  • Execution State: Added hasPendingTools() and getPendingToolsCount() to the Task class. The CoderAgentExecutor now uses these to safely pause its execution loop and yield the turn to the user when tool confirmations are pending.
  • Sequential File Writes: Updated _isParallelizable in the scheduler to treat WRITE_FILE_TOOL_NAME as non-parallelizable. This ensures multiple file edits requested in a single LLM batch do not conflict with each other.
  • Trust Configuration: Extracted the trust resolution into a new setIsTrusted helper, allowing the GEMINI_FOLDER_TRUST environment variable to take precedence over internal agent settings.
  • Testing: Added comprehensive unit and integration tests across the agent, configuration, and scheduler modules to guarantee these behaviors.

Related Issues

Fixes b/521342062 # 400 error when using the write file tool
Fixes b/522312717 # The "Untrusted Folder" message appears in chat even when working within a trusted folder.

How to Validate

  1. Run unit tests for the A2A server:
    npm test -w @google/gemini-cli-a2a-server
  2. Verify that all 140 tests pass.
  3. Run unit test for core:
    yarn workspace @google/gemini-cli-core build
    yarn test -w @google/gemini-cli-core
  4. Verify that all tests modified in this PR pass.

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
  • Validated on required platforms/methods:
    • MacOS
      • npm run
      • npx
      • Docker
      • Podman
      • Seatbelt
    • Windows
      • npm run
      • npx
      • Docker
    • [ x] Linux
      • [ x] npm run
      • npx
      • Docker

@jvargassanchez-dot

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for handling pending tools waiting for approval in the agent executor, yielding the turn when tools are pending. It also adds a setIsTrusted configuration helper that respects the GEMINI_FOLDER_TRUST environment variable, and updates the scheduler to force sequential execution for edit tools. Comprehensive unit tests have been added to verify these behaviors. I have no feedback to provide.

Note: Security Review did not run due to the size of the PR.

@galz10 galz10 self-requested a review June 15, 2026 22:03
@galz10 galz10 enabled auto-merge June 15, 2026 22:05
@galz10 galz10 added this pull request to the merge queue Jun 15, 2026
Merged via the queue into google-gemini:main with commit 0f8a157 Jun 15, 2026
32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/l A large sized PR size/m A medium sized PR status/need-issue Pull requests that need to have an associated issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants