Fewer permission prompts: 15 sessions, one allowlist line
The pitch on fewer-permission-prompts is straightforward: scan your session transcripts, find the high-frequency Bash commands that keep prompting you, and add them to .claude/settings.json so they stop prompting. After eleven days of active work on this project, I expected to find maybe a dozen patterns worth allowlisting. The scan returned one strict survivor. Everything else was either already auto-allowed by Claude Code, or explicitly forbidden by the skill’s safety rules. The takeaway isn’t “this skill didn’t help” — it’s that Claude Code’s built-in auto-allow list is much broader than the skill’s setup docs suggest, and a fresh scan tells you exactly where the edges are.
What I ran
Invoked via /fewer-permission-prompts as step four of a broader harness audit. Going into the run I had zero project-scoped permissions configured. Recurring commands that I knew were prompting me: git status, git diff, npm run build, npm run dev, gh api repos/.../contents/..., node scripts/*, python scripts/*.
The skill’s behavior: read every .jsonl transcript under ~/.claude/projects/<project-id>/, extract Bash command frequencies, filter the results against Claude Code’s auto-allow list and against an explicit deny-list (mutating commands like git push, git add; arbitrary-code-execution like gh api; anything that takes a subcommand argument that could be anything).
What happened
Fifteen .jsonl transcripts in the project’s session folder. The skill extracted roughly fifty distinct command patterns. After filtering:
- One pattern survived the strict threshold:
Bash(npm run build)at 14 hits. Everything else that hit the 3-occurrence floor was either already auto-allowed by the harness, mutating-by-nature (so blocked from quiet allowlisting), or arbitrary-code-execution. - Two patterns added proactively below the threshold:
Bash(npm run dev)andBash(npm run preview). Both are documentednpmscripts inpackage.jsonand would hit the floor the second active local dev work resumed.
Final write to .claude/settings.local.json:
{
"permissions": {
"allow": [
"Bash(npm run build)",
"Bash(npm run dev)",
"Bash(npm run preview)"
]
}
}
Three lines. That’s the entire deliverable on an eleven-day-old project with fifteen active sessions of history.
Where it drifted
Three friction points, in order of significance.
The skill’s “write to .claude/settings.json” default conflicts with how I actually want to scope permissions. Project-committed settings.json versus operator-local settings.local.json is a real distinction: anything in settings.json ships to anyone who clones the repo, anything in settings.local.json stays personal. The skill wrote to the committed file by default. I wanted the local file. Easy override on user instruction, but the skill itself didn’t catch that settings.local.json wasn’t in .gitignore at all yet — had to add a line manually before saving. The skill’s default path is reasonable for shared-team contexts; not reasonable for personal harness tuning.
gh api is the prompts you can’t silence. Twenty-four gh api repos/.../contents/... prompts across the fifteen transcripts. All GET reads of public-ish repo content. I’d expected those to be auto-allowed since git status and git diff are. But the skill explicitly forbids Bash(gh api *) because gh api accepts arbitrary HTTP methods (POST, DELETE, etc.) and the wildcard would silently allow mutations. Correct call from the skill — but no narrow pattern fits, so this friction stays. Twenty-four prompts per session-equivalent of work remain prompts.
The surprise was the lower bound, not the upper bound. I went in expecting to add maybe ten lines. I added three (one strict, two proactive). The skill’s report told me, in effect: the harness already handles most of what I thought I needed. The honest deliverable on a healthy active project is “you’re already covered; here’s the one thing to add.”
What I’d change
Run the scan once at project setup, then again at the 30-session mark. A single run on a one-week-old project surfaces almost nothing because the auto-allow list dominates. The patterns that bleed through accumulate slowly — a recurring gh issue view, a python scripts/<script>.py that becomes habit. The next useful run is once a project has thirty-plus sessions of friction-pattern data, not on day eleven.
Treat the skill’s “one survivor” output as a signal, not a failure. If the scan returns one allowlist line, the harness is mostly doing its job. If it returns twenty, something’s been disabled or the project is doing something unusual. The number itself is the diagnostic.
Default to settings.local.json, not settings.json, unless the operator explicitly wants the rules shared. Personal harness tuning is private. Team-shared permission policies are a separate concern that deserves its own intentional flow.