{
  "name": "forge-tool",
  "language": "rust",
  "version": "0.2.0",
  "description": "Tool definition, execution, approval, and registry for the Forge SDK",
  "manifest": "forge-rs/crates/forge-tool/Cargo.toml",
  "manifestSha256": "bb4691c4cdaa0e79c73825a4e85faafa7a282ed01096022ea9c99a9110d4b77f",
  "status": "source-reference",
  "registryPublicationVerified": false,
  "route": "/libraries/rust/forge-tool",
  "features": {},
  "files": [
    {
      "path": "forge-rs/crates/forge-tool/src/approval.rs",
      "sha256": "7fdf558c438c98f1e0f367cc48bb461c71f0991c80a8cb5ef04edf31249ec513",
      "artifactSha256": "9866caa437da1d60534cdebaa890bd01cc75ff8fc056382cfa3aee75fd2b64e8",
      "url": "/reference/source/forge-rs/crates/forge-tool/src/approval.rs.txt",
      "declarations": [
        {
          "name": "::ApprovalHandler",
          "line": 87,
          "signature": "#[async_trait]\npub trait ApprovalHandler: Send + Sync {\n    /// Checks whether a tool call should be approved, denied, or modified.\n    ///\n    /// # Arguments\n    ///\n    /// * `call` - The tool call to evaluate.\n    /// * `tier` - The tool's tier classification, which may influence the decision.\n    ///\n    /// # Returns\n    ///\n    /// A [`ToolApproval`] indicating the decision:\n    /// - [`ToolApproval::Approve`] -- proceed with execution as-is.\n    /// - [`ToolApproval::Deny`] -- reject the call with a reason.\n    /// - [`ToolApproval::Modify`] -- approve but with modified arguments.\n    async fn check(&self, call: &ToolCall, tier: ToolTier) -> ToolApproval;\n}",
          "documentation": "Trait for tool approval handlers.\n\nImplementors decide whether a tool call should proceed, be denied, or be\nmodified before execution. The approval handler is invoked after schema\nvalidation but before execution.\n\n# ANVIL Spec SS8.6\n\nThe approval step is mandatory. Skipping it is forbidden (except in\nlegacy mode, handled at a higher layer in `forge-agent`).\n\n# Thread Safety\n\nApproval handlers must be `Send + Sync` because they are shared across\nasync tasks.\n\n# Examples\n\n```\nuse async_trait::async_trait;\nuse forge_tool::approval::ApprovalHandler;\nuse forge_core::tool::{ToolCall, ToolTier, ToolApproval};\n\nstruct AllowList {\n    allowed: Vec<String>,\n}\n\n#[async_trait]\nimpl ApprovalHandler for AllowList {\n    async fn check(&self, call: &ToolCall, _tier: ToolTier) -> ToolApproval {\n        if self.allowed.contains(&call.name) {\n            ToolApproval::Approve\n        } else {\n            ToolApproval::Deny {\n                reason: format!(\"tool '{}' not in allow list\", call.name),\n            }\n        }\n    }\n}\n```"
        },
        {
          "name": "::AutoApprove",
          "line": 133,
          "signature": "pub struct AutoApprove;",
          "documentation": "An approval handler that always approves tool calls.\n\nThis is the simplest approval handler. It approves every call regardless\nof tool name, tier, or arguments. Useful for development, testing, and\nscenarios where all tools are pre-authorized.\n\n# Security Consideration\n\nUsing `AutoApprove` in production means every tool call is permitted.\nFor production use with Host-tier tools, prefer [`TierBasedApproval`]\nor a custom handler that checks Arsenal ACTs.\n\n# Examples\n\n```\nuse forge_tool::approval::{ApprovalHandler, AutoApprove};\nuse forge_core::tool::{ToolCall, ToolTier, ToolApproval};\n\n# tokio::runtime::Runtime::new().unwrap().block_on(async {\nlet call = ToolCall {\n    id: \"c1\".to_string(),\n    name: \"dangerous_tool\".to_string(),\n    arguments: serde_json::json!({}),\n};\n\nlet approval = AutoApprove.check(&call, ToolTier::External).await;\nassert_eq!(approval, ToolApproval::Approve);\n# });\n```"
        },
        {
          "name": "::DenyAll",
          "line": 181,
          "signature": "pub struct DenyAll {\n\n}",
          "documentation": "An approval handler that always denies tool calls with a configured reason.\n\nUseful for testing denial flows, maintenance mode, and as a fallback\nwhen no authorization context is available.\n\n# Examples\n\n```\nuse forge_tool::approval::{ApprovalHandler, DenyAll};\nuse forge_core::tool::{ToolCall, ToolTier, ToolApproval};\n\n# tokio::runtime::Runtime::new().unwrap().block_on(async {\nlet deny = DenyAll::new(\"system under maintenance\");\n\nlet call = ToolCall {\n    id: \"c1\".to_string(),\n    name: \"any_tool\".to_string(),\n    arguments: serde_json::json!({}),\n};\n\nlet approval = deny.check(&call, ToolTier::Platform).await;\nmatch approval {\n    ToolApproval::Deny { reason } => {\n        assert!(reason.contains(\"maintenance\"));\n    }\n    _ => panic!(\"expected Deny\"),\n}\n# });\n```"
        },
        {
          "name": "::DenyAll::new",
          "line": 204,
          "signature": "pub fn new(reason: impl Into<String>) -> Self;",
          "documentation": "Creates a new `DenyAll` handler with the given denial reason.\n\n# Arguments\n\n* `reason` - The reason included in every [`ToolApproval::Deny`] response.\n\n# Returns\n\nA new `DenyAll` handler.\n\n# Examples\n\n```\nuse forge_tool::approval::DenyAll;\n\nlet deny = DenyAll::new(\"no tools allowed\");\n```"
        },
        {
          "name": "::TierBasedApproval",
          "line": 274,
          "signature": "pub struct TierBasedApproval;",
          "documentation": "A tier-based approval handler that auto-approves Platform and Embedded tools\nbut denies Host-tier tools.\n\nThis is the default ANVIL-compliant approval policy:\n\n| Tier | Decision | Rationale |\n|------|----------|-----------|\n| Platform (1) | Approve | Always available, sandbox-confined |\n| Host (2) | Deny | Requires Arsenal ACT authorization |\n| Embedded (3) | Approve | Module-scoped, sandbox-confined |\n\n# ANVIL Spec SS8.1\n\nHost-tier tools execute outside the sandbox and have access to external\nresources (network, databases, APIs). They MUST be authorized via Arsenal\nACTs. Without an ACT check integration (provided by `forge-auth`), this\nhandler conservatively denies all Host-tier calls.\n\n# Examples\n\n```\nuse forge_tool::approval::{ApprovalHandler, TierBasedApproval};\nuse forge_core::tool::{ToolCall, ToolTier, ToolApproval};\n\n# tokio::runtime::Runtime::new().unwrap().block_on(async {\nlet call = ToolCall {\n    id: \"c1\".to_string(),\n    name: \"clock\".to_string(),\n    arguments: serde_json::json!({}),\n};\n\n// Platform tools are auto-approved\nlet approval = TierBasedApproval.check(&call, ToolTier::Platform).await;\nassert_eq!(approval, ToolApproval::Approve);\n\n// Host tools are denied (no ACT context available)\nlet approval = TierBasedApproval.check(&call, ToolTier::External).await;\nassert!(matches!(approval, ToolApproval::Deny { .. }));\n\n// Embedded tools are auto-approved\nlet approval = TierBasedApproval.check(&call, ToolTier::Embedded).await;\nassert_eq!(approval, ToolApproval::Approve);\n# });\n```"
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-tool/src/definition.rs",
      "sha256": "40b6baeaf79042a40cef1a02c8946cd6583bdd3cccd97ae83f93534bf003cebe",
      "artifactSha256": "382bf919c78ad5da34424b40249fef9259a98834f0cdcc76cdf69c328eea1031",
      "url": "/reference/source/forge-rs/crates/forge-tool/src/definition.rs.txt",
      "declarations": [
        {
          "name": "::ToolBuilder",
          "line": 69,
          "signature": "pub struct ToolBuilder {\n\n}",
          "documentation": "A fluent builder for constructing tool definitions with optional executors.\n\n`ToolBuilder` pairs a [`ToolDefinition`] with an optional [`ToolExecutor`],\nproducing both in a single build step. This ensures that tool metadata and\nimplementation stay in sync.\n\n# ANVIL Spec SS8.2\n\nEvery tool has a unique name, human-readable description, parameter schema,\nand tier classification. The builder enforces that at minimum a name is provided.\n\n# Examples\n\n```\nuse forge_tool::definition::ToolBuilder;\nuse forge_core::tool::ToolTier;\nuse forge_core::schema::JsonSchema;\n\n// Build a tool definition without an executor\nlet (def, executor) = ToolBuilder::new(\"clock\")\n    .description(\"Returns the current UTC time\")\n    .tier(ToolTier::Platform)\n    .build();\n\nassert_eq!(def.name(), \"clock\");\nassert!(executor.is_none());\n```"
        },
        {
          "name": "::ToolBuilder::new",
          "line": 103,
          "signature": "pub fn new(name: impl Into<String>) -> Self;",
          "documentation": "Creates a new `ToolBuilder` with the given tool name.\n\nThe builder starts with sensible defaults:\n- Empty description\n- [`ToolTier::External`] (the most restrictive default)\n- An empty object parameter schema\n- No executor\n\n# Arguments\n\n* `name` - The unique tool name. Must be non-empty and unique within a registry.\n\n# Returns\n\nA new `ToolBuilder` ready for configuration.\n\n# Examples\n\n```\nuse forge_tool::definition::ToolBuilder;\n\nlet builder = ToolBuilder::new(\"my_tool\");\nlet (def, _) = builder.build();\nassert_eq!(def.name(), \"my_tool\");\n```"
        },
        {
          "name": "::ToolBuilder::description",
          "line": 136,
          "signature": "pub fn description(mut self, description: impl Into<String>) -> Self;",
          "documentation": "Sets the human-readable description shown to the model.\n\nThe description helps LLMs understand when and how to use the tool.\nIt should be concise but informative.\n\n# Arguments\n\n* `description` - A human-readable description of the tool's purpose.\n\n# Returns\n\nThe builder for method chaining.\n\n# Examples\n\n```\nuse forge_tool::definition::ToolBuilder;\n\nlet (def, _) = ToolBuilder::new(\"search\")\n    .description(\"Search the web for information\")\n    .build();\nassert_eq!(def.description(), \"Search the web for information\");\n```"
        },
        {
          "name": "::ToolBuilder::tier",
          "line": 170,
          "signature": "pub fn tier(mut self, tier: ToolTier) -> Self;",
          "documentation": "Sets the tool tier classification.\n\n# ANVIL Spec SS8.1\n\n| Tier | Name | Location | Auth |\n|------|------|----------|------|\n| 1 | Platform | Inside sandbox | Always available |\n| 2 | Host | Outside sandbox | Arsenal ACT required |\n| 3 | Embedded | Inside WASM module | Module-scoped |\n\n# Arguments\n\n* `tier` - The tier classification for this tool.\n\n# Returns\n\nThe builder for method chaining.\n\n# Examples\n\n```\nuse forge_tool::definition::ToolBuilder;\nuse forge_core::tool::ToolTier;\n\nlet (def, _) = ToolBuilder::new(\"clock\")\n    .tier(ToolTier::Platform)\n    .build();\nassert_eq!(def.tier(), ToolTier::Platform);\n```"
        },
        {
          "name": "::ToolBuilder::parameters",
          "line": 203,
          "signature": "pub fn parameters(mut self, schema: JsonSchema) -> Self;",
          "documentation": "Sets the JSON Schema for the tool's parameters.\n\nThe schema defines what arguments the tool accepts. It is used for\nvalidation before execution and is passed to the LLM for structured\ntool calling.\n\n# Arguments\n\n* `schema` - A [`JsonSchema`] defining the tool's parameter shape.\n\n# Returns\n\nThe builder for method chaining.\n\n# Examples\n\n```\nuse forge_tool::definition::ToolBuilder;\nuse forge_core::schema::JsonSchema;\n\nlet (def, _) = ToolBuilder::new(\"greet\")\n    .parameters(\n        JsonSchema::object()\n            .property(\"name\", JsonSchema::string())\n            .required(\"name\"),\n    )\n    .build();\n```"
        },
        {
          "name": "::ToolBuilder::executor",
          "line": 244,
          "signature": "pub fn executor(mut self, executor: Arc<dyn ToolExecutor>) -> Self;",
          "documentation": "Attaches a [`ToolExecutor`] implementation to this tool.\n\nThe executor is responsible for the actual tool logic when the tool\nis invoked by an agent.\n\n# Arguments\n\n* `executor` - An implementation of [`ToolExecutor`].\n\n# Returns\n\nThe builder for method chaining.\n\n# Examples\n\n```\nuse forge_tool::definition::ToolBuilder;\nuse forge_tool::execution::FnToolExecutor;\nuse forge_core::tool::{ToolCall, ToolResult};\nuse forge_tool::error::ForgeToolError;\nuse std::sync::Arc;\n\nlet executor = FnToolExecutor::new(\"echo\", |call: &ToolCall| {\n    Ok(ToolResult {\n        tool_call_id: call.id.clone(),\n        name: call.name.clone(),\n        content: call.arguments.to_string(),\n        is_error: false,\n    })\n});\n\nlet (def, exec) = ToolBuilder::new(\"echo\")\n    .executor(Arc::new(executor))\n    .build();\nassert!(exec.is_some());\n```"
        },
        {
          "name": "::ToolBuilder::handler",
          "line": 282,
          "signature": "pub fn handler<F>(self, handler: F) -> Self\n    where\n        F: Fn(\n                &forge_core::tool::ToolCall,\n            ) -> Result<forge_core::tool::ToolResult, crate::error::ForgeToolError>\n            + Send\n            + Sync\n            + 'static,;",
          "documentation": "Attaches a synchronous closure as the tool executor.\n\nThis is a convenience method that wraps the closure in a [`FnToolExecutor`].\nFor async executors, use [`executor`](Self::executor) with a custom\n[`ToolExecutor`] implementation.\n\n# Arguments\n\n* `handler` - A closure that takes a `&ToolCall` and returns a `Result<ToolResult, ForgeToolError>`.\n\n# Returns\n\nThe builder for method chaining.\n\n# Examples\n\n```\nuse forge_tool::definition::ToolBuilder;\nuse forge_core::tool::{ToolCall, ToolResult};\nuse forge_tool::error::ForgeToolError;\n\nlet (def, exec) = ToolBuilder::new(\"echo\")\n    .handler(|call: &ToolCall| {\n        Ok(ToolResult {\n            tool_call_id: call.id.clone(),\n            name: call.name.clone(),\n            content: call.arguments.to_string(),\n            is_error: false,\n        })\n    })\n    .build();\nassert!(exec.is_some());\n```"
        },
        {
          "name": "::ToolBuilder::build",
          "line": 323,
          "signature": "pub fn build(self) -> (ToolDefinition, Option<Arc<dyn ToolExecutor>>);",
          "documentation": "Builds the [`ToolDefinition`] and optional [`ToolExecutor`].\n\nConsumes the builder and returns a tuple of the definition and the\nexecutor (if one was attached). The definition uses `forge-core`'s\n[`ToolDefinition::builder`] internally to ensure type consistency.\n\n# Returns\n\nA tuple of `(ToolDefinition, Option<Arc<dyn ToolExecutor>>)`.\n\n# Examples\n\n```\nuse forge_tool::definition::ToolBuilder;\nuse forge_core::tool::ToolTier;\n\nlet (def, executor) = ToolBuilder::new(\"clock\")\n    .description(\"Get current UTC time\")\n    .tier(ToolTier::Platform)\n    .build();\n\nassert_eq!(def.name(), \"clock\");\nassert!(executor.is_none());\n```"
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-tool/src/error.rs",
      "sha256": "d9e1be312229b153fe0d4b430038f70412fc469adaec34a7a227a245cd758e7b",
      "artifactSha256": "17eeda2aef5826e6a88739149a326c2054011ada1e07f8017a90d4317275f352",
      "url": "/reference/source/forge-rs/crates/forge-tool/src/error.rs.txt",
      "declarations": [
        {
          "name": "::ForgeToolError",
          "line": 31,
          "signature": "#[derive(Debug, Error)]\npub enum ForgeToolError {\n    /// A tool was looked up by name but does not exist in the registry.\n    ///\n    /// # Remediation\n    ///\n    /// Register the tool with [`crate::registry::ToolRegistry::register`] before use.\n    #[error(\"tool '{name}' not found in registry; register it with ToolRegistry::register() before invoking\")]\n    ToolNotFound {\n        /// The tool name that was looked up.\n        name: String,\n    },\n\n    /// A tool execution failed at runtime.\n    ///\n    /// This wraps errors produced by [`crate::execution::ToolExecutor`] implementations.\n    #[error(\"tool '{name}' execution failed: {reason}\")]\n    ExecutionFailed {\n        /// The tool that failed.\n        name: String,\n        /// What went wrong during execution.\n        reason: String,\n    },\n\n    /// A tool invocation was denied by the approval handler.\n    ///\n    /// See ANVIL Spec SS8.6 -- the approval step is mandatory in the tool execution lifecycle.\n    #[error(\"tool '{name}' invocation denied by approval handler: {reason}\")]\n    ApprovalDenied {\n        /// The tool that was denied.\n        name: String,\n        /// Why the invocation was denied.\n        reason: String,\n    },\n\n    /// Schema validation failed for tool arguments.\n    ///\n    /// The arguments provided to a tool call did not conform to the tool's\n    /// declared parameter schema.\n    #[error(\"schema validation failed for tool '{name}' at path '{path}': {reason}\")]\n    SchemaValidation {\n        /// The tool whose schema was violated.\n        name: String,\n        /// JSON pointer path to the failing field.\n        path: String,\n        /// Human-readable description of what was expected.\n        reason: String,\n    },\n\n    /// A tool was registered or invoked with an incorrect tier classification.\n    ///\n    /// See ANVIL Spec SS8.1--8.4 -- tool tier classification is immutable.\n    #[error(\n        \"tool '{name}' has invalid tier: expected {expected}, got {actual} (see ANVIL Spec SS8.1)\"\n    )]\n    InvalidTier {\n        /// The tool whose tier is mismatched.\n        name: String,\n        /// The expected tier classification.\n        expected: String,\n        /// The actual tier classification provided.\n        actual: String,\n    },\n\n    /// A registry operation failed (e.g., duplicate registration, capacity exceeded).\n    #[error(\"tool registry error: {reason}\")]\n    RegistryError {\n        /// What went wrong with the registry operation.\n        reason: String,\n    },\n}",
          "documentation": "Errors that can occur during tool definition, execution, approval, and registry operations.\n\nEvery variant includes actionable context: what failed, why, and what the\ndeveloper should check.\n\n# Examples\n\n```\nuse forge_tool::error::ForgeToolError;\n\nlet err = ForgeToolError::ToolNotFound {\n    name: \"get_weather\".to_string(),\n};\nassert!(err.to_string().contains(\"get_weather\"));\nassert!(err.to_string().contains(\"not found\"));\n```"
        },
        {
          "name": "::ForgeToolResult",
          "line": 103,
          "signature": "pub type ForgeToolResult<T> = Result<T, ForgeToolError>;",
          "documentation": "A specialized `Result` type for `forge-tool` operations."
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-tool/src/execution.rs",
      "sha256": "a9ddfd4dfdc41b74c859fd7f2c5371354d47b000ed4c66017475e94ba72e5214",
      "artifactSha256": "55f126f5df90c1051a313fce8c1b1dbdcbd6281fb301069cc1ae6fdabb273d19",
      "url": "/reference/source/forge-rs/crates/forge-tool/src/execution.rs.txt",
      "declarations": [
        {
          "name": "::ToolExecutor",
          "line": 88,
          "signature": "#[async_trait]\npub trait ToolExecutor: Send + Sync {\n    /// Executes the tool with the given call arguments.\n    ///\n    /// # Arguments\n    ///\n    /// * `call` - The tool call containing the call ID, tool name, and JSON arguments.\n    ///\n    /// # Returns\n    ///\n    /// A [`ToolResult`] with the execution output on success, or a\n    /// [`ForgeToolError::ExecutionFailed`] on failure.\n    ///\n    /// # Errors\n    ///\n    /// Returns [`ForgeToolError::ExecutionFailed`] if the tool logic fails for\n    /// any reason (network timeout, invalid state, computation error, etc.).\n    async fn execute(&self, call: &ToolCall) -> Result<ToolResult, ForgeToolError>;\n\n    /// Returns the name of the tool this executor handles.\n    ///\n    /// This must match the [`ToolDefinition::name`](forge_core::tool::ToolDefinition::name)\n    /// of the corresponding tool definition.\n    fn name(&self) -> &str;\n}",
          "documentation": "Trait for tool execution implementations.\n\nImplementors provide the actual logic that runs when an agent invokes a tool.\nEach executor is associated with a single tool by name.\n\n# ANVIL Spec SS8.5\n\nThe executor receives a validated, approved [`ToolCall`] and returns a\n[`ToolResult`]. The executor MUST NOT perform its own authorization checks --\nthat is the approval handler's responsibility.\n\n# Thread Safety\n\nExecutors must be `Send + Sync` because they may be shared across async\ntasks and stored in `Arc`.\n\n# Examples\n\n```\nuse async_trait::async_trait;\nuse forge_tool::execution::ToolExecutor;\nuse forge_core::tool::{ToolCall, ToolResult};\nuse forge_tool::error::ForgeToolError;\n\nstruct ClockExecutor;\n\n#[async_trait]\nimpl ToolExecutor for ClockExecutor {\n    async fn execute(&self, call: &ToolCall) -> Result<ToolResult, ForgeToolError> {\n        Ok(ToolResult {\n            tool_call_id: call.id.clone(),\n            name: call.name.clone(),\n            content: \"2026-02-18T12:00:00Z\".to_string(),\n            is_error: false,\n        })\n    }\n\n    fn name(&self) -> &str {\n        \"clock\"\n    }\n}\n```"
        },
        {
          "name": "::FnToolExecutor",
          "line": 142,
          "signature": "pub struct FnToolExecutor<F>\nwhere\n    F: Fn(&ToolCall) -> Result<ToolResult, ForgeToolError> + Send + Sync + 'static, {\n\n}",
          "documentation": "A tool executor that wraps a synchronous closure.\n\n`FnToolExecutor` allows defining simple tools as closures without\nimplementing the full [`ToolExecutor`] trait. The closure is called\nfrom within an async context but runs synchronously.\n\n# Thread Safety\n\nThe closure must be `Send + Sync + 'static` because the executor\nmay be shared across threads via `Arc`.\n\n# Examples\n\n```\nuse forge_tool::execution::{FnToolExecutor, ToolExecutor};\nuse forge_core::tool::{ToolCall, ToolResult};\nuse forge_tool::error::ForgeToolError;\n\nlet executor = FnToolExecutor::new(\"echo\", |call: &ToolCall| {\n    Ok(ToolResult {\n        tool_call_id: call.id.clone(),\n        name: call.name.clone(),\n        content: call.arguments.to_string(),\n        is_error: false,\n    })\n});\n\nassert_eq!(executor.name(), \"echo\");\n```"
        },
        {
          "name": "::FnToolExecutor<F>::new",
          "line": 185,
          "signature": "pub fn new(name: impl Into<String>, handler: F) -> Self;",
          "documentation": "Creates a new `FnToolExecutor` wrapping the given closure.\n\n# Arguments\n\n* `name` - The tool name this executor handles. Must match the corresponding\n  [`ToolDefinition`](forge_core::tool::ToolDefinition) name.\n* `handler` - A synchronous closure that processes tool calls.\n\n# Returns\n\nA new `FnToolExecutor` ready to be registered in a [`ToolRegistry`](crate::registry::ToolRegistry).\n\n# Examples\n\n```\nuse forge_tool::execution::FnToolExecutor;\nuse forge_core::tool::{ToolCall, ToolResult};\nuse forge_tool::error::ForgeToolError;\n\nlet executor = FnToolExecutor::new(\"add\", |call: &ToolCall| {\n    // Parse arguments, compute, return result\n    Ok(ToolResult {\n        tool_call_id: call.id.clone(),\n        name: call.name.clone(),\n        content: \"42\".to_string(),\n        is_error: false,\n    })\n});\n```"
        },
        {
          "name": "::execute_tool_call",
          "line": 302,
          "signature": "pub async fn execute_tool_call(\n    call: &ToolCall,\n    definition: &forge_core::tool::ToolDefinition,\n    executor: &dyn ToolExecutor,\n    approval_handler: &dyn crate::approval::ApprovalHandler,\n) -> Result<ToolResult, ForgeToolError>;",
          "documentation": "Executes a tool call through the full pipeline: schema validation, approval, execution.\n\nThis function implements the complete ANVIL tool execution lifecycle:\n\n1. **Schema validation** -- Validates `call.arguments` against the tool's parameter schema.\n2. **Approval gate** -- Checks with the approval handler whether the call is permitted.\n3. **Execution** -- Delegates to the tool executor.\n\n# ANVIL Spec SS8.5--8.6\n\nThe execution pipeline is mandatory. Skipping the approval step is forbidden\n(except in legacy mode, which is handled at a higher layer).\n\n# Arguments\n\n* `call` - The tool call to execute.\n* `definition` - The tool definition (for schema validation and tier info).\n* `executor` - The tool executor implementation.\n* `approval_handler` - The approval handler to check before execution.\n\n# Returns\n\nA [`ToolResult`] on success.\n\n# Errors\n\n- [`ForgeToolError::SchemaValidation`] if arguments fail schema validation.\n- [`ForgeToolError::ApprovalDenied`] if the approval handler denies the call.\n- [`ForgeToolError::ExecutionFailed`] if the executor fails.\n\n# Examples\n\n```\nuse forge_tool::execution::{execute_tool_call, FnToolExecutor};\nuse forge_tool::approval::AutoApprove;\nuse forge_core::tool::{ToolDefinition, ToolTier, ToolCall, ToolResult};\nuse forge_core::schema::JsonSchema;\nuse std::sync::Arc;\n\n# tokio::runtime::Runtime::new().unwrap().block_on(async {\nlet definition = ToolDefinition::builder(\"greet\")\n    .description(\"Greet someone\")\n    .tier(ToolTier::Platform)\n    .parameters(\n        JsonSchema::object()\n            .property(\"name\", JsonSchema::string())\n            .required(\"name\"),\n    )\n    .build();\n\nlet executor = Arc::new(FnToolExecutor::new(\"greet\", |call: &ToolCall| {\n    let name = call.arguments.get(\"name\")\n        .and_then(|v| v.as_str())\n        .unwrap_or(\"world\");\n    Ok(ToolResult {\n        tool_call_id: call.id.clone(),\n        name: call.name.clone(),\n        content: format!(\"Hello, {name}!\"),\n        is_error: false,\n    })\n}));\n\nlet call = ToolCall {\n    id: \"call-1\".to_string(),\n    name: \"greet\".to_string(),\n    arguments: serde_json::json!({\"name\": \"Alice\"}),\n};\n\nlet result = execute_tool_call(\n    &call,\n    &definition,\n    executor.as_ref(),\n    &AutoApprove,\n).await;\n\nassert!(result.is_ok());\n# });\n```"
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-tool/src/lib.rs",
      "sha256": "fbbc99f594d837c039a89e463d04725bbdc85f269e8487b6290c4d7cac9b6453",
      "artifactSha256": "64a662c3c324539366a527eefe3cdc6326ce9fd0ffa6a21a02629dd255678dc2",
      "url": "/reference/source/forge-rs/crates/forge-tool/src/lib.rs.txt",
      "declarations": [
        {
          "name": "approval",
          "line": 112,
          "signature": "pub mod approval;",
          "documentation": "# forge-tool\n\nTool definition, execution, approval, and registry for the Forge SDK.\n\nThis crate provides the complete tool subsystem for ANVIL-compliant agents.\nIt handles tool definition with fluent builders, a pluggable execution pipeline\nwith schema validation and approval gates, tier-based classification, and a\nruntime tool registry.\n\n# ANVIL Spec Reference\n\nThis crate implements the following ANVIL specification sections:\n- SS8.1 -- Tool Classification: three-tier system (Platform, Host, Embedded).\n- SS8.2 -- Tool Definition: name, description, schema, tier.\n- SS8.3 -- Tool Registration: immutable tool registration at initialization.\n- SS8.4 -- Tier Behavior: execution context and authorization requirements.\n- SS8.5 -- Tool Execution: validation -> approval -> execution pipeline.\n- SS8.6 -- Approval Gate: mandatory approval before execution.\n\n# Architecture\n\n```text\nToolBuilder -> ToolDefinition + ToolExecutor\n                      |               |\n                      v               v\n                 ToolRegistry (stores both)\n                      |\n                      v\n           execute_tool_call()\n             1. Schema validation\n             2. ApprovalHandler::check()\n             3. ToolExecutor::execute()\n                      |\n                      v\n                  ToolResult\n```\n\n# Modules\n\n- [`definition`] -- Fluent builder for constructing tool definitions.\n- [`execution`] -- Tool executor trait and the complete execution pipeline.\n- [`approval`] -- Approval handler trait and built-in implementations.\n- [`tiers`] -- Tier classification logic and execution context.\n- [`registry`] -- Runtime tool registry for managing registered tools.\n- [`error`] -- Typed error enum for all tool operations.\n\n# Examples\n\n## Registering and executing a tool\n\n```\nuse forge_tool::definition::ToolBuilder;\nuse forge_tool::execution::{execute_tool_call, FnToolExecutor};\nuse forge_tool::approval::AutoApprove;\nuse forge_tool::registry::ToolRegistry;\nuse forge_core::tool::{ToolTier, ToolCall, ToolResult};\nuse forge_core::schema::JsonSchema;\nuse std::sync::Arc;\n\n# tokio::runtime::Runtime::new().unwrap().block_on(async {\n// 1. Define a tool\nlet (definition, executor) = ToolBuilder::new(\"get_time\")\n    .description(\"Get the current UTC time\")\n    .tier(ToolTier::Platform)\n    .handler(|call: &ToolCall| {\n        Ok(ToolResult {\n            tool_call_id: call.id.clone(),\n            name: call.name.clone(),\n            content: \"2026-02-18T00:00:00Z\".to_string(),\n            is_error: false,\n        })\n    })\n    .build();\n\n// 2. Register in the registry\nlet mut registry = ToolRegistry::new();\nregistry.register(definition, executor.unwrap()).unwrap();\n\n// 3. Look up and execute\nlet call = ToolCall {\n    id: \"call-1\".to_string(),\n    name: \"get_time\".to_string(),\n    arguments: serde_json::json!({}),\n};\n\nif let Some((def, exec)) = registry.get(\"get_time\") {\n    let result = execute_tool_call(&call, def, exec.as_ref(), &AutoApprove).await;\n    assert!(result.is_ok());\n}\n# });\n```\n\n## Tier-based approval\n\n```\nuse forge_tool::tiers::{classify_tier, ExecutionContext};\nuse forge_core::tool::ToolTier;\n\n// Platform tools run in-sandbox, no auth needed\nlet cls = classify_tier(\"clock\", ToolTier::Platform);\nassert!(!cls.requires_authorization);\nassert_eq!(cls.execution_context, ExecutionContext::InSandbox);\n\n// Host tools run out-of-sandbox, auth required\nlet cls = classify_tier(\"web_browse\", ToolTier::External);\nassert!(cls.requires_authorization);\nassert_eq!(cls.execution_context, ExecutionContext::OutOfSandbox);\n```"
        },
        {
          "name": "definition",
          "line": 113,
          "signature": "pub mod definition;",
          "documentation": ""
        },
        {
          "name": "error",
          "line": 114,
          "signature": "pub mod error;",
          "documentation": ""
        },
        {
          "name": "execution",
          "line": 115,
          "signature": "pub mod execution;",
          "documentation": ""
        },
        {
          "name": "registry",
          "line": 116,
          "signature": "pub mod registry;",
          "documentation": ""
        },
        {
          "name": "tiers",
          "line": 117,
          "signature": "pub mod tiers;",
          "documentation": ""
        },
        {
          "name": "prelude",
          "line": 120,
          "signature": "pub mod prelude;",
          "documentation": "Re-exports of the most commonly used types."
        },
        {
          "name": "pub use crate::approval::{ApprovalHandler, AutoApprove, DenyAll, TierBasedApproval};",
          "line": 121,
          "signature": "pub use crate::approval::{ApprovalHandler, AutoApprove, DenyAll, TierBasedApproval};",
          "documentation": ""
        },
        {
          "name": "pub use crate::definition::ToolBuilder;",
          "line": 122,
          "signature": "pub use crate::definition::ToolBuilder;",
          "documentation": ""
        },
        {
          "name": "pub use crate::error::{ForgeToolError, ForgeToolResult};",
          "line": 123,
          "signature": "pub use crate::error::{ForgeToolError, ForgeToolResult};",
          "documentation": ""
        },
        {
          "name": "pub use crate::execution::{execute_tool_call, FnToolExecutor, ToolExecutor};",
          "line": 124,
          "signature": "pub use crate::execution::{execute_tool_call, FnToolExecutor, ToolExecutor};",
          "documentation": ""
        },
        {
          "name": "pub use crate::registry::ToolRegistry;",
          "line": 125,
          "signature": "pub use crate::registry::ToolRegistry;",
          "documentation": ""
        },
        {
          "name": "pub use crate::tiers::{\n        classify_tier, execution_context_for, requires_authorization, ExecutionContext,\n        TierClassification,\n    };",
          "line": 126,
          "signature": "pub use crate::tiers::{\n        classify_tier, execution_context_for, requires_authorization, ExecutionContext,\n        TierClassification,\n    };",
          "documentation": ""
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-tool/src/registry.rs",
      "sha256": "d05270eb3dd4169101f2ffd197f9e81b42e1cb7282d2506bd738e13a2bcf5c35",
      "artifactSha256": "08c455c90f4a1c5164dddace43e886d3c916f8092b7ae3d0cd6b709e7fc44138",
      "url": "/reference/source/forge-rs/crates/forge-tool/src/registry.rs.txt",
      "declarations": [
        {
          "name": "::ToolRegistry",
          "line": 100,
          "signature": "#[derive(Clone)]\npub struct ToolRegistry {\n\n}",
          "documentation": "A registry that maps tool names to their definitions and executors.\n\nThe registry provides:\n- **Registration** -- adding tools with definitions and executors.\n- **Lookup** -- retrieving a tool by name in O(1) time.\n- **Listing** -- enumerating all registered tools.\n\n# ANVIL Spec SS8.3\n\nTools are registered during agent initialization. Duplicate registrations\nare rejected to prevent accidental overwrites.\n\n# Thread Safety\n\nThe registry itself is not thread-safe. For concurrent access, wrap it in\n`Arc<RwLock<ToolRegistry>>` or use a concurrent map. The individual executors\nstored within are `Arc<dyn ToolExecutor>` and are safe to share.\n\n# Examples\n\n```\nuse forge_tool::registry::ToolRegistry;\nuse forge_tool::execution::FnToolExecutor;\nuse forge_core::tool::{ToolDefinition, ToolTier, ToolCall, ToolResult};\nuse forge_tool::error::ForgeToolError;\nuse std::sync::Arc;\n\nlet mut registry = ToolRegistry::new();\nassert!(registry.is_empty());\n\nlet def = ToolDefinition::builder(\"echo\")\n    .description(\"Echo back the input\")\n    .tier(ToolTier::Embedded)\n    .build();\n\nlet exec = Arc::new(FnToolExecutor::new(\"echo\", |call: &ToolCall| {\n    Ok(ToolResult {\n        tool_call_id: call.id.clone(),\n        name: call.name.clone(),\n        content: call.arguments.to_string(),\n        is_error: false,\n    })\n}));\n\nregistry.register(def, exec).unwrap();\nassert_eq!(registry.len(), 1);\nassert!(!registry.is_empty());\n```"
        },
        {
          "name": "::ToolRegistry::new",
          "line": 121,
          "signature": "pub fn new() -> Self;",
          "documentation": "Creates a new, empty `ToolRegistry`.\n\n# Returns\n\nAn empty registry with no tools registered.\n\n# Examples\n\n```\nuse forge_tool::registry::ToolRegistry;\n\nlet registry = ToolRegistry::new();\nassert!(registry.is_empty());\nassert_eq!(registry.len(), 0);\n```"
        },
        {
          "name": "::ToolRegistry::register",
          "line": 178,
          "signature": "pub fn register(\n        &mut self,\n        definition: ToolDefinition,\n        executor: Arc<dyn ToolExecutor>,\n    ) -> Result<(), ForgeToolError>;",
          "documentation": "Registers a tool definition and executor pair.\n\nThe tool is indexed by its name. Duplicate names are rejected with a\n[`ForgeToolError::RegistryError`] to prevent accidental overwrites.\n\n# ANVIL Spec SS8.3\n\nTools are registered during initialization and remain immutable.\n\n# Arguments\n\n* `definition` - The tool definition containing name, description, schema, and tier.\n* `executor` - The executor that handles tool calls for this tool.\n\n# Returns\n\n`Ok(())` on successful registration.\n\n# Errors\n\nReturns [`ForgeToolError::RegistryError`] if a tool with the same name is\nalready registered.\n\n# Examples\n\n```\nuse forge_tool::registry::ToolRegistry;\nuse forge_tool::execution::FnToolExecutor;\nuse forge_core::tool::{ToolDefinition, ToolTier, ToolCall, ToolResult};\nuse forge_tool::error::ForgeToolError;\nuse std::sync::Arc;\n\nlet mut registry = ToolRegistry::new();\n\nlet def = ToolDefinition::builder(\"clock\")\n    .tier(ToolTier::Platform)\n    .build();\n\nlet exec = Arc::new(FnToolExecutor::new(\"clock\", |call: &ToolCall| {\n    Ok(ToolResult {\n        tool_call_id: call.id.clone(),\n        name: call.name.clone(),\n        content: \"ok\".to_string(),\n        is_error: false,\n    })\n}));\n\nassert!(registry.register(def.clone(), exec.clone()).is_ok());\n// Duplicate registration fails\nassert!(registry.register(def, exec).is_err());\n```"
        },
        {
          "name": "::ToolRegistry::get",
          "line": 242,
          "signature": "pub fn get(&self, name: &str) -> Option<(&ToolDefinition, &Arc<dyn ToolExecutor>)>;",
          "documentation": "Looks up a tool by name.\n\nReturns a reference to the tool's definition and executor if found.\n\n# Arguments\n\n* `name` - The tool name to look up.\n\n# Returns\n\n`Some((&ToolDefinition, &Arc<dyn ToolExecutor>))` if the tool exists,\nor `None` if not found.\n\n# Examples\n\n```\nuse forge_tool::registry::ToolRegistry;\nuse forge_tool::execution::FnToolExecutor;\nuse forge_core::tool::{ToolDefinition, ToolTier, ToolCall, ToolResult};\nuse forge_tool::error::ForgeToolError;\nuse std::sync::Arc;\n\nlet mut registry = ToolRegistry::new();\n\n// Not found before registration\nassert!(registry.get(\"clock\").is_none());\n\nlet def = ToolDefinition::builder(\"clock\")\n    .tier(ToolTier::Platform)\n    .build();\nlet exec = Arc::new(FnToolExecutor::new(\"clock\", |call: &ToolCall| {\n    Ok(ToolResult {\n        tool_call_id: call.id.clone(),\n        name: call.name.clone(),\n        content: \"ok\".to_string(),\n        is_error: false,\n    })\n}));\nregistry.register(def, exec).unwrap();\n\n// Found after registration\nlet result = registry.get(\"clock\");\nassert!(result.is_some());\n```"
        },
        {
          "name": "::ToolRegistry::list",
          "line": 279,
          "signature": "pub fn list(&self) -> Vec<&ToolDefinition>;",
          "documentation": "Returns a list of references to all registered tool definitions.\n\nThe order is not guaranteed (based on `HashMap` iteration order).\n\n# Returns\n\nA `Vec` of references to all [`ToolDefinition`] values in the registry.\n\n# Examples\n\n```\nuse forge_tool::registry::ToolRegistry;\nuse forge_tool::execution::FnToolExecutor;\nuse forge_core::tool::{ToolDefinition, ToolTier, ToolCall, ToolResult};\nuse forge_tool::error::ForgeToolError;\nuse std::sync::Arc;\n\nlet mut registry = ToolRegistry::new();\nassert!(registry.list().is_empty());\n\nlet def = ToolDefinition::builder(\"t1\").tier(ToolTier::Platform).build();\nlet exec = Arc::new(FnToolExecutor::new(\"t1\", |call: &ToolCall| {\n    Ok(ToolResult {\n        tool_call_id: call.id.clone(),\n        name: call.name.clone(),\n        content: String::new(),\n        is_error: false,\n    })\n}));\nregistry.register(def, exec).unwrap();\n\nassert_eq!(registry.list().len(), 1);\n```"
        },
        {
          "name": "::ToolRegistry::definitions",
          "line": 318,
          "signature": "pub fn definitions(&self) -> Vec<ToolDefinition>;",
          "documentation": "Returns cloned copies of all registered tool definitions.\n\nThis is useful when the definitions need to be serialized (e.g., for\nsending to an LLM provider as available tools).\n\n# Returns\n\nA `Vec` of cloned [`ToolDefinition`] values.\n\n# Examples\n\n```\nuse forge_tool::registry::ToolRegistry;\nuse forge_tool::execution::FnToolExecutor;\nuse forge_core::tool::{ToolDefinition, ToolTier, ToolCall, ToolResult};\nuse forge_tool::error::ForgeToolError;\nuse std::sync::Arc;\n\nlet mut registry = ToolRegistry::new();\n\nlet def = ToolDefinition::builder(\"t1\").tier(ToolTier::Platform).build();\nlet exec = Arc::new(FnToolExecutor::new(\"t1\", |call: &ToolCall| {\n    Ok(ToolResult {\n        tool_call_id: call.id.clone(),\n        name: call.name.clone(),\n        content: String::new(),\n        is_error: false,\n    })\n}));\nregistry.register(def, exec).unwrap();\n\nlet defs = registry.definitions();\nassert_eq!(defs.len(), 1);\nassert_eq!(defs[0].name(), \"t1\");\n```"
        },
        {
          "name": "::ToolRegistry::len",
          "line": 336,
          "signature": "pub fn len(&self) -> usize;",
          "documentation": "Returns the number of registered tools.\n\n# Returns\n\nThe count of tools in the registry.\n\n# Examples\n\n```\nuse forge_tool::registry::ToolRegistry;\n\nlet registry = ToolRegistry::new();\nassert_eq!(registry.len(), 0);\n```"
        },
        {
          "name": "::ToolRegistry::is_empty",
          "line": 354,
          "signature": "pub fn is_empty(&self) -> bool;",
          "documentation": "Returns `true` if the registry contains no tools.\n\n# Returns\n\n`true` if empty, `false` otherwise.\n\n# Examples\n\n```\nuse forge_tool::registry::ToolRegistry;\n\nlet registry = ToolRegistry::new();\nassert!(registry.is_empty());\n```"
        },
        {
          "name": "::ToolRegistry::remove",
          "line": 401,
          "signature": "pub fn remove(&mut self, name: &str) -> Option<(ToolDefinition, Arc<dyn ToolExecutor>)>;",
          "documentation": "Removes a tool from the registry by name.\n\nReturns the removed definition and executor if the tool existed.\n\n# Arguments\n\n* `name` - The name of the tool to remove.\n\n# Returns\n\n`Some((ToolDefinition, Arc<dyn ToolExecutor>))` if the tool was found\nand removed, or `None` if no tool with that name existed.\n\n# Examples\n\n```\nuse forge_tool::registry::ToolRegistry;\nuse forge_tool::execution::FnToolExecutor;\nuse forge_core::tool::{ToolDefinition, ToolTier, ToolCall, ToolResult};\nuse forge_tool::error::ForgeToolError;\nuse std::sync::Arc;\n\nlet mut registry = ToolRegistry::new();\n\nlet def = ToolDefinition::builder(\"t1\").tier(ToolTier::Platform).build();\nlet exec = Arc::new(FnToolExecutor::new(\"t1\", |call: &ToolCall| {\n    Ok(ToolResult {\n        tool_call_id: call.id.clone(),\n        name: call.name.clone(),\n        content: String::new(),\n        is_error: false,\n    })\n}));\nregistry.register(def, exec).unwrap();\nassert_eq!(registry.len(), 1);\n\nlet removed = registry.remove(\"t1\");\nassert!(removed.is_some());\nassert!(registry.is_empty());\n\n// Removing again returns None\nassert!(registry.remove(\"t1\").is_none());\n```"
        },
        {
          "name": "::ToolRegistry::contains",
          "line": 441,
          "signature": "pub fn contains(&self, name: &str) -> bool;",
          "documentation": "Checks whether a tool with the given name is registered.\n\n# Arguments\n\n* `name` - The tool name to check.\n\n# Returns\n\n`true` if a tool with that name exists in the registry.\n\n# Examples\n\n```\nuse forge_tool::registry::ToolRegistry;\nuse forge_tool::execution::FnToolExecutor;\nuse forge_core::tool::{ToolDefinition, ToolTier, ToolCall, ToolResult};\nuse forge_tool::error::ForgeToolError;\nuse std::sync::Arc;\n\nlet mut registry = ToolRegistry::new();\nassert!(!registry.contains(\"clock\"));\n\nlet def = ToolDefinition::builder(\"clock\").tier(ToolTier::Platform).build();\nlet exec = Arc::new(FnToolExecutor::new(\"clock\", |call: &ToolCall| {\n    Ok(ToolResult {\n        tool_call_id: call.id.clone(),\n        name: call.name.clone(),\n        content: String::new(),\n        is_error: false,\n    })\n}));\nregistry.register(def, exec).unwrap();\n\nassert!(registry.contains(\"clock\"));\nassert!(!registry.contains(\"other\"));\n```"
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-tool/src/tiers.rs",
      "sha256": "370f7dec0bd5265ae0c27532ee29a14831588ea4655ab36562ddc9be9c078bdc",
      "artifactSha256": "8f200691278eddba1a64274a75035017c85a81221d509f20f0c3ad29061ee3fb",
      "url": "/reference/source/forge-rs/crates/forge-tool/src/tiers.rs.txt",
      "declarations": [
        {
          "name": "::ExecutionContext",
          "line": 51,
          "signature": "#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]\npub enum ExecutionContext {\n    /// The tool executes inside the WASM sandbox.\n    ///\n    /// Applies to Platform (Tier 1) and Embedded (Tier 3) tools. These tools\n    /// cannot access external resources without going through host functions.\n    InSandbox,\n\n    /// The tool executes outside the WASM sandbox via host functions.\n    ///\n    /// Applies to Host (Tier 2) tools. These tools have access to external\n    /// resources and MUST be authorized via Arsenal ACTs.\n    OutOfSandbox,\n}",
          "documentation": "The execution context for a tool based on its tier classification.\n\nDetermines whether the tool runs inside the WASM sandbox or outside it\nvia host function calls.\n\n# ANVIL Spec SS8.1\n\n- `InSandbox`: Platform (Tier 1) and Embedded (Tier 3) tools run inside\n  the sandbox. They cannot access external resources directly.\n- `OutOfSandbox`: Host (Tier 2) tools run outside the sandbox via host\n  functions. They can access network, filesystem, databases, etc."
        },
        {
          "name": "::TierClassification",
          "line": 92,
          "signature": "#[derive(Debug, Clone, PartialEq, Eq)]\npub struct TierClassification {\n/// The name of the tool that was classified.\n\npub tool_name: String,\n/// The tool's tier classification.\n\npub tier: ToolTier,\n/// Whether this tool requires Arsenal ACT authorization before execution.\n\n///\n\n/// Only `true` for Host (Tier 2) tools.\n\npub requires_authorization: bool,\n/// The execution context (sandbox or host) for this tool.\n\npub execution_context: ExecutionContext\n}",
          "documentation": "The result of classifying a tool by its tier.\n\nContains the tier, whether authorization is required, and the execution\ncontext (sandbox or host).\n\n# Examples\n\n```\nuse forge_tool::tiers::{classify_tier, ExecutionContext};\nuse forge_core::tool::ToolTier;\n\nlet cls = classify_tier(\"db_query\", ToolTier::External);\nassert_eq!(cls.tier, ToolTier::External);\nassert!(cls.requires_authorization);\nassert_eq!(cls.execution_context, ExecutionContext::OutOfSandbox);\nassert_eq!(cls.tool_name, \"db_query\");\n```"
        },
        {
          "name": "::classify_tier",
          "line": 156,
          "signature": "pub fn classify_tier(tool_name: &str, tier: ToolTier) -> TierClassification;",
          "documentation": "Classifies a tool by its tier, returning authorization requirements and execution context.\n\nThis is the central function for the ANVIL 3-tier tool classification system.\nGiven a tool name and its tier, it returns a [`TierClassification`] with all\nthe information needed to determine how the tool should be executed and\nwhat authorization is required.\n\n# ANVIL Spec SS8.1--8.4\n\nThe tier classification is immutable. There are exactly three tiers:\n- **Platform (1)**: sandbox-confined, always available, no authorization.\n- **Host (2)**: out-of-sandbox, requires Arsenal ACT authorization.\n- **Embedded (3)**: compiled into WASM module, sandbox-confined, no authorization.\n\nYou cannot create a Tier 4. You cannot merge tiers. You cannot bypass\nTier 2 ACT checks.\n\n# Arguments\n\n* `tool_name` - The name of the tool being classified.\n* `tier` - The tool's tier classification.\n\n# Returns\n\nA [`TierClassification`] with the tool's authorization requirements and\nexecution context.\n\n# Examples\n\n```\nuse forge_tool::tiers::{classify_tier, ExecutionContext};\nuse forge_core::tool::ToolTier;\n\n// Platform tools: no auth, in-sandbox\nlet cls = classify_tier(\"clock\", ToolTier::Platform);\nassert!(!cls.requires_authorization);\nassert_eq!(cls.execution_context, ExecutionContext::InSandbox);\n\n// Host tools: auth required, out-of-sandbox\nlet cls = classify_tier(\"web_browse\", ToolTier::External);\nassert!(cls.requires_authorization);\nassert_eq!(cls.execution_context, ExecutionContext::OutOfSandbox);\n\n// Embedded tools: no auth, in-sandbox\nlet cls = classify_tier(\"json_parse\", ToolTier::Embedded);\nassert!(!cls.requires_authorization);\nassert_eq!(cls.execution_context, ExecutionContext::InSandbox);\n```"
        },
        {
          "name": "::requires_authorization",
          "line": 202,
          "signature": "pub fn requires_authorization(tier: ToolTier) -> bool;",
          "documentation": "Returns `true` if the given tier requires Arsenal ACT authorization.\n\nThis is a convenience function equivalent to checking\n[`TierClassification::requires_authorization`] after calling [`classify_tier`].\n\n# Arguments\n\n* `tier` - The tool tier to check.\n\n# Returns\n\n`true` if the tier is Host (Tier 2), `false` otherwise.\n\n# Examples\n\n```\nuse forge_tool::tiers::requires_authorization;\nuse forge_core::tool::ToolTier;\n\nassert!(!requires_authorization(ToolTier::Platform));\nassert!(requires_authorization(ToolTier::External));\nassert!(!requires_authorization(ToolTier::Embedded));\n```"
        },
        {
          "name": "::execution_context_for",
          "line": 226,
          "signature": "pub fn execution_context_for(tier: ToolTier) -> ExecutionContext;",
          "documentation": "Returns the [`ExecutionContext`] for a given tier.\n\n# Arguments\n\n* `tier` - The tool tier to look up.\n\n# Returns\n\nThe execution context for the tier.\n\n# Examples\n\n```\nuse forge_tool::tiers::{execution_context_for, ExecutionContext};\nuse forge_core::tool::ToolTier;\n\nassert_eq!(execution_context_for(ToolTier::Platform), ExecutionContext::InSandbox);\nassert_eq!(execution_context_for(ToolTier::External), ExecutionContext::OutOfSandbox);\nassert_eq!(execution_context_for(ToolTier::Embedded), ExecutionContext::InSandbox);\n```"
        }
      ]
    }
  ]
}
