anthropics / anthropics/claude-code
[Bug] Interactive auto mode bypasses permissions.ask rules for PreToolUse decisions
- Langage dominant
- Python
- Étoiles
- 145k
- Forks
- 23.1k
- Métriques de merge des PR
- Métriques de PR en attente
Description
**Version:** 2.1.234 · Linux (Fedora, kernel 7.1.8) · fish shell · Pro/Max login
**Summary**
In an interactive session started with `--permission-mode auto`, a matching
`permissions.ask` rule from user settings did not produce a permission prompt.
The Bash command ran. A `PreToolUse` hook that returned
`permissionDecision: "ask"` for the same command was also ignored, and that
command ran too. The same rules gate correctly in a `-p` run on the same build,
so the rule syntax and rule loading are not the problem.
**Setup**
`~/.claude/settings.json` contained:
```json
{
"permissions": {
"ask": ["Bash(git add:*)", "Bash(git commit:*)"],
"defaultMode": "default"
}
}
```
The session was started as `claude --permission-mode auto --name="" /start <ticket>`
from a git worktree. No `--settings` flag, no `--dangerously-skip-permissions`.
The working directory had no project `.claude/settings.json`, and no allow rule
anywhere covered `git add`.
**What happened**
1. Claude ran this single Bash call with no prompt:
```
git add -A >/dev/null 2>&1; git diff --cached --stat | tail -3; git diff --cached > /tmp/simplify.diff
```
The transcript entry is a main-loop tool call, `isSidechain: false`, and every
`permission-mode` record in the session file reads `auto`.
2. To work around it I added a `PreToolUse` hook on `Bash` that returns:
```json
{"hookSpecificOutput": {"hookEventName": "PreToolUse", "permissionDecision": "ask", "permissionDecisionReason": "..."}}
```
I proved the hook was live in the running session with a sentinel that appends
to a file, and I proved it emitted `permissionDecision: "ask"` for the exact
probe command by piping that command through the stored hook script by hand.
Claude Code ran the probe command anyway, with no prompt.
3. Moving the two entries from `permissions.ask` to `permissions.deny` works.
The same session then rejected `git add --dry-run --`, the same command inside
a compound line, and `git commit --dry-run`, each recorded as
`toolDenialKind: "permission-rule"`.
**Expected**
Per the docs, an explicit content-scoped ask rule always forces a prompt, even in
auto mode: https://code.claude.com/docs/en/auto-mode-config#add-a-human-checkpoint
**Control tests that pass (so these are not the cause)**
All run on 2.1.234 in a scratch git repo with `claude -p --permission-mode auto`:
- `Bash(git add:*)` via `--settings`, prompt for `git add -A`: blocked, nothing staged.
- Same rule, the exact compound command from above with the redirections: blocked.
- The user-scope rule `Bash(bd update:*)` against the user-scope allow rule
`Bash(bd * --help)`: `bd update --help` was refused for approval, so ask
outranked allow and user-scope ask rules do load in auto mode.
So `:*` matching, compound-command splitting, and user-scope loading all behave.
The failure appears only in an interactive auto-mode session.
**Impact**
`permissions.ask` is the documented way to keep a human checkpoint while running
auto mode. If it can be skipped silently, the only durable boundary left is
`permissions.deny`, which blocks the action outright and is much blunter than
what the ask rule offers.
Guide de contribution
Aucun guide de contribution indexé pour ce dépôt
Piste de recherche
Start by reproducing the interactive `--permission-mode auto` session with the supplied settings and `PreToolUse` hook, then compare it with `claude -p --permission-mode auto`. Trace how the interactive path handles `permissions.ask` and `permissionDecision: "ask"`; done means both produce a prompt while the documented deny and control-test behavior remains unchanged.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- fish, git
- Domaine
- authorization, cli
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- Active
- Clarté
- Plutôt claire
- Accessibilité débutants
- 55/100