Enforce tool permissions before execution
The Rust CLI/runtime now models permissions as ordered access levels, derives tool requirements from the shared tool specs, and prompts REPL users before one-off danger-full-access escalations from workspace-write sessions. This also wires explicit --permission-mode parsing and makes /permissions operate on the live session state instead of an implicit env-derived default. Constraint: Must preserve the existing three user-facing modes read-only, workspace-write, and danger-full-access Constraint: Must avoid new dependencies and keep enforcement inside the existing runtime/tool plumbing Rejected: Keep the old Allow/Deny/Prompt policy model | could not represent ordered tool requirements across the CLI surface Rejected: Continue sourcing live session mode solely from RUSTY_CLAUDE_PERMISSION_MODE | /permissions would not reliably reflect the current session state Confidence: high Scope-risk: moderate Reversibility: clean Directive: Add required_permission entries for new tools before exposing them to the runtime Tested: cargo fmt; cargo clippy --workspace --all-targets -- -D warnings; cargo test -q Not-tested: Manual interactive REPL approval flow in a live Anthropic session
This commit is contained in:
@@ -408,7 +408,8 @@ mod tests {
|
||||
.sum::<i32>();
|
||||
Ok(total.to_string())
|
||||
});
|
||||
let permission_policy = PermissionPolicy::new(PermissionMode::Prompt);
|
||||
let permission_policy = PermissionPolicy::new(PermissionMode::WorkspaceWrite)
|
||||
.with_tool_requirement("add", PermissionMode::DangerFullAccess);
|
||||
let system_prompt = SystemPromptBuilder::new()
|
||||
.with_project_context(ProjectContext {
|
||||
cwd: PathBuf::from("/tmp/project"),
|
||||
@@ -487,7 +488,8 @@ mod tests {
|
||||
Session::new(),
|
||||
SingleCallApiClient,
|
||||
StaticToolExecutor::new(),
|
||||
PermissionPolicy::new(PermissionMode::Prompt),
|
||||
PermissionPolicy::new(PermissionMode::WorkspaceWrite)
|
||||
.with_tool_requirement("blocked", PermissionMode::DangerFullAccess),
|
||||
vec!["system".to_string()],
|
||||
);
|
||||
|
||||
@@ -536,7 +538,7 @@ mod tests {
|
||||
session,
|
||||
SimpleApi,
|
||||
StaticToolExecutor::new(),
|
||||
PermissionPolicy::new(PermissionMode::Allow),
|
||||
PermissionPolicy::new(PermissionMode::ReadOnly),
|
||||
vec!["system".to_string()],
|
||||
);
|
||||
|
||||
@@ -563,7 +565,7 @@ mod tests {
|
||||
Session::new(),
|
||||
SimpleApi,
|
||||
StaticToolExecutor::new(),
|
||||
PermissionPolicy::new(PermissionMode::Allow),
|
||||
PermissionPolicy::new(PermissionMode::ReadOnly),
|
||||
vec!["system".to_string()],
|
||||
);
|
||||
runtime.run_turn("a", None).expect("turn a");
|
||||
|
||||
Reference in New Issue
Block a user