Runs & events
When a journey runs, Mockflow records every step as an event: a request leaving a component, a cache miss, a retry, or a response arriving. Events are the ordered record of the run — and the source the playback views read.
What an event is
Each event has a 1-based sequence, a virtual time in milliseconds, an optional virtual duration, a kind, a stage, and a plain safe summary. It can also carry the token, root token, correlation or interaction IDs, attempt number, call depth, node or edge, and payload references involved in that step.
Virtual time is simulated time from the run's start, not wall-clock time. The sequence is the append order. If two events have the same virtual time, their sequence still tells you which one was recorded first. Earlier events are not rewritten when a run finishes.
A completed run artifact keeps the event list with the execution plan, graph and scenario hashes, engine and executor versions, the reproducibility key, payload entries, state timeline, and run summary. That pinned context is why a playback can be checked against the run that produced it.
How time and ordering work
The deterministic scheduler orders pending work by virtual time, then priority, then the order in which it was scheduled. A node's configured duration or latency advances virtual time; a boundary latency or retry backoff can add another delay. No real timer is required for the simulated clock to move.
The same virtual millisecond can contain several steps
Run limits are also recorded as events. For example, RUN_GUARD_TRIGGERED explains a max-events, max-tokens, traversal, payload, state, or virtual-time safety stop;SCHEDULE_TICK_SKIPPED records a schedule tick that falls outside the configured horizon.
The event lifecycle
After a compatible scenario is compiled into an execution plan, the recorder appends RUN_STARTED. An entry creates a TOKEN_EMITTED event. For an ordinary inbound edge, the record normally shows EDGE_TRAVERSE_STARTED, EDGE_TRAVERSE_COMPLETED, and then NODE_ENTERED. The handler evaluates conditions, chooses routes, performs calls or data operations, and exits the node. Those actions schedule the next arrivals at a later virtual time or at the same time with a later sequence.
Handler actions are ordered. Conditions produce ROUTE_EVALUATED and, when a route is chosen, ROUTE_SELECTED. A map or assignment can produce TRANSFORM_APPLIED. A for-each records COLLECTION_ITERATION_STARTED and one COLLECTION_ITEM_DISPATCHED for each bounded item. Calls and awaits expose their waiting, response, timeout, and completion events. A stateful operation records its mutation and a STATE_PATCH_APPLIED event.
A run ends with RUN_COMPLETED, RUN_CANCELLED, RUN_FAILED, or RUN_GUARD_TRIGGERED. Completion waits for the configured completion policy: all tokens must drain unless a failure, cancellation, or guard ends the run first.
Event kind reference
The transcript uses a stable kind for each important step. The groups below are a quick lookup; the lifecycle sections explain how the kinds relate to one another in a real run.
| Group | Kinds | Meaning |
|---|---|---|
| Run lifecycle | RUN_STARTED · RUN_COMPLETED · RUN_FAILED · RUN_CANCELLED · RUN_GUARD_TRIGGERED · SCHEDULE_TICK_SKIPPED | The run starting and ending. A guard is a safety stop; a skipped schedule tick records work outside the run horizon. |
| Tokens and graph movement | TOKEN_EMITTED · TOKEN_FORKED · TOKEN_JOINED · TOKEN_COMPLETED · EDGE_TRAVERSE_STARTED · EDGE_TRAVERSE_COMPLETED · NODE_ENTERED · NODE_EXITED | A token being created, split, joined, completed, moved over an edge, or processed by a node. |
| Calls and waiting | CALL_STARTED · CALLER_WAITING · RESPONSE_SENT · RESPONSE_RECEIVED · CALL_COMPLETED · CALL_FRAME_UNWOUND · INTERACTION_TIMED_OUT · WAIT_STARTED · WAIT_COMPLETED | A call or await starting, waiting, receiving a response, timing out, completing, or unwinding through a handler catch. |
| Handlers and routing | ROUTE_EVALUATED · ROUTE_SELECTED · SCHEMA_VALIDATED · TRANSFORM_APPLIED · COLLECTION_ITERATION_STARTED · COLLECTION_ITEM_DISPATCHED | A handler condition being checked, an output being chosen, data being validated or transformed, or a for-each item being dispatched. |
| Databases and caches | DB_READ · DB_RESULT · DB_MUTATION · CACHE_LOOKUP · CACHE_HIT · CACHE_MISS · CACHE_WRITE · CACHE_DELETE · CACHE_EXPIRED | A database read or mutation, or a cache lookup and its hit, miss, write, delete, or expiry result. |
| Queues and messages | QUEUE_ENQUEUED · QUEUE_AVAILABLE · QUEUE_DEQUEUED · MESSAGE_ACKED · MESSAGE_REQUEUED · MESSAGE_DEAD_LETTERED | A message entering a queue, becoming available, being taken, acknowledged, requeued, or sent to a dead-letter path. |
| Topics and joins | TOPIC_PUBLISHED · JOIN_ARRIVED · JOIN_SATISFIED · JOIN_TIMED_OUT | Topic publication and fan-in barriers: each related branch arriving, the join becoming satisfied, or the join timing out. |
| Workflows | WORKFLOW_STARTED · WORKFLOW_STEP_STARTED · WORKFLOW_STEP_COMPLETED · WORKFLOW_STEP_FAILED · WORKFLOW_COMPENSATED · WORKFLOW_COMPLETED · WORKFLOW_FAILED | A workflow and its steps starting, completing, failing, or running compensation. |
| Object storage | OBJECT_PUT · OBJECT_GET · OBJECT_MISSING · OBJECT_DELETED | An object being stored, fetched, found missing, or deleted. |
| Errors and retries | ERROR_RAISED · ERROR_HANDLED · RETRY_SCHEDULED · RETRY_STARTED · RETRY_EXHAUSTED | A failure being raised or handled, or a retry being scheduled, attempted, or exhausted. |
| Limits and state | WINDOW_COUNTER_RECORDED · WINDOW_COUNTER_REJECTED · CAPACITY_ACQUIRED · CAPACITY_QUEUED · CAPACITY_REJECTED · CAPACITY_RELEASED · STATE_PATCH_APPLIED | A rate-window or capacity decision, or a change applied to simulated component state. |
Branches, joins, and child work
A fan-out records TOKEN_FORKED when it creates related child work. Each child has lineage fields linking it back to its root token and correlation. A topic publication can create one child token per subscriber; a collection dispatch carries iteration context.
A join records JOIN_ARRIVED for each matching branch. When the barrier has the arrivals it needs, it records JOIN_SATISFIED and TOKEN_JOINED. If the barrier reaches its deadline first, JOIN_TIMED_OUT identifies the missing-branch path; a handler catch or run failure can then follow it.
Where to read them
After a run, the workbench dock shows three views. Transcript is the ordered list: each row shows the virtual time, event kind, token, and safe summary under stage headings. Timeline lays the same events out by virtual time with filters. Inspect shows the selected event, its lineage and routing details, and available payload and state differences.
The timeline is still an event list, not a measurement of elapsed screen time. A virtual gap over two seconds is shown as a compressed gap for playback. Searching can match event kind, safe summary, stage, and lineage IDs; additional filters cover token, component, and interaction. Next warning or error moves to the next event whose severity is error.
A transcript excerpt, in plain words
The timestamps and labels are illustrative; the sequence and kinds in a real run depend on its graph and fixtures.
Timeouts, retries, and failure paths
An interaction can have a timeout, a maximum attempt count, and fixed or exponential backoff with a maximum delay. The event trail shows INTERACTION_TIMED_OUT, then RETRY_SCHEDULED and RETRY_STARTED when another attempt is allowed. RETRY_EXHAUSTED records that no more attempts are available.
A handler failure starts with ERROR_RAISED. A matching catch can unwind the call frame with CALL_FRAME_UNWOUND and record ERROR_HANDLED, with a rejected or degraded handled outcome. Without a handled continuation, the run can end in RUN_FAILED.
Queue paths expose MESSAGE_REQUEUED and, when the configured failure path ends there, MESSAGE_DEAD_LETTERED. Workflow paths can expose WORKFLOW_STEP_FAILED followed by WORKFLOW_COMPENSATED, or finish with WORKFLOW_FAILED. Look at the terminal event and the events immediately before it to distinguish a handled failure from a failed run.
Every event has information or error severity. Filtering to errors, then stepping backward through the same stage and token, is usually the shortest path to the first useful failure evidence.
Payloads, state, and safe projections
Events do not repeat every JSON value. The recorder stores payload entries by content hash and events point to them with payloadBeforeRef and payloadAfterRef. The two references can be the same when a step does not change the payload. The event inspector resolves both entries and shows a structural before/after diff when the values are available.
Component state starts from the scenario fixtures. State deltas are tied to event sequences. The state timeline adds reconstruction checkpoints as needed, so Inspect can reconstruct state immediately before and after an event instead of replaying the whole run each time. A missing value or state reference is shown as unavailable.
API and agent projections are deliberately smaller than the local artifact. A summary projection keeps representative lifecycle and failure events, up to 100 events. A full projection is filtered and paged, with up to 500 debug events per page, and includes hashes, version pins, counts, and payload/state references. Compact output can use aliases such as event:1; resource mode keeps addressable references.
Value visibility follows the caller's payload policy: schemas_only redacts values by policy, approved_examples exposes only an approved example, and permitted_full_values permits values subject to depth and byte limits. A reference can therefore be valid even when its value is not returned. Treat the safe summary and the run hashes as the stable diagnostic surface when values are redacted.
How to read the run summary
The summary separates status from outcome. Status says how the run stopped: completed, cancelled, guarded, or failed. Outcome says what the terminal behavior was: success, rejected, degraded, cancelled, guarded, or failed. It also reports event, stage, and token counts; virtual duration; warning and error counts; changed component IDs; and, when known, a terminal code, responsible object, and remediation.
Read the summary first to decide whether the run completed and where to look. Then use the terminal event, the first error in sequence, and the relevant token or interaction lineage to explain the path. The summary is a map; the event sequence is the evidence.
Replay and pause at useful moments
Use the playback controls to play, pause, step one event or one stage in either direction, scrub, restart, and change speed. The canvas highlights the selected node or connection. Reduced-motion playback keeps discrete focus changes while removing travel animation; it does not alter the event log.
Breakpoints can pause at a node, stage, event kind, error, or simple condition such as an attempt or virtual-time threshold. Breakpoints change only how you review the completed artifact. They do not rerun the scenario or change its result.