Skip to content

Operators

An operator executes one workflow node — a dataset scan, a GPU job, a registry push, an eval. Operators are the only things that touch tools, and every one of them inherits the budget, policy gate, and audit automatically. The full list ships in the operators catalog.

An operator is a class implementing Operation[I, O], registered under the single entry-point group cairn.operators with a stable capability name like dataset/pii_scan or model/register. It declares:

  • input_schema / output_schema — Pydantic models (required).
  • config_schema — optional deployment-tunable knobs, each tagged with a scope: governance (environment-owned, lockable) or operational (workflow/run-tunable; the default for untagged fields). See Configuration.
  • Behavior flags (all default off): long_running, requires_gpu, supports_cancel, supports_heartbeat, supports_mock (a .mock() path for --mock runs), side_effect_free, sandbox_safe (Playground rules).
  • Lifecycle methods: run() (required), plus optional mock(), cancel(), heartbeat().

In pack.toml, each operator additionally declares a risk class (read_only / external_write / production_mutation / paid_compute), its executors (in_process, mcp_tool, remote_job, …), and whether it requires_approval — a durable HITL gate fires before it runs.

Operators get an OperationContext with exactly what they need: artifact store, secret store (values by reference, never printed), metrics, cost ledger, a resolved compute connection for remote jobs, and a logger. They cannot read other nodes’ outputs, touch graph state, spawn operators, or reach the runtime directly — that boundary is what makes them swappable and auditable.

A template names a capability; the active profile’s [profile.bindings] decides which operator satisfies it. Bind storage.put to the local filesystem in dev and to S3 in production — the template is unchanged. The same seam backs the substrate services: memory, RAG search/parse/rerank, redaction, audit sink, secrets, notifications.

Operators degrade explicitly rather than silently: heavy backends are optional extras with deterministic fallbacks, and outputs carry flags (e.g. checked=false, backend_used) when a lighter path ran. The catalog documents each operator’s default behavior — including which ones sample, stub, or no-op without their extra — so a deployment can be configured fail-closed where it matters.

Terminal window
cairn init operator my_ops --op my/thing

scaffolds an operator pack (a wheel bundling one or more operators) with the entry-point wiring, schemas, and a test skeleton in place.