Scenario to Trace Data Flow¶
This diagram traces how a YAML scenario file flows through the FCC simulation engine, producing messages, workflow transitions, structured traces, and events on the bus. It spans scenarios/loader.py, simulation/engine.py, simulation/messages.py, simulation/traces.py, and messaging/bus.py. Every node transition emits an event, and every message is recorded into a MessageHistory ring so the run can be replayed. A simulation run terminates with a SimulationResult aggregating persona executions, validations, and traceability metadata.
The diagram below traces the scenario-to-trace pipeline.
flowchart LR
subgraph Input
S1[(Scenario YAML)]
S2[ScenarioLoader.load]
end
subgraph Execute
E1[SimulationEngine.run]
E2{Next node?}
E3[PersonaExecution]
E4[Message payload]
end
subgraph Record
R1[MessageHistory.record]
R2[Trace append]
R3[ValidationResult]
end
subgraph Publish
P1[EventBus.publish]
P2[(simulation.step events)]
P3[(simulation.completed event)]
P4[SimulationResult]
end
S1 --> S2 --> E1
E1 --> E2
E2 -- yes --> E3 --> E4 --> R1
R1 --> R2
E4 --> P1 --> P2
E2 -- no --> R3 --> P1
P1 --> P3 --> P4
Once SimulationEngine.run(start_node) begins, the scenario graph drives a loop: each iteration resolves the next workflow node, invokes the bound persona, captures the resulting Message, and appends to MessageHistory. The engine publishes simulation.step with the edge label so subscribers can build a live progress dashboard. On any ValidationResult with passed=False, a simulation.validation_failed event is published before the loop continues.
At termination the engine assembles a SimulationResult(scenario_id, status, personas_executed, artifacts, validations, traceability) and publishes simulation.completed. Subscriber failures push envelopes into the dead-letter queue so downstream consumers can reprocess without blocking the main loop. The same trace can be replayed offline via EventReplay against a serialized event log.
Data shapes¶
- Stage 1 - Input: Scenario YAML on disk loaded by
ScenarioLoader.loadinto aScenarioSpecwithsetup.ai_configand workflow graph reference. - Stage 2 - Dispatch:
SimulationEngine.run(start_node)walks theWorkflowGraph, materialising onePersonaExecution(persona, started_at, status, messages)per visited persona node. - Stage 3 - Message: Each node emits a
Message(payload, origin, timestamp)consumed by the next node. - Stage 4 - Record:
MessageHistory.record(node_id, msg, edge_label)captures the message plus the edge label for trace reconstruction. - Stage 5 - Validate:
FCCValidatorproducesValidationResult(rule, passed, severity, message, details)for schema and invariant checks. - Stage 6 - Publish:
EventBus.publish(Event(event_type, source, payload, correlation_id, timestamp))firessimulation.stepduring andsimulation.completedat end of run. - Stage 7 - Aggregate:
SimulationResultreturned to the caller with full traceability dict for audit replay.
See also¶
- Source:
src/fcc/scenarios/loader.py,src/fcc/scenarios/models.py:26,56,67 - Source:
src/fcc/simulation/engine.py,src/fcc/simulation/messages.py,src/fcc/simulation/traces.py - Source:
src/fcc/messaging/bus.py,src/fcc/messaging/events.py - Related class diagram:
../class-diagrams/simulation-engine.md - For audience tier:
docs/for-beginners/quickstart-first-simulation.md