# Actions and Sessions

An action is one requested unit of work. A session is an optional durable
relationship that groups related work between two principals.

The distinction matters because clients disconnect, workers restart, and
external providers may take longer than one request. AIP does not use the
transport connection as the source of truth for work state.

## Action Identity

Each action has a stable `act_...` id and names one capability. The action also
contains structured input and may include:

- `mode`: `sync`, `async`, or `streaming`;
- an idempotency key and timeout;
- conversation or memory context;
- identity, compliance, and observability context;
- a callback target;
- a delegation chain;
- an approval decision;
- transaction context.

An action id identifies one operation. A retry with the same business intent
should use the capability's idempotency contract rather than reuse an unrelated
action id.

## Lifecycle

The durable action read model uses these states:

```text
accepted -> queued -> running -> streaming -> completed
                      |           |
                      |           +---------> failed
                      +-----> pending_approval -> running
                      +-----> cancelling -> cancelled
                      +-----> dead_lettered
```

Not every action visits every state. `completed`, `failed`, `cancelled`,
`expired`, and `dead_lettered` are terminal operational states.

The read model also has `unknown` for an action id that is not visible or not
known to the current runtime. It is a query sentinel, not a persisted execution
stage.

`pending_approval` is durable, not an error. The same action resumes after an
authorized decision.

## Results and Chunks

A final `ActionResult` reports `completed`, `failed`, `cancelled`,
`pending_approval`, or `requires_human`. Failed results include a structured
protocol error.

Streaming actions emit monotonically sequenced chunks. Chunk kinds distinguish
data, progress, tool events, previews, pending approval, errors, and the terminal
marker. Consumers should order by `sequence`, tolerate duplicate delivery after
reconnect, and use the final action result as terminal authority.

## Cancellation

Cancellation is a request, not proof that the external side effect stopped. A
runtime transitions through cancellation state and asks the handler or provider
to cancel. The final action status records whether cancellation was confirmed,
the operation completed first, or the outcome needs reconciliation.

Do not retry a mutating action merely because cancellation timed out.

## Operational Queries

Authorized clients can:

- list actions using lifecycle, capability, session, principal, approval,
  transaction, and tenant filters;
- read one status with optional result, chunks, and receipts;
- read the terminal result with a bounded wait;
- read or follow action-scoped events;
- issue cancellation.

Query limits are bounded to 1-1000 records. Bounded waits cannot exceed 30
seconds in the native validation contract. Long-running clients should use
events or repeat status reads with backoff.

## Sessions

A session records an initiator, responder, creation time, and lifecycle state.
It is useful for:

- a durable agent conversation;
- a sequence of related workflow actions;
- reconnect and event replay;
- a channel handoff that outlives one request.

Session states are `new`, `active`, `queued`, `processing`, `streaming`,
`waiting_for_human`, `completed`, `cancelled`, `failed`, and `settled`.
Transitions are validated; a terminal session cannot silently become active
again.

## Resume Tokens

A successful handshake may return a single-use opaque resume token. On resume,
the runtime verifies the token, returns the current session view, replays events
after the supplied cursor, and rotates the token. The previous token becomes
invalid.

Treat resume tokens as credentials. Do not log them or place them in URLs.

## Choosing Sync, Async, or Streaming

| Mode | Use when | Caller behavior |
|---|---|---|
| `sync` | Work is short and predictably bounded | Wait for the final result |
| `async` | Work may queue, wait for approval, or survive disconnects | Store `action_id` and query or receive callbacks |
| `streaming` | Incremental output is useful | Consume chunks and still verify the final result |

The capability contract is authoritative. A caller must not request a mode the
capability does not advertise.
