Information Hierarchy
The canonical names for the project’s top-level concepts. Each concept is named once, with its lifetime, its code type or identifier, and the vocabulary to use when referring to it. This is the source of truth the Glossary (the fine-grained term reference) and all later vocabulary work align to.
Read the whole hierarchy as one sentence:
The five canonical concepts
Section titled “The five canonical concepts”The concepts separate cleanly by lifetime. Two are durable — they live on disk and are studied, version-controlled, and re-used (Scenario, config file). One is persistent for the life of a process (Engine). One is ephemeral, existing only while a single run is in flight (Experiment). One is the durable saved output of an ephemeral run (Experiment Dataset).
Engine
Section titled “Engine”The persistent runtime machinery. An Engine loads Scenarios and runs many Experiments over its lifetime, holding no per-run state of its own. It is the single application core that every surface — CLI, REST API, MCP, tests — drives identically.
Lifetime: process-lived. Code type: the facade entry type Lab, top of the Lab → Workbench → Scenario → Experiment facade
(mock_machine.New()); implementation under internal/engine. Vocabulary:
“Engine” is the persistent runtime — never a single run, a loop, or a directory.
Use Experiment for a run.
Scenario
Section titled “Scenario”A folder under scenarios/ (e.g. OnlineShopping/) holding a complete, studyable
setup: a config file (<Name>.yaml) plus seed/, tools/, and
docs/. The folder name, the config-file name, and the scenario name are all the
same. A Scenario is the durable thing you keep, version, and load into the Engine.
Lifetime: durable; lives on disk and in version control. Code type: the
on-disk package under scenarios/<Name>/, loaded by the scenario loader; deployed onto a workbench it becomes a Scenario handle.
Vocabulary: “Scenario” is the on-disk setup. Avoid “Configuration” for this —
that word is reserved for the config file and informal parameterizations (see
below). For the minimal, single-concern setups used in tests, use
“fixture”.
config file
Section titled “config file”The YAML document <Scenario>.yaml at the root of a Scenario. It declares the
state machines, taxonomies, catalogs, events, messages, and scheduling regime, and
is loaded and validated into the Config struct. The term is kept because it is
well understood.
Lowercase “a configuration” is a distinct, informal idea: a particular parameterization of a run — a config file together with the chosen seed files and execution arguments. It is a description, not a type.
Lifetime: durable; the source artifact of a Scenario. Code type: the YAML
file → the Config struct (see Data Model).
Vocabulary: “config file” = the YAML; Config = the loaded struct; “a
configuration” = an informal parameterization. Do not use the bare word
“Configuration” to mean the on-disk setup — that is a Scenario.
Experiment
Section titled “Experiment”One run of a Scenario for N turns with a given set of execution arguments. It is the live in-memory context of that run: the entities, partitions, clocks and message queues, and log writers. An Experiment is created, run to completion (or stepped interactively), and then discarded.
Lifetime: ephemeral; exists only while the run is in flight. Code type: the
Experiment struct (Run / Step), in
internal/engine/runtime/experiment.go. The type was formerly named Simulation.
Vocabulary: “Experiment” is the run; run one via the --run CLI flag or the
Run method. “Simulation” survives only as the informal product noun for the whole
modelling activity (e.g. “agent-based simulation engine”) — never as the runtime
object, the run, the loop, a CLI flag, or a directory. See overloaded terms.
Experiment Dataset
Section titled “Experiment Dataset”The durable saved output of one Experiment: an experiment.json manifest plus the
entity CSV tables and the event log, written under
experiments/<expid>/ within the Scenario. It is the artifact you analyse after a
run, and (via the event log) is fully reconcilable — replaying the log reproduces
the CSV tables.
Lifetime: durable; persisted after the Experiment ends. Code type: the
on-disk experiments/<expid>/ directory; the manifest is the ExperimentManifest
struct, written as experiment.json. Vocabulary: “Experiment Dataset” is the
saved output — a noun. It is chosen over “run”, which reads as a verb. See
overloaded terms.
Overloaded terms to disambiguate
Section titled “Overloaded terms to disambiguate”Four words carry more than one meaning in conversation and in older code. For each, the table states the overload and the canonical term to use for each meaning. These are vocabulary steers for writing and naming — not runtime deprecations.
| Overloaded word | Meaning in play | Canonical term to use |
|---|---|---|
| Simulation | the runtime object / one run | Experiment (the code type is the Experiment struct, formerly named Simulation) |
| Simulation | the per-turn loop | the Step / turn loop (a phase of an Experiment) |
| Simulation | the modelling activity in general | ”simulation” as an informal product noun is fine; never for the runtime, the run, the loop, a CLI flag, or a directory |
| run | the act of running (verb) | “run” / “run an Experiment” — verb only |
| run | the saved output files | Experiment Dataset |
| run | the output directory | experiments/<expid>/ (an Experiment Dataset directory) |
| configuration | the YAML file / loaded struct | config file (the YAML) · Config (the struct) |
| configuration | a particular parameterization of a run | lowercase “a configuration” (config file + seed files + execution arguments) — informal, not a type |
| scenario vs. fixture | a real, studyable on-disk setup | Scenario (under scenarios/) |
| scenario vs. fixture | a minimal, single-concern setup built to exercise one engine capability in tests | ”fixture” (e.g. internal/engine/testdata/Fixture<Concern>/) — not a Scenario |
RL vocabulary
Section titled “RL vocabulary”The decision (sub-issue CON-630) is to adopt the mapping at documentation
level and defer code adoption. Two facts drive it. First, a trajectory is already
latent in the data model: the event log records one ordered row per mutation, each
tagged with partition, turn, instance_id, event_name, and
from_state/to_state, so one entity’s ordered state-and-action history is
recovered by filtering the log on its instance_id — no new structure is required
to have trajectories. Second, the project’s naming principle is that a canonical
term names a thing that exists in code; these terms are not yet in code, and their
consumer has not landed. Recording the mapping now makes the future code adoption a
mechanical step and gives the sibling project a shared vocabulary, while keeping the
engine’s canonical surface honest. The decision is fully reversible: when the terms
are adopted in code, this section graduates from “reserved” to canonical.
The intended mapping, for when these are adopted:
| RL term | Maps onto | Concretely |
|---|---|---|
| trajectory | one entity’s ordered history within an Experiment | the event-log rows for a single instance_id, ordered by turn — the entity’s state and action sequence, reconstructable from an Experiment Dataset without re-running. |
| rollout | the set of trajectories produced by one Experiment | all per-entity trajectories in one Experiment Dataset. One run of a Scenario yields one rollout — the term names the run’s output viewed as a collection of trajectories. |
| episode | one entity’s trajectory from creation to terminal state | the segment of a trajectory bounded by the entity’s creation and its passivation or terminal transition. An episode is finer than a rollout: a rollout is the whole population’s output, an episode is one entity’s single life. A partition bounds a self-contained world, so per-partition grouping is the natural unit when a model needs episodes scoped to one world rather than one entity. |
| reward | a Scenario-authored measure field — not an engine concept | a numeric field the modeller accumulates with update actions (e.g. CliffWalking’s total_reward). The engine has no built-in reward signal; reward stays a per-Scenario convention until a model or the policy-evaluation work defines an engine-level signal. Out of scope as canonical engine vocabulary for now. |
Summary table
Section titled “Summary table”| Canonical term | Lifetime | Code type / identifier | Synonyms to avoid |
|---|---|---|---|
| Engine | persistent (process-lived) | facade Lab (mock_machine.New()); impl internal/engine | ”the simulation” (the runtime), “the runner” |
| Scenario | durable (on disk) | scenarios/<Name>/ package; deployed → Scenario handle | ”Configuration” (for the on-disk setup), “fixture” (reserve for test setups) |
| config file | durable (on disk) | <Name>.yaml → Config struct | ”Configuration” the type; “the scenario” (the file is one part of a Scenario) |
| Experiment | ephemeral (in-memory) | Experiment struct (formerly named Simulation) | “Simulation” (the object/run), “run” (the noun) |
| Experiment Dataset | durable (saved output) | experiments/<expid>/; manifest ExperimentManifest → experiment.json | ”run” (the directory/files), “output dir” |
For the fine-grained reference of every engine term (Action, Archetype, Cascade queue, Partition, Turn, NextWake, and 70+ more), see the Glossary.