Skip to main content

usage-rules/workflow-authoring.md

# Squid Mesh Workflow Authoring Usage Rules

## Workflow Shape

- Define workflows as compiled Elixir modules with `use SquidMesh.Workflow`.
- Use business names for triggers, steps, and transitions.
- Keep workflow branches, retries, waits, recovery routes, and manual gates in
  the workflow definition when operators need to understand them.
- Use `SquidMesh.Workflow.to_spec/1` and `SquidMesh.Workflow.validate_spec/1` when tooling needs a
  normalized data representation.
- Do not build runtime-authored workflows from request input.

## Steps

- Prefer `use SquidMesh.Step` for custom steps.
- Return `{:ok, output}` for success.
- Return `{:error, reason}` for terminal failure governed by workflow routing.
- Return `{:retry, reason}` or `{:retry, reason, opts}` for retryable failure.
- Keep side-effect idempotency inside the step or host domain boundary.
- Use raw `Jido.Action` modules only for explicit interop.

## Data Mapping

- Use payload contracts for start input validation.
- Use step `input:` to select only the data a step needs.
- Use step `output:` to place returned data under stable keys.
- Use conditional transitions for inspectable routing decisions.
- Keep condition `equals` values JSON-safe.

## Manual And Long-Running Work

- Use `:pause` or `approval_step/2` for operator-controlled boundaries.
- Resolve manual gates through `unblock_run/3`, `approve_run/3`, and
  `reject_run/3`.
- Use `:wait` for workflow-scale delays, not arbitrary timers.
- Prefer cron or host scheduling when the whole workflow should start later.

## Recovery

- Mark irreversible external side effects with `irreversible: true` or
  `compensatable: false`.
- Use `recovery: :compensation` or `recovery: :undo` on error transitions when
  the route has operational meaning.
- Do not rely on "this step should only run once" as the side-effect safety
  model.