Skip to main content

resolve_policy

Function resolve_policy 

Source
pub fn resolve_policy(
    tool_name: &str,
    is_builtin: bool,
    launch_overrides: &HashMap<String, ToolPolicy>,
    stage_permissions: &HashMap<String, String>,
    agent_permissions: &HashMap<String, String>,
    global_permissions: &HashMap<String, ToolPolicy>,
) -> ToolPolicy
Expand description

Resolve the effective policy for a tool call.

Scope order is narrowest-first - stage, then agent, then the user’s global config, then the built-in default - but narrower does not mean stronger. The stage and agent layers come out of agent.leviath, which for any agent installed with lev add is a file the user downloaded. So a blueprint may only ever tighten what the user configured, never loosen it: whatever the user explicitly wrote in [tool_permissions] is a ceiling on how permissive a manifest can be for that tool.

Only an explicitly configured global entry acts as a ceiling. A tool the user has said nothing about falls through to default_tool_policy, and a blueprint is free to set it - otherwise no shipped agent could pre-approve its own tools (the researcher’s web_fetch = "allow" would stop working) and the model would become a wall rather than a floor.

A user who wants to grant one specific agent more than their global setting says so in their own config, keyed by agent name - see crate::config::Config::permissions_for_agent, which is folded into global_permissions at spawn.

launch_overrides (--allow/--ask/--deny/--yolo) come from the person at the terminal, so they may relax Ask to Allow. They may not override a Deny: a denied tool stays denied under --yolo, matching the guarantee other agent runtimes make about their deny rules. To lift a Deny, edit the config that set it.