IvoryOS 2.0 preview

No new framework. Just your Python, reflected into a UI.

A note on versions — the IvoryOS in the Nature Communications paper was one app, UI and hardware control together. This page describes 2.0, a from-scratch rearchitecture into the three pieces below. Parts are shipped, parts are still being built, and each section says which.

The three pieces
On the web
Automation Hub

Holds the drivers and their schemas. Where you assemble a stack and design against it.

Next to your instruments
Core

Reflects your drivers into a UI and actually runs them. Works with no network at all.

Above your Cores
Cloud

Coordinates several Cores as one workflow. Early prototype.

01 · The mechanism

Introspection, not integration.

Most orchestration tools need a plugin written against their SDK before they can control an instrument. IvoryOS instead inspects the Python you’ve already written — method names, type hints, docstrings, default values — and builds a matching form automatically. There is no schema to author by hand and no plugin API to keep in sync. Rename a parameter in your driver, and the generated interface updates with it.

Your existing driver
pump.py
def set_flow_rate( self, rate: float ): """mL/min, 0-50""" ...
Generated, automatically
Rate (float) *#flow_rate
mL/min, 0–50
no hand-written schema · no plugin code

This is why onboarding a new instrument is writing normal Python, not learning IvoryOS — and it’s the same mechanism that lets a driver contributed by one lab work, unmodified, in another.

02 · Why a platform at all

You can write the Python. So can a model.

Scientists sweep parameters, engineers write drivers, and models now write workflow code too. The gap is in between: someone has to see what is about to run, before it runs.

And it compounds. The schema closes both gaps by giving all three the same thing to look at.

your-lab-machine.local/designer
pump.set_flow_rate()from your driver
ratefloatsweep 10 → 50, 5 steps
hplc.run_analysis()
duration12.0
balance.read() proposed
Added by the assistant. Review before this run.
generated from your driversv4 · 1 change from v3

One place the workflow lives

Ten experiments in, workflows are usually scattered across notebooks and nobody is sure which version ran last week. Here they are stored, versioned and findable.

A preview before anything moves

Whoever proposed the step — a colleague or an assistant — you see the real parameters and their values before hardware does.

The driver stays the driver

The engineer writes ordinary Python. No interface code to keep in sync, and nothing to rewrite when the workflow changes.

03 · What a workflow can do

Built for what wet-lab automation actually needs.

This is the Optimize page that Core serves beside your instruments. Every field on it maps directly to one of the capabilities on the right, generated from your own driver’s parameters.

your-lab-machine.local/optimize
Optimization Setup20 iterations
Optimizer
Ax (BoTorch)
Batch size
4
Error recovery
Skip
flow_rateOptimize
vial_indexPer-Iteration
Configured in the table below
Objective vs. iteration
trialcurrent best

Prep / Main / Cleanup phases

Setup and teardown steps run once per workflow; the main sequence is what repeats, gets batched, or gets optimized.

Batch-aware execution

Mark a step as “per-sample” or “batch.” A batch step runs once per group of N samples — for equipment that processes several samples at once — instead of once per row.

Closed-loop optimization

Ax, BayBE, and NIMO are wired in behind one suggest/observe interface, with parallel-trial batches, live convergence plots, and per-objective early-stop criteria.

Human-in-the-loop pauses

A workflow can pause and ask a person for a value — load a sample, confirm a reading — then resume exactly where it left off, from any device on the network.

Full run history

Every run, step, phase, and parameter is recorded to SQLite or Postgres — queryable later, not just streamed to a CSV and forgotten.

Typed, validated parameters

Every generated form inherits your driver's real type hints, so a string typed into a float field is caught before it ever reaches your hardware.

Early prototype
04 · Cloud

When one queue stops being enough.

Core already coordinates every instrument on its own network, but as one linear workflow, one queue, at a time. That holds until a lab has two things that need to happen on their own clocks. These are the three cases that made us start building Cloud.

Two cadences, one workflow

One station needs a step every four minutes, the next every five. Core runs one queue, so today they take turns. Cloud lets each keep its own timeline.

A sample that moves

Synthesis on one platform, analysis on another, and a physical transfer in between. The handoff is the part that has to be scheduled, and the run and its data have to travel with the sample.

An instrument two platforms share

A lightly used instrument rarely deserves its own platform. Give it its own Core and both sides reserve time on it, instead of discovering the conflict when an arm is already moving.

What it never touches

Drivers. Every one still runs in-process inside its own local Core, and Cloud only ever talks to a Core’s API. Hardware control stays exactly as local as it is today, and a lab keeps working if Cloud is unreachable.

Where it actually stands

The dashboard exists. The cross-Core orchestration protocol does not yet. This is the least mature part of 2.0 and the furthest from a release — the three cases above are why we are building it, not a description of what runs today.

05 · Automation Hub

Design your lab before you install a thing.

A directory of instrument drivers, optimizer plugins and workflow templates, contributed by the community. Because every contributed driver is introspected once and its schema stored, picking a stack and opening a working Designer are the same click — with nothing installed and no instrument on the bench.

Next.js + Supabase
Open driver registry
Stored schemas

A driver is contributed

Someone shares a Python driver to the Hub, which registers its install metadata: the package, its constructor arguments, how to launch it.

Its schema is captured too

The same introspection Core runs against real hardware runs once against the contributed driver, and the resulting schema is stored on the row beside it.

The Designer opens on it

Pick a stack and the full Designer opens in your browser, forms and all. It only ever needed the schema, never a live connection.

Architecture | IvoryOS