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 it for the About content 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
parameters:
seed: 42
- path: ../models/organism-population
alias: rabbits
parameters:
name: Rabbits
initial_count: 100
- path: ../models/predation
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: 0Key rules
runtime.communication_stepis required and must be positiveruntime.settle_stepsis optional, defaults to0, and must be a non-negative integer- set input values when starting a run; persistent scalar defaults should be model or lab parameters when appropriate
- the old external tick field is not supported
- every model entry needs an
aliasand a relativepath; validation rejectspackageorversionon a model entry - model entries should not declare legacy per-module timing or ordering fields
- wiring references use
alias.port
For finite downstream report, export, or visualisation work, implement
execute() with ExecutionPolicy.ONCE_AFTER_RUN; BioWorld drains any dependent
chain automatically. Keep settle_steps only for legacy temporal modules that
deliberately need zero-time propagation. Settling does not extend simulated time
and does not invoke canonical modules.
Compose child labs
A child lab is a composed subgraph that a parent lab uses through explicit external ports.
Expose the child’s ports
schema_version: "2.0"
title: "E/I Microcircuit"
models:
- path: ../../models/excitatory
alias: exc
- path: ../../models/inhibitory
alias: inh
wiring:
- from: exc.spikes
to:
- inh.input_spikes
runtime:
duration: 1.0
communication_step: 0.001
io:
inputs:
- name: external_current
maps_to: exc.current
outputs:
- name: exc_spikes
maps_to: exc.spikesWithout io, the child lab has no external ports for parent wiring.
Reference the child from the parent
children:
- path: ../ei-microcircuit
alias: circuit_a
parameters: {}
wiring:
- from: stim.current
to:
- circuit_a.external_currentA child uses either path or package + version, not both. The old lab_id
form is rejected.
How children are flattened
During 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.
Package-backed child Labs require a sibling biosimulant.lock entry with the
same package, exact version, and the Hub archive’s artifact_sha256. See
Compose Hub Labs Locally.
Validate
biosimulant labs validate ./my-labTo validate and build release packages, see Package & Publish.