# `Pixir.Tools.Executor`
[🔗](https://github.com/Ranvier-Technologies/pixir/blob/main/lib/pixir/tools/executor.ex#L1)

Central tool execution (CONTEXT.md): Pixir — not the model — runs Tools. The Executor
resolves the tool, validates `args` against its schema, then dispatches to `execute/2`
(or `dry_run/2` when `context.dry_run`).

`run/2` is the Turn-loop entry point: it records the canonical `tool_call` Event
before running and the `tool_result` Event after (both via `Pixir.Session`, so they
get a `seq`, hit the Log, and publish). `execute_call/2` is the side-effect-free core
(no Events) used directly in unit tests.

# `call`

```elixir
@type call() :: %{call_id: String.t(), name: String.t(), args: map()}
```

# `execute_call`

```elixir
@spec execute_call(%{name: String.t(), args: map()}, Pixir.Tool.context()) ::
  Pixir.Tool.result()
```

Resolve, validate, and run (or dry-run) a tool call without emitting Events.

# `run`

```elixir
@spec run(call(), Pixir.Tool.context()) :: Pixir.Tool.result()
```

Run a tool call within a Session: record `tool_call`, protect the Session's own
evidence (`.pixir`), apply the permission policy (ADR 0006), execute (or refuse),
record `tool_result`. Returns the raw `{:ok, result} | {:error, structured}` from
the tool.

The permission policy is read from `context.permission` (`%{mode, asker}`); it
defaults to `:auto` (allow everything) so the common path has zero overhead.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
