Skip to content

fix(cli): propagate resolved folder trust state in headless mode (#29031) - #29528

Merged
DavidAPierce merged 8 commits into
google-gemini:mainfrom
amelidev:b_561554862
Sep 29, 2026
Merged

DavidAPierce merged 8 commits into
google-gemini:mainfrom
amelidev:b_561554862

Conversation

@amelidev

Copy link
Copy Markdown
Contributor

Summary

Fixes an issue where useFolderTrust in headless mode unconditionally reported onTrustChange(true) to the parent component (AppContainer) even when the workspace was untrusted (isTrusted === false). This created a split-brain state where the hook's internal state and history log warned of an untrusted folder while AppContainer and its consumers were informed that the folder was trusted.

Details

  • Root Cause: In PR feat(cli): disable folder trust in headless mode #18407 (Feb 2026), folder trust checks were bypassed in headless mode and onTrustChange(true) was hardcoded into useFolderTrust.ts. In PR feat(cli): secure .env loading and enforce workspace trust in headless mode #25814 (April 2026), workspace trust enforcement was introduced for headless mode, but useFolderTrust.ts was not updated, leaving the stale onTrustChange(true) logic behind.
  • Implementation:
    • Unified useFolderTrust mounting logic so that onTrustChange(trusted) receives the actual resolved trust value (true, false, or undefined).
    • Suppresses isFolderTrustDialogOpen in headless mode (!isHeadlessMode() && trusted === undefined) so interactive dialogs are not rendered without falsely asserting trust.
    • Zero new eslint-disable rules added.
  • Test Coverage:
    • Replaced the obsolete test in packages/cli/src/ui/hooks/useFolderTrust.test.ts with comprehensive coverage for headless mode across all three trust states: untrusted (false), trusted (true), and undetermined (undefined).

Related Issues

Fixes #29031

How to Validate

Run the relevant unit and integration test suites:

# 1. Run useFolderTrust hook tests (verifies headless & interactive states)
npm test -w @google/gemini-cli -- src/ui/hooks/useFolderTrust.test.ts

# 2. Run related trust and startup tests
npm test -w @google/gemini-cli -- src/ui/hooks/useIncludeDirsTrust.test.tsx src/config/trustedFolders.test.ts src/utils/userStartupWarnings.test.ts

# 3. Run core trust logic tests
npm test -w @google/gemini-cli-core -- src/utils/trust.test.ts

# 4. Verify typecheck and linter
npm run typecheck
npm run lint

Manual Verification Matrix

Mode Workspace Trust Dialog State Hook isTrusted Parent onTrustChange History Message
Headless false false (hidden) false false Untrusted warning emitted
Headless true false (hidden) true true No warning emitted
Headless undefined false (hidden) undefined undefined No warning emitted
Interactive false false (hidden) false false Untrusted warning emitted
Interactive true false (hidden) true true No warning emitted
Interactive undefined true (opens dialog) undefined undefined No warning emitted

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
    • Linux
      • npm run
      • npx
      • Docker

@amelidev
amelidev requested a review from a team as a code owner September 27, 2026 23:23
@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 addresses a split-brain issue in headless mode where the useFolderTrust hook was incorrectly reporting a trusted state to the application even when the workspace was untrusted. By unifying the trust resolution logic and properly suppressing interactive dialogs during headless execution, the changes ensure that the internal trust state and external notifications remain consistent with the actual workspace configuration.

Highlights

  • Headless Mode Trust Logic: Unified the mounting logic in useFolderTrust to correctly propagate the actual resolved trust state (true, false, or undefined) instead of forcing a trusted state in headless mode.
  • Dialog Suppression: Updated the hook to suppress the folder trust dialog in headless mode, ensuring interactive elements are not rendered while maintaining accurate trust reporting.
  • Test Coverage: Replaced obsolete tests with comprehensive scenarios covering all three trust states (trusted, untrusted, and undetermined) in headless mode.
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. ↩

@github-actions github-actions Bot added the size/m A medium sized PR label Sep 27, 2026
@github-actions

github-actions Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

📊 PR Size: size/L

  • Lines changed: 297
  • Additions: +279
  • Deletions: -18
  • Files changed: 2

@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 refactors the useFolderTrust hook to streamline how folder trust is handled in headless mode. Instead of forcing trust to true and hiding the dialog, the hook now correctly propagates the actual trust state (trusted) to onTrustChange and updates the dialog visibility conditionally based on whether headless mode is active. Corresponding unit tests have been updated and expanded to verify these behaviors under different trust scenarios (trusted, untrusted, and undefined). I have no feedback to provide as the changes are clean and well-tested.

@gemini-cli gemini-cli Bot added priority/p1 Important and should be addressed in the near term. area/core Issues related to User Interface, OS Support, Core Functionality labels Sep 27, 2026
@amelidev

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 refactors the useFolderTrust hook to simplify headless mode handling by unifying state updates and correctly propagating the actual trust state (rather than forcing true) to onTrustChange. It also adds unit tests covering various trust scenarios in headless mode. The review feedback identifies a critical risk of an infinite loop and performance degradation because onTrustChange and addItem are included in the useEffect dependency array, and recommends capturing these callbacks in refs to avoid unnecessary re-runs.

Comment thread packages/cli/src/ui/hooks/useFolderTrust.ts
@amelidev

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 refactors the useFolderTrust hook to stabilize its callbacks (onTrustChange and addItem) using useRef, preventing unnecessary re-runs of the trust discovery effect when callback references change. It also updates and adds comprehensive unit tests to verify headless mode behavior and callback stability. The reviewer suggests further optimizing the hook by also storing the settings object in a useRef to safely omit settings.merged from the useEffect dependency array, preventing unnecessary executions when unrelated settings change.

Comment thread packages/cli/src/ui/hooks/useFolderTrust.ts Outdated
@github-actions github-actions Bot added the size/l A large sized PR label Sep 28, 2026
@amelidev

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 improves the stability of the useFolderTrust hook by refactoring it to use React refs (useRef) for callbacks (onTrustChange, addItem) and settings. This prevents unnecessary re-runs of the main discovery effect when these callback references or unrelated settings change. Additionally, the headless mode logic is simplified to propagate the correct trust status and show warnings when untrusted, rather than forcing trust. Comprehensive unit tests have been added to verify callback stability and the updated headless mode behavior. I have no further feedback to provide as the changes are well-implemented and thoroughly tested.

auto-merge was automatically disabled September 29, 2026 20:05

Head branch was pushed to by a user without write access

@DavidAPierce
DavidAPierce added this pull request to the merge queue Sep 29, 2026
Merged via the queue into google-gemini:main with commit 478f771 Sep 29, 2026
33 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/core Issues related to User Interface, OS Support, Core Functionality priority/p1 Important and should be addressed in the near term. size/l A large sized PR size/m A medium sized PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: headless mode reports an untrusted folder as trusted to the rest of the app (state/callback mismatch)

2 participants