CONCEPTUAL MODEL • AMI · DSL v2

Core concepts

Understand Memrail's runtime model: decision points, ATOMs, EMUs, actions, policies, project coherence, reachability, and traces.

View raw Markdown

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.

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.

Where control lives
Your applicationStructured contextTyped context at a decision point, including events, tags, and scalars
MemrailExplicit policyMatch context to an EMU
Connected actions
  • Tool call
  • Routing
  • Agent context
  • Skills

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 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. 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.

Memrail 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, then follow the production rollout.

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.