Skip to main content
Most of what Airlock captures is access. An agent read a document, called a tool, hit a host. Decision events are different: they’re for the narrower case of an agent (yours, running anywhere — it doesn’t have to be inside an Airlock sandbox) making a call that has real consequences attached, and you want that call visible and, later, automatically flagged if it looks unreliable. Consider, for example, a system that uses an AI agent to resolve prediction-market contracts. A wrong resolution can move real money, so the agent reporting how it decided (what it cited, how confident it was) matters as much as what it decided.

Sending a decision event

Decision events go through the same ingestion endpoint as every other event kind, authenticated with a bearer token (an admin mints one for your agent identity via POST /api/v1/admin/users/:id/tokens).

Fields

dedupe_key (on the envelope, not the decision object) works the same as every other event kind: retrying the same POST with the same key is a no-op, so it’s safe to retry on a timeout without double-reporting a decision.
Keep target stable across agents, not just across retries. Pointing two independent resolvers at the same targets is the cheapest cross-check available - no shared prompt or failure mode. A stable target is what lets their answers be lined up against each other.

What happens to it right now

Today: it’s stored, queryable via GET /api/v1/events?kind=decision and GET /api/v1/sessions/:id, and shows up in the dashboard timeline like any other event. What it does not do yet: automatically flag anything. Access and chat events use the same endpoint with kind set accordingly — the CLI’s airlock publish is just another client of this contract. See audit log for what it ships.