Squidie - durable workflow runtime - 0.3.0 released

Squidie 0.3.0 is out.

Main announcement thread:

Hex: squidie | Hex
GitHub release: Release v0.3.0 · dark-trench/squidie · GitHub
Docs / Livebooks: squidie v0.3.0 — Documentation

Short naming note: Squidie was previously called Squid Mesh. The package, modules, docs, examples, and repository metadata now use the shorter Squidie name.

Squidie is an embedded durable workflow runtime for Elixir/Phoenix and OTP apps. It keeps workflow state in the host app, rather than running as a separate workflow service.

{:ok, run} =
Squidie.start(MyApp.Workflows.Checkout, :manual, %{order_id: “order_123”})

{:ok, _snapshot} =
Squidie.execute_next(owner_id: “checkout-worker-1”)

Current capability shape:

Authored / visual workflows

  • Runtime-authored workflow specs via start_spec/3 and start_spec/4
  • JSON-safe visual editor round trips with Squidie.Workflow.EditorSpec
  • Draft graph previews and editor diffing
  • Host-owned action and guardrail registries
  • UI-friendly run graph serialization
  • Dynamic work preview, record, and schedule APIs
:ok = Squidie.Workflow.EditorSpec.validate_map(editor_map,
  action_registry: registry
)

{:ok, graph} = Squidie.Workflow.EditorSpec.preview_graph(editor_map,
  action_registry: registry
)

Code DSL workflows

  • Spark-backed workflow DSL
  • Durable run history, attempts, retries, approvals (HITL), replay, cancellation, and inspection
  • Squidie.execute_next/1 execution boundary for host-owned workers
defmodule MiddleEarth.Workflows.RingErrand do
  use Squidie.Workflow

  workflow do
    trigger :leave_shire do
      manual()

      payload do
        field :bearer, :string, default: "Frodo"
        field :ring_id, :string
        field :route_preference, :string, default: "moria"
      end
    end

    step :pack_provisions, Hobbiton.Steps.PackProvisions,
      output: :provisions

    step :hide_at_prancing_pony, :pause

    approval_step :council_vote,
      output: :council,
      deadline: [within: 300_000, due_soon: 60_000, escalation: :operator_action]

    step :choose_path, Rivendell.Steps.ChoosePath,
      input: [bearer: [:bearer], decision: [:council, :decision]],
      output: :route

    step :cross_moria, Fellowship.Steps.CrossMoria,
      input: [:bearer, :provisions, :route],
      retry: [max_attempts: 3, backoff: [type: :exponential]],
      deadline: [within: 30_000, due_soon: 5_000, escalation: :diagnostic]

    step :reserve_eagle, Eagles.Steps.ReserveRide,
      compensate: Eagles.Steps.CancelRide

    step :toss_ring, Mordor.Steps.TossRing,
      irreversible: true

    transition :pack_provisions, on: :ok, to: :hide_at_prancing_pony
    transition :hide_at_prancing_pony, on: :ok, to: :council_vote
    transition :council_vote, on: :ok, to: :choose_path
    transition :choose_path, on: :ok, to: :cross_moria
    transition :cross_moria, on: :ok, to: :reserve_eagle
    transition :cross_moria, on: :error, to: :complete, recovery: :undo
    transition :reserve_eagle, on: :ok, to: :toss_ring
    transition :toss_ring, on: :ok, to: :complete
  end
end

Cron-triggered workflows use scheduling declarations:

defmodule Gondor.Workflows.BeaconWatch do
  use Squidie.Workflow

  workflow do
    trigger :nightly_beacon_check do
      cron "0 21 * * *", timezone: "Etc/UTC"

      payload do
        field :beacon_count, :integer, default: 7
      end
    end

    step :inspect_hilltops, Gondor.Steps.InspectHilltops,
      retry: [max_attempts: 3]

    step :light_beacon, Gondor.Steps.LightBeacon,
      compensate: Gondor.Steps.ExtinguishBeacon

    transition :inspect_hilltops, on: :ok, to: :light_beacon
    transition :light_beacon, on: :ok, to: :complete
  end
end


The runtime is executor-agnostic. A simple supervised worker loop can call Squidie.execute_next/1, or a host app can put a backend behind the delivery/lease boundary. Bedrock is a good fit when the app needs backend-owned delivery, delayed visibility, leases, heartbeats, retries, and dead-letter behavior.

Under the hood, Squidie uses a Jido journal runtime: actions, signals, agents, thread journals, checkpoints, storage, and supervised execution are used as runtime primitives, while Squidie exposes workflow-level APIs.

What is new in 0.3.0:

  • Projection-backed run timeline inspection

  • Runtime spec preview execution for visual editors and draft workflow validation

  • Guardrail validator registries for host-approved input, action, and output guardrails

  • Persisted completed guardrail decisions for inspection/explanations

  • Better validation for incompatible guardrail policy/placement combinations and malformed
    guardrail config

  • Structural quality gates in release and CI verification

There are Livebooks for the docs/getting-started path, including workflow creation, durable run execution, inspection, runtime-authored specs, and visual editor round trips.

There is also SquidSonar: GitHub - dark-trench/squid_sonar: Durable Workflow Dashboard · GitHub

SquidSonar is the optional read-only Phoenix LiveView dashboard for Squidie. It can be mounted inside a Phoenix host app to inspect recent runs, filter by status, search runtime metadata, and view run details with diagnosis, history counts, last error information, and workflow graph visualization.

There’s a short example workflow OTP that fetches Elixir CVEs every 15min and posts to a discord channel, for quick reference: GitHub - dark-trench/the-beacon: Plain OTP app for scheduled monitoring and notifications · GitHub

3 Likes