<!-- Source: https://docs.biosimulant.com/references/library/lab-manifest -->

# lab.yaml Schema

`lab.yaml` describes a composed simulation: model instances, wiring, runtime, and optional child labs.

`README.md` is the companion human-readable description for a lab root. Place it beside `lab.yaml`; Biosimulant shows it in the lab About view when present.

## Schema

```yaml
schema_version: "2.0"
title: string
description: string

models:
  - path: string
    alias: string
    parameters: object
  - package: string
    version: string
    alias: string
    parameters: object
    # A matching biosimulant.lock entry is required.

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
```

## 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`.

```yaml
runtime:
  duration: 10.0
  communication_step: 0.1
  settle_steps: 0
```

Set input values at run time through the run modal or run payloads. Use
parameters for persistent scalar defaults that belong in the lab manifest.

Use `settle_steps` when downstream modules should consume outputs produced at
the final simulation boundary. For example, a one-step docking model wired to a
separate visualisation module usually needs `settle_steps: 1`; a
producer-to-postprocessor-to-visualisation chain needs `settle_steps: 2`.
Settling does not extend simulated time.

The old external tick field is not supported.

## Lab README

Each root lab and each owned child lab can include a `README.md` next to its own `lab.yaml`:

```text
my-lab/
  lab.yaml
  README.md
  owned/
    labs/
      child-lab/
        lab.yaml
        README.md
```

Use the README for context that belongs to the lab as a working artifact: purpose, assumptions, input and output notes, interpretation guidance, citations, and operational caveats. Web reads this file into the About tab for packaged labs, and Desktop can edit it from **About Lab**. If the file is missing, Biosimulant falls back to generated details from `lab.yaml`.

For screenshots or other README images, place the files under the lab root, usually in `assets/`, and reference them with relative Markdown paths such as `![Run results](assets/results.png)`. Avoid base64-embedded images in README files; keep the Markdown text small and let the package carry the image files separately. Use subfolders under `assets/` only when the files are specific to one purpose.

## Models

Each `models[]` entry creates one module instance in the lab.

| Field | Meaning |
|-------|---------|
| `path` | Relative path to a local model directory |
| `package` + `version` | Published package reference |
| `alias` | Unique name used in wiring |
| `parameters` | Constructor overrides merged into `biosim.init_kwargs` |

For package-backed models, `package` uses `namespace/name` and `version` is the exact SemVer package version. This pair is equivalent to the CLI ref `namespace/name@x.y.z`; for example, `package: biosimulant/predation` with `version: 1.2.0` resolves as `biosimulant/predation@1.2.0`.

When Desktop hydrates a package-backed model dependency, it persists the package metadata and caches the exact requested version under `.bsimcache`.

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:

```yaml
wiring:
  - from: retina.visual_stream
    to:
      - lgn.retina
  - from: lgn.thalamus
    to:
      - sc.vision
```

Fan-out is supported by listing multiple destinations under `to`.

## Composability

Expose lab-level ports with an `io` block:

```yaml
io:
  inputs:
    - name: stimulus
      maps_to: neuron.current
  outputs:
    - name: spike_train
      maps_to: recorder.spikes
```

Parent labs wire to `child_alias.external_port_name`.

## Nested child labs

```yaml
children:
  - path: ../labs/microcircuit
    alias: circuit_a
    parameters: {}
```

Children can be addressed in wiring just like models:

```yaml
wiring:
  - from: stim.current
    to:
      - circuit_a.stimulus
```

Package-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](/how-to/library/compose-hub-labs-locally).

**Info:**

  For portable local package builds, prefer path-based embedded dependencies. Hub package references are primarily for hosted or Hub-backed workflows, and they require an explicit version instead of falling back to `latest`.

## See Also

- [How to Write a lab.yaml](/how-to/library/write-lab-manifest)
- [Compose Nested Labs](/how-to/library/compose-nested-labs)
- [model.yaml Schema](/references/library/model-manifest)
