Documentation
¶
Overview ¶
Package perms reads Claude Code permission rules, reports the ones that cannot do what their author intended, and answers whether a given command is covered by them.
It is public rather than internal because two products depend on it: pitwall audits a ruleset with it, and steward enforces one with it. They must agree — an audit that says a rule is dead while the enforcer still honours it is worse than either tool alone — so there is one matcher and both import it.
The matching rules implemented here follow Claude Code's documented behaviour. They are deliberately conservative: where the documentation is silent, this package declines to make a claim rather than guessing, because a linter that invents findings is worse than no linter.
Index ¶
- func Apply(p Plan, backupDir string) (backup string, err error)
- func CategoryRank(c string) int
- func Covers(a, b string) bool
- func HasSeparator(s string) bool
- func ManagedPath() string
- func MatchBash(pattern, cmd string) bool
- func MatchBashPattern(pattern, sub string) bool
- func ParseRule(raw string) (tool, arg string, bare bool)
- func SplitCommand(cmd string) (parts []string, ok bool)
- type Finding
- type Options
- type Plan
- type Prefix
- type Rewrite
- type Rule
- type Scope
- type Source
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Apply ¶
Apply writes the plan to disk after copying the original into backupDir. It rebuilds only the permission lists and leaves every other key byte-identical and in its original order, so the diff a user reviews is the change itself and nothing else.
func Covers ¶
Covers reports whether pattern a approves everything pattern b approves, so b adds nothing. It is answered only for cases that can be decided by inspection: an exact duplicate, or a literal b that a already matches. Anything else returns false rather than a guess.
func HasSeparator ¶
HasSeparator reports whether s contains a shell command separator.
func ManagedPath ¶
func ManagedPath() string
ManagedPath is where an administrator's settings live on this platform.
func MatchBash ¶
MatchBash reports whether a pattern approves a whole command line. Every subcommand must match independently, so Bash(safe-cmd *) does not approve "safe-cmd && other-cmd".
func MatchBashPattern ¶
MatchBashPattern reports whether a single Bash pattern matches one subcommand. It does not split on separators; use MatchBash for a full command line.
func ParseRule ¶
ParseRule splits "Tool(arg)" into its parts. An entry with no parentheses is a bare tool name, which in a deny rule removes the tool from Claude's context entirely.
func SplitCommand ¶
SplitCommand breaks a command line into the subcommands Claude Code matches separately. Quoted regions are left alone, so "echo 'a && b'" stays one subcommand — splitting inside quotes would invent separators that the shell never sees and make a working rule look unused. A trailing separator with nothing after it makes the whole command unparseable, which Claude Code treats as "no allow rule applies"; ok reports that case.
Types ¶
type Finding ¶
type Finding struct {
Rule Rule
Category string
Why string
Fix string // what to write instead; empty means the rule should go
Redacted bool // the rule text carries a secret and must not be printed
}
Finding is one rule that does not do what its author intended, with the documented reason it fails and what to do instead.
type Options ¶
type Options struct {
// DropOneOffs also removes literal allow rules. They work; they are just
// clutter that only ever matches one command again. Removing one means
// Claude Code asks about that command the next time, which is a change in
// behaviour, so it is off by default.
DropOneOffs bool
}
Options controls how aggressive a fix plan is.
type Plan ¶
type Plan struct {
Source Source
Remove []Finding
Rewrite []Rewrite
Report []Finding // findings this plan deliberately leaves alone
}
Plan is the set of edits for a single settings file.
type Rule ¶
type Rule struct {
Raw string // exactly as it appears in the file
Kind string // allow, deny or ask
Tool string // the tool name, or the whole entry when it is a bare name
Arg string // the text inside the parentheses
Bare bool // written without parentheses
Source Source
Index int // position within its list, for stable ordering
}
Rule is a single permission entry as written.
type Scope ¶
type Scope int
Scope is where a settings file sits in Claude Code's precedence order. Managed settings win over everything, including command line arguments.
type Source ¶
type Source struct {
Path string
Scope Scope
Repo string // the project the file belongs to, empty for user and managed
}
Source is one settings file that contributed rules.