Spectre.Lifecycle (Spectre v0.3.0)

Copy Markdown View Source

Pure lifecycle state machine for effects and policy awaitables.

Every operation validates its source state and returns an immutable Spectre.Transition. Capability execution remains outside this module.

Summary

Functions

Applies one canonical lifecycle command.

Moves a waiting effect to approved. The separate awaitable resolution is retained for compatibility with callers that attach their own policy label.

Cancels all non-terminal pending effects and open awaitables.

Cancels pending lifecycle work owned by one Run.

Completes an executable pending effect, or returns its stored terminal transition when completion is repeated.

Expires an open policy and cancels its gated work atomically.

Fails an executable pending effect, with repeat-safe terminal replay.

Projects a result to the single next host decision.

Records one unmatched policy response without resolving the policy.

Returns the canonical lifecycle projection used by results and turns.

Removes a stale pending copy when the same effect already has a terminal history entry. No capability is invoked and the stored outcome is replayed.

Resolves the active policy and its gated effect atomically.

Resolves one explicitly identified policy awaitable.

Stages one effect and optionally opens its policy awaitable.

Types

command()

@type command() ::
  {:stage_effect, Spectre.Effect.t(), term()}
  | {:approve_effect, term()}
  | {:complete_effect, term(), term()}
  | {:fail_effect, term(), term()}
  | {:cancel_pending, term()}
  | {:cancel_pending, term(), String.t()}
  | {:resolve_policy, :accept | :reject, atom()}
  | {:resolve_policy, term(), :accept | :reject, atom()}
  | {:policy_attempt, term()}
  | {:expire_policy, term()}
  | {:replay_effect, term()}
  | {:replace_awaitable, Spectre.Awaitable.t()}
  | :clear_open_awaitables
  | :clear_pending

result()

@type result() :: {:ok, Spectre.Transition.t()} | {:error, term()}

Functions

apply(state, command)

@spec apply(Spectre.State.t(), command()) :: result()

Applies one canonical lifecycle command.

The named functions below remain available for compatibility, while this entry point gives policy, runner, execution, and hosts one command surface.

approve_effect(state, effect_id)

@spec approve_effect(Spectre.State.t(), term()) :: result()

Moves a waiting effect to approved. The separate awaitable resolution is retained for compatibility with callers that attach their own policy label.

cancel_pending(state, reason \\ :cancel_pending)

@spec cancel_pending(Spectre.State.t(), term()) :: result()

Cancels all non-terminal pending effects and open awaitables.

cancel_pending(state, reason, run_id)

@spec cancel_pending(Spectre.State.t(), term(), String.t()) :: result()

Cancels pending lifecycle work owned by one Run.

complete_effect(state, effect_id, result)

@spec complete_effect(Spectre.State.t(), term(), term()) :: result()

Completes an executable pending effect, or returns its stored terminal transition when completion is repeated.

expire_policy(state, awaitable_id)

@spec expire_policy(Spectre.State.t(), term()) :: result()

Expires an open policy and cancels its gated work atomically.

fail_effect(state, effect_id, reason)

@spec fail_effect(Spectre.State.t(), term(), term()) :: result()

Fails an executable pending effect, with repeat-safe terminal replay.

next(result)

Projects a result to the single next host decision.

policy_attempt(state, awaitable_id)

@spec policy_attempt(Spectre.State.t(), term()) :: result()

Records one unmatched policy response without resolving the policy.

projection(result)

@spec projection(Spectre.Result.t()) :: map()

Returns the canonical lifecycle projection used by results and turns.

replay_effect(state, effect_id)

@spec replay_effect(Spectre.State.t(), term()) :: result()

Removes a stale pending copy when the same effect already has a terminal history entry. No capability is invoked and the stored outcome is replayed.

resolve_policy(state, kind, label)

@spec resolve_policy(Spectre.State.t(), :accept | :reject, atom()) :: result()

Resolves the active policy and its gated effect atomically.

resolve_policy(state, awaitable_id, kind, label)

@spec resolve_policy(Spectre.State.t(), term(), :accept | :reject, atom()) :: result()

Resolves one explicitly identified policy awaitable.

stage(state, effect, policy \\ nil)

@spec stage(Spectre.State.t(), Spectre.Effect.t(), term()) :: result()

Stages one effect and optionally opens its policy awaitable.