Documentation

Deployment Actions

The Deployments surface is AuditTrail's audited control plane for operational changes proposed against your live agent fleet. Every action is recorded as an immutable DeploymentAction row with a deterministic state machine, approval TTL, and — for the highest-tier irreversible actions — typed confirmation + second-approver requirements.

Visit /deployments after demo-login to see the queue in action.

The 3 tiers

TierAction typesExecution rule
Tier 1alert · tag_trace · create_incidentAutonomous-safe. In mode="autonomous", auto-executes on creation.
Tier 2throttle · switch_model · disable_flagSupervised only. Requires explicit approval before execution, even in autonomous mode.
Tier 3kill_run · rollback_deploy · scale_downExplicit-enable only. Requires typed confirmation (first 8 chars of target ref) + operator reason.

Modes

  • dry_run — proposal surfaces in the queue, never executes
  • supervised — execute after explicit approval within the TTL
  • autonomous — Tier 1 executes immediately on creation; Tier 2/3 still require supervised approval regardless of mode

State machine

          propose
             │
             ▼
        proposed ──── reject ──► rejected
             │
             ├─ approve ───► approved ──── reject ──► rejected
             │                   │
             │                   └─ mark-executed ──► executed
             │
             ├─ TTL exceeded ──► expired
             │
             └─ propose w/ mode=autonomous + Tier 1 ──► executed
  • proposed → approved → executed is the standard supervised flow
  • Tier 1 in autonomous mode: single-step proposed → executed
  • TTL enforcement: approval attempts after the TTL window flip the row to expired and 400 the request

The /deployments page

When you open /deployments, the page renders:

  1. A KPI strip summarizing Proposed · Pending approval · Executed today · Rejected today counts
  2. A filter tab bar (All · Proposed · Approved · Executed · Rejected · Expired)
  3. A table listing every deployment action visible to your user, sorted by proposed-at descending, with columns: Tier · Type · Target · Reason · Mode · Status · Proposed at · Actions
  4. Clicking a row opens a side drawer with the full payload, outcome JSON, approver note, rejection note, audit timestamps, and — when the proposal targeted a trace/span — a "Why this action" evidence panel (see below)
  5. Approve / Reject / Mark-executed buttons on each row (visible only for valid state transitions)

Attribution evidence ("Why this action")

Since v3.30.0, a proposal that targets a trace or span carries attribution evidence computed at propose time — the same no-LLM surrogate SHAP attribution that powers the Sankey view, attached directly to the action row so the approval drawer shows why, not just a reason string.

How it works:

  1. When an action is proposed (via the API, the assistant, or a WS command) with a target_ref that resolves to one of your traces or spans, AuditTrail picks the decision-relevant tool span — the explicitly-targeted span if it is a tool span, otherwise the most recent tool span carrying an amber/red constitutional evaluation (the offending span), otherwise the trace's last tool span.
  2. It resolves the user prompt for that span (walking up to the root ancestor when the tool span only carries tool arguments), extracts the surrogate feature vector, and runs surrogate.explain — real SHAP values when the startup-trained model exists.
  3. The result is stored on the action's evidence field: a deterministic English explanation, the top feature weights, the surrogate F1, the violated rule (if one triggered the concern), and the span/trace ids for a one-click jump into the trace's XAI tabs.

Honesty notes:

  • Provenance is explicit. source: "surrogate" appears only when the model is really trained (≥ 5 tool spans at startup); before that the evidence is labelled heuristic and the explanation says so.
  • No target, no evidence. Actions against deploy/flag refs (or with no target at all) have evidence: null, and the drawer states that no span-level attribution exists — nothing is fabricated.
  • Evidence never blocks a propose. It is computed best-effort; a failure logs a warning and the proposal proceeds without it.

Typed confirmation (Tier 3)

Tier 3 actions (kill_run, rollback_deploy, scale_down) require the operator to type the first 8 characters of the target reference before the Approve button activates. This is the same pattern used by the right-click NodeActionMenu in the DAG viewer — implemented as a single reusable <ConfirmTypedDialog> component.

Endpoints

All endpoints are user-scoped (JWT or sk-at-* API key).

MethodPathPurpose
GET/api/v1/deployments/actions?status=&limit=List actions, ordered by proposed_at desc
POST/api/v1/deployments/actionsPropose a new action
POST/api/v1/deployments/actions/{id}/approveApprove a proposed action
POST/api/v1/deployments/actions/{id}/rejectReject a proposed or approved action
POST/api/v1/deployments/actions/{id}/mark-executedExternal runner callback

See api-reference for full schemas.

Demo data

On demo-login, the seed function _seed_demo_deployment_actions populates 10 rows spanning every (tier × status) combo so the queue renders populated immediately. Each row has a realistic reason string describing the kind of operational concern that would trigger the action (cost spikes, latency degradation, canary drift, etc.). Proposed rows that can target a real seeded trace also carry attribution evidence, computed through the same builder real proposals use; the Tier-3 rollback proposal targets a deploy ref and honestly shows the no-evidence state.

Rate limits

State-transition routes (propose / approve / reject / mark-executed) are bounded at 30/minute per client. List reads are unrestricted.


Shipped in: prod-v2.6.4 — backend was in place since V1.3 (2026-Q1); the frontend queue page landed in this sprint.