How to Write a lab.yaml
lab.yaml composes models into a graph with shared runtime settings and explicit wiring.
Keep a README.md beside each lab root’s lab.yaml for the narrative About content that users see in Biosimulant.
Annotated example
schema_version: "2.0"
title: "Predator-Prey Ecosystem"
description: "Lotka-Volterra style toy composition"
models:
- path: ../models/environment
alias: env
module_config:
seed: 42
- path: ../models/organism-population
alias: rabbits
parameters:
name: Rabbits
initial_count: 100
- package: biosimulant/predation
version: 1.2.0
alias: predation
parameters:
predation_rate: 0.01
wiring:
- from: env.conditions
to:
- rabbits.conditions
- from: rabbits.population_state
to:
- predation.prey_state
runtime:
duration: 100.0
communication_step: 0.1
settle_steps: 0
initial_inputs: {}Key rules
runtime.communication_stepis required and must be positiveruntime.settle_stepsis optional, defaults to0, and must be a non-negative integer- the old external tick field is not supported
- every model entry needs an
alias - model entries should not declare legacy per-module timing or ordering fields
- wiring references use
alias.port README.md, when present besidelab.yaml, is loaded as the lab About content
Use settle_steps when the lab contains downstream report, export, or
visualisation modules that should consume outputs produced at the final
simulation boundary. One direct producer-to-visualisation edge usually needs
settle_steps: 1; a two-hop chain usually needs settle_steps: 2. Settling does
not extend simulated time.
README.md
Use the root README.md for explanations that do not belong in structured manifest fields: what the lab is for, assumptions, expected inputs and outputs, run interpretation, citations, and caveats. Owned nested labs can have their own README.md beside their own lab.yaml, and Biosimulant uses that child README when the child lab is the active view.
If no README is present, the app shows generated About details from lab.yaml.
When a README needs screenshots, put them under the lab root, preferably assets/, and use relative Markdown image paths. Do not embed images as base64; Desktop and Web load the image files from the lab package. Use subfolders under assets/ only for files tied to a narrow purpose.
Model entries
| Field | Meaning |
|---|---|
path | Relative path to a local model directory |
package + version | Published model reference |
alias | Local name used in wiring |
parameters | Constructor overrides |
module_config | Per-module setup() config |
For package-backed models, package uses namespace/name and version must be the exact SemVer package version to hydrate. The equivalent CLI ref is namespace/name@x.y.z, for example biosimulant/predation@1.2.0.
External I/O for child labs
io:
inputs:
- name: stimulus
maps_to: neuron.current
outputs:
- name: spikes
maps_to: recorder.spikesNested child labs
children:
- path: ../labs/microcircuit
alias: circuit_a
parameters: {}Parent wiring uses child_alias.external_port_name:
wiring:
- from: stim.current
to:
- circuit_a.stimulusDuring execution, Biosimulant flattens child labs with the same rules as the
open-source biosimulant runtime. Child model aliases are scoped as
child_alias.model_alias, and parent wiring references to
child_alias.external_port_name are remapped through the child lab’s io.maps_to
contract. Child lab nesting is limited to depth 5, circular child references are
rejected, and unresolved child labs fail validation/execution instead of being
silently skipped.
For Biosimulant upload and registry-backed hydration, use biosimulant labs package, biosimulant labs pull, and biosimulant labs release ....
Validate by building
biosimulant labs release validate biosimulant-packages.yaml
biosimulant labs release build biosimulant-packages.yaml --out dist/biosimulant-packages