---
title: Core concepts
description: Understand Memrail's runtime model: decision points, ATOMs, EMUs, actions, policies, project coherence, reachability, and traces.
eyebrow: CONCEPTUAL MODEL
keywords: Memrail concepts, EMU ATOM, deterministic policy engine, SOMA AMI
last_updated: 2026-09-30
---

# Core concepts

Memrail's AMI (Adaptive Memory Intelligence) engine evaluates typed context (ATOMs) against versioned condition/action policies (EMUs). A decision point is where your application requests that evaluation; the application then authorizes and handles the selected action. These guides use the v2 trigger DSL; HTTP routes retain the `/v1` prefix. Neither identifies an SDK package version.

For the architectural motivation, read [Why declarative agent control matters](/declarative-agent-control/).

## From context to connected action

Your application supplies structured context—state scalars, bounded tags, and timestamped events—at a named decision point. Memrail evaluates that context against explicit EMU policy and returns a prescribed action for the application to handle.

<!-- control-map -->

Tool calls, routes, and agent context map directly to Memrail action types. Skills are connected by your application through a reviewed tool, route, or context directive; `skill` is not a separate AMI action type.

## Steering, control, and authority

**Steering** shapes what an agent considers or proposes. A `context_directive` can add policy-relevant guidance before the next model call.

**Control** constrains what the surrounding system permits. A selected route, approval prompt, or tool call is handled outside the model by application code.

**Authority** is the right to cause a consequential state change. A well-enforced Memrail integration gives explicit policy and application authorization checks that authority. Models can provide bounded evidence, but they must not get an unobserved fallback path to execute. The engine returns prescriptions; it does not enforce your application's tool dispatcher for you.

This framing is practical: you can use Memrail only for prompt steering, only as a pre-tool control gate, or at several decision points across a workflow.

## Decision points

A decision point is a named invocation site where behavior may change based on context. Examples:

- `agent.before_tool_call`
- `support.response_protocol`
- `billing.refund`
- `onboarding.next_step`
- `security.account_access`

Pass the name with `decision_point` in Python or `decisionPoint` in TypeScript. Stable names make traces, policy ownership, and topology audits legible even when code moves.

Set `"decision_point": "support.response"` on the EMU and pass that same name to the SDK. Named invocations select only EMUs bound to that exact point. Choose the name in application code, never from model output or an unchecked request field.

One decision point should have a documented atom contract and a bounded family of actions. Avoid a universal `agent.decide_everything` hook whose context and semantics change on every call.

## Integration invariants

This is the shared execution and deployment contract for every guide and example.

### Bindings and lifecycle

Keep the EMU's `decision_point` and the caller's name identical. In JSONL updates, omission preserves an existing binding; explicit `null` clears it. Review binding changes as routing changes.

`--target-state` sets the initial state of new EMUs. Transition existing EMUs with `change-state`, then reconcile the JSONL and lock snapshot with `emu-pull`. Conflicting lifecycle edits in JSONL are rejected. Shadow candidates have separate arbitration, appear in traces, and never enter `selected`. Canary is a lifecycle state, not a traffic percentage: the application must supply affirmative cohort membership before SDK execution.

### Evaluation and execution

Dry run can return action payloads, but they must not reach handlers or live prompts. The combined SDK execution helpers skip handlers and ACK automatically; custom dispatchers need the same guard. Dry run skips new cooldown and action-idempotency locks, not existing suppressions, schema observation, traces, analytics, or billing.

Selection alone does not authorize a side effect. Preserve the full selection's policy and lifecycle metadata through dispatch. The SDK executor enforces supported modes and lifecycle states; your handlers still enforce business permissions, tool arguments, and durable duplicate protection. `require_human` needs authenticated consent for the specific operation, not a model assertion. [Policy modes](/emus/#mode) specifies selection and execution behavior by action type.

### Outcomes and acknowledgment

Emit success events after material outcomes, not after selection; use distinct failure topics and include entity identifiers for later `WHERE` filters. Event ingestion is not automatically idempotent: reconcile ambiguous delivery before retrying. Events and activation ACK are separate records.

ACK only after the intended outcome. Live activation receipts are independent of tracing and expire after seven days; dry runs create none. Retry ACK delivery without repeating a completed action, and retain a durable application execution record.

### Two layers of idempotency

A request idempotency key identifies one immutable evaluation within the full tenant/project scope. During its 120-second cache lifetime, identical retries replay the selection with a new invocation ID; changed context, point, options, or project returns `409 IDEMPOTENCY_KEY_REUSED`. Keys must fit within 256 UTF-8 bytes.

Action idempotency is a separate policy control. For side-effecting tools, use literal atom keys in `policy.idempotency.scope` and supply them on every call. Neither layer guarantees exactly-once business execution; retain executor/provider duplicate protection, including across policy version changes and rollbacks.

## ATOMs: typed decision context

ATOMs are the facts evaluated by policy.

| Type | Meaning | Example | Source |
|---|---|---|---|
| State | a current structured fact | `state.customer.tier` | database, request, service |
| Tag | a bounded classification | `tag.intent` | classifier, metadata, deterministic mapping |
| Event | a timestamped occurrence | `event.agent.sent.email` | material outcome or observation |

```python
from memrail.atoms import state, tag

context = [
    state("customer.id", "cust_123"),
    state("customer.tier", "enterprise"),
    state("ticket.priority", "critical"),
    tag("intent", "escalation"),
]
```

State values are scalars. Flatten nested objects with `atoms_from_dict(data, prefix="customer")` or `atomsFromDict(data, "customer")`.

Use an LLM to produce tags only when its output is constrained to a fixed taxonomy. Include an explicit `unknown` value when classification can fail. Never insert free-form model prose into a trigger.

## EMUs: executable memory units

An EMU is a versioned conditional action. Its trigger evaluates deterministically; its action describes what the application should do; its policy controls arbitration and execution behavior.

```json
{
  "emu_key": "support.critical_enterprise",
  "decision_point": "support.response_protocol",
  "trigger": "state.customer.tier == 'enterprise' AND state.ticket.priority == 'critical'",
  "action": {
    "type": "context_directive",
    "directive": "Follow the critical enterprise escalation protocol."
  },
  "policy": {
    "mode": "auto",
    "priority": 9
  },
  "expected_utility": 0.9,
  "confidence": 0.95,
  "state": "shadow"
}
```

Invoke this policy at `decision_point="support.response_protocol"`. Determinism applies to the complete evaluation state: context, policies, event history, evaluation time, cooldowns, locks, and options. Repeated requests can differ when those inputs change. EMUs are not selected by an LLM.

## Action types

| Action | What it asks the application to do | Required connection |
|---|---|---|
| `context_directive` | add guidance to a prompt or UI | prompt/context builder |
| `decision_prompt` | ask a human to choose from options | review UI, queue, or chat handler |
| `route` | send work to a destination | route registry and destination handler |
| `tool_call` | execute a versioned tool with arguments | registered tool schema and executor |

Connect actions under the [integration invariants](#integration-invariants). Every `tool_call` tool object also requires a version such as `"version": "1.0.0"`.

## Policy and arbitration

Policy metadata controls what happens when EMUs match:

- `mode="require_human"` suppresses all action types without API `options.human_consent`; it does not automatically create a review task. Advisory actions can still be selected;
- the default score is `0.7 × expected_utility + 0.3 × confidence`; `priority` (0–9) breaks score ties, so a priority-9 denial is not guaranteed to win;
- `cooldown` suppresses the EMU key across its workspace/project, not separately for each customer;
- action `idempotency` reduces duplicate activations; executor-level duplicate protection remains necessary;
- `exclusion_groups` prevent conflicting policies from winning together;
- `expected_utility` and `confidence` provide explicit arbitration signals.

Treat policies with side effects more strictly than context directives. Give tool calls cooldown, idempotency, timeouts, error handling, and a material outcome event.

## Trigger reachability

A trigger can match only when its dependencies are available.

```dsl
state.customer.tier == 'enterprise' AND tag.intent == 'refund'
```

This positive conjunction requires both `state("customer.tier", ...)` and `tag("intent", ...)` at the decision point. A positive predicate on an absent atom evaluates false, including `!=`; outer `NOT` can make it true, and `OR` can match another branch. Guard required inputs with `EXISTS` before negation.

Reachability includes values, not just keys. A builder that omits `days_since_last_login` when the user has never logged in makes `state.user.days_since_last_login > 30` false for the most inactive users. Represent that business state explicitly with a separate boolean or a documented sentinel.

Negative event clauses require special attention. If `event.agent.sent.email` is never emitted, `NOT event.agent.sent.email IN 'P7D'` is always true. The absence of instrumentation looks like permission.

## Action connectivity

Trigger reachability asks, “Can this policy match?” Action connectivity asks, “Can the selected outcome actually happen?” A complete integration has both.

For each EMU, verify:

1. at least one decision point supplies its atom dependencies;
2. the action type has a handler;
3. a `tool_call` has a matching registered tool and runtime executor;
4. route and prompt destinations exist;
5. success and failure are acknowledged or recorded as designed.

## Project coherence

Use the project as an explicit integration boundary for EMUs, decision points, tools, and events. Verify every tool schema, version, and executor in that boundary. This is an application contract, not a registry security guarantee: the validator can fall back to workspace/organization schemas, and runtime selection does not check that an executor exists.

Cross-project event queries are possible within a workspace, but they create a declared dependency and should be documented in the topology. Do not use them to bypass unclear ownership.

## Events and traces

Events are ingested separately from `decide` calls and retained for 90 days by default; check the organization's configured retention. Name them as `subject.verb.object`, include timestamps, and attach the entity attributes required for scoped `WHERE` clauses.

A decision trace records context, matches, suppressions, and selected results. Use it alongside the [outcome and acknowledgment contract](#outcomes-and-acknowledgment), then follow the [production rollout](/production/).

## SOMA and AMI terminology

SOMA AMI is the implementation name used in the API and SDK. AMI means Adaptive Memory Intelligence. The atom schema registry (ASR) records observed atom keys, types, and values for validation and reachability analysis; observation is not a guarantee that every invocation supplies an input. For product conversations, “deterministic agent steering and control” describes the outcome more directly.
