MergeDenyInto: prune allow entries shadowed by canonical denies #26
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Symptom
cli-guard/lockdown.MergeDenyIntoreasserts the canonical deny list at an ancestorsettings.local.jsonbut explicitly preserves every existing allow entry. This leaves shadowed allows in place — entries that are dead because the deny-before-allow rule within a file makes them unreachable.Example: parent
settings.local.jsonhadBash(gh issue *)andBash(xargs ls -lt)as allows. AfterMergeDenyIntomerged canonical denies (Bash(gh:*),Bash(xargs:*)), those allows are still in the file but effectively dead. They re-accumulate every session as Claude prompts for tools the lockdown denies and the user clicks Allow into local.After a recent sweep, the parent had ~20 such residue entries.
Fix
Extend
MergeDenyIntoso that when merging a canonical denyBash(<verb>:*), it also drops any allowBash(<verb>...)in the same file. The match rule: allow's leading bash verb token matches a canonical deny's verb prefix.Bash(gh issue *)+ canonical denyBash(gh:*)→ drop the allowBash(xargs ls -lt)+ canonical denyBash(xargs:*)→ drop the allowBash(coily git :*)+ canonical denyBash(make:*)→ keep (no match)Non-Bash allows (Read/Write/MCP) are untouched.
Out of scope for this issue
rm -rf, MCP tools for retired servers). Harder to detect programmatically. Leave for a separate cleanup.~/.claude/settings.jsonhandling. Lockdown today doesn't touch user-level. File separately.Context
Surfaced during the same renormalization sweep that produced coilysiren/coily#124 and coilysiren/coily#125. The manual prune of the parent local file should be re-runnable via
coily lockdown --apply --recursiverather than a one-time hand-edit.