# Agent Decision Model

> How a proposed agent action becomes (or does not become) an executed action.

_Verified against `app/Services/Agents/*` (AgentDecisionService, ActionPolicyService, ApprovalService, ExecutionRequestService, ExpectedStateValidator) on 2026-07-23._

---

> This is the **runtime decision engine**. For architectural/product decisions (ADRs), see [`../06-history/decisions-log.md`](../06-history/decisions-log.md).

## `AgentDecisionService::decide()` — deterministic sequence

1. **Idempotency (Option B):** one decision per `agent_run_id`. A replay returns the same prior outcome — never re-branches or re-executes.
2. **Freeze analysis** onto the run.
3. **Runtime pause/disable gate (TD-003):** global `*` override or a paused/inactive agent blocks before acting.
4. **Policy resolution (TD-004):** active runtime **override** → **designed** policy (versioned, environment-scoped, full history) → **default `blocked`**. Values: `always_allow`, `needs_approval`, `blocked`.
5. **Branch:**
   - `always_allow` → claim an `ExecutionRequest` slot (idempotency key `agent-run-{id}:{slug}`) → **expected-state validation (TD-005)** → execute via `AgentActionExecutor` (canonical action service).
   - `needs_approval` → `ApprovalService::createFromRun()` creates a PENDING `AgentApprovalRequest`; human decides via `POST /api/v1/ai/approvals/{id}/decide|approve|reject` (one-shot).
   - `blocked` → record blocked run; no execution, no approval.
6. **Audit:** every step recorded by `AgentAuditLogger`.

## Persisted artifacts
`AgentRun`, `AgentApprovalRequest`, `ExecutionRequest`, `Handoff`, `AgentActionPolicy`, `PolicyRuntimeOverride`, plus `AiActivityLog`. Rollback surfaces exist in the admin console.

## Execution ownership (locked)
Approved actions are **executed by Numu** via `AgentActionExecutor`. Some source comments mention Make re-validating before executing; per the locked decision, **Numu is the authoritative executor** — see [`../01-architecture/ai-architecture.md`](../01-architecture/ai-architecture.md). The precise division of re-validation labor with Make is **Unknown - requires confirmation** (no Make service class/config found in-repo).

## Risk & status
Risk levels default HIGH for `reject`. Overall runtime is **implemented; deployment status requires confirmation.**
