# `Squidie.Workflow`
[🔗](https://github.com/dark-trench/squidie/blob/main/lib/squidie/workflow.ex#L2)

Declarative workflow contract for Squidie workflow modules.

## Example

    defmodule Billing.InvoiceReminder do
      use Squidie.Workflow

      workflow do
        trigger :invoice_delivery do
          manual()

          payload do
            field :account_id, :string
            field :invoice_id, :string
          end
        end

        step :load_invoice, Billing.Steps.LoadInvoice
        step :send_email, Billing.Steps.SendReminderEmail, retry: [max_attempts: 3]

        transition :load_invoice, on: :ok, to: :send_email
      end
    end

The contract defined here captures workflow structure. Validation and runtime
execution behavior are added in subsequent slices.

# `__before_compile__`
*macro* 

```elixir
@spec __before_compile__(Macro.Env.t()) :: Macro.t()
```

Validates the collected workflow declarations and emits runtime accessors.

# `__resolve_runtime_definition__`

```elixir
@spec __resolve_runtime_definition__(map()) :: map()
```

Resolves late-bound runtime metadata for generated workflow definitions.

Workflow modules store a compile-time definition, but step modules may expose
Squidie step metadata that should be read when the workflow definition is
consumed. This keeps generated workflow modules small while preserving the
runtime contract used by dispatch and inspection.

# `__using__`
*macro* 

```elixir
@spec __using__(keyword()) :: Macro.t()
```

Injects the workflow DSL into a workflow module.

# `action_catalog`

```elixir
@spec action_catalog(term()) ::
  {:ok, [Squidie.Workflow.ActionRegistry.catalog_entry()]}
  | {:error,
     {:invalid_action_catalog,
      [Squidie.Workflow.ActionRegistry.catalog_error()]}}
```

Projects a host-owned action registry into editor-safe action catalog metadata.

The catalog includes stable action keys, display metadata, contracts, enabled
state, and credential requirements without exposing executable modules or
credential values. Use `validate_spec/2` or `resolve_spec_actions/2` with the
same registry before activating runtime-authored specs.

# `guardrail_catalog`

```elixir
@spec guardrail_catalog(term()) ::
  {:ok, [Squidie.Workflow.GuardrailRegistry.catalog_entry()]}
  | {:error,
     {:invalid_guardrail_catalog,
      [Squidie.Workflow.GuardrailRegistry.catalog_error()]}}
```

Projects a host-owned guardrail registry into editor-safe catalog metadata.

# `resolve_spec_actions`

```elixir
@spec resolve_spec_actions(
  Squidie.Workflow.Spec.t() | map() | term(),
  keyword()
) ::
  {:ok, Squidie.Workflow.Spec.t() | map()}
  | {:error, {:invalid_workflow_spec, [map()]}}
```

Resolves runtime-authored `:action` step keys to host-approved modules.

# `to_spec`

```elixir
@spec to_spec(module()) ::
  {:ok, Squidie.Workflow.Spec.t()}
  | {:error, Squidie.Workflow.Definition.load_error()}
```

Converts a compiled workflow module into Squidie's normalized workflow spec.

# `validate_spec`

```elixir
@spec validate_spec(Squidie.Workflow.Spec.t() | map() | term()) ::
  :ok | {:error, {:invalid_workflow_spec, [map()]}}
```

Validates a normalized workflow spec without resolving workflow or step modules.

This validates the structural contract used by Squidie planner state. It
does not prove that arbitrary module atoms are owned by the host application
or executable as runtime-authored workflow code.

# `validate_spec`

```elixir
@spec validate_spec(
  Squidie.Workflow.Spec.t() | map() | term(),
  keyword()
) :: :ok | {:error, {:invalid_workflow_spec, [map()]}}
```

Validates a normalized workflow spec after resolving host-approved action keys.

Runtime-authored specs can use stable `:action` keys instead of raw module
atoms when the host provides an `:action_registry`. Module-authored workflow
specs without action keys keep using the normal validation path.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
