flow/run/journal

Source: src/flow/run/journal.ts

The journal of a run: one JSON line per fact, appended when it happens and never rewritten, which is what a resume and the live view read back.

The runner writes it through a port, never a reporter: unplug every reporter and the journal is the same. A real run given a run directory appends to journal.jsonl there; one given none writes nowhere; a dry run keeps the entries in an array it hands back. A fact is written once it no longer changes, so branches running together only ever add a line.

JournalEntry

type

export type JournalEntry =
	/** A life of the run began: its first start, or a resume. Written before anything else it does. */
	| { readonly type: "life_start"; readonly startedAt: string }
	| VisitEnd
	/** The `carry` the iteration `path`, `review#2`, reads. */
	| { readonly type: "carry"; readonly path: string; readonly value: unknown }
	/** The list the `map` visit `path` runs over, frozen when it starts. */
	| { readonly type: "map_items"; readonly path: string; readonly items: readonly unknown[] }
	/** An obligation the `verdict:` visit `visit` raised in the ledger of the scope opened at the visit `ledger`: a loop's, or a `map` item's. */
	| { readonly type: "obligation_raised"; readonly ledger: string; readonly visit: string; readonly obligation: Obligation }
	| { readonly type: "obligation_closed"; readonly ledger: string; readonly visit: string; readonly id: string; readonly closure: Closure }
	/** The copy the branch `path` runs in: its directory, git branch and the commit it started from, none in a dry run, which makes no copy. */
	| { readonly type: "copy_opened"; readonly path: string; readonly dir?: string; readonly branch?: string; readonly base?: string }
	/** What landing the branch `path`'s patch gave, once every branch of its block ended. */
	| { readonly type: "copy_landed"; readonly path: string; readonly landed: boolean; readonly refused?: string }
	/** A resume found the copy of the branch `path` gone, or its work not landed: every fact under it before this line is forgotten, and it starts over. */
	| { readonly type: "copy_lost"; readonly path: string; readonly why: string }
	/** The run's own branch, opened by its first commit. */
	| { readonly type: "branch_opened"; readonly branch: string }
	/** How the run ended: what `runFlow` returned, written down. */
	| { readonly type: "run_end"; readonly ok: boolean; readonly output?: unknown; readonly error?: FlowError; readonly path?: string; readonly usage: Usage };

One fact of a run. A path is a visit’s, deliver#2/work[1]/review.

readJournal

function

export function readJournal(runDir: string): JournalEntry[] { /* … */ }

The journal in runDir, in the order it was written; none when the run wrote nothing. A line a crash cut short can only be the last, and it is ignored. Any other line that is not an entry throws: the file was not written by a run.

VisitEnd

type

export type VisitEnd = Extract<VisitEvent, { type: "visit_end" }>;

A visit that ended: its visit_end, written down.