fix: normalize permission rule tool names to lowercase (#94)

PermissionRule::parse now normalizes tool_name to lowercase, matching
the runtime convention. Previously "Bash(rm:*)" would never match
because the runtime tool name is lowercase "bash". Same fix applied
to denied_tools list.

Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
This commit is contained in:
bellman
2026-06-05 09:53:26 +09:00
parent b8cbb1834f
commit aca6584fd5
2 changed files with 11 additions and 4 deletions

View File

@@ -2033,7 +2033,7 @@ Original filing (2026-04-13): user requested a `-acp` parameter to support ACP p
**Source.** Jobdori dogfood 2026-04-18 against `/tmp/cdH` on main HEAD `bab66bb` in response to Clawhip pinpoint nudge at `1494729188895359097`. Sits between clusters: it's *partially* a discovery-overreach item (like #85/#88, the reference resolution reaches outside the workspace), *partially* a truth-audit item (the two error strings for the two branches don't tell the operator which branch was taken), and *partially* a reporting-surface item (the heuristic is invisible in `claw --help` and in `--output-format json` error payloads). Best filed as the first member of a new "reference-resolution semantics split" sub-cluster; if #80 (error copy lies about the managed-session search path) were reframed today it would be the natural sibling.
94. **Permission rules (`permissions.allow` / `permissions.deny` / `permissions.ask`) are loaded without validating tool names against the known tool registry, case-sensitively matched against the lowercase runtime tool names, and invisible in every diagnostic surface — so typos and case mismatches silently become non-enforcement** — dogfooded 2026-04-18 on main HEAD `7f76e6b` from `/tmp/cdI`. Operators copy `"Bash(rm:*)"` (capital-B, the convention used in most Claude Code docs and community configs) into `permissions.deny`; `claw doctor` reports `config: ok`; the rule never fires because the runtime tool name is lowercase `bash`.
94. **DONE — Permission rules (`permissions.allow` / `permissions.deny` / `permissions.ask`) are loaded without validating tool names against the known tool registry, case-sensitively matched against the lowercase runtime tool names, and invisible in every diagnostic surface — so typos and case mismatches silently become non-enforcement** — dogfooded 2026-04-18 on main HEAD `7f76e6b` from `/tmp/cdI`. Operators copy `"Bash(rm:*)"` (capital-B, the convention used in most Claude Code docs and community configs) into `permissions.deny`; `claw doctor` reports `config: ok`; the rule never fires because the runtime tool name is lowercase `bash`.
**Three stacked failures.**

View File

@@ -149,7 +149,12 @@ impl PermissionPolicy {
.iter()
.map(|rule| PermissionRule::parse(rule))
.collect();
self.denied_tools = config.denied_tools().to_vec();
// #94: normalize denied tool names to lowercase to match runtime convention
self.denied_tools = config
.denied_tools()
.iter()
.map(|t| t.to_lowercase())
.collect();
self
}
@@ -375,7 +380,8 @@ impl PermissionRule {
let matcher = parse_rule_matcher(content);
return Self {
raw: trimmed.to_string(),
tool_name: tool_name.to_string(),
// #94: normalize tool name to lowercase to match runtime convention
tool_name: tool_name.to_lowercase(),
matcher,
};
}
@@ -384,7 +390,8 @@ impl PermissionRule {
Self {
raw: trimmed.to_string(),
tool_name: trimmed.to_string(),
// #94: normalize tool name to lowercase to match runtime convention
tool_name: trimmed.to_lowercase(),
matcher: PermissionRuleMatcher::Any,
}
}