Skip to content

Journal & resume

packages/core/src/journal.ts

A run persists every agent result as JSONL, keyed by its sequence number. Crash, kill, or edit-and-rerun: the longest unchanged prefix replays from disk in milliseconds and burns zero model calls. Drag the crash point below and hit resume — journaled entries (green) flash back instantly; only the fresh ones (amber) spawn a model.

seq 0agent("scan repo for smells")1200 tokjournal hit
seq 1agent("rank by severity")800 tokjournal hit
seq 2agent("verify bug #1")1500 tokjournal hit
seq 3agent("verify bug #2")1500 tok
seq 4agent("synthesize report")2100 tok
resume control
49%
replayed free
3600
tokens still spent

Same-session, same script + args ⇒ 100% cache hit. The first edited/new agent() call and everything after it runs live.

How the cache hit works

The journal is a Map<seq, entry>. On a fresh run it starts empty; on resume it's seeded from the persisted JSONL, so lookup(seq) returns a hit for everything that completed before the crash. Step 4 of the agent lifecycle returns that cached value immediately, before any adapter is touched.

js
export function createJournal(seed = []) {
  const bySeq = new Map();
  for (const e of seed) bySeq.set(e.seq, e);   // ← resume seeds from persisted JSONL
  return {
    lookup: (seq) => bySeq.get(seq),
    record: (entry) => { bySeq.set(entry.seq, entry); },
    entries: () => [...bySeq.values()].sort((a, b) => a.seq - b.seq),
  };
}

Resume rules

  • Same session, same script + args ⇒ 100% cache hit. Nothing re-runs.
  • Editing the script invalidates from the first changed agent() call onward — that call and everything after it runs live, because their recorded results no longer match.
  • Determinism is the precondition. If your script branched on Math.random() or wall-clock time, the seq order would differ on replay and the journal would line up against the wrong calls. That's why the sandbox bans those outright.

Runs are stored under ~/.workflow/runs/{runId}/ as the event log + journal. That on-disk pair is the source of truth that powers defineworkflow watch, defineworkflow resume, and defineworkflow save.

Built from the source of @workflow/{schema,core,adapters,cli,ui}.