---
name: biosimulant-lab-authoring
title: Biosimulant Lab Authoring
description: Create or restructure Biosimulant labs and models with clean manifests, stable layout, explicit wiring, friendly ports, and validation-ready source trees.
version: 2026.05.23
tags: [biosimulant, lab-yaml, model-yaml, authoring, validation]
audience: Claude Code, Cursor, Continue, Aider
recommended: true
---

# Biosimulant Lab Authoring

Use this skill when creating, restructuring, or validating a Biosimulant lab or model source tree.

## Biosimulant Concepts

A Biosimulant lab is a runnable composition. `lab.yaml` defines the world-level runtime, public lab inputs/outputs,
model nodes, and wiring. Each model node points at a `model.yaml` that exposes a Python `BioModule` entrypoint. A
`BioModule` receives typed input signals during `setup()` / `advance_window()` and publishes typed output signals used
by downstream models and visualisations.

Agents should assume a generic model may know nothing about Biosimulant. Start by locating `lab.yaml`, then inspect each
referenced `model.yaml`, then inspect the Python entrypoint and bundled source artifacts.

## Standard Layout

For curated publish-worthy labs, use:

```text
labs/<lab-slug>/
  lab.yaml
  models/
    core/
      model.yaml
      src/
      data/
      tests/
    visualisation/
      model.yaml
      src/
      tests/
  assets/
  README.md
```

Use `models/core` for the primary simulator or executable model. Use `models/visualisation` for visual-only modules.
Avoid a top-level `model/` directory once a lab has a `models/` namespace.

CLI-vendored dependencies may use `owned/models/<alias>`; that is valid for simple CLI labs. Curated model repositories
should prefer `models/core` and `models/visualisation` so package structure, tests, README assets, and validation scripts
stay predictable.

## Lab Folder Names

Use concise, stable, user-facing slugs:

```text
<author><year>-<short-scientific-topic>
```

Examples:

```text
hodgkin1952-classic-huxley-squid-axon
topp2000-glucose-insulin
calzone2007-drosophila-embryo-cell-cycle
```

Avoid generated wrapper names, raw database IDs as the whole slug, and vague names such as `model-1`.

## Manifests

`lab.yaml` composes models, runtime settings, public lab ports, and wiring. `model.yaml` describes one BioModule,
its entrypoint, runtime dependencies, parameters, and ports.

Rules:

- Keep model aliases stable once referenced by `lab.yaml`.
- Use `maps_to` to preserve traceability from public lab ports to model ports.
- Set `runtime.duration`, `runtime.communication_step`, and `runtime.initial_inputs` deliberately.
- Use `runtime.settle_steps: 1` when visualisation modules need final producer outputs.
- Keep upstream source IDs, papers, licenses, source URLs, and export metadata in structured manifest metadata.

Minimal model manifest example:

```yaml
id: hodgkin1952-classic-huxley-squid-axon
runtime:
  kind: python
entrypoint:
  module: src.model
  class: HodgkinHuxleySquidAxon
io:
  inputs:
    - name: initial_membrane_voltage
      type: float
      description: Initial membrane voltage. Maps to CellML variable `membrane.V`.
  outputs:
    - name: state
      type: record
    - name: membrane_voltage
      type: timeseries
```

Minimal lab wiring example:

```yaml
models:
  - id: core
    path: models/core
  - id: visualisation
    path: models/visualisation
wires:
  - from: core.state
    to: visualisation.state
io:
  inputs:
    - name: initial_membrane_voltage
      maps_to: core.initial_membrane_voltage
  outputs:
    - name: membrane_voltage
      maps_to: core.membrane_voltage
```

## Public Inputs And Outputs

Public port names are visible to users. They must be readable `snake_case`, not raw source noise.

Good:

```yaml
- name: initial_membrane_voltage
  label: Initial Membrane Voltage
  maps_to: core.initial_membrane_voltage
  description: Initial value for membrane voltage. Maps to source symbol `Vm`.
```

Bad:

```yaml
- name: v_u
- name: y_y
- name: source_v
```

Only expose inputs that map to real source symbols or implemented scenario controls: parameters, initial conditions,
boundary conditions, stimulus/protocol controls, tensors, files, or documented preprocessing options. Do not expose an
arbitrary internal constant just to make a lab interactive.

If no safe source-backed public input exists, expose no public input and document `no_public_input_deliberate` in the
cleanup plan and README.

## Visualisation Modules

Every kept lab should have a visualisation model unless it is deliberately a headless package.

Visual modules should:

- subclass `BioModule`
- accept core outputs through explicit wiring
- emit non-empty visuals from actual runtime data
- use desktop schemas:
  - timeseries: `data.series[*].points`
  - bar: `data.items: [{"label": str, "value": number}]`
  - scatter: `data.points`
  - table: `data.columns` and `data.rows`
- include a Q/A table with `Scientific question`, `Observed answer`, `Evidence`, `Dominant module`, and `Caveat`
- suppress cards when there is no renderable data

## Validation Checklist

Run before calling a lab ready:

```bash
biosimulant labs validate /absolute/path/to/lab --strict --json
python -m compileall -q labs scripts tests
```

Also run repository-specific tests for:

- zero `labs/*/model` directories in curated repos
- manifests match model `inputs()` and `outputs()`
- entrypoints import and instantiate as `BioModule`
- `setup()` and `advance_window()` emit finite, non-empty outputs
- visualisations emit no empty cards and no wrong schemas
- public port names are friendly and traceable
- README assets exist and are referenced

## Final Acceptance

A lab is authoring-complete only when source layout, manifests, entrypoints, ports, runtime outputs, visuals, README, and
tests are all consistent.
