Schema Format
Define state machines in JSON for workflow management, infrastructure monitoring, and agent lifecycle tracking.
When do you need schemas? Guard rules (from Quick Start) block individual actions. Schemas go further: they define the sequence of allowed states. Use schemas when you need to enforce that step A happens before step B, track entity lifecycles, or monitor infrastructure state transitions. Most developers start with guard rules and add schemas later.
Full Example
{
"id": "my-workflow",
"version": "1.0",
"initial_state": "draft",
"states": {
"draft": { "type": "initial" },
"review": { "type": "active" },
"published": { "type": "terminal" }
},
"events": ["submit", "approve", "reject", "reset"],
"transitions": [
{ "from": "draft", "event": "submit", "to": "review" },
{ "from": "review", "event": "approve", "to": "published" },
{ "from": "review", "event": "reject", "to": "draft" }
],
"universal_fallbacks": [],
"terminal_reset": { "event": "reset", "to": "draft" },
"timeouts": [
{ "state": "review", "hours": 48, "event": "timeout_review" }
]
} State Types
| Type | Behavior |
|---|---|
initial | Starting state. Every schema must have exactly one. |
active | Accepts transitions. Can have guards and timeouts. |
terminal | Done. Blocks all transitions except reset. Nothing stays in limbo. |
Key guarantee: Terminal states are absolute. Once an entity reaches a terminal state, the only way out is reset. The AI cannot override this.
Fields
| Field | Required | Description |
|---|---|---|
id | Yes | Unique identifier for this schema |
version | Yes | Semver version string |
initial_state | Yes | Starting state name |
states | Yes | Map of state names to type objects |
events | Yes | Array of all valid event names |
transitions | Yes | Array of from/event/to objects |
universal_fallbacks | No | Events that work from any non-terminal state (emergency exits) |
terminal_reset | No | The one event that works from terminal states |
timeouts | No | Auto-fire events after elapsed time |
Transitions
Each transition is an object with three fields:
{ "from": "draft", "event": "submit", "to": "review" } When the FSM is in state draft and receives event submit, it moves to review. If a guard exists for this transition, it must evaluate to true first.
Universal Fallbacks
Emergency exits that work from ANY non-terminal state. Guards do NOT apply to fallbacks (by design — you need to be able to rollback without permission).
"universal_fallbacks": [
{ "event": "rollback", "to": "rolled_back" },
{ "event": "cancel", "to": "cancelled" }
] Timeouts
Auto-fire events when an entity stays in a state too long. Prevents things from staying in limbo.
"timeouts": [
{ "state": "review", "hours": 48, "event": "timeout_review" },
{ "state": "waiting", "hours": 72, "event": "timeout_abandoned" }
] Try it: Paste this schema into the Playground to see it in action.