What you'll learn
- The difference between agent state and process runtime state
- Why immutable transitions improve debuggability and replayability
- How to model domain state with explicit schemas
- How signal routes map events to behavior
Prerequisites
- You can read Elixir structs and modules comfortably
- You have seen an OTP supervisor in a Phoenix or Elixir app
- You understand that BEAM processes fail independently
Lesson Breakdown
- Mental model: an agent is a typed state container plus behavior contracts.
- State schema: define required fields, defaults, and constraints up front.
- Routing: map signal types to action modules using predictable naming.
- Execution: keep domain transitions deterministic; isolate side effects.
- Failure: rely on supervisor strategies for process-level recovery.
Hands-on Exercise
Build a small InventoryAgent with fields sku, quantity, and updated_at.
- Create the schema with defaults and type checks.
- Add signal routes for
inventory.adjust and inventory.recount. - Implement one action that increments/decrements quantity.
- Add an out-of-bounds guard (
quantity cannot go below zero). - Simulate two command calls and confirm each returns a new agent struct.
Validation Checklist
- [ ] Agent schema rejects invalid
quantity input. - [ ] Route table includes both signal types.
- [ ] Action returns a state delta, not direct side effects.
- [ ] You can show old and new state in a deterministic diff.
Next Module
Continue with Actions and Schema Validation.