<!-- Generated by scripts/gen-docs.ts from the TSDoc in src/. Do not edit by hand. -->

# `flow/run/journal`

Source: [`src/flow/run/journal.ts`](https://github.com/AI-for-dev/combo/blob/main/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*

```typescript
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 }
	| VisitStart
	| 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*

```typescript
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*

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

A visit that ended: its `visit_end`, written down.

## `VisitStart`

*type*

```typescript
export type VisitStart = Extract<VisitEvent, { type: "visit_start" }>;
```

A visit that started: its `visit_start`, written down, so a reader of the file alone knows what is running.
