[Bug] Wildcard permissions don't supersede specific permissions in system prompt
Bug Description
Title: Redundant specific permissions accumulate in system prompt after wildcard permissions added
Description:
When a wildcard permission like Bash(gh:*) is configured in .claude/settings.local.json, previously-approved specific commands (e.g., Bash(gh pr create --title "..." --body "...")) continue to appear in the system prompt's allowed tools list.
Steps to reproduce:
- Start with no gh permissions
- Run gh pr create - approve when prompted (specific command gets added)
- Run different gh commands - approve each (more specific entries accumulate)
- Edit .claude/settings.local.json to add Bash(gh:*)
- Start new session
- Observe system prompt still contains all the specific gh pr create --title "..." --body "..." entries
Expected behavior:
Wildcard permissions should supersede specific permissions. When Bash(gh:*) is present, specific gh command entries should be removed or at minimum not included in the system prompt.
Actual behavior:
Both wildcard and all historical specific permissions are included in the system prompt, consuming context unnecessarily.
Impact:
- Wastes context window with redundant permission entries
- Some entries include full command bodies (heredocs with PR descriptions), adding significant bloat
- In my case, I see entries like Bash(gh pr create --title "feat: Add FredCollector MCP server" --body "$(cat <<''EOF''... with multi-line PR bodies
Environment:
- Claude Code (CLI)
- Ubuntu 24
- Permissions stored in .claude/settings.local.json
Environment Info
- Platform: linux
- Terminal: vscode
- Version: 2.0.54
- Feedback ID: f786bd80-bc80-4bad-86fd-2b9c7ec2eb67
Errors
[{"error":"Error\n at NO (/$bunfs/root/claude:27:1143)\n at <anonymous> (/$bunfs/root/claude:32:10056)\n at emit (node:events:92:22)\n at endReadableNT (internal:streams/readable:862:50)\n at processTicksAndRejections (native:7:39)\n at request (/$bunfs/root/claude:34:2147)\n at processTicksAndRejections (native:7:39)","timestamp":"2025-11-27T12:28:57.013Z"},{"error":"Error\n at NO (/$bunfs/root/claude:27:1143)\n at <anonymous> (/$bunfs/root/claude:32:10056)\n at emit (node:events:92:22)\n at endReadableNT (internal:streams/readable:862:50)\n at processTicksAndRejections (native:7:39)\n at request (/$bunfs/root/claude:34:2147)\n at processTicksAndRejections (native:7:39)","timestamp":"2025-11-27T12:28:57.017Z"},{"error":"Error\n at NO (/$bunfs/root/claude:27:1143)\n at <anonymous> (/$bunfs/root/claude:32:10056)\n at emit (node:events:92:22)\n at endReadableNT (internal:streams/readable:862:50)\n at processTicksAndRejections (native:7:39)\n at request (/$bunfs/root/claude:34:2147)\n at processTicksAndRejections (native:7:39)","timestamp":"2025-11-27T12:28:57.151Z"},{"error":"Error\n at NO (/$bunfs/root/claude:27:1143)\n at <anonymous> (/$bunfs/root/claude:32:10056)\n at emit (node:events:92:22)\n at endReadableNT (internal:streams/readable:862:50)\n at processTicksAndRejections (native:7:39)\n at request (/$bunfs/root/claude:34:2147)\n at processTicksAndRejections (native:7:39)","timestamp":"2025-11-27T12:28:57.178Z"},{"error":"Error: EISDIR: illegal operation on a directory, read\n at readFileSync (unknown)\n at readFileSync (/$bunfs/root/claude:12:370)\n at WaI (/$bunfs/root/claude:4240:17094)\n at call (/$bunfs/root/claude:1456:912)\n at call (/$bunfs/root/claude:1452:5768)\n at rt1 (/$bunfs/root/claude:2161:20843)\n at processTicksAndRejections (native:7:39)","timestamp":"2025-11-27T12:30:27.078Z"}]This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗