# EMU Development Guide

**Adaptive Memory Intelligence (AMI) v2 - Comprehensive Developer Documentation**

## Overview

This guide provides complete documentation for building Executable Memory Units (EMUs) for the AMI v2 API. EMUs are conditional actions that fire deterministically based on system state, providing intelligent automation for agent systems.

**Key Principle:** Deterministic - same inputs ALWAYS produce same outputs.

## What You'll Learn

1. **[EMU Fundamentals](01-emu-fundamentals.md)** - Core concepts, structure, and lifecycle
2. **[DSL Reference](02-dsl-reference.md)** - Complete trigger DSL syntax and functions
3. **[Trigger Reachability](03-trigger-reachability.md)** - Understanding ATOM dependencies and when triggers can fire
4. **[EMU Cookbook](04-emu-cookbook.md)** - Common patterns and real-world examples
5. **[SDK Integration](05-sdk-integration.md)** - Using the Python SDK to register EMUs and invoke the engine
6. **[API Integration Guide](06-api-integration-guide.md)** - HTTP API setup, IaC workflow, and project structure

**Additional docs** (in main repo `docs/developers/skills/memrail/`):
- **06-decision-topology.md** - Decision points, topology mapping, and named invocation sites
- **07-action-connectivity.md** - Action type connectivity and routing
- **08-static-analysis.md** - Static analysis for EMU validation
- **09-tool-registry-executors.md** - Tool registry and executor integration
- **10-llm-integration-guide.md** - LLM integration patterns
- **11-emu-design-heuristics.md** - Design heuristics and best practices
- **12-emu-jsonl-workflow.md** - IaC workflow with JSONL files (emu-pull/plan/apply)

## Quick Start

### 1. Install the SDK

```bash
pip install memrail
```

### 2. Register Your First EMU

```python
from memrail import AsyncAMIClient
from memrail.atoms import state

async def register_welcome_emu():
    async with AsyncAMIClient(
        api_key="your-api-key",
        org="your-org",
        team="your-team",
        workspace="production",
        project="onboarding"
    ) as client:
        # Register EMU
        response = await client.register_emu(
            emu_key="welcome_premium_users",
            trigger="state.user.tier == 'premium' AND NOT event.agent.sent.welcome_email IN 'P7D'",
            action={
                "type": "tool_call",
                "intent": "SEND_WELCOME_EMAIL",
                "tool": {
                    "tool_id": "mailer",
                    "version": "1.0.0",
                    "args": {"template": "premium_welcome"}
                }
            },
            policy={
                "mode": "auto",
                "priority": 8,
                "cooldown": {"seconds": 604800, "gate": "activation"}
            },
            expected_utility=0.9,
            confidence=0.95
        )
        print(f"Registered: {response['emu_id']}")
```

### 3. Invoke the Decision Engine

```python
async def check_user_actions(user_id: str, user_tier: str):
    async with AsyncAMIClient(...) as client:
        # Invoke with current state
        response = await client.decide(
            context=[
                state("user.id", user_id),
                state("user.tier", user_tier)
            ]
        )

        # Process selected actions
        for item in response.selected:
            print(f"Execute: {item.action}")
```

## EMU Anatomy

An EMU consists of:

```python
{
    "emu_key": "unique-identifier",           # Unique key for this EMU
    "trigger": "DSL expression",              # When to fire (DSL)
    "action": {...},                          # What to do (tool_call, decision_prompt, route, context_directive)
    "policy": {                               # How to fire
        "mode": "auto|require_human|advisory",
        "priority": 1-10,
        "cooldown": {...},
        "idempotency": {...}
    },
    "expected_utility": 0.0-1.0,             # Expected value
    "confidence": 0.0-1.0,                    # Confidence in trigger/action
    "intent": "Human-readable description",   # Optional description
    "state": "active|canary|shadow|archived"  # Lifecycle state
}
```

## Core Concepts

### 1. ATOMs (Typed Facts)

ATOMs are typed facts that drive decisions:

- **State ATOMs**: Structured data from your system (`user.tier`, `ticket.priority`)
- **Tag ATOMs**: Categorizations and metadata (`intent: 'upgrade'`, `sentiment: 'negative'`)
- **Event ATOMs**: Timestamped occurrences (`user.login.success`, `agent.sent.email`)

### 2. Triggers (DSL)

Triggers are boolean expressions written in the AMI DSL:

```javascript
// Simple state check
state.user.tier == 'premium'

// Recent event check
event.agent.sent.email IN 'PT24H'

// Complex logic
state.ticket.priority == 'high' AND
state.customer.tier == 'vip' AND
NOT event.agent.escalated.ticket IN 'PT2H'
```

### 3. Actions

Four action types:

- **`tool_call`**: Execute an external tool/service
- **`decision_prompt`**: Present options to a human
- **`route`**: Route to a destination/queue
- **`context_directive`**: Provide context/guidance

### 4. Trigger Reachability

**Critical concept**: A trigger can only fire if ATOMs are available.

```python
# This trigger requires:
trigger = "state.user.tier == 'premium' AND event.user.login.success IN 'PT1H'"

# ATOM builders needed:
# 1. state("user.tier", ...) - Must be provided by your ATOM builder
# 2. event("user.login.success", ...) - Must be ingested when user logs in

# If either ATOM is missing, trigger = FALSE (unreachable)
```

## Navigation

- **New to EMUs?** Start with [EMU Fundamentals](01-emu-fundamentals.md)
- **Writing triggers?** See [DSL Reference](02-dsl-reference.md)
- **Debugging triggers?** Read [Trigger Reachability](03-trigger-reachability.md)
- **Need examples?** Browse [EMU Cookbook](04-emu-cookbook.md)
- **Integrating with SDK?** Check [SDK Integration](05-sdk-integration.md)

## Training AI to Build EMUs

This documentation is designed to train LLMs to generate valid EMUs. Key considerations:

1. **Validate trigger reachability**: Ensure ATOM builders exist for all state/tag keys
2. **Consider event ingestion**: Verify events are captured for recent_event() checks
3. **Account for ML dependencies**: Some triggers require classifiers (intent, sentiment, tool_usage)
4. **Follow naming conventions**: Use lowercase, dot-notation, semantic naming
5. **Set appropriate policies**: Consider cooldowns, idempotency, and priority

## Example: Complete Workflow

Here's a complete workflow from ATOM builder to EMU execution:

```python
# 1. ATOM Builder (Your Application)
# When ticket is created, translate to ATOMs
async def on_ticket_created(ticket):
    await client.decide(
        context=[
            state("ticket.id", ticket.id),
            state("ticket.priority", ticket.priority),
            state("customer.tier", ticket.customer.tier),
            tag("department", ticket.department),
            event("ticket.created.zendesk", ts=datetime.now(timezone.utc))
        ]
    )

# 2. EMU Definition (Registered in AMI)
{
    "emu_key": "vip_escalation",
    "trigger": "state.customer.tier == 'vip' AND state(ticket.priority, >=, 'high')",
    "action": {
        "type": "tool_call",
        "intent": "ESCALATE_TO_VIP_TEAM",
        "tool": {
            "tool_id": "zendesk_escalator",
            "version": "2.1.0",
            "args": {"queue": "vip-support", "priority": "critical"}
        }
    }
}

# 3. Action Execution (Your Application)
# AMI returns selected actions, you execute them
for item in response.selected:
    if item.action.type == "tool_call":
        await execute_tool(item.action.tool)
```

## Best Practices

1. **Start simple**: Begin with single state checks, add complexity gradually
2. **Test thoroughly**: Use `dry_run=True` to test triggers without side effects
3. **Monitor trigger reach**: Track how often triggers evaluate to TRUE
4. **Version carefully**: EMU versioning creates new versions, test before activating
5. **Document dependencies**: Clearly document which ATOM builders are required

## Common Pitfalls

1. **Missing ATOM builders**: Trigger references state that's never provided
2. **Event not ingested**: Using recent_event() without ingesting events
3. **Incorrect dot notation**: Using `user_tier` instead of `user.tier`
4. **Case sensitivity**: DSL operators must be UPPERCASE (`AND`, not `and`)
5. **Invalid durations**: ISO 8601 format required (`'PT1H'`, not `'1h'`)

## Getting Help

- **API Documentation**: [https://api.example.com/docs](https://api.example.com/docs)
- **GitHub Issues**: [https://github.com/your-org/ami-api/issues](https://github.com/your-org/ami-api/issues)
- **DSL Playground**: Test triggers at [https://ami-playground.example.com](https://ami-playground.example.com)

---

**Next**: [EMU Fundamentals →](01-emu-fundamentals.md)
