fix: switch agent permission mode from bypassPermissions to allowFullAutoEdit
bypassPermissions ignored the worktree's .claude/settings.json entirely, letting agents run any Bash command including cargo test (which they'd spawn 4+ times concurrently, deadlocking on the build directory lock). allowFullAutoEdit respects the settings.json allowlist, so agents can only use the Bash commands we explicitly permit (cargo check, cargo build, git) and must use MCP tools for everything else (run_tests, run_lint, run_build). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -198,9 +198,13 @@ fn run_agent_pty_blocking(
|
||||
// and instead leak as unstructured PTY text.
|
||||
cmd.arg("--include-partial-messages");
|
||||
|
||||
// Supervised agents don't need interactive permission prompts
|
||||
// Agents use allowFullAutoEdit so the worktree's .claude/settings.json
|
||||
// controls which tools are pre-approved. Anything not in the allowlist
|
||||
// triggers the permission prompt tool, which auto-denies for agents.
|
||||
cmd.arg("--permission-mode");
|
||||
cmd.arg("bypassPermissions");
|
||||
cmd.arg("allowFullAutoEdit");
|
||||
cmd.arg("--permission-prompt-tool");
|
||||
cmd.arg("mcp__huskies__prompt_permission");
|
||||
|
||||
cmd.cwd(cwd);
|
||||
cmd.env("NO_COLOR", "1");
|
||||
|
||||
@@ -150,14 +150,26 @@ pub(super) async fn tool_prompt_permission(
|
||||
let request_id = uuid::Uuid::new_v4().to_string();
|
||||
let (response_tx, response_rx) = tokio::sync::oneshot::channel();
|
||||
|
||||
ctx.perm_tx
|
||||
// Try to forward to the interactive session (WebSocket/Matrix).
|
||||
// If no session is active (headless agent), auto-deny the permission.
|
||||
if ctx.perm_tx
|
||||
.send(crate::http::context::PermissionForward {
|
||||
request_id: request_id.clone(),
|
||||
tool_name: tool_name.clone(),
|
||||
tool_input: tool_input.clone(),
|
||||
response_tx,
|
||||
})
|
||||
.map_err(|_| "No active WebSocket session to receive permission request".to_string())?;
|
||||
.is_err()
|
||||
{
|
||||
crate::slog!(
|
||||
"[permission] Auto-denied '{tool_name}' (no interactive session — agent mode)"
|
||||
);
|
||||
return serde_json::to_string_pretty(&json!({
|
||||
"behavior": "deny",
|
||||
"message": format!("Permission denied for '{tool_name}'. Use the appropriate MCP tool instead (e.g. run_tests, run_build, run_lint).")
|
||||
}))
|
||||
.map_err(|e| format!("Serialization error: {e}"));
|
||||
}
|
||||
|
||||
use crate::http::context::PermissionDecision;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user