fix(planning): use default permission mode so MCP planning tools don't prompt

Interactive planning sessions launched with --permission-mode plan, which
gates EVERY MCP tool call regardless of --allowedTools (verified: even a
read-only mcp__claudedo__list_task_lists is denied under plan mode). So the
session prompted the user on the first CreateChildTask -- the whole point of
a planning session.

Switch BuildPlanningStartArgs/BuildPlanningResumeArgs to --permission-mode
default, which honours the allowlist. File edits stay blocked via the planning
system prompt + AllowedTools omitting Write/Edit/Bash. Resume also re-passes
--allowedTools, since the CLI does not restore it across --resume.

The earlier 'glob does not match' hypothesis was empirically falsified:
mcp__claudedo__*, the bare server name, and the explicit tool name all allow
the tool with zero permission_denials in default mode.
This commit is contained in:
mika kuns
2026-07-24 12:38:45 +02:00
parent 3e9ea3ad58
commit 624ec7a668
4 changed files with 29 additions and 11 deletions
@@ -80,7 +80,9 @@ public sealed class WindowsTerminalLauncherTests
Assert.Equal("--model", args[0]);
var permIdx = args.ToList().IndexOf("--permission-mode");
Assert.True(permIdx >= 0);
Assert.Equal("plan", args[permIdx + 1]);
// Default mode, NOT plan mode: plan mode gates every MCP tool call regardless of the
// allowlist, which would prompt on the first CreateChildTask.
Assert.Equal("default", args[permIdx + 1]);
Assert.Contains("--allowedTools", args);
Assert.Contains(ctx.Files.SessionDirectory, args);
Assert.Contains(ctx.Files.SystemPromptPath, args);
@@ -89,10 +91,16 @@ public sealed class WindowsTerminalLauncherTests
}
[Fact]
public void BuildPlanningResumeArgs_PinsPlanModeAndResume()
public void BuildPlanningResumeArgs_DefaultModeAllowlistsMcpAndResumes()
{
var args = WindowsTerminalLauncher.BuildPlanningResumeArgs("sess-9");
Assert.Equal(new[] { "--permission-mode", "plan", "--resume", "sess-9" }, args);
Assert.Equal("--permission-mode", args[0]);
Assert.Equal("default", args[1]);
Assert.Equal("--allowedTools", args[2]);
// The MCP planning tools must be re-allowlisted on resume: the CLI does not restore
// --allowedTools across a --resume, so without it CreateChildTask would prompt again.
Assert.Contains("mcp__claudedo__", args[3]);
Assert.Equal(new[] { "--resume", "sess-9" }, args.Skip(4).ToArray());
}
[Fact]