MAXIM
Embodiment
Composable hardware & world abstraction through Sensor-Entity-Modulator triples
The SEM Protocol
Core Insight
Hardware varies wildly — cameras, joints, wheels, grippers, IMUs, swords, NPCs. Rather than building monolithic abstractions per robot type, every interactive thing is described as a composable triple: an Entity (the thing), its Sensors (how you read it), and its Modulators (how you change it).
Entity
The physical or virtual thing. Entities compose into trees: arm → elbow → wrist → gripper. Each entity is self-describing.
Examples: joint, camera, wheel, sword, NPC, door
Sensor
Reads state from an entity. One sensor = one readable quantity. Returns structured SensorReading with value, unit, and timestamp.
Examples: angle, temperature, durability, trust, frame
Modulator
Changes state of an entity. Exposes named affordances — each with typed parameters, description, and timeout.
Examples: rotate_angle, slash, speak, restart, sharpen
Auto-Generated Tools
When an entity tree loads from YAML, tools are automatically created and registered. No hand-written tool classes per hardware component.
| Tool Name | Type | Description |
|---|---|---|
| sense_shoulder | EntitySense | Read all sensors on shoulder |
| read_shoulder_angle | SensorRead | Read angle sensor |
| shoulder_rotate_angle | Affordance | Rotate shoulder joint |
| rusty_sword_slash | Affordance | Slash at a target |
| grim_ferryman_speak | Affordance | Say something to the ferryman |
Name collisions are handled by progressive prefixing: shoulder_rotate_angle → robot2_shoulder_rotate_angle if two robots share the same entity name.
Cerebellum: Forward Models
Biological Inspiration
The biological cerebellum stores forward models that predict sensory consequences of motor commands. Climbing-fiber complex spikes carry prediction error; massive microcircuit specialization enables fast, accurate motor control without conscious thought.
Maxim's Cerebellum stores lightweight predictors per (entity, modulator, affordance, param_bucket). Each learns via Rescorla-Wagner prediction error:
- Confidence < 0.3 → LLM fallback (teaches the Cerebellum)
- Confidence ≥ 0.3 → cached prediction (no LLM call)
- High variance → LLM fallback (uncertain predictions need grounding)
The LLM is a teacher, not a per-tick oracle. After enough observations, the Cerebellum handles predictions deterministically. In testing, LLM calls drop from 100 to ≤40 over 100 actions.
The SEM Learning Loop
Biological Inspiration
In the brain, the cerebellum doesn't just predict — it emits signals when predictions fail or succeed. These signals propagate to the hippocampus (contextual memory) and nucleus accumbens (reward learning) simultaneously, closing the loop between motor execution and long-term behavioral adaptation. Success and failure are not symmetric: negative outcomes carry disproportionate weight, a phenomenon known as negativity bias.
When the Cerebellum evaluates an affordance, the outcome flows through the bio-pipeline as a reaction — a typed evaluative signal that drives learning across multiple systems simultaneously. This is the SEM Learning Loop.
CerebellumModulator Outcomes
The CerebellumModulator classifies each affordance execution into one of three outcome paths:
Confident Prediction
Confidence ≥ 0.3 and low variance. The Cerebellum handles the prediction without LLM fallback. Emits a success reaction with positive valence.
LLM Fallback
Confidence < 0.3 or high variance. The LLM acts as teacher. The Cerebellum trains on the LLM's response via Rescorla-Wagner update. No reaction emitted — the system is still learning.
Failure
Affordance execution triggers a failure mode (e.g., shatter, overheat). Emits a pain reaction with negative valence via the PainBus.
Signal Flow
Both success and pain reactions flow through the ReactionBus, which dispatches to two subscribers in parallel:
Negativity Bias
Success reactions carry positive valence but at lower intensity than pain reactions — mirroring biological negativity bias. A single painful failure creates a stronger learning signal than several routine successes. This asymmetry means the agent develops caution around dangerous affordances faster than it develops confidence around safe ones, which is the correct survival trade-off for an embodied system.
Cerebellum Activation via BioStack
In production, the Cerebellum is wired through BioStack.cerebellum and activated by build_executor. This means every agent entry point that constructs a bio-stack gets Cerebellum forward models and the full SEM Learning Loop automatically — no per-caller wiring required.
Behavioral Convergence Wiring
The SEM Learning Loop produces valence and reward bias in the substrate, but the LLM also needs to see this information. Behavioral convergence wiring (shipped 2026-04-17) closes four gaps: valence annotations in PromptAssembler so the LLM sees “this entity is associated with negative experiences,” observe_episode_event in the agent loop for real-time episode capture, an energy→Reaction bridge that fires hunger/fatigue/satiation interoceptive reactions from energy depletion, and bundled food/water/poison SEM specs. Validated by two experiments: cross-session affective memory (11/11 PASS) and energy-driven consumable learning (13/13 PASS). See Experiments & Results for details.
Motor Programs
A reach-and-grasp isn't three separate LLM decisions. It's one motor program — an ordered sequence of SEM actions that fires as a unit. Programs crystallize when the agent repeats the same sequence 3+ times for the same goal.
Triple-Indexed Registry
The ProgramRegistry indexes programs in three directions:
- By goal — "I want to reach forward" → matching programs
- By entity — "I'm holding a sword" → all programs involving swords
- By affordance — "I want to slash" → programs for sword, axe, arm, claws
Pain-Gated Execution
Each step has an optional pain gate — a sensor threshold that aborts the program before damage occurs. Gates tighten by 10% after each painful execution. The PainBus is subscribed for real-time mid-sequence interrupts.
Motor Engrams
Biological Inspiration
Hippocampal-cerebellar interactions are well-documented: the hippocampus provides contextual scaffolding for motor learning ("where and when did I learn this movement?"), while the cerebellum stores the procedural knowledge itself.
Motor engrams are ephemeral cross-system traces linking motor programs to situational context:
- Cerebellum stores the how (motor program steps)
- Hippocampus stores the when/where/what (contextual episode)
- The engram links them via the associative graph
Engrams form only on significant outcomes — pain > 0.3, surprising results (RPE > 0.3), or novel programs. Routine successes don't need episodic context. Engrams decay after ~2 days unless reinforced, using the standard hippocampal consolidation cycle.
The Cyclical Feedback Loop
Virtual Entities: Beyond Robotics
The SEM protocol is hardware-agnostic. A sword is just an Entity with sensors (durability, sharpness) and modulators (slash, parry) backed by NarrativeModulator instead of hardware. The same cognitive stack that learns about robot joints also learns about swords, NPCs, and doors.
Rusty Sword
Sensors: durability, sharpness, weight
Modulators: slash, parry, throw, sharpen, repair
Failure: shatter (durability < 0.1), dulled (sharpness < 0.15)
Grim Ferryman (NPC)
Sensors: trust, mood, health
Modulators: speak, offer_payment, threaten, punch
Failure: hostility (trust < 0.1), refusal (mood < -0.5)
The Cerebellum learns "swinging a damaged sword at a stone golem reduces durability by ~0.15" the same way it learns "rotating an elbow at 90°/s increases strain by ~0.1." Same Rescorla-Wagner update, same forward model, same pain triggers.
Composable Failure Modes
Six base failure modes: overextension, overheating, strain, fatigue, impact, exhaustion. Custom failures compose from these without taxonomy explosion:
Failures route through the existing PainBus and ToolPainBridge. NAc learns (affordance, entity_state) → failure causal links. Persistent failures stay active until recovery conditions are met. All failure state persists across sessions.
Default Embodiment 0.7
New in 0.7
Simulations now load bodies/base_humanoid by default when no --embodiment flag is provided. The agent always has a body in sim mode — 5 sensors, 8 affordances, and 3 failure modes. Pass --no-embodiment to explicitly opt out.
base_humanoid
Genre-neutral humanoid body. Works in any campaign setting.
ref: bodies/base_humanoid
Running an Agent with a SEM Body
A live agent can take a SEM body in one CLI flag. --embodiment <ref> loads a bundled component, wraps it in Embodiment(pain_bus=...), and registers all of its affordance tools into the agent's tool registry — the agent can then invoke them on its own timeline through normal tool dispatch with the full pain cascade running end-to-end.
If the ref is wrong, doctor groups same-category alternatives first so a typo in weapons/X shows you the other weapons before unrelated categories:
Behind the Scenes
cli.pyreads--embodiment weapons/rusty_sword.runtime/bootstrap.py::build_executor— the canonical agent-construction site since the executor bootstrap unification — instantiates the entity viaComponentRegistry, wraps it inEmbodiment(pain_bus=...), and callsgenerate_tools_for_entity.- The agent's LLM sees the affordance tools alongside the standard tools and can invoke them via normal tool dispatch.
- When the agent invokes
rusty_sword_slashon a low-durability sword,embodiment.evaluate_failures()fires theshatterfailure mode →PainBus.publish(PainSignal)→ the executor'sToolPainBridgecallsrecord_tool_embodiment_failure→ NAc forms a NEGATIVE causal link. - On the next turn,
nac.predict()returns NEGATIVE for that tool, informing the agent's policy.
Structural enforcement: the build_executor constructor requires an explicit pain_bus= decision (no default), so forgetting to wire the bridge is a TypeError instead of a silent no-op. Every agent entry point in the codebase makes an explicit pain_bus decision; the prior helper-discipline approach was deprecated after three identical "forgot to wire ToolPainBridge" bugs in three weeks — three-times-is-structural.
Verified end-to-end by tests/substrate/test_sem_execution_production.py against the real bundled weapons/rusty_sword.yaml — no mocks in the cascade chain. Current constraints: --embodiment is mutually exclusive with --sim (sim-mode SEM body wiring is tracked under the AgentFactory canonicalization plan); only one entity can be loaded via the flag (multi-entity bodies are still loaded the old way via Embodiment(spec.root_entity) in code).
Component Library & Genre Gating
SEM components are reusable YAML templates stored in src/maxim/_data/components/ across 5 categories: bodies, creatures, environments, npcs, and weapons. The ComponentRegistry discovers them automatically from three search paths: campaign-local, user (~/.maxim/components/), and bundled.
Fantasy (20 components)
wolf, guard, merchant, ferryman, rusty_sword, longbow, tavern_interior, forest_clearing
Genre-neutral: base_humanoid (usable in any campaign)
Cyberpunk (13 components)
patrol_drone, cyberdog, netrunner, corpo_guard, street_fixer, shock_baton, neural_disruptor, cybernetic_arm, megarm_v3, neon_alley, server_room, megacorp_lobby, ripperdoc_clinic
Genre gating prevents cross-genre contamination. When a campaign declares genre: fantasy, the ComponentRegistry and EntityDesigner only suggest genre-matching or genre-neutral components. A fantasy campaign won't accidentally spawn a cyberpunk patrol drone.
Recognized genre tags: fantasy, cyberpunk, scifi, modern, devops, horror, historical. Explicit registry refs bypass the genre gate — you can intentionally cross genres when needed.
Asset Foundry E1+E2 — 0.6+
LLM-Driven Entity Generation
The Asset Foundry generates new SEM components via LLM, validates them against the protocol, runs them through a 3-encounter gauntlet, and scores them on 4 bio-system engagement dimensions. Pass or fail, the pipeline produces actionable feedback.
Scoring Dimensions
Sensor Engagement
Do sensors change meaningfully during the gauntlet?
Failure Diversity
Do failure modes trigger under different conditions?
Affordance Coverage
Are all affordances exercised during the encounters?
NAc Learning Signal
Does the entity produce causal links the agent can learn from?
Auto-Curation E3 — 0.7
Before a simulation starts, --auto-curate scans the campaign for entity references that have no matching component in the registry. Missing entities are generated via the Asset Foundry, validated, and promoted to the user directory — filling coverage gaps before the first percept fires.
Deduplication uses the ComponentIndex two-layer lookup (alias + embedding) to avoid generating components that already exist under a different name. Components that pass validation are saved to ~/.maxim/components/.
Architecture
| Module | Purpose |
|---|---|
| embodiment/sem.py | Core protocols: Sensor, Modulator, Entity, FailureMode |
| embodiment/spec.py | YAML loader, SpecSensor/SpecModulator stubs |
| embodiment/tool_bridge.py | Auto-tool generation with collision detection |
| embodiment/body.py | Embodiment runtime, failure eval, vital drift, prompt state |
| embodiment/cerebellum.py | Forward models, motor program registry, engram formation/recall |
| embodiment/motor.py | MotorProgram, MotorStep, ProgramRegistry (triple-indexed) |
| embodiment/engrams.py | MotorEngram, salience computation, formation logic |
| embodiment/program_executor.py | Step-by-step runner, pain gates, PainBus interrupt |
| embodiment/llm_backend.py | LLM + Narrative sensor/modulator backends |
| embodiment/percepts.py | EmbodimentPerceptSource (1Hz polling, demand mode) |
| embodiment/atl_integration.py | Auto-register ATL body_part concepts |
| embodiment/component_registry.py | Component discovery, genre filtering, instantiation, inheritance, ephemeral overlay (thread-safe) |
| embodiment/component_index.py | Semantic discovery: alias hash table (O(1)) + embedding index (cosine similarity) |
| imagination/trigger.py | Entity noun-phrase extraction, ComponentIndex lookup, design dispatch |
| imagination/designer.py | ImaginationDesigner: wraps EntityDesigner for real-time entity generation |
| imagination/cache.py | Session-scoped ImaginationCache, thread-safe, shared AUT + orchestrator |
| prompts/acting_coach.py | B3 Acting Coach: bio-modulated exploration meta-prompt (NAc valence, pain anticipation, cerebellum predictions) |
Imagination I1+I2 — 0.7
Biological Inspiration
Imagination fires during low-arousal idle states — the same way you don't daydream while fighting. When the brain encounters something unfamiliar, it constructs a mental model from prior experience to reason about the novel entity before physically interacting with it. The Default Network, which activates during rest and mind-wandering, gates this process.
When the agent encounters a novel entity mentioned in percept text that has no existing SEM component, the imagination system designs one in real-time:
Entity Extraction
Lightweight NLP heuristics extract entity-like noun phrases from narration text — physical objects, creatures, weapons, environmental features, items, vehicles, and NPCs. Abstract concepts, body parts, and clothing are filtered out. Two strategies: sentence-level intro patterns ("You see a rusty gate") and head-noun scanning against a curated indicator vocabulary.
ComponentIndex: Two-Layer Lookup
Before imagining, each candidate phrase is checked against the ComponentIndex:
- Layer 1: Alias table (O(1)) — exact match against component names and synonyms
- Layer 2: Embedding similarity — cosine similarity against all component signatures (threshold 0.65)
This means "old iron door" finds environments/rusty_gate and skips imagination.
Ephemeral Registration
Imagined entities are registered in a separate overlay (_ephemeral_index) from the persistent component index. They're visible to get(), has(), and query() during the session, but cleared at session end via clear_ephemeral().
Provenance Tagging
Episodes and CausalLinks from imagined entity interactions carry imagined=True. On entity discard (session end), imagined causal links get 50% confidence decay — partial learning is useful, but reduced confidence reflects simulated origin.
Gates
Mention Threshold
Default 2 mentions before triggering. Prevents one-off noise from spawning entities.
DN Arousal
Only fires during low-arousal idle states. Blocked when DN is inhibited or recent interesting events occurred.
Energy Budget
Skipped when LLM energy is critical (<10%). Falls back gracefully to verbal-only interaction.
Acting Coach B3 — 0.7
The Acting Coach is a meta-prompt system that prevents the agent from entering respond loops when embodied. Instead of asking "what should I do?", the agent explores its physical affordances proactively.
Bio-System Modulation (not suppression)
The coach is a default policy that three bio-systems continuously modulate:
- NAc valence — learned caution or preference annotations on specific affordances ("sword_slash has caused damage before")
- Pain anticipation — anticipatory anxiety from hippocampal pattern-matching against past pain episodes
- Cerebellum predictions — forward model outcome forecasts ("predicted low success, risks: jammed")
Composition order: base directive → NAc caution → pain anticipation → cerebellum predictions. Each layer adds information; none removes the base exploration directive.