---
title: Actions
description: "What the agent can do here: a safety-classified action surface, the predict-then-verify shape, and the act-then-record loop."
---

## What Actions Are

Most agents decide what to do by reading the room. A prompt mentions a deploy, and somewhere downstream the model talks itself into shipping. Actions close that gap. A belief state tells the agent what is true; intent tells it what it is after; actions answer the next question in the frame: *what can I do here?* They are the verbs available in this world, declared up front, so the agent chooses from a known set instead of improvising whatever the context window seemed to license.

An action is an **affordance**: a verb the agent may choose in this world. Commit. Deploy. Gather evidence. Open a position. Each one carries a description the agent reasons over when it picks among them, so the choice is grounded in what the action does rather than in what a sentence implied it could do.

That is the difference between a world model and a chat loop. A chat loop acts on intentions inferred from prose. A world model acts over a declared surface where every verb has a name, a safety class, and a predicted effect.

## Safety Classes

Every affordance carries a safety class. It is the first thing a developer declares about an action and the first thing the engine reasons over when it surfaces the set.

| Safety class | Meaning |
|--------------|---------|
| `info` | Read-only. Looks at the world, changes nothing. |
| `mutates` | Changes state. A commit, a write, a position. |
| `needs-approval` | Gated. Requires a human on the loop before it runs. |

The point of the class is that the agent decides over a set that is already sorted by consequence. A read-only lookup and a production deploy are not the same kind of choice, and the agent should never have to infer the difference from tone. An `info` action is free to take. A `mutates` action carries weight. A `needs-approval` action stops and waits for a person. Declaring the class is how a developer makes that distinction structural instead of hoping the model picks it up.

## Preconditions and Effects

An affordance can declare two more things, and together they give it the shape of a real action model:

- a **precondition**: when the action applies, the gate that says this verb is even a candidate right now.
- an **effect**: the predicted state change, what the world should look like after the action fires.

The effect earns its keep twice. Going in, it is the agent's expectation; coming out, it is the verification target. Predict what the action should do, fire it, then check that the world actually matched. That predict-then-verify shape is what lets the agent catch a deploy that "succeeded" while the thing it was supposed to change never changed. An action with a declared effect is an action you can hold accountable.

```ts
// Conceptual: an affordance, as the world declares it.
{
  id: 'deploy',
  description: 'Ship the current build to production',
  safetyClass: 'needs-approval',
  precondition: 'tests are green and the build artifact exists',
  effect: 'the production version matches the current commit',
}
```

## Actions Are Policy-Gated Before the Agent Sees Them

The action surface the agent reads is not the raw set. It is the set after [policy](/dev/core/policy) has run over it. An affordance that violates an active rule shows up flagged or blocked, with the rule that flagged it named, so the agent is choosing from a surface that already respects the constraints of the world.

The gating is structured, not a matter of taste:

- a `needs-approval` action is always flagged for a human.
- a `mutates` action is flagged when a hard constraint is active.
- an action whose name appears in a constraint is blocked outright, and the blocking rule rides along as the reason.

A policy that advises and a policy that constrains are not the same thing. Advice sits in the prompt hoping to be honored. Constraints reshape the action set before the choice is ever made, and the agent sees exactly which rule narrowed its options and why.

## The Act-Then-Record Loop

The agent acts; the engine records. When the agent fires an action, that action rides back as part of the next [observation](/dev/core/observations), stamped onto the loop as the thing that just happened. This is the act-then-effect seam: the move the agent made becomes evidence about how this world responds.

Over many turns, that is how the world model learns its own dynamics. Each recorded action sits next to the belief change that followed it, and the engine accumulates a picture of how each action tends to move this particular world. The forecasting layer reads that history.

```ts
// The action the agent took rides back in as the next observation,
// so the engine can attribute the belief change to the move that caused it.
await beliefs.observe({
  content: 'Deployed build 4f2a to production',
  surface: 'tool',
  kind: 'agent_action',
  actor: 'system',
  tags: ['build:4f2a'],
})
```

That recorded history is what the forecasting layer reads to project an action's value a few steps forward. It lives in [Moves](/dev/core/moves), and stays low-confidence until the act-to-effect history is real.

## Affordances Are Not Moves

Two surfaces in the world model both look like "things the agent could do," and they are not the same.

- **Affordances** are the *declared action surface*: the verbs this world supports, classified by safety, gated by policy. The developer encodes them as part of defining the world.
- **[Moves](/dev/core/moves)** are the engine's *VOI-ranked epistemic next steps*: where to look to reduce the most uncertainty, ranked by expected information gain off the belief state.

Affordances are about acting on the world. Moves are about sharpening the picture of it. The top move rides back on the turn result as `context.moves[0]`; the affordances come back on the world model as the action surface for the decision at hand. Most agents read both each turn: the move points at the open question, the affordances say what the agent is allowed to do about it.

<Callout type="info" title="What the engine does and does not do">
The action set is a modeling lens the developer encodes when defining the world. The engine surfaces affordances, gates them through policy, ranks them, and records their effects so the world model can learn its own dynamics. It does not execute arbitrary side effects on your behalf. There is no `actions.register()` call. You declare the action surface as part of the world definition, your agent fires the verbs in your own runtime, and you record what happened back through `beliefs.observe`. The declarative config surface for policy and actions is on the roadmap; today it is the lens you encode, not a contract the engine enforces.
</Callout>

<CardGroup cols={3}>
  <DocsCard title="World Model" description="The full frame: environment, belief, intent, policy, actions." href="/dev/core/world" />
  <DocsCard title="Policy" description="The rules that gate the action surface before the agent sees it." href="/dev/core/policy" />
  <DocsCard title="Observations" description="The act-then-effect seam: a fired action rides back as the next observation." href="/dev/core/observations" />
  <DocsCard title="Moves" description="VOI-ranked epistemic next steps, distinct from the declared action surface." href="/dev/core/moves" />
  <DocsCard title="Worldview" description="The bounded projection the agent reads, where the gated affordances surface." href="/dev/core/worldview" />
</CardGroup>
