Docket.Runtime.Moment (docket v0.1.0)

Copy Markdown View Source

Substrate-neutral pre-commit value for exactly one runtime transition.

Initialization, advancement, and graph signals each calculate one moment: the proposed Docket.Run, the runtime events already assigned from the run's sequences, the checkpoint type/metadata for the commit boundary, and an explicit disposition telling the driver what the run needs next. Calculating a moment performs no storage write, no checkpoint delivery, and no telemetry emission.

A moment is not a committed Docket.Checkpoint and carries no storage vocabulary. Drivers own commitment:

  • A durable driver persists the proposed run and assigned events inside its outer storage transaction and, only after transaction success, builds the committed checkpoint with checkpoint/1/context/2 and delivers observers and telemetry. A lost fence or failed event append discards the moment; no committed checkpoint value ever exists for a discarded moment, and observer failure after commit cannot change durable state.
  • The processless Docket.Test shell applies the moment directly and returns its checkpoint as a read-only assertion value. Nothing in the checkpoint path can veto the transition.

Dispositions:

dispositionmeaning
:continuethe run is advanceable now; propose the next moment
{:park, :immediate, reason}commit, then wake immediately
{:park, :external, reason}nothing dispatchable until an external signal (open interrupts)
{:park, {:at, timestamp}, reason}nothing dispatchable before timestamp (earliest retry deadline)
{:park, :terminal, reason}the run is terminal; it never wakes again

{:park, :immediate, reason} is reserved for driver yield boundaries and graph signals; resolving an interrupt produces this disposition unless every active attempt is parked behind a future retry deadline, in which case resolution parks at the earliest deadline.

checkpoint_metadata is the JSON-safe identity envelope shared with the moment's :checkpoint_committed event. It records the checkpoint fence, checkpoint type, committed graph step, park reason, wake disposition, and any active retry-superstep/attempt identity.

Disposition is decided by the runtime core; storage contracts receive only the schedule effect a lifecycle composer derives from it.

Summary

Functions

Builds the committed Docket.Checkpoint value for a moment.

Builds the Docket.Checkpoint.Context for a moment's checkpoint.

Narrows a :continue moment to an immediate driver-yield park.

Types

disposition()

@type disposition() :: :continue | {:park, park_kind(), term()}

event_entry()

@type event_entry() :: %{
  type: Docket.Event.type(),
  step: non_neg_integer(),
  node_id: String.t() | nil,
  channel_id: String.t() | nil,
  task_id: String.t() | nil,
  payload: map()
}

park_kind()

@type park_kind() :: :immediate | :external | {:at, DateTime.t()} | :terminal

t()

@type t() :: %Docket.Runtime.Moment{
  checkpoint_metadata: map(),
  checkpoint_type: Docket.Checkpoint.type(),
  disposition: disposition(),
  events: [Docket.Event.t()],
  pending_attempts: [Docket.Run.PendingWrite.t()],
  proposed_at: DateTime.t(),
  run: Docket.Run.t()
}

Functions

checkpoint(moment)

@spec checkpoint(t()) :: Docket.Checkpoint.t()

Builds the committed Docket.Checkpoint value for a moment.

Production callers build this value only after the moment has durably committed. Docket.Test may build it while driving processless semantics.

context(moment, application \\ %{})

@spec context(t(), map()) :: Docket.Checkpoint.Context.t()

Builds the Docket.Checkpoint.Context for a moment's checkpoint.

application is the host application context configured on the runtime.

yield(moment, reason)

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

Narrows a :continue moment to an immediate driver-yield park.

This is the only sanctioned way for a driver to rewrite a proposed moment's disposition. It accepts exactly a structurally valid moment whose disposition is :continue and returns the same moment parked as {:park, :immediate, reason}, with the checkpoint metadata envelope and the single final :checkpoint_committed event's metadata rebuilt consistently for the new disposition.

Everything else is preserved: the proposed run and its sequences, every event's sequence and timestamp, runtime event payloads, the checkpoint type (a yielded barrier keeps :step_committed or :interrupt_requested), pending-attempt identity, and proposed_at.

A moment that already parks (including terminal) is never overridden and returns {:error, {:not_continue, disposition}}. A malformed moment - missing, duplicated, or misplaced final checkpoint event, or an envelope that does not match that event - returns {:error, :malformed_moment}.