Skip to content

fix(hook-env): suppress repeated untrusted config warnings#10589

Merged
jdx merged 2 commits into
mainfrom
codex/hook-env-untrusted-once-per-dir
Jun 24, 2026
Merged

fix(hook-env): suppress repeated untrusted config warnings#10589
jdx merged 2 commits into
mainfrom
codex/hook-env-untrusted-once-per-dir

Conversation

@jdx

@jdx jdx commented Jun 23, 2026

Copy link
Copy Markdown
Owner

Summary

  • suppress repeated hook-env untrusted-config warnings while staying in the same directory
  • clear the suppression marker after hook-env successfully runs from a different directory, so re-entering warns again
  • keep explicit commands reporting the full trust error
  • update zsh prompt-hook coverage and add a focused e2e for same-directory suppression and re-entry

Tests

  • mise run test:e2e e2e/cli/test_hook_env_untrusted_once_per_dir e2e/cli/test_zsh_precmd_runs_once

Note

Medium Risk
Touches shell activation trust handling and early-exit logic; mistakes could hide security warnings or break zsh hook timing, but scope is limited to hook-env and covered by new e2e tests.

Overview
hook-env no longer spams the same untrusted-config message on every shell prompt in one directory. The first failure still prints the full trust error and exports __MISE_LAST_UNTRUSTED_CONFIG_WARNING_KEY (hashed from cwd, trust root, config path, and file mtime). Later hook-env calls with the same key exit quietly with code 1 instead of repeating stderr.

A successful hook-env run removes that marker so leaving and re-entering the project warns again; editing .mise.toml changes mtime and re-enables the warning in place. Early-exit fast paths are skipped while the marker is set so suppression stays consistent. Explicit commands like mise run are unchanged and still surface the full trust error.

E2e coverage adds test_hook_env_untrusted_once_per_dir and tightens the zsh chpwd/precmd test (trust-warning grep, real cd when hooks fire).

Reviewed by Cursor Bugbot for commit 5fb16f1. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

Release Notes

  • New Features

    • Untrusted configuration warnings now show once per directory context, re-enabling when you return to a previously visited directory. The warning is still reported when runs are forced to fail.
  • Bug Fixes

    • Improved zsh behavior to ensure hook/pre-command logic runs once per cd, avoiding duplicate side effects.
    • Expanded detection of untrusted-config warning text to match both singular/plural phrasing.
  • Tests

    • Added end-to-end coverage for “warn once per directory,” including config changes, directory exit/re-entry, and failure scenarios.

@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: caf938c0-c9be-49af-a47f-449cbb74cd10

📥 Commits

Reviewing files that changed from the base of the PR and between c8de934 and 5fb16f1.

📒 Files selected for processing (4)
  • e2e/cli/test_hook_env_untrusted_once_per_dir
  • e2e/cli/test_zsh_precmd_runs_once
  • src/cli/hook_env.rs
  • src/hook_env.rs
🚧 Files skipped from review as they are similar to previous changes (2)
  • e2e/cli/test_zsh_precmd_runs_once
  • e2e/cli/test_hook_env_untrusted_once_per_dir

📝 Walkthrough

Walkthrough

Adds per-directory gating for the untrusted config warning in mise hook-env. The warning state is tracked in an env-var keyed by the current config context, wired into hook-env error handling, and covered by a new Bash end-to-end test plus a zsh precmd test update.

Changes

Untrusted config warning once per directory

Layer / File(s) Summary
Warning state tracking
src/hook_env.rs
Adds the warning marker env-var, exports helpers to extract untrusted-config paths from eyre::Report, decide whether to show the warning, mark it as seen, clear queued removals, and compute the warning key from canonicalized paths, trust-root, and config mtime.
HookEnv error-path integration
src/cli/hook_env.rs
Resolves the shell before loading config, branches on untrusted-config errors to mark the warning as seen or exit immediately, removes the later shell lookup, and applies untrusted-warning clearing during patch generation.
Bash e2e coverage
e2e/cli/test_hook_env_untrusted_once_per_dir
Adds a Bash end-to-end script that exercises warning emission, suppression, re-emission after config changes, directory re-entry behavior, and the failing mise run make path while checking stderr for the untrusted-config message.
Zsh precmd test update
e2e/cli/test_zsh_precmd_runs_once
Expands trust-warning matching to accept singular and plural wording, and changes the cd project handling so the test only manually runs chpwd_functions when zsh has not already fired the hook.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 I hopped through hooks with careful feet,
One warning once, then none repeat.
The dir remembers what it saw,
With bash and zsh in tidy law.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 57.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: suppressing repeated untrusted config warnings in hook-env.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR suppresses the per-prompt untrusted-config warning in hook-env by storing a hash key (__MISE_LAST_UNTRUSTED_CONFIG_WARNING_KEY) in the shell environment after the first warning; subsequent hook-env invocations in the same directory silently exit without repeating the message, and the key is cleared automatically when hook-env succeeds in a trusted directory so re-entering warns again.

  • src/hook_env.rs adds current_untrusted_warning_key (hashes cwd + trust_root + config_path + mtime), plus mark/check/clear helpers; both fast- and slow-path early-exit checks now return false while the marker is present, ensuring the key can always be rechecked.
  • src/cli/hook_env.rs moves shell detection before Config::get() so the formatter is available in the error path, routes first-occurrence errors through mark_untrusted_config_warning_seen + return Err, and routes suppressed occurrences through exit(1); clear_untrusted_config_warning is appended to the successful patch output to unset the marker in the shell.
  • New test_hook_env_untrusted_once_per_dir e2e exercises all key scenarios: first warn, same-dir suppression, re-warn after mtime change, marker cleared on parent, re-entry warns again, and explicit mise run continues to surface the full error.

Confidence Score: 5/5

Safe to merge; the change is limited to the hook-env warning path and does not affect any trust enforcement or env-loading correctness.

The suppression logic is keyed on an exact (cwd + config path + mtime) hash, so it cannot fire for a different directory or a stale file. Both fast- and slow-path early-exit checks are guarded so the marker is always re-evaluated on every prompt. Explicit commands (mise run, etc.) never consult the marker. The new e2e covers first-warn, suppression, mtime-reset, parent-clear, and re-entry. No correctness regressions are visible in the changed paths.

No files require special attention.

Important Files Changed

Filename Overview
src/hook_env.rs Adds marker-based suppression logic: current_untrusted_warning_key hashes (cwd + trust_root + config_path + mtime), should_show_untrusted_config_warning / mark_untrusted_config_warning_seen / clear_untrusted_config_warning implement the set/check/clear lifecycle; both fast and slow exit paths bypass early-exit while the marker is set.
src/cli/hook_env.rs Shell detection moved before Config::get() so the shell formatter is available in the error path; untrusted-config errors now either mark-and-return-err (first occurrence) or exit(1) silently (subsequent, same key); clear_untrusted_config_warning added to successful patch output.
e2e/cli/test_hook_env_untrusted_once_per_dir New e2e covering first-warn, same-dir suppression, re-warn-on-mtime-change, parent-dir clear, re-entry re-warn, and explicit mise run still failing with full trust error.
e2e/cli/test_zsh_precmd_runs_once Updated contains_trust_warning regex to match both "Config file" and "Config files"; cd project now attempted first to fire chpwd naturally, with manual fallback when non-interactive zsh doesn't trigger it.

Reviews (3): Last reviewed commit: "fix(hook-env): key untrusted warning by ..." | Re-trigger Greptile

Comment thread src/main.rs Outdated
Comment thread src/hook_env.rs Outdated
Comment thread src/hook_env.rs Outdated
Comment on lines +130 to +147
fn hook_env_shell_arg() -> Option<ShellType> {
let args = env::ARGS.read().unwrap();
let mut iter = args.iter();
while let Some(arg) = iter.next() {
if arg == "-s" || arg == "--shell" {
return iter.next().and_then(|s| s.parse().ok());
}
if let Some(shell) = arg.strip_prefix("--shell=") {
return shell.parse().ok();
}
if let Some(shell) = arg.strip_prefix("-s")
&& !shell.is_empty()
{
return shell.parse().ok();
}
}
None
}

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.

P2 Duplicated shell-arg parsing creates a maintenance risk

hook_env_shell_arg re-implements the -s/--shell argument parsing by scanning ARGS directly, duplicating logic already handled by the CLI framework. If a new short-flag form is added to the hook-env subcommand (or if parsing order changes), this function will silently diverge. Consider exposing the parsed ShellType through the existing CLI structures rather than re-parsing raw args here.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Claude Code

@jdx jdx force-pushed the codex/hook-env-untrusted-once-per-dir branch 2 times, most recently from fe52195 to 972a350 Compare June 23, 2026 19:13

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 972a350. Configure here.

Comment thread src/hook_env.rs
Comment thread src/cli/hook_env.rs

@coderabbitai coderabbitai 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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@e2e/cli/test_hook_env_untrusted_once_per_dir`:
- Around line 7-9: The contains_trust_warning function is checking for "Config
files in" but the actual untrusted task error message from src/task/task_list.rs
uses "Config file(s) in ... are not trusted" format. Update the grep pattern in
the contains_trust_warning function to match the actual error text being
generated, ensuring it can match both singular and plural forms of the file
reference or use a pattern that correctly matches the error message as it
appears in the code.

In `@e2e/cli/test_zsh_precmd_runs_once`:
- Around line 86-88: The current check using contains_trust_warning as a proxy
to detect if chpwd hooks already ran is unreliable because trust warnings can be
suppressed, leading to the run_hooks_to_file function potentially executing
hooks twice. Replace the contains_trust_warning check on chpwd_file with a
direct signal check that looks for a hook signal variable like
__MISE_ZSH_CHPWD_RAN instead of relying on the presence or absence of warning
text, ensuring the fallback only runs when hooks genuinely haven't been invoked
by zsh.

In `@src/hook_env.rs`:
- Around line 74-80: The deduplication mechanism for untrusted config warnings
is using only the directory as the key via current_untrusted_warning_dir(),
which is too coarse and allows configuration changes within the same directory
to remain incorrectly suppressed. Replace the directory-only marker with a
composite config-state key that includes cwd, trust root, config path, and
mtime. Update the LAST_UNTRUSTED_CONFIG_WARNING_DIR_ENV environment variable to
store this composite key instead, and ensure all related functions
(should_show_untrusted_config_warning, the mark functions at lines 92-94, and
the clear functions at lines 99-102 and 109-117) consistently use the same
composite key for storing and comparing configuration state.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 1e4b9360-2c4e-4147-a474-01b67bda6b21

📥 Commits

Reviewing files that changed from the base of the PR and between 65987cb and fe52195.

📒 Files selected for processing (5)
  • e2e/cli/test_hook_env_untrusted_once_per_dir
  • e2e/cli/test_zsh_precmd_runs_once
  • src/cli/hook_env.rs
  • src/hook_env.rs
  • src/main.rs

Comment thread e2e/cli/test_hook_env_untrusted_once_per_dir
Comment thread e2e/cli/test_zsh_precmd_runs_once Outdated
Comment thread src/hook_env.rs Outdated
@jdx jdx force-pushed the codex/hook-env-untrusted-once-per-dir branch from 972a350 to c4b7c16 Compare June 23, 2026 19:21
@jdx jdx force-pushed the codex/hook-env-untrusted-once-per-dir branch from c4b7c16 to c8de934 Compare June 23, 2026 19:24
@github-actions

github-actions Bot commented Jun 23, 2026

Copy link
Copy Markdown

Hyperfine Performance

mise x -- echo

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.6.13 x -- echo 23.7 ± 1.8 19.3 30.3 1.11 ± 0.14
mise x -- echo 21.5 ± 2.2 18.1 42.7 1.00
✅ Performance improvement for x -- echo is 11%

mise env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.6.13 env 19.3 ± 1.2 17.4 24.3 1.00
mise env 20.2 ± 1.5 17.8 26.4 1.05 ± 0.10

mise hook-env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.6.13 hook-env 19.6 ± 1.2 17.7 26.4 1.00
mise hook-env 21.3 ± 1.4 18.4 28.7 1.09 ± 0.10

mise ls

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.6.13 ls 17.6 ± 1.2 14.9 22.4 1.00
mise ls 18.2 ± 1.9 15.1 26.3 1.03 ± 0.13

xtasks/test/perf

Command mise-2026.6.13 mise Variance
install (cached) 136ms 138ms -1%
ls (cached) 59ms 63ms -6%
bin-paths (cached) 65ms 65ms +0%
task-ls (cached) 133ms 133ms +0%

@jdx jdx merged commit 23fa453 into main Jun 24, 2026
34 checks passed
@jdx jdx deleted the codex/hook-env-untrusted-once-per-dir branch June 24, 2026 19:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant