# `Cairnloop.Workers.ToolExecutionWorker`
[🔗](https://github.com/szTheory/cairnloop/blob/main/lib/cairnloop/workers/tool_execution_worker.ex#L1)

The ONLY place `run/3` is ever called in Cairnloop.

Consumes a `:execution_pending` `ToolApproval` lane, re-validates the proposal
against current policy/scope, calls the tool's `run/3` on success, and
co-commits the outcome (`:executed` + `:succeeded` result state + append-only event).

Fail-closed on re-validation: policy/scope change since the resume worker ran causes
`:invalidated`/`:execution_failed` with a humanized reason — nothing is written (T-16-02).

## Idempotency layers (D16-05, T-16-01)

1. **Oban job uniqueness** — `unique: [period: :infinity, keys: [:approval_id]]` prevents
   double-enqueue (no two workers race for the same approval).
2. **Pre-execution terminal guard (LAYER-1)** — any non-`:execution_pending` status is a
   true no-op (replayed/duplicate job, wrong-lane approval, already executed).
3. **LAYER-2 terminal guard** — if `ToolProposal.result_state == :succeeded`, the approval
   has already been executed; another no-op (guards against TOCTOU between LAYER-1 check
   and commit, e.g. very fast replay).
4. **Run-level idempotency key** — passed into `run/3` context as `:run_idempotency_key`;
   the tool uses an indexed existence check to dedup its own host write (Stripe-style).

## Retry semantics (D16-07)

- Transient `{:error, reason}` from `run/3` with `attempt < max_attempts` → return
  `{:error, reason}` so Oban's built-in backoff retries.
- Permanent failure (re-validation fail, or `attempt >= max_attempts`) → record terminal
  `:execution_failed` and return `{:cancel, reason}` (Oban discards; never retries).

## Telemetry (D16-10)

`[:cairnloop, :governance, :action_executed]` and `[:cairnloop, :governance, :action_failed]`
are emitted AFTER a successful `with` pipeline via `Governance.Telemetry` — never inside
the clause list and never instead of a `ToolActionEvent` (D-29).

---

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