Repository navigation
PreToolUse hook permissionDecision: "ask" auto-approved by TUI since v1.0.53 #3590
Description
Describe the bug
When a PreToolUse hook returns permissionDecision: "ask", the TUI permission dialog flashes on screen for milliseconds and is immediately auto-approved without user interaction. The hook fires correctly, the permission.requested event is emitted with kind=hook, but the prompt is resolved as "approved" before the user can interact with it.
This is a regression introduced in v1.0.53 and persists in v1.0.56. Version 1.0.52 works correctly — the permission dialog stays visible and waits for user input.
Additionally, since v1.0.53, selection highlight colors and user question background colors in the TUI appear broken (likely same root cause — a TUI rendering change).
Affected version
- Broken: 1.0.53, 1.0.54, 1.0.55, 1.0.56 (all tested, all broken)
-
- Working: 1.0.52 (prompts stay visible and wait for user interaction)
Steps to reproduce the behavior
Steps to reproduce
1. Create a minimal hook (e.g. ~/.copilot/hooks/hooks.json):
{
"hooks": {
"PreToolUse": [
{
"hooks": [
{
"type": "command",
"command": "python3 -c \"import json,sys; d=json.load(sys.stdin); print(json.dumps({'permissionDecision':'ask','permissionDecisionReason':'Testing hook prompt'}) if d.get('toolName')=='bash' else json.dumps({}))\"",
"timeout": 5
}
]
}
]
}
}2. Start a new session:
COPILOT_AUTO_UPDATE=false copilot3. Ask the agent to run any shell command:
ls -l ~/
4. Observe: The permission dialog flashes on screen for ~50 ms and disappears. The command executes immediately without user approval.
Expected behavior
The permission dialog should remain visible and wait for the user to select "Yes" or "No" before proceeding — exactly as it does on v1.0.52.
Additional context
Evidence from events.jsonl
Timing from a v1.0.56 session shows the prompt is resolved in 79ms:
permission.requested → timestamp T
permission.completed → timestamp T + 79ms (result: "approved")For comparison, in a session created under v1.0.51 , the same hook waits 3–5 seconds for user interaction:
permission.requested → timestamp T
permission.completed → timestamp T + 4200ms (result: "approved" after user clicks Yes)Key observation
Sessions created under v1.0.52 or earlier continue to show prompts correctly, even when the binary has been auto-updated to v1.0.56. This suggests the regression is in the TUI session initialization or component mounting code, not in the hook execution pipeline itself.
### Additional context
- Tested with both global hooks (
~/.copilot/hooks/hooks.json) and plugin hooks — same behavior - The hook itself executes correctly — stdout returns valid JSON with
permissionDecision: "ask" - The
permission.requestedevent showskind=hookandresolvedByHook=N/A(correct) - Non-hook permission prompts (e.g., native trust prompts for new directories) are NOT affected — they still wait for user input
Environment
- OS: Linux (Ubuntu)
- Terminal: Standard terminal (no tmux)
- Shell: bash
Activity
BGMLAI commentedon Jul 14, 2026
An ask verdict must never be representable as allow inside the TUI. Normalize hook output to a tri-state decision before it reaches any auto-approval logic, then suspend the exact tool call until a user response arrives. The response should be bound to tool_use_id and policy generation, and stale responses should be rejected. A regression should cover ask under normal, allow-all, resumed, non-interactive, and autopilot modes and assert that no process starts before a fresh human decision.
fix(skills): Copilot の hook ask バグ回避を追加
fix(skills): 承認ゲートを実行指示より前に置く
docs(agents): hook ask が Copilot で自動承認される件を記録
docs(agents): ask の強制範囲を CLI ごとに明記
fix(agents): コミット承認を常時読込の指示に移す
docs: document the project-vs-global axis for ask entries