Add 3 new commands for auditing and optimizing Claude Code permission configurations, leveraging the marketplace's multi-layer review architecture. New commands: - /config-audit-settings - 100-point scoring across redundancy, coverage, safety alignment, and profile fit - /config-optimize-settings - apply optimizations with dry-run, named profiles (conservative, reviewed, autonomous), consolidation modes - /config-permissions-map - Mermaid diagram of review layer coverage New skill: - settings-optimization.md - 7 sections covering file formats, syntax reference, consolidation rules, review-layer-aware recommendations, named profiles, scoring criteria, and hook detection Updated agent maintainer.md with new "Audit Settings Files" responsibility. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
378 lines
12 KiB
Markdown
378 lines
12 KiB
Markdown
# Settings Optimization Skill
|
|
|
|
This skill provides comprehensive knowledge for auditing and optimizing Claude Code `settings.local.json` permission configurations.
|
|
|
|
---
|
|
|
|
## Section 1: Settings File Locations & Format
|
|
|
|
Claude Code uses two configuration formats for permissions:
|
|
|
|
### Newer Format (Recommended)
|
|
|
|
**Primary target:** `.claude/settings.local.json` (project-local, gitignored)
|
|
|
|
**Secondary locations:**
|
|
- `.claude/settings.json` (shared, committed)
|
|
- `~/.claude.json` (legacy global config)
|
|
|
|
```json
|
|
{
|
|
"permissions": {
|
|
"allow": ["Edit", "Write(plugins/**)", "Bash(git *)"],
|
|
"deny": ["Read(.env*)", "Bash(rm *)"],
|
|
"ask": ["Bash(pip install *)"]
|
|
}
|
|
}
|
|
```
|
|
|
|
**Field meanings:**
|
|
- `allow`: Operations auto-approved without prompting
|
|
- `deny`: Operations blocked entirely
|
|
- `ask`: Operations that always prompt (overrides allow)
|
|
|
|
### Legacy Format
|
|
|
|
Found in `~/.claude.json` with per-project entries:
|
|
|
|
```json
|
|
{
|
|
"projects": {
|
|
"/path/to/project": {
|
|
"allowedTools": ["Read", "Write", "Bash(git *)"]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**Detection strategy:**
|
|
1. Check `.claude/settings.local.json` first (primary)
|
|
2. Check `.claude/settings.json` (shared)
|
|
3. Check `~/.claude.json` for project entry (legacy)
|
|
4. Report which format is in use
|
|
|
|
---
|
|
|
|
## Section 2: Permission Rule Syntax Reference
|
|
|
|
| Pattern | Meaning |
|
|
|---------|---------|
|
|
| `Tool` or `Tool(*)` | Allow all uses of that tool |
|
|
| `Bash(npm run build)` | Exact command match |
|
|
| `Bash(npm run test *)` | Prefix match (space+asterisk = word boundary) |
|
|
| `Bash(npm*)` | Prefix match without word boundary |
|
|
| `Write(plugins/**)` | Glob — all files recursively under `plugins/` |
|
|
| `Write(plugins/projman/*)` | Glob — direct children only |
|
|
| `Read(.env*)` | Pattern matching `.env`, `.env.local`, etc. |
|
|
| `mcp__gitea__*` | All tools from the gitea MCP server |
|
|
| `mcp__netbox__list_*` | Specific MCP tool pattern |
|
|
| `WebFetch(domain:github.com)` | Domain-restricted web fetch |
|
|
|
|
### Important Nuances
|
|
|
|
**Word boundary matching:**
|
|
- `Bash(ls *)` (with space) matches `ls -la` but NOT `lsof`
|
|
- `Bash(ls*)` (no space) matches both `ls -la` AND `lsof`
|
|
|
|
**Precedence rules:**
|
|
- `deny` rules take precedence over `allow` rules
|
|
- `ask` rules override both (always prompts even if allowed)
|
|
- More specific patterns do NOT override broader patterns
|
|
|
|
**Command operators:**
|
|
- Piped commands (`cmd1 | cmd2`) may not match individual command rules (known Claude Code limitation)
|
|
- Shell operators (`&&`, `||`) — Claude Code is aware of these and won't let prefix rules bypass them
|
|
- Commands with redirects (`>`, `>>`, `<`) are evaluated as complete strings
|
|
|
|
---
|
|
|
|
## Section 3: Pattern Consolidation Rules
|
|
|
|
The audit detects these optimization opportunities:
|
|
|
|
| Issue | Example | Recommendation |
|
|
|-------|---------|----------------|
|
|
| **Exact duplicates** | `Write(plugins/**)` listed twice | Remove duplicate |
|
|
| **Subset redundancy** | `Write(plugins/projman/*)` when `Write(plugins/**)` exists | Remove the narrower pattern — already covered |
|
|
| **Merge candidates** | `Write(plugins/projman/*)`, `Write(plugins/git-flow/*)`, `Write(plugins/pr-review/*)` ... (4+ similar patterns) | Merge to `Write(plugins/**)` |
|
|
| **Overly broad** | `Bash` (no specifier = allows ALL bash) | Flag as security concern, suggest scoped patterns |
|
|
| **Stale patterns** | `Write(plugins/old-plugin/**)` for a plugin that no longer exists | Remove stale entry |
|
|
| **Missing MCP permissions** | MCP servers in `.mcp.json` but no `mcp__servername__*` in allow | Suggest adding if server is trusted |
|
|
| **Conflicting rules** | Same pattern in both `allow` and `deny` | Flag conflict — deny wins, but allow is dead weight |
|
|
|
|
### Consolidation Algorithm
|
|
|
|
1. **Deduplicate:** Remove exact duplicates from each array
|
|
2. **Subset elimination:** For each pattern, check if a broader pattern exists
|
|
- `Write(plugins/projman/*)` is subset of `Write(plugins/**)`
|
|
- `Bash(git status)` is subset of `Bash(git *)`
|
|
3. **Merge detection:** If 4+ patterns share a common prefix, suggest merge
|
|
- Threshold: 4 patterns minimum before suggesting consolidation
|
|
4. **Stale detection:** Cross-reference file patterns against actual filesystem
|
|
5. **Conflict detection:** Check for patterns appearing in multiple arrays
|
|
|
|
---
|
|
|
|
## Section 4: Review-Layer-Aware Recommendations
|
|
|
|
This is the key section. Map upstream review processes to directory scopes:
|
|
|
|
| Directory Scope | Active Review Layers | Auto-Allow Recommendation |
|
|
|----------------|---------------------|---------------------------|
|
|
| `plugins/*/commands/*.md` | Sprint approval, PR review, doc-guardian PostToolUse | `Write(plugins/*/commands/**)` — 3 layers cover this |
|
|
| `plugins/*/skills/*.md` | Sprint approval, PR review | `Write(plugins/*/skills/**)` — 2 layers |
|
|
| `plugins/*/agents/*.md` | Sprint approval, PR review, contract-validator | `Write(plugins/*/agents/**)` — 3 layers |
|
|
| `mcp-servers/*/mcp_server/*.py` | Code-sentinel PreToolUse, sprint approval, PR review | `Write(mcp-servers/**)` + `Edit(mcp-servers/**)` — sentinel catches secrets |
|
|
| `docs/*.md` | Doc-guardian PostToolUse, PR review | `Write(docs/**)` + `Edit(docs/**)` |
|
|
| `.claude-plugin/*.json` | validate-marketplace.sh, PR review | `Write(.claude-plugin/**)` |
|
|
| `scripts/*.sh` | Code-sentinel, PR review | `Write(scripts/**)` — with caution flag |
|
|
| `CLAUDE.md`, `CHANGELOG.md`, `README.md` | Doc-guardian, PR review | `Write(CLAUDE.md)`, `Write(CHANGELOG.md)`, `Write(README.md)` |
|
|
|
|
### Critical Rule: Hook Verification
|
|
|
|
**Before recommending auto-allow for a scope, the agent MUST verify the hook is actually configured.**
|
|
|
|
Read the relevant `plugins/*/hooks/hooks.json` file:
|
|
- If code-sentinel's hook is missing or disabled, do NOT recommend auto-allowing `mcp-servers/**` writes
|
|
- If doc-guardian's hook is missing, do NOT recommend auto-allowing `docs/**` without caution
|
|
- Count the number of verified review layers before making recommendations
|
|
|
|
**Minimum threshold:** Recommend auto-allow only for scopes covered by ≥2 verified review layers.
|
|
|
|
---
|
|
|
|
## Section 5: Permission Profiles
|
|
|
|
Three named profiles for different project contexts:
|
|
|
|
### `conservative` (Default for New Users)
|
|
|
|
Minimal permissions, prompts for most write operations:
|
|
|
|
```json
|
|
{
|
|
"permissions": {
|
|
"allow": [
|
|
"Read",
|
|
"Glob",
|
|
"Grep",
|
|
"LS",
|
|
"Write(docs/**)",
|
|
"Edit(docs/**)",
|
|
"Bash(git status *)",
|
|
"Bash(git diff *)",
|
|
"Bash(git log *)",
|
|
"Bash(cat *)",
|
|
"Bash(ls *)",
|
|
"Bash(head *)",
|
|
"Bash(tail *)",
|
|
"Bash(wc *)",
|
|
"Bash(grep *)"
|
|
],
|
|
"deny": [
|
|
"Read(.env*)",
|
|
"Read(./secrets/**)",
|
|
"Bash(rm -rf *)",
|
|
"Bash(sudo *)"
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
### `reviewed` (Projects with ≥2 Upstream Review Layers)
|
|
|
|
This is the target profile for projects using the marketplace's multi-layer review architecture:
|
|
|
|
```json
|
|
{
|
|
"permissions": {
|
|
"allow": [
|
|
"Read",
|
|
"Glob",
|
|
"Grep",
|
|
"LS",
|
|
"Edit",
|
|
"Write",
|
|
"MultiEdit",
|
|
"Bash(git *)",
|
|
"Bash(python *)",
|
|
"Bash(pip install *)",
|
|
"Bash(cd *)",
|
|
"Bash(cat *)",
|
|
"Bash(ls *)",
|
|
"Bash(head *)",
|
|
"Bash(tail *)",
|
|
"Bash(wc *)",
|
|
"Bash(grep *)",
|
|
"Bash(find *)",
|
|
"Bash(mkdir *)",
|
|
"Bash(cp *)",
|
|
"Bash(mv *)",
|
|
"Bash(touch *)",
|
|
"Bash(chmod *)",
|
|
"Bash(source *)",
|
|
"Bash(echo *)",
|
|
"Bash(sed *)",
|
|
"Bash(awk *)",
|
|
"Bash(sort *)",
|
|
"Bash(uniq *)",
|
|
"Bash(diff *)",
|
|
"Bash(jq *)",
|
|
"Bash(npm *)",
|
|
"Bash(npx *)",
|
|
"Bash(node *)",
|
|
"Bash(pytest *)",
|
|
"Bash(python -m *)",
|
|
"Bash(./scripts/*)",
|
|
"WebFetch",
|
|
"WebSearch"
|
|
],
|
|
"deny": [
|
|
"Read(.env*)",
|
|
"Read(./secrets/**)",
|
|
"Bash(rm -rf *)",
|
|
"Bash(sudo *)",
|
|
"Bash(curl * | bash*)",
|
|
"Bash(wget * | bash*)"
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
### `autonomous` (Trusted CI/Sandboxed Environments Only)
|
|
|
|
Maximum permissions for automated environments:
|
|
|
|
```json
|
|
{
|
|
"permissions": {
|
|
"allow": [
|
|
"Read",
|
|
"Glob",
|
|
"Grep",
|
|
"LS",
|
|
"Edit",
|
|
"Write",
|
|
"MultiEdit",
|
|
"Bash",
|
|
"WebFetch",
|
|
"WebSearch"
|
|
],
|
|
"deny": [
|
|
"Read(.env*)",
|
|
"Read(./secrets/**)",
|
|
"Bash(rm -rf /)",
|
|
"Bash(sudo *)"
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
**Warning:** The `autonomous` profile allows unscoped `Bash` — only use in fully sandboxed environments.
|
|
|
|
---
|
|
|
|
## Section 6: Scoring Criteria (Settings Efficiency Score — 100 points)
|
|
|
|
| Category | Points | What It Measures |
|
|
|----------|--------|------------------|
|
|
| **Redundancy** | 25 | No duplicates, no subset patterns, merged where possible |
|
|
| **Coverage** | 25 | Common tools allowed, MCP servers covered, no unnecessary gaps |
|
|
| **Safety Alignment** | 25 | Deny rules cover secrets, destructive commands; review layers verified |
|
|
| **Profile Fit** | 25 | How close to recommended profile for the project's review layer count |
|
|
|
|
### Scoring Breakdown
|
|
|
|
**Redundancy (25 points):**
|
|
- 25: No duplicates, no subsets, patterns are consolidated
|
|
- 20: 1-2 minor redundancies
|
|
- 15: 3-5 redundancies or 1 merge candidate group
|
|
- 10: 6+ redundancies or 2+ merge candidate groups
|
|
- 5: Significant redundancy (10+ issues)
|
|
- 0: Severe redundancy (20+ issues)
|
|
|
|
**Coverage (25 points):**
|
|
- 25: All common tools allowed, MCP servers covered
|
|
- 20: Missing 1-2 common tool patterns
|
|
- 15: Missing 3-5 patterns or 1 MCP server
|
|
- 10: Missing 6+ patterns or 2+ MCP servers
|
|
- 5: Significant gaps causing frequent prompts
|
|
- 0: Minimal coverage (prompts on most operations)
|
|
|
|
**Safety Alignment (25 points):**
|
|
- 25: Deny rules cover secrets + destructive ops, review layers verified
|
|
- 20: Minor gaps (e.g., missing one secret pattern)
|
|
- 15: Overly broad allow without review layer coverage
|
|
- 10: Missing deny rules for secrets or destructive commands
|
|
- 5: Unsafe patterns without review layer justification
|
|
- 0: Security concerns (e.g., unscoped `Bash` without review layers)
|
|
|
|
**Profile Fit (25 points):**
|
|
- 25: Matches recommended profile exactly
|
|
- 20: Within 90% of recommended profile
|
|
- 15: Within 80% of recommended profile
|
|
- 10: Within 70% of recommended profile
|
|
- 5: Significant deviation from recommended profile
|
|
- 0: No alignment with any named profile
|
|
|
|
### Score Interpretation
|
|
|
|
| Score Range | Status | Meaning |
|
|
|-------------|--------|---------|
|
|
| 90-100 | Optimized | Minimal prompt interruptions, safety maintained |
|
|
| 70-89 | Good | Minor consolidation opportunities |
|
|
| 50-69 | Needs Work | Significant redundancy or missing permissions |
|
|
| Below 50 | Poor | Likely getting constant approval prompts unnecessarily |
|
|
|
|
---
|
|
|
|
## Section 7: Hook Detection Method
|
|
|
|
To verify which review layers are active, read these files:
|
|
|
|
| File | Hook Type | Tool Matcher | Purpose |
|
|
|------|-----------|--------------|---------|
|
|
| `plugins/code-sentinel/hooks/hooks.json` | PreToolUse | Write\|Edit\|MultiEdit | Blocks hardcoded secrets |
|
|
| `plugins/doc-guardian/hooks/hooks.json` | PostToolUse | Write\|Edit\|MultiEdit | Tracks documentation drift |
|
|
| `plugins/project-hygiene/hooks/hooks.json` | PostToolUse | Write\|Edit | Cleanup tracking |
|
|
| `plugins/data-platform/hooks/hooks.json` | PostToolUse | Edit\|Write | Schema diff detection |
|
|
| `plugins/cmdb-assistant/hooks/hooks.json` | PreToolUse | (if exists) | Input validation |
|
|
|
|
### Verification Process
|
|
|
|
1. **Read each hooks.json file**
|
|
2. **Parse the JSON to find hook configurations**
|
|
3. **Check the `type` field** — must be `"command"` (not `"prompt"`)
|
|
4. **Check the `event` field** — maps to when hook runs
|
|
5. **Check the `tools` array** — which operations are intercepted
|
|
6. **Verify plugin is in marketplace** — check `.claude-plugin/marketplace.json`
|
|
|
|
### Example Hook Structure
|
|
|
|
```json
|
|
{
|
|
"hooks": [
|
|
{
|
|
"event": "PreToolUse",
|
|
"type": "command",
|
|
"command": "./hooks/security-check.sh",
|
|
"tools": ["Write", "Edit", "MultiEdit"]
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Review Layer Count
|
|
|
|
Count verified review layers for each scope:
|
|
|
|
| Layer | Verification |
|
|
|-------|-------------|
|
|
| Sprint approval | Check if projman plugin is installed (milestone workflow) |
|
|
| PR review | Check if pr-review plugin is installed |
|
|
| code-sentinel PreToolUse | hooks.json exists with PreToolUse on Write/Edit |
|
|
| doc-guardian PostToolUse | hooks.json exists with PostToolUse on Write/Edit |
|
|
| contract-validator | Plugin installed + hooks present |
|
|
|
|
**Recommendation threshold:** Only recommend auto-allow for scopes with ≥2 verified layers.
|