feat(settings): rebuild destructive-command cover in autoMode, scope the classifier environment

`permissions.ask` gates nothing under `defaultMode: auto` (LRN-146,
verified live), so the ten rules that left the static tiers had no cover
left: rsync / kill -9 / killall / pkill out of deny, and python3 -c /
python -c / xargs / sed / cp / mv out of ask.

autoMode.soft_deny (7 rules) takes over what an explicit instruction
should be able to clear: writes outside the working directory,
rsync --delete, SIGKILL and kill-by-name, in-place edits spanning more
than one file, directory moves, and inline interpreters or xargs that
delete or write outside the cwd. Intent clears a soft block for the
current turn only, stated as a rule since no setting expresses it.

autoMode.hard_deny (3 rules) takes the classes no command pattern can
express: secret exfiltration, production deployment, and disarming the
guardrails. Adding a restriction stays allowed, removing one does not.

permissions.deny gains ten .env reader rules (sed awk cut tr sort uniq
diff od xxd strings). Six of those tools sat in permissions.allow, so
reading a .env through them triggered nothing.

autoMode.environment named another project, its FTP deploy target and its
customer data, inside the file link.sh:21 symlinks to
~/.claude/settings.json, where it reached every repo and contradicted
this one's Gitea remote. Rewritten machine-generic; the project facts
moved to that project's gitignored .claude/settings.local.json. All three
lists now open with "$defaults", which the original omitted, so the
built-in classifier entries are inherited rather than replaced.

doctor.sh check_automode backstops both defects. SETTINGS.md documents
the block and a tier-choice table. README no longer claims the ask tier
makes every mcp__magic__* call require a live confirmation.
This commit is contained in:
Bastien Chanot
2026-09-15 19:44:24 +02:00
parent 3228acabfc
commit 3b0167c6cb
5 changed files with 226 additions and 15 deletions
+9 -4
View File
@@ -300,10 +300,15 @@ check) for up to 10 minutes per call; any local process or open browser tab
can `POST` to it and that body is injected **verbatim** into the tool result
the model consumes (job8 audit, `dist/utils/callback-server.js:36`). This is
in the third-party package's code, not this repo's config — **we don't patch
it**. The mitigation lives entirely on our side: `settings.json`
`permissions.ask` explicitly lists all 4 `mcp__magic__*` tools,
so every call — builder included — requires a live confirmation and can
never auto-execute. Don't allowlist
it**. The mitigation lives on our side: `settings.json`
`permissions.ask` explicitly lists all 4 `mcp__magic__*` tools.
Read that as a declared intent, not a proven hard gate: under
`defaultMode: auto` (this config's default) Bash `ask` rules were observed
auto-approving with no prompt raised (LRN-146). Whether MCP `ask` rules
behave the same has not been verified here, so re-check before relying on
it. `deny` is the only tier the auto-mode classifier cannot lift; for a
gate that holds under auto mode without banning the tool outright, the
right home is `autoMode.soft_deny`. Don't allowlist
`21st_magic_component_builder` or `21st_magic_component_refiner` (arbitrary
absolute-path read → vendor exfil, same audit) under any circumstance.