SagaJournal

interface SagaJournal<P>

Pluggable append-only event log for saga executions.

Each saga run appends entries in the following lifecycle order:

  1. EntryPhase.Started — emitted once, seq = 0.

  2. EntryPhase.Intent / EntryPhase.Effect — one pair per successful step.

  3. EntryPhase.Compensation — for each step rolled back (with JournalEntry.reverses set).

  4. EntryPhase.Terminal — emitted once as the final entry.

Implementation contract

Implementations MUST:

  • Be thread-safe — multiple concurrent saga runs may append simultaneously.

  • Preserve insertion order within a single RunId.

  • Assign monotonic, gapless seq values within a RunId starting at 0.

  • Treat payload bytes as opaque — never inspect or transform them.

Implementations SHOULD:

  • Make append durable before returning JournalOutcome.Ok (audit-grade consumers depend on it).

  • Respect coroutine cancellation in all suspend operations.

All operations return JournalOutcome instead of kotlin.Result to avoid historical compiler restrictions on kotlin.Result in suspend-interface positions (critic A2 HIGH).

Parameters

P

Payload type. InMemorySagaJournal stores P directly; persistent adapters use a PayloadCodec to convert to/from ByteArray.

Inheritors

Functions

Link copied to clipboard
abstract suspend fun append(entry: JournalEntry<P>): JournalOutcome<AppendedEntry<P>>

Appends entry to the journal.

Link copied to clipboard
abstract suspend fun head(runId: RunId): JournalOutcome<ChainHead?>

Returns a ChainHead pointing at the last appended entry for runId, or null if runId is unknown.

Link copied to clipboard
abstract suspend fun read(runId: RunId): JournalOutcome<List<JournalEntry<P>>>

Returns all entries for runId in insertion order.

Link copied to clipboard
abstract suspend fun since(runId: RunId, seq: Long, limit: Int): JournalOutcome<List<JournalEntry<P>>>

Returns up to limit entries for runId whose JournalEntry.seq>= seq.

Link copied to clipboard
suspend fun <P> SagaJournal<P>.verify(runId: RunId, fromSeq: Long = 0, toSeq: Long = Long.MAX_VALUE, pageSize: Int = DEFAULT_VERIFY_PAGE_SIZE): JournalOutcome<VerifyResult>

Verifies the tamper-evident hash chain for runId over entries with seq in [fromSeq, toSeq].