Permission check
Skill pedrohcgs/claude-code-my-workflow/.claude/skills/permission-check
A ready-to-fork Claude Code template for academics using LaTeX/Beamer + R. Multi-agent review, quality gates, adversarial QA, and replication protocols.
npx -y skills add pedrohcgs/claude-code-my-workflow --skill permission-checkAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
What its author says it does
Copied from the file, not written here
Diagnose why Claude Code is (or isn't) prompting for permission. By default reads only repo-local layers (CLI project, CLI project-local, VSCode workspace). Host-global layers (CLI user `~/.claude/`, VSCode user settings) are read ONLY when the user explicitly confirms — those files may contain unrelated paths or secrets. Use when user says "why is it asking me to approve?", "permission check", "why am I getting prompts?", "bypass isn't working", "check my permissions". Read-only diagnostic.
SKILL.md
7.8 KB, as published. Nobody here has run it
Permission Check
Purpose
Surface the full permission-mode picture across every layer Claude Code honors, so the user can see at a glance why prompts are (or aren't) firing. Claude Code resolves permission mode from a 6-tier stack; a single misconfigured layer produces silent overrides that are hard to debug by eye.
The 6 layers (precedence: bottom wins)
- VSCode user settings —
~/Library/Application Support/Code/User/settings.json(macOS),%APPDATA%/Code/User/settings.json(Windows),~/.config/Code/User/settings.json(Linux). Key:claudeCode.initialPermissionMode. - VSCode workspace settings —
<repo>/.vscode/settings.json. Same key. Wins over user. - CLI user settings —
~/.claude/settings.json. Key:permissions.defaultMode. - CLI project settings —
<repo>/.claude/settings.json. Same key. Wins over user. - CLI project-local settings —
<repo>/.claude/settings.local.json. Same key. Wins over project. - In-session mode — set at session start from layers 1-5, then mutable via
Shift+Tabor/permission-mode. Authoritative until session ends.
Key insight: initialPermissionMode only fires at session start. If you toggled mid-session (or the session started before a settings change), the file-level settings are correct but the runtime mode differs. That's the #1 source of "bypass isn't working" confusion.
Privacy contract
Host-global settings files (~/.claude/settings.json, VSCode user settings) may contain:
- Paths to unrelated projects and secrets
- API keys, tokens, or provider credentials added outside this repo
- Permission policies set by the user's org or employer
This skill is designed for defense-in-depth: Phase A runs automatically and reads only repo-local files. Phase B reads host-global files only after the user explicitly confirms — never silently. When reporting host-global layers, redact any key that is not directly relevant to permissions.* or claudeCode.*.
Protocol
Phase A: Repo-local layers (auto-runs)
Read these immediately — they are checked into (or gitignored inside) the repo and do not cross the trust boundary:
VSCODE_WS="${CLAUDE_PROJECT_DIR}/.vscode/settings.json"
CLI_PROJECT="${CLAUDE_PROJECT_DIR}/.claude/settings.json"
CLI_LOCAL="${CLAUDE_PROJECT_DIR}/.claude/settings.local.json"
For each file that exists, extract:
- VSCode workspace:
claudeCode.initialPermissionMode,claudeCode.allowDangerouslySkipPermissions - CLI project / project-local:
permissions.defaultMode,permissions.allow,permissions.deny
Missing files are fine — report "not present" rather than erroring.
Print the resolved defaultMode from these three layers alone. If that already explains the prompt behavior (e.g., CLI project-local has defaultMode: "default" while project has bypassPermissions), stop here and surface the diagnosis.
Phase B: Host-global layers (requires explicit user confirmation)
If Phase A is inconclusive — e.g., all repo-local layers agree on bypass but the user is still being prompted — ask the user:
"To complete the diagnosis, I need to read two files outside this repo:
~/.claude/settings.json(CLI user-level)- your VSCode user settings (
~/Library/Application Support/Code/User/settings.jsonon macOS; Linux/Windows vary)These may contain unrelated paths or secrets. I will redact any key that isn't in
permissions.*orclaudeCode.*. Proceed?"
Only after the user confirms, read:
# VSCode user (platform-dependent path; try all three)
case "$(uname -s)" in
Darwin) VSCODE_USER="${HOME}/Library/Application Support/Code/User/settings.json" ;;
Linux) VSCODE_USER="${HOME}/.config/Code/User/settings.json" ;;
MINGW*|MSYS*|CYGWIN*) VSCODE_USER="${APPDATA}/Code/User/settings.json" ;;
*) VSCODE_USER="" ;;
esac
CLI_USER="${HOME}/.claude/settings.json"
When reporting their contents, extract only the relevant keys:
- CLI user:
permissions.defaultMode,permissions.allow,permissions.deny - VSCode user: any key starting with
claudeCode.
Never print the full file. Redact everything else to (other keys redacted).
Step 2: Compute resolved state
The resolved defaultMode is the value from the highest-precedence layer that sets it. Report:
- Which layer won the
defaultModecontest. - Merged
allowlist (union across CLI tiers). - Merged
denylist (union; anydenyblocks the action even if allowed elsewhere). - Whether VSCode says
bypassbut CLI says otherwise (or vice versa) — this is a legitimate conflict to flag.
Step 3: Report runtime mode
The live in-session mode is exposed via the status line (see .claude/scripts/statusline.sh). Tell the user:
"Your status line shows the current in-session mode in the top-right of the Claude Code panel. If that disagrees with the resolved
defaultModeabove, you (or Shift+Tab) overrode it mid-session. Press Shift+Tab to cycle back."
If the status line isn't configured, emit a warning and point at .claude/scripts/statusline.sh.
Step 4: Flag common failure modes
Check for and explicitly call out:
- Layer drift: CLI project says bypass but CLI local says default → local wins, explains the prompts.
- VSCode-only bypass: VSCode layers say bypass but no CLI layer does → terminal Claude Code will still prompt; extension may or may not.
- Empty allowlist + default mode:
defaultMode: "default"with emptyallow→ every tool prompts, as designed. - Stale session: settings are correct but user reports prompts → almost always a session that pre-dates the fix. Advise "Cmd+Shift+P → Developer: Reload Window, then new Claude Code session."
denywins: any match in adenylist blocks the tool regardless ofallow. Rare but deadly.
Output format
=== PERMISSION STATE ===
Layer 1 — VSCode user: bypassPermissions (allowDangerouslySkipPermissions: true)
Layer 2 — VSCode workspace: bypassPermissions
Layer 3 — CLI user: bypassPermissions (allow: ["*"])
Layer 4 — CLI project: bypassPermissions (allow: ["Edit(**)", "Bash(*)", ...])
Layer 5 — CLI project-local: bypassPermissions (allow: [...], deny: [])
Resolved defaultMode: bypassPermissions (set by Layer 5)
Merged allow: Edit(**), Write(**), Bash(*), ...
Merged deny: (none)
=== RUNTIME ===
Check the status line at the top of the Claude Code panel. Expected: [BYPASS].
If it shows [PROMPT], [AUTO-EDIT], or [PLAN] — that's an in-session override. Press Shift+Tab to cycle.
=== DIAGNOSIS ===
No layer drift detected. If you are still seeing prompts:
1. Session is stale (started before settings were applied) — reload window + new session.
2. VSCode extension bug — check extension version and file an issue.
3. Tool was previously denied in this session — that denial is remembered. New session clears it.
If any layer disagrees, replace the "No layer drift detected" line with a specific flagged issue.
Notes
- This skill is read-only. It never modifies settings.
- If
$CLAUDE_PROJECT_DIRis unset, fall back togit rev-parse --show-toplevel. - Platform-aware: detect macOS vs Linux vs Windows for the VSCode user path.