auto-promote: single quotes in regex break single-quoted TOML literals #12
Labels
No labels
enhancement
observability
research
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
jbr870/claude-permit#12
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?
Problem
The auto-promote writer emits regex patterns as single-quoted TOML literal strings:
TOML single-quoted literals do not support any form of escaping — they cannot contain a literal
'. When the LLM suggests a regex that includes a single quote character (typically inside a character class like['"]?), the generated line parses as a truncated string followed by garbage:toml::from_strthen fails withexpected newline, \#`` and — as in #11 — all auto-promoted rules after the broken block are silently dropped.Impact
validate/reportinvocation.~/.claude/claude-permit/auto-rules.tomlafter repairing the #11 damage.auto-rules.toml(1292, 4606, 5774, 7244), all from regexes matching shell-quoted args (['"]…['"]). The earliest (line 1292, dated 2026-04-16) abortstoml::from_strfirst → all 1100+ promoted rules silently dropped at runtime → user experience: "I keep granting the same permissions; nothing seems to be learned."claude-permit validatedoes report the parse error, but the message scrolls past at hook time and there is no other visible signal.Affected code
src/auto_promote.rs::format_rule_toml— writes each field as{key} = '{pattern}'with no awareness of single quotes in{pattern}.src/config.rs::load_and_merge_auto_rules(lines 262-274) — on parse failure, logs to stderr and returns. The whole file is dropped on a single bad block; there is no per-rule fault tolerance and no visible health signal beyond stderr.Proposed fix
The fix has two halves: stop writing corrupt rules, and survive corrupt rules without losing data or hiding the problem.
1. Quote-safe emit (prevention)
Switch to double-quoted TOML strings when the pattern contains
', escaping\,", and control chars per the TOML spec. Preserves single-quoted literals for the common case (keeps the "no double-backslash pain" benefit). Add a regression test that round-trips a rule whose regex pattern contains'throughtoml::from_str, in the same shape as the multiline regression test added in #11.2. Per-rule fault tolerance + loud failure (resilience)
Skipping individual bad rules is the right behavior, but every skip MUST leave a paper trail in multiple places — otherwise we trade the #11/#12 silent-loss failure mode for a subtler "10 % of rules vanished and nothing told me" failure mode.
Required signals when one or more rules are skipped:
event: "AutoRulesHealth"JSONL line on hook startup whenever the load skips one or more blocks:{skipped_count, total_count, sample_errors: [{line, error}, …]}. This makes the signal queryable and feeds the report.claude-permit reportshows a prominent banner at the top: "⚠ N auto-rules unparseable — being ignored. Runclaude-permit validateto inspect."validateexits non-zero when auto-rules has skipped blocks, prints them with line numbers and parse errors.validatebecomes a real health check, not just a syntax check.3. Corruption-rate guardrail (catastrophe protection)
If more than ~5 % of auto-rules fail to parse, treat it as a corruption event rather than a routine skip: emit a higher-severity audit entry and either fail closed (force user attention before the next hook fires) or, at minimum, surface the warning on every hook invocation until acknowledged. This is the backstop that prevents a future analogue of #11/#12 from quietly invalidating most of the user's promoted rules.
4. One-time cleanup
The four corrupt lines currently in
auto-rules.toml(1292, 4606, 5774, 7244) need a one-time cleanup before any of the above helps the existing live install.auto-rules.toml.bak(Apr 24) is the reference point.Acceptance criteria
'in the regex round-trip throughtoml::from_str.auto-rules.tomlno longer prevents the surrounding rules from loading.AutoRulesHealthaudit entry, a banner inclaude-permit report, and a non-zero exit fromclaude-permit validate.auto-rules.tomlis repaired in the live install andvalidateexits clean.Discovery context
Found while repairing existing damage caused by issue #11. The multi-line-leak repair revealed single-quote handling as a second, independent bug in the same writer path. The 2026-04-25 recurrence confirmed that fixing the writer alone is not sufficient — the loader also needs to fail loudly per-rule rather than fail-open silently per-file.
Related