Concepts

Automations

An automation is the durable process you build in Mobius. It has a name, a handle, a concurrency policy, one or more triggers, and an ordered list of steps. Every execution is a run against one frozen version of the automation.

Automation (latest_version, published_version)
  └── AutomationVersion 1, 2, 3, ...
        └── AutomationRun 1, 2, ...
              └── steps, events

What goes in a spec

Five things matter, in roughly this order of importance:

  1. Triggers. What starts a run.
  2. Steps. What the run does.
  3. Concurrency policy. What happens when a trigger fires while a prior run is in flight.
  4. Default agent and default inputs. Convenience defaults for steps that don't override.
  5. Tags. For organization (env: prod, owner: platform).

Here's a realistic spec:

name: Triage GitHub issues
handle: triage-issues
default_agent_id: agt_triager
settings:
  concurrency:
    policy: queue        # allow | forbid | replace | queue
    max: 5
triggers:
  - kind: event
    event_type: github.issue.created
    config:
      repos: ["deepnoodle-ai/api"]
steps:
  - name: classify
    type: agent
    prompt: |
      Classify this issue. Return JSON: {label, severity, summary}.
      Issue: {{ .inputs.issue.title }}\n\n{{ .inputs.issue.body }}
    save_as: triage
  - name: approve
    type: interaction
    kind: request_approval
    title: "Apply label '{{ .context.triage.label }}'?"
    target_user_ids: ["usr_oncall"]
    expires_at: 1h
    on_timeout: skip
  - name: label
    type: action
    action: github.add_label
    with:
      issue_number: "{{ .inputs.issue.number }}"
      label: "{{ .context.triage.label }}"

Three steps, one trigger, one human checkpoint. Most useful automations don't need much more shape than this.

Step types

TypeWhat it does
agentOne bounded agentic turn with tools.
actionOne deterministic call into a worker or platform action.
sleepSuspends the run for a time or duration.
wait_for_eventSuspends until a matching source event arrives.
interactionSuspends until a targeted human/agent interaction resolves.

Steps run in order. Each step's output lands in the run context under the step name (or save_as), so later steps can reference it like {{ .context.classify.summary }} or {{ .context.triage.label }}.

Picking a concurrency policy

This is the choice that catches most new users. The runtime applies the policy when a trigger fires while a previous run on the same automation is still active.

PolicyUse it when
allow (default)The work is independent per run. Event-driven triage usually wants this.
forbidA second run would be wasteful or destructive. Most nightly cleanups.
replaceOnly the latest input matters. "Sync to upstream"-style automations.
queueOrder matters and you want all of them to run. Cap with max.

If you don't know which to pick, default to allow and tighten it the first time you see overlapping runs cause trouble.

Versions

Every edit produces a new version. Versions are immutable: once a run starts on v3, it executes v3 forever, even if you publish v4 halfway through. That matters when you're rolling out a risky change.

The workflow:

# Inspect
mobius automations list
mobius automations get triage-issues
mobius automations list-versions triage-issues
 
# Iterate
mobius automations create-version triage-issues --file spec.yaml
mobius automations publish-automation-version triage-issues 4

Publishing flips the new version to published, sets it as the automation's published_version, and marks the previous published version superseded. Existing runs keep running on whatever version they started.

Status

Automations have four statuses:

StatusMeaning
draftNo published version yet. You can still start test runs against the latest draft.
activePublished version executes on triggers and API starts.
pausedTriggers are suppressed. In-flight runs keep going.
archivedSoft-deleted. History is readable; new runs are rejected.

Pause an automation before doing a risky change. Archive it when it's genuinely done.

Common CLI operations

mobius automations list
mobius automations get triage-issues
mobius automations list-runs --automation-id aut_01...
mobius automations start-automation-run triage-issues --inputs @issue.json
mobius automations update triage-issues --file spec.yaml
mobius automations delete triage-issues          # archives, doesn't drop history