Processes and event logs
A lifecycle says which states a row's history contains. A process says how that history unfolds: which step follows which, how often a case loops back (a reopened ticket, a failed payment retried, a claim sent back for more documents), and how long each step takes. It writes one row per event, the shape process-mining tools read.
tables:
tickets:
rows: 5000
columns:
ticket_id: {type: int, primary_key: true}
opened_at: {type: datetime, start: "2024-01-01", end: "2024-06-30"}
status: {type: text}
processes:
- name: ticket_flow
cases_table: tickets
case_key: ticket_id
start_column: opened_at # the first event is at the case's start
initial: opened
transitions: # a state with no row is terminal (closed)
opened: {triaged: 1.0}
triaged: {resolved: 0.85, escalated: 0.15}
escalated: {resolved: 1.0}
resolved: {closed: 0.9, reopened: 0.1}
reopened: {triaged: 1.0}
dwell: # time in a state before leaving it
opened: {distribution: lognormal, mu: 0, sigma: 0.8, unit: hours}
"escalated->resolved": {distribution: exponential, scale: 2, unit: days}
final_state_column: status # the ticket agrees with its log
max_steps: 25 # bounds rework loopsThis produces a ticket_flow_events table (event_id, ticket_id, step,
activity, timestamp; names configurable) next to tickets, from Python,
YAML, dict schemas and the CLI alike.
What is exact and what is drawn#
Exact, and re-checked from the rows by misata.process_audit(events, spec, cases):
- every case starts in
initial, at or after itsstart_column; - only declared transitions occur, numbered
1..nper case; - timestamps never go backwards, in whole seconds;
- every case ends in a terminal state or at
max_steps; - with
final_state_column, the case row holds its log's last state.
Drawn from the declaration (emergent, not exact): which path each case takes, so the share of escalations or reopens lands near, not on, 15% and 10%; and each step's duration.
Dwell times#
Keyed by state (opened), or by one transition ("escalated->resolved"),
which wins. Distributions: lognormal (mu, sigma), exponential
(scale), gamma (shape, scale), uniform (min, max), fixed
(value), each with a unit of seconds, minutes, hours or days.
Steps without one take lognormal(0, 1) hours.
Export for process mining#
misata.to_xes(tables["ticket_flow_events"], "tickets.xes", case_column="ticket_id")writes IEEE 1849 XES, which ProM, PM4Py, Disco and Celonis import.
What it is not#
A semi-Markov chain, simulated for every case at once with numpy (200,000 tickets in about a second), not a discrete-event simulation. There are no queues or shared resources, so a step does not take longer because the system is busy. If waits that depend on load are what you need to test, that is a simulator's job (SimPy, salabim); a process here gives you the event log's structure and timing shape without one.
Prefer generating data visually?
Misata Studio lets you turn natural language prompts into relational schemas with exact outcome invariants, live preview tables, and one-click database seeding without writing code.

