Found while reading a studio session's studio-resume.log (per #3374): every launch, Claude Code prints warnings that the app's generated permission rules are wrong.
Evidence (real session stderr)
Permission allow rule (.claude/settings.json): MultiEdit(scratch/**) is not matched by file permission checks — only Edit(path) rules are. Use Edit(scratch/**) instead (Edit rules cover all file-editing tools).
Permission allow rule (.claude/settings.json): Write(scratch/**) … Use Edit(scratch/**) instead.
Permission allow rule (.claude/settings.json): NotebookEdit(scratch/**) … Use Edit(scratch/**) instead.
Permission deny rule "MultiEdit(.claude/**)" matches no known tool — check for typos.
The bug
The app expands every path-scoped file rule over ["Edit","Write","MultiEdit","NotebookEdit"] (launchRules.ts WRITE_TOOLS, and sessionLaunch.ts confinementConfigDeny). But Claude Code only honors Edit(<path>) as a file-path rule — and it covers ALL file-editing tools. So:
Write(path) / NotebookEdit(path) rules are silently ignored (noise on the designer's scratch/** allow).
MultiEdit no longer exists as a tool → its path form is a "matches no known tool" error, its bare form a dead deny.
The consequence that matters: the .claude/** write-DENY is emitted as Write(.claude/**)/MultiEdit(.claude/**)/NotebookEdit(.claude/**) — none of which Claude Code enforces. Only Edit(.claude/**) actually denies. The settings-level protection of the session config is not being applied as intended (the PreToolUse hooks + fsConfine remain the real floor, so this is defence-in-depth, not an open door — but the settings rule is wrong and every studio session logs it).
Fix
- Path-scoped file rules (allow + deny) → emit
Edit(<glob>) ONLY.
- Drop
MultiEdit (removed tool).
- Whole-tool write denies (a
code:none role with no carve-out) → the real bare tool names, no MultiEdit.
- Update the TS + Rust tests to the corrected model.
Affects all four studio roles (they share the write-scope path), plus every role's .claude/** confinement deny.
Acceptance
Found while reading a studio session's
studio-resume.log(per #3374): every launch, Claude Code prints warnings that the app's generated permission rules are wrong.Evidence (real session stderr)
The bug
The app expands every path-scoped file rule over
["Edit","Write","MultiEdit","NotebookEdit"](launchRules.tsWRITE_TOOLS, andsessionLaunch.tsconfinementConfigDeny). But Claude Code only honorsEdit(<path>)as a file-path rule — and it covers ALL file-editing tools. So:Write(path)/NotebookEdit(path)rules are silently ignored (noise on the designer'sscratch/**allow).MultiEditno longer exists as a tool → its path form is a "matches no known tool" error, its bare form a dead deny.The consequence that matters: the
.claude/**write-DENY is emitted asWrite(.claude/**)/MultiEdit(.claude/**)/NotebookEdit(.claude/**)— none of which Claude Code enforces. OnlyEdit(.claude/**)actually denies. The settings-level protection of the session config is not being applied as intended (the PreToolUse hooks + fsConfine remain the real floor, so this is defence-in-depth, not an open door — but the settings rule is wrong and every studio session logs it).Fix
Edit(<glob>)ONLY.MultiEdit(removed tool).code:nonerole with no carve-out) → the real bare tool names, noMultiEdit.Affects all four studio roles (they share the write-scope path), plus every role's
.claude/**confinement deny.Acceptance
.claude/**writes are actually denied at the settings level (viaEdit(.claude/**)).scratch/**allow usesEdit(scratch/**).