Squidie Runtime Usage Rules

Copy Markdown View Source

Journal Runtime

  • Treat the Jido journal runtime as the only execution path.
  • Treat journal entries as the durable source of truth.
  • Treat checkpoints as rebuild accelerators, not authority.
  • Preserve ordered per-thread appends and optimistic conflict detection.
  • Rebuild workflow and dispatch projections from persisted facts after conflicts, restarts, or checkpoint loss.
  • Keep claim_id and claim-token fences on heartbeat, completion, and failure.
  • Store only claim token hashes in durable entries.
  • Apply completed dispatch results to the run thread only after completion is durable in the dispatch thread.
  • Preserve terminal-run fencing: later claims, completions, manual actions, or wakeups for a terminal run must not mutate terminal state.
  • Preserve child-run lineage as durable journal facts. Child starts must be idempotent for the parent run, parent step, child workflow, child trigger, and child_key.
  • Preserve dynamic-work records as validated journal facts. record_dynamic_work/3 remains inspection-only; schedule_dynamic_work/3 must append the dynamic-work fact and planned runnable intents together before dispatch scheduling.
  • Reject missing, unknown, disabled, or incompatible dynamic node action keys before scheduling executable dynamic work. schedule_dynamic_work/3 requires the host-owned :action_registry.
  • Require the dynamic-work origin runnable to be applied before scheduling executable dynamic nodes.
  • Treat dynamic edges as inspection metadata until dependency-ordered dynamic scheduling is explicitly implemented.
  • Treat scheduled dynamic nodes as replay-unsafe by default unless a future API persists a stronger host-owned recovery policy.

Execution

  • Execute visible work through Squidie.execute_next/1.
  • Use a stable owner_id for workers when possible.
  • Use heartbeat_interval_ms on Squidie.execute_next/1 for long-running steps that may exceed the journal claim lease window. Keep intervals at or above the runtime minimum and large enough to avoid unnecessary journal write volume.
  • Keep internal execution controls private; public callers must not pass claim tokens or private runner options.
  • Keep external backend leases separate from journal claim leases; Bedrock, Oban, or another host scheduler must renew its own delivery lease if needed.
  • Retry scheduling must be durable journal intent with a future visible_at.
  • Built-in :wait must create delayed journal intent instead of sleeping in a worker.
  • Deferred continuation must persist a same-step planned runnable with deferred metadata and future visible_at; it must not be represented as failure or consume retry budget.
  • Cancellation, replay, pause, approval, rejection, and unblock behavior must append durable facts before exposing success.
  • Starting a child run must append parent lineage and start the child as one repairable journal operation; stale parent contexts and terminal parent runs must be rejected at the boundary.
  • Previewing or recording dynamic work must not schedule dispatch attempts, change dependency readiness, or mutate terminal-state decisions.
  • Scheduling dynamic work must use durable planned runnable intents and the normal Squidie.execute_next/1 claim, completion, failure, and application path.
  • Dynamic node retry must be persisted in the planned runnable metadata; do not recover retry behavior from current host code alone.
  • Terminal runs must reject new dynamic-work previews, records, and schedules.

Runtime Command Signals

  • Treat Squidie.Runtime.Signal as the Squidie-native command envelope for runtime control.
  • Public control APIs and Squidie.apply_signal/2 must apply signals through the journal runtime, including starts, cron starts, replays, cancellation, and manual controls.
  • Use Squidie.Runtime.Signal.JidoAdapter only at the Jido interop boundary for agents, routers, or other Jido primitives. Do not leak raw Jido.Signal into normal workflow authoring.
  • Preserve :run_signal_received command history for applied commands.
  • Reusing an idempotency key means duplicate delivery. A different idempotency key is a different command and must not be silently collapsed.

Storage

  • Keep Squidie.Runtime.Journal.Storage as the Squidie-owned storage boundary.
  • Default to Ecto/Postgres-backed Jido storage for documented host setup.
  • Keep the boundary database-agnostic, but require production adapters to provide ordered appends, conflict detection, deterministic replay, durable checkpoint reads, and trusted configuration.
  • Never derive journal_storage from request input.