Skip to content

feat(cosim): generic co-simulation plugin surface + cosim-step CLI#471

Draft
w1ne wants to merge 1 commit into
mainfrom
feat/cosim-plugins
Draft

feat(cosim): generic co-simulation plugin surface + cosim-step CLI#471
w1ne wants to merge 1 commit into
mainfrom
feat/cosim-plugins

Conversation

@w1ne

@w1ne w1ne commented Jul 4, 2026

Copy link
Copy Markdown
Owner

What

Adds a generic, domain-neutral co-simulation plugin surface to LabWired: external physical-plant models can be declared in the system manifest and stepped through an adapter, with typed signal routing — independent of any specific device or vendor.

LabWired keeps owning deterministic firmware execution, topology, traces, and fault orchestration; a co-sim model owns the plant approximation behind a clean boundary.

How it fits together

  • Manifest (labwired-config): a cosim_models list with external_process | fmi | mock adapters, inputs/outputs signal-path maps, step_ns, and manifest-relative model paths. validate_cosim_models() enforces a non-empty id, a positive step_ns, and a model for external_process/fmi.
  • Core (labwired-core::cosim): a CosimAdapter trait, StaticCosimAdapter, typed CosimStep/CosimStepResult, an external-process JSONL adapter, and a CosimRunner that steps each model only at its configured boundary and routes model I/O into and out of a signal store.
  • CLI: labwired cosim-step <system.yaml> --set <path>=<value>… builds the runner from a manifest, seeds the signal store, steps the models, and prints routed outputs (table, or --json).
  • Example: examples/cosim-plant-demo — a minimal reduced-order discrete plant that exercises the whole contract (manifest parse → validation → manifest-relative load → adapter → signal routing).
  • Docs: docs/cosimulation_plugins.md.

adapter: fmi intentionally returns a clear "not wired yet" error, marking the next integration seam.

Example

$ labwired cosim-step examples/cosim-plant-demo/system.yaml \
    --set plant.channels.0.enabled=true \
    --set plant.channels.1.enabled=true \
    --set 'scenario.disabled_channels=["channel11"]' --json
[
  {
    "model": "discrete_plant",
    "outputs": {
      "plant.active_channels": 2,
      "plant.output.current": 2.0,
      "plant.output.voltage": 2.0
    }
  }
]

Tests

crates/core/tests/cosim_contract.rs covers the static adapter, the external-process JSONL round-trip, the mock registry, runner step boundaries, signal-path routing, and manifest-relative loading (8 tests). labwired-config gains manifest parse + validation tests.

Verified locally: full workspace cargo test green, cargo fmt --check clean, and clippy -D warnings clean on the touched crates (labwired-core, labwired-config, labwired-cli).

Note

Existing SystemManifest constructors across the workspace gained the new cosim_models field (defaulted to empty) — that accounts for most of the one-line diffs.

🤖 Generated with Claude Code

Adds a domain-neutral co-simulation boundary so external physical-plant
models can be declared in the system manifest and stepped through an adapter,
independent of any specific device or vendor.

- Manifest: `cosim_models` with external_process | fmi | mock adapters,
  typed inputs/outputs signal routing, manifest-relative model paths, and
  validation (non-empty id, positive step_ns, model required for
  external_process/fmi).
- Core: `CosimAdapter` trait, `StaticCosimAdapter`, typed
  `CosimStep`/`CosimStepResult`, an external-process JSONL adapter, and a
  `CosimRunner` that steps models at their configured boundaries and routes
  signals into/out of a signal store.
- CLI: `labwired cosim-step <system.yaml> --set <path>=<value>` builds the
  runner from a manifest and prints routed outputs (table or --json).
- Example: `examples/cosim-plant-demo` — a minimal reduced-order discrete
  plant exercising the full contract.
- Docs: docs/cosimulation_plugins.md.
- Contract tests cover the static/external-process adapters, registry,
  runner boundaries, signal routing, and manifest-relative loading.

Existing SystemManifest constructors gain the new `cosim_models` field.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant