RISE Framework Specification
Spec ID: 60
Version: 1.1
Document ID: caishen-rise-smdf-v1.1
Last Updated: 2026-02-23
Source: Extracted from StateMachineDotNet-v1.xsd, StateMachineXmlModel.cs, StateMachineType.cs
Implementation: smcraft — Python: smcraft/py/smcraft/model.py, parser.py | TypeScript: smcraft/ts/src/model.ts, parser.ts
What SMDF Enables Users to Create:
Desired Outcomes:
A State Machine Definition consists of three required sections:
StateMachineDefinition
├── Settings (namespace, name, async mode, object references)
├── Events (grouped event sources with typed parameters)
└── State (root state containing the full state hierarchy)
States organize hierarchically. Every definition has exactly one root state containing all other states:
Root State
├── Composite State (has children, first child is initial)
│ ├── Leaf State (no children, may have transitions)
│ ├── Leaf State
│ └── Final State (terminal — triggers completion)
├── State with Parallel Region
│ └── Parallel
│ ├── Orthogonal Region A (independent sub-machine)
│ └── Orthogonal Region B (independent sub-machine)
└── History State (remembers previous active state)
| Kind | Description |
|---|---|
| Leaf | Terminal state node with no children. Processes events and transitions. |
| Composite | Contains child states. First child is the initial sub-state. |
| Root | The outermost state. Exactly one per definition. |
| Final | Signals state machine completion. No outgoing transitions allowed. |
| History | Remembers which sibling state was active before leaving the parent. When re-entered, restores the remembered state instead of the default initial child. |
| Parallel | Contains orthogonal regions that execute independently. All regions must reach their final states before the parallel state transitions to its nextState. |
A transition connects a source state to a target state, triggered by an event:
Transition:
- event: EventId (required) — the triggering event
- nextState: StateId (optional) — target state
- condition: Expression (optional) — guard that must evaluate true
- actions: Action[] (optional) — code/timer operations during transition
Transition Types:
- External: Has nextState → exits source, enters target (onExit/onEntry fire)
- Self: nextState equals containing state → onExit then onEntry fire
- Internal: No nextState → actions execute without state change (no onExit/onEntry)
Events are grouped into Event Sources. Each event source may optionally generate a feeder class — a partial class that provides methods to feed events into the state machine context.
EventSource:
- name: string (required) — identifier, also interface name if file is set
- file: string (optional) — source file containing the interface
- feeder: string (optional) — name of partial class to generate
- events: Event[]
- timers: Timer[]
Event:
- id: string (required, unique) — referenced by transition.event
- name: string (optional) — display name
- description: string (optional)
- parameters: Parameter[] — typed parameters passed with the event
- preAction: string (optional) — always executes when event fires, before transitions
- postAction: string (optional) — always executes after transitions
Parameter:
- name: string (required)
- type: string (required) — language-native type (string, int, float, etc.)
Timers are specialized events that fire after a configured duration:
Timer:
- id: string (required) — referenced by transition.event
- name: string (required) — referenced by timerStart/timerStop actions
- description: string (optional)
TimerStart Action:
- timer: string — timer name to start
- duration: string — milliseconds until the timer event fires
TimerStop Action:
- timer: string — timer name to stop
Actions execute code during state entry, exit, or transitions:
Action Types:
- Code Action: Inline code expression (language-specific in generated output)
- TimerStart: Start a named timer with a duration
- TimerStop: Stop a named timer
Actions appear in:
- state.onEntry — executed when entering the state
- state.onExit — executed when leaving the state
- transition.actions — executed during the transition (after onExit, before onEntry)
Settings:
- namespace: string (required) — target namespace for generated code
- name: string (optional) — state machine name (defaults to filename)
- asynchronous: boolean (required) — whether events are queued asynchronously
- objects: ObjectRef[] — domain objects accessible within actions/conditions
- context: ContextConfig (optional) — override context class/instance naming
- using: string[] — additional namespace imports
ObjectRef:
- instance: string (required) — variable name used in actions/conditions
- class: string (required) — class/type name
- namespace: string (optional) — where to find the class
ContextConfig:
- class: string (optional) — override generated context class name
- instance: string (optional) — override context instance variable name
While the original format is XML (StateMachineDotNet-v1.xsd), the canonical format for new implementations is JSON:
{
"settings": {
"namespace": "Trading.Strategies",
"name": "BDBOStrategy",
"asynchronous": true,
"objects": [
{ "instance": "strategy", "class": "BDBOStrategyEntity" }
],
"context": { "class": "BDBOStrategyContext" },
"using": ["Trading.Common"]
},
"events": [
{
"name": "StrategyEvents",
"feeder": "StrategyFeeder",
"events": [
{
"id": "StrategyCreated",
"parameters": [
{ "name": "strategyId", "type": "string" }
]
},
{
"id": "PriceBreakout",
"parameters": [
{ "name": "price", "type": "float" },
{ "name": "direction", "type": "string" }
]
},
{ "id": "SignalFound" },
{ "id": "OrderFilled" },
{ "id": "StrategyCompleted" },
{ "id": "StrategyFailed" }
],
"timers": [
{ "id": "evTimeout", "name": "Timeout" }
]
}
],
"state": {
"name": "Root",
"states": [
{
"name": "Idle",
"transitions": [
{ "event": "StrategyCreated", "nextState": "Active_WaitingBreakout" }
]
},
{
"name": "Active",
"states": [
{
"name": "Active_WaitingBreakout",
"onEntry": { "actions": [{ "code": "strategy.StartMonitoring()" }] },
"transitions": [
{ "event": "PriceBreakout", "nextState": "Active_WaitingSignal" },
{ "event": "StrategyFailed", "nextState": "Failed" }
]
},
{
"name": "Active_WaitingSignal",
"onEntry": {
"actions": [
{ "timerStart": { "timer": "Timeout", "duration": "60000" } }
]
},
"onExit": {
"actions": [
{ "timerStop": { "timer": "Timeout" } }
]
},
"transitions": [
{ "event": "SignalFound", "nextState": "Active_WaitingEntry" },
{ "event": "evTimeout", "nextState": "Active_WaitingBreakout" }
]
},
{
"name": "Active_WaitingEntry",
"transitions": [
{ "event": "OrderFilled", "nextState": "Completed" },
{
"event": "StrategyFailed",
"nextState": "Active_WaitingSignal",
"condition": "strategy.CanRetry()"
}
]
}
]
},
{ "name": "Completed", "kind": "final" },
{ "name": "Failed", "kind": "final" }
]
}
}
The original XML format uses namespace http://www.stateforge.com/StateMachineDotNet-v1:
<StateMachine xmlns="http://www.stateforge.com/StateMachineDotNet-v1">
<settings asynchronous="true" namespace="Trading.Strategies">
<object instance="strategy" class="BDBOStrategyEntity"/>
</settings>
<events>
<eventSource name="StrategyEvents" feeder="StrategyFeeder">
<event id="StrategyCreated">
<parameter name="strategyId" type="string"/>
</event>
<event id="PriceBreakout">
<parameter name="price" type="float"/>
<parameter name="direction" type="string"/>
</event>
<timer id="evTimeout" name="Timeout"/>
</eventSource>
</events>
<state name="Root">
<state name="Idle">
<transition event="StrategyCreated" nextState="Active_WaitingBreakout"/>
</state>
<state name="Active">
<state name="Active_WaitingBreakout">
<onEntry><action>strategy.StartMonitoring()</action></onEntry>
<transition event="PriceBreakout" nextState="Active_WaitingSignal"/>
</state>
<!-- ... -->
</state>
<state name="Completed" kind="final"/>
<state name="Failed" kind="final"/>
</state>
</StateMachine>
A valid state machine definition must satisfy:
| Rule ID | Description |
|---|---|
| V001 | Exactly one root state exists |
| V002 | All state names are unique within the definition |
| V003 | All event IDs are unique within the definition |
| V004 | All timer IDs are unique and do not collide with event IDs |
| V005 | Every transition.event references a defined event ID |
| V006 | Every transition.nextState references a defined state name |
| V007 | Final states have no outgoing transitions |
| V008 | Final states have no child states |
| V009 | History states exist only as children of composite states |
| V010 | Parallel regions contain at least one orthogonal state |
| V011 | Parallel nextState references a valid state outside the parallel region |
| V012 | Every composite state has at least one child state |
| V013 | At least one event source is defined |
| V014 | Timer names referenced in timerStart/timerStop are defined |
Desired Outcome: A trader defines a BDBO strategy lifecycle as a state machine
Current Reality: Strategy behavior is scattered across procedural code
Natural Progression:
Desired Outcome: One definition generates working code in Python, TypeScript, and C#
Current Reality: State machine logic is manually duplicated per language
Natural Progression:
┌─────────────────┐
│ JSON / XML │
│ Definition │
│ File (.smdf) │
└────────┬────────┘
│
┌────────▼────────┐
│ Parser │
│ (validates │
│ against │
│ schema) │
└────────┬────────┘
│
┌────────▼────────┐
│ Object Model │
│ (in-memory │
│ StateMachine │
│ Type) │
└────────┬────────┘
│
┌──────────────┼──────────────┐
│ │ │
┌────────▼──────┐ ┌────▼────┐ ┌───────▼──────┐
│ Code Generator│ │ Runtime │ │ Designer │
│ (Spec 62) │ │ (Spec 61)│ │ (Spec 63) │
└───────────────┘ └─────────┘ └──────────────┘
.smdf.json — JSON format (canonical).smdf.xml or .fsm — XML format (legacy compatibility)| Definition Type | Python | TypeScript | C# |
|---|---|---|---|
string |
str |
string |
string |
int |
int |
number |
int |
float |
float |
number |
double |
bool |
bool |
boolean |
bool |
object |
Any |
any |
object |
| Custom class | Class name | Interface/class name | Class name |