Spectre.Operation.Definition (Spectre v0.3.0)

Copy Markdown View Source

Versioned definition loaded from a Work, Vigil or external controller.

The definition is code-owned discovery data. Checkpoints retain only its controller module, stable identity and version, then resolve it again after restart. Directive Definitions may explicitly grant can_start: [:work]; trigger correlation and public projection policy remain declarative parts of the Definition.

Summary

Functions

Decides whether a stored checkpoint contract is compatible with the current one.

Resolves the definition exposed by a controller module, trying __spectre_loop_definition__/0 first and then definition/0.

Builds a validated definition from a struct, map or keyword list.

Fetches the registered operation spec for id.

Checks every invariant of the definition, including portability of its declarative data and validity of every registered operation spec.

Same as validate/1 but returns the definition on success and raises ArgumentError on failure.

Types

t()

@type t() :: %Spectre.Operation.Definition{
  artifact_policy: map(),
  blockers: [atom() | String.t()],
  branches: %{optional(atom() | String.t()) => [atom() | String.t()]},
  budget: Spectre.Operation.Budget.t(),
  can_start: [:work],
  checkpoint: term(),
  id: atom() | String.t(),
  imports: [atom() | String.t()],
  input: Spectre.Operation.Spec.validator(),
  kind: :work | :vigil | :directive,
  metadata: map(),
  on_budget_exhausted: term(),
  operations: %{optional(atom() | String.t()) => Spectre.Operation.Spec.t()},
  security: map(),
  state: Spectre.Operation.Spec.validator(),
  triggers: [atom()],
  update: Spectre.Operation.Spec.validator(),
  update_fields: [:all | atom() | String.t()],
  version: pos_integer() | String.t(),
  waits: [atom()]
}

Functions

compatible?(controller, stored, current)

@spec compatible?(module(), term(), term()) :: boolean()

Decides whether a stored checkpoint contract is compatible with the current one.

Equal contracts are always compatible; otherwise the controller's optional checkpoint_compatible?/2 is consulted. Any crash in the callback counts as incompatible.

load(controller)

@spec load(module()) :: {:ok, t()} | {:error, term()}

Resolves the definition exposed by a controller module, trying __spectre_loop_definition__/0 first and then definition/0.

Any raise or throw from the controller is captured and returned as a tagged {:error, reason} tuple, never propagated.

new(definition)

@spec new(t() | map() | keyword()) :: t()

Builds a validated definition from a struct, map or keyword list.

Operation entries are normalized into a map of Spec.t() keyed by operation id. Raises ArgumentError on invalid attributes or duplicate operation ids.

operation(definition, id)

@spec operation(t(), atom() | String.t()) ::
  {:ok, Spectre.Operation.Spec.t()} | {:error, term()}

Fetches the registered operation spec for id.

Returns {:ok, spec} or {:error, {:operation_not_registered, id}}.

validate(definition)

@spec validate(t()) :: :ok | {:error, term()}

Checks every invariant of the definition, including portability of its declarative data and validity of every registered operation spec.

Returns :ok or {:error, reason} naming the first violated invariant.

validate!(definition)

@spec validate!(t()) :: t()

Same as validate/1 but returns the definition on success and raises ArgumentError on failure.