lab.yaml Schema
lab.yaml describes a composed simulation: model instances, wiring, runtime, and optional child labs.
Put a README.md beside each root or owned child lab.yaml. Biosimulant shows
it in the lab About view and falls back to generated details from lab.yaml when
it is missing. Keep README images under assets/ and reference them with
relative paths such as , not base64.
Schema
schema_version: "2.0"
title: string
description: string
models:
- path: string
alias: string
parameters: object
wiring:
- from: string
to:
- string
runtime:
duration: number
communication_step: number
settle_steps: number
io:
inputs:
- name: string
maps_to: string
outputs:
- name: string
maps_to: string
children:
- path: string
alias: string
parameters: object
- package: string
version: string
alias: string
parameters: object
# A matching biosimulant.lock entry is required.Runtime
runtime.communication_step is required and must be positive.
runtime.settle_steps is optional, must be a non-negative integer, and defaults to 0.
runtime:
duration: 10.0
communication_step: 0.1
settle_steps: 0Set input values at run time through the run modal or run payloads. Use parameters for persistent scalar defaults that belong in the lab manifest.
Finite downstream report, export, or visualisation modules should implement
execute() with ExecutionPolicy.ONCE_AFTER_RUN. BioWorld drains arbitrary
chains of those modules automatically after the final simulation boundary.
settle_steps remains available for legacy temporal modules that deliberately
need zero-time propagation. Settling does not extend simulated time and does not
invoke canonical modules.
The old external tick field is not supported.
Execution timing
Biosimulant sorts a lab into one of three timings using the
biosim.execution_policy each model declares in its model.yaml (see
Execution policy). The timing
tells tools whether duration, communication step and settle steps matter for a
run.
| Timing | When | Run settings |
|---|---|---|
finite | Every model declares a policy and none declares each_window | Studio, Desktop and biosimulant labs serve hide duration, communication step and settle steps when you run the lab |
temporal | At least one model declares each_window | Shown |
unknown | No model declares each_window and at least one model doesn’t declare a policy | Shown |
Timing only changes which settings the Run dialog shows. The runtime block
keeps the same rules for every lab:
runtime.communication_stepis still required inlab.yaml, andbiosim.communication_stepis still required in eachmodel.yaml.runtime.durationmust stay positive. A zero-duration run only sets modules up, so run-once modules never run.
When no module runs each window, BioWorld crosses the whole run in one step instead of stepping through empty communication windows. Before-run modules run at the start and after-run modules run at the end, as before.
A lab can’t override a model’s policy. You can mix policies in one lab, but data can only move forward through the phases:
| Source policy | Can feed |
|---|---|
once_before_run | Any policy |
each_window | each_window or once_after_run |
once_after_run | once_after_run only |
Modules that run once can’t form a cycle. Cycles between each_window modules
are still allowed.
When you validate a lab source directory, biosimulant labs validate prints the
lab’s timing, names any models that don’t declare a policy, and reports invalid
wiring between models that do. With --json, the timing is under
metadata.execution. A package-backed child lab counts as undeclared.
Run input files
biosimulant labs run --run-input-file inputs.json overrides runtime values,
initial inputs and model parameters for one run without changing lab.yaml. The
file is a JSON object with optional parameters and simulation_config keys,
the same shape Studio and Desktop send:
{
"simulation_config": {
"runtime": {
"duration": 20.0,
"initial_inputs": { "stimulus": 1.5 }
}
},
"parameters": {
"neuron": { "gain": 2.0 }
}
}- Runtime values (
duration,communication_step,settle_steps) can go undersimulation_config.runtimeor directly undersimulation_config. If both are set,simulation_config.runtimewins. - Initial inputs can go under
simulation_config.runtime.initial_inputs,simulation_config.initial_inputsorparameters.initial_inputs, merged in that order so a later location wins. Use a public lab input name or analias.portreference as the key. - Model parameters can be keyed by alias, as
parameters.<alias>orparameters.per_model.<alias>. They’re merged onto that model’sparametersinlab.yaml.
Models
Each models[] entry creates one module instance in the lab.
| Field | Meaning |
|---|---|
path | Relative path to a local model directory |
alias | Unique name used in wiring |
parameters | Constructor overrides merged into biosim.init_kwargs |
Model entries use path only. Validation rejects package or version on a
model entry. To reuse a published Lab, add it under children.
Current-kernel labs should not declare per-entry timing or ordering fields. Promote model-specific configuration to parameters, and expose runtime values as typed io.inputs.
Wiring
Connections use alias.port references:
wiring:
- from: retina.visual_stream
to:
- lgn.retina
- from: lgn.thalamus
to:
- sc.visionFan-out is supported by listing multiple destinations under to.
Composability
Expose lab-level ports with an io block:
io:
inputs:
- name: stimulus
maps_to: neuron.current
outputs:
- name: spike_train
maps_to: recorder.spikesParent labs wire to child_alias.external_port_name.
Nested child labs
children:
- path: ../labs/microcircuit
alias: circuit_a
parameters: {}Children can be addressed in wiring just like models:
wiring:
- from: stim.current
to:
- circuit_a.stimulusPackage-backed child Labs use an exact package + version and require a
matching entry in the sibling biosimulant.lock with artifact_sha256. The
archive is verified and resolved into the parent Lab’s
.biosimulant/dependencies/ state. Path-backed children remain supported for
existing self-contained Labs. See Compose Hub labs locally.
For portable local package builds, prefer path-based children. Package-backed children always need an explicit version; they never fall back to latest.