Skip to content

Capabilities

A capability is a semantic operation that an executor can perform. Executors include instruments, robots, humans, compute systems, analysis routines, optimizers, and simulators.

A capability definition includes its identifier, version, executor type, input and output schemas, resource requirements, side effects, risk class, timeout, retries, retry safety, cancellation support, and simulation status.

Two of those fields are declared but not yet acted on. version is recorded and never read: a workflow step names a capability by identifier only and cannot request a version. supports_cancellation has no reader in the runtime. See compatibility and versioning.

Workflows use the capability identifier. Adapters own vendor or transport details. This allows the same workflow to use a simulator, staging device, or production integration through configuration.

Retry safety

A capability declares what the runtime may do when it dispatched an operation and cannot establish whether the dispatch took effect. That is the only moment the question is asked, and it is the moment the runtime used to guess — differently in two places.

retry_safety Repeat a failed dispatch? A timed-out task is recorded
repeatable Yes, within max_retries failed, and so resumable
repeatable_if_not_dispatched Only on proof that nothing was dispatched intervention_required
not_repeatable Never intervention_required

The default is not_repeatable. A definition that says nothing has told the runtime nothing, and the only reading of nothing that cannot cause an incident is the strictest one. A simulator or a pure computation should declare repeatable; a capability that moves, dispenses or heats should not.

Declaring max_retries above zero together with not_repeatable is refused when the definition is constructed. The two fields are one statement, and a runtime that silently resolved the contradiction is how a declared budget becomes a surprise at an instrument.

repeatable_if_not_dispatched needs evidence or it collapses into one of the other two. That evidence is NotDispatchedError, which an adapter raises when the command provably never left the client — a refused connection, a rejected handshake. Nothing verifies the claim; it is the adapter's statement about its own transport. A timeout is never such evidence: the runtime stopped waiting, which establishes nothing about the equipment.

This is the retry safety SAFETY.md requires an operational adapter to define. It could not be expressed before.

Adapter contract

An adapter exposes capability definitions, execution, health, start and close lifecycle hooks, and conformance cases. The registry calls start and close around the process lifetime. Public adapters are discovered through the opensdl.adapters entry-point group. See add an adapter for the full path from generation to a running workflow.

CapabilityAdapter also declares abort(request_id), which is reserved and not wired. The runtime has no cancellation path, so nothing calls it and the base implementation returns False. An adapter that implements it is writing code that will not run until a cancellation path exists. Do not treat it as a stop mechanism, and do not let a laboratory's ability to halt an operation depend on it. A physical stop comes from the deployment's own protective systems. See SAFETY.md.

Explicit cancellation and abort receipts are v0.2 work on the roadmap.