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_idand 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/3remains inspection-only;schedule_dynamic_work/3must 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/3requires 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_idfor workers when possible. - Use
heartbeat_interval_msonSquidie.execute_next/1for 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
:waitmust 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/1claim, 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.Signalas the Squidie-native command envelope for runtime control. - Public control APIs and
Squidie.apply_signal/2must apply signals through the journal runtime, including starts, cron starts, replays, cancellation, and manual controls. - Use
Squidie.Runtime.Signal.JidoAdapteronly at the Jido interop boundary for agents, routers, or other Jido primitives. Do not leak rawJido.Signalinto normal workflow authoring. - Preserve
:run_signal_receivedcommand 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.Storageas 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_storagefrom request input.