> ## Documentation Index
> Fetch the complete documentation index at: https://codexceed.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# avatar.event_types

Typed lifecycle events — the `HarnessEvent` discriminated union (ADR-0001/0002, Phase 3.0).

The closed, versioned union the engine *emits* and the cockpit *renders*. Unlike
the sync `Emitter`'s raw dicts (`events.py`, kept for back-compat + the CLI), these
are exhaustively matchable and carry a `schema_version` + global `event_id`, so the
journal can round-trip them verbatim and a renderer can switch on `type` safely.

`event_id` / `session_id` / `ts` are *stamped by the bus at publish* (see
`session.EventBus`); a freshly built event carries placeholder defaults until then.

## Classes

### `AgentEnd`

A run has settled to a terminal `outcome` (the stream's end).

```python theme={null}
AgentEnd(*, schema_version: Literal[1] = 1, event_id: int = 0, session_id: str = '', task_id: str | None = None, turn: int | None = None, ts: datetime = <factory>, type: Literal['agent_end'] = 'agent_end', outcome: str | None = None) -> None
```

**Fields**

| Field            | Type                   | Required |    |
| ---------------- | ---------------------- | -------- | -- |
| `schema_version` | `Literal[1]`           | no       |    |
| `event_id`       | `int`                  | no       |    |
| `session_id`     | `str`                  | no       |    |
| `task_id`        | \`str                  | None\`   | no |
| `turn`           | \`int                  | None\`   | no |
| `ts`             | `datetime`             | no       |    |
| `type`           | `Literal['agent_end']` | no       |    |
| `outcome`        | \`str                  | None\`   | no |

### `AgentStart`

A run has begun on `goal`.

`task_kind` is the resolved kind the run opens with; `mode_source` records how it was
decided ("override"/"classifier"/"heuristic", or `None` when the core was driven directly)
so a dogfood journal can distinguish a classifier miss from a classifier outage.

```python theme={null}
AgentStart(*, schema_version: Literal[1] = 1, event_id: int = 0, session_id: str = '', task_id: str | None = None, turn: int | None = None, ts: datetime = <factory>, type: Literal['agent_start'] = 'agent_start', goal: str = '', task_kind: str = '', mode_source: str | None = None) -> None
```

**Fields**

| Field            | Type                     | Required |    |
| ---------------- | ------------------------ | -------- | -- |
| `schema_version` | `Literal[1]`             | no       |    |
| `event_id`       | `int`                    | no       |    |
| `session_id`     | `str`                    | no       |    |
| `task_id`        | \`str                    | None\`   | no |
| `turn`           | \`int                    | None\`   | no |
| `ts`             | `datetime`               | no       |    |
| `type`           | `Literal['agent_start']` | no       |    |
| `goal`           | `str`                    | no       |    |
| `task_kind`      | `str`                    | no       |    |
| `mode_source`    | \`str                    | None\`   | no |

### `ApprovalController`

The awaited control hook the runner consults for a gated (tier-3 `ask`) call.

The controller *announces* the need (an `ApprovalRequested` event) and then blocks
this run only until a control method resolves it — the §13 two-plane boundary.

```python theme={null}
ApprovalController(*args, **kwargs)
```

#### `ApprovalController.request_approval(self, approval_id: str, tool: str, reason: str, tool_input: dict) -> bool`

Announce the gated call and block this run until a control method resolves it.

Args:
approval\_id: Correlates the announcement with its resolution.
tool: The tool name awaiting approval.
reason: The gate's reason, shown to the human.
tool\_input: The proposed call arguments.

Returns:
True iff the call was allowed.

### `ApprovalRequested`

A gated (tier-3 `ask`) call awaits a human decision — announce only (§13).

```python theme={null}
ApprovalRequested(*, schema_version: Literal[1] = 1, event_id: int = 0, session_id: str = '', task_id: str | None = None, turn: int | None = None, ts: datetime = <factory>, type: Literal['approval_requested'] = 'approval_requested', approval_id: str, tool: str, reason: str = '', input: dict = <factory>) -> None
```

**Fields**

| Field            | Type                            | Required |    |
| ---------------- | ------------------------------- | -------- | -- |
| `schema_version` | `Literal[1]`                    | no       |    |
| `event_id`       | `int`                           | no       |    |
| `session_id`     | `str`                           | no       |    |
| `task_id`        | \`str                           | None\`   | no |
| `turn`           | \`int                           | None\`   | no |
| `ts`             | `datetime`                      | no       |    |
| `type`           | `Literal['approval_requested']` | no       |    |
| `approval_id`    | `str`                           | yes      |    |
| `tool`           | `str`                           | yes      |    |
| `reason`         | `str`                           | no       |    |
| `input`          | `dict`                          | no       |    |

### `ApprovalResolved`

A pending approval (`approval_id`) was decided via the control plane.

`via` records who decided: `"human"` answered a prompt, `"grant"` was auto-allowed
by a session-scoped `ApprovalGrant` with no prompt, `"auto"` was auto-denied by an
unattended/batch run's deny-by-default disposition or the approval-timeout backstop
(no human present). All are observable (invariant #5).

```python theme={null}
ApprovalResolved(*, schema_version: Literal[1] = 1, event_id: int = 0, session_id: str = '', task_id: str | None = None, turn: int | None = None, ts: datetime = <factory>, type: Literal['approval_resolved'] = 'approval_resolved', approval_id: str, allowed: bool, via: Literal['human', 'grant', 'auto'] = 'human') -> None
```

**Fields**

| Field            | Type                                | Required |    |
| ---------------- | ----------------------------------- | -------- | -- |
| `schema_version` | `Literal[1]`                        | no       |    |
| `event_id`       | `int`                               | no       |    |
| `session_id`     | `str`                               | no       |    |
| `task_id`        | \`str                               | None\`   | no |
| `turn`           | \`int                               | None\`   | no |
| `ts`             | `datetime`                          | no       |    |
| `type`           | `Literal['approval_resolved']`      | no       |    |
| `approval_id`    | `str`                               | yes      |    |
| `allowed`        | `bool`                              | yes      |    |
| `via`            | `Literal['human', 'grant', 'auto']` | no       |    |

### `CancellationObserved`

The loop observed a tripped cancellation token and is stopping (§8).

```python theme={null}
CancellationObserved(*, schema_version: Literal[1] = 1, event_id: int = 0, session_id: str = '', task_id: str | None = None, turn: int | None = None, ts: datetime = <factory>, type: Literal['cancellation_observed'] = 'cancellation_observed', reason: str = '') -> None
```

**Fields**

| Field            | Type                               | Required |    |
| ---------------- | ---------------------------------- | -------- | -- |
| `schema_version` | `Literal[1]`                       | no       |    |
| `event_id`       | `int`                              | no       |    |
| `session_id`     | `str`                              | no       |    |
| `task_id`        | \`str                              | None\`   | no |
| `turn`           | \`int                              | None\`   | no |
| `ts`             | `datetime`                         | no       |    |
| `type`           | `Literal['cancellation_observed']` | no       |    |
| `reason`         | `str`                              | no       |    |

### `DecisionError`

A malformed model reply — either recovered by an in-client retry or a lost turn (§6).

Closes the observability gap where a failed decision attempt (e.g. a truncated
`str_replace` emission) left no trace: every malformed attempt is journaled with
its error and a capped excerpt of the raw reply, so a struggling run is legible
live and debuggable after the fact (invariant #5).

```python theme={null}
DecisionError(*, schema_version: Literal[1] = 1, event_id: int = 0, session_id: str = '', task_id: str | None = None, turn: int | None = None, ts: datetime = <factory>, type: Literal['decision_error'] = 'decision_error', error: str = '', raw: str = '', recovered: bool = True) -> None
```

**Fields**

| Field            | Type                        | Required |    |
| ---------------- | --------------------------- | -------- | -- |
| `schema_version` | `Literal[1]`                | no       |    |
| `event_id`       | `int`                       | no       |    |
| `session_id`     | `str`                       | no       |    |
| `task_id`        | \`str                       | None\`   | no |
| `turn`           | \`int                       | None\`   | no |
| `ts`             | `datetime`                  | no       |    |
| `type`           | `Literal['decision_error']` | no       |    |
| `error`          | `str`                       | no       |    |
| `raw`            | `str`                       | no       |    |
| `recovered`      | `bool`                      | no       |    |

### `DeclarationRequired`

A greenfield edit was refused pending a declared verification contract (ADR-0038).

Emitted at the investigating → editing boundary when the task is greenfield (no
detected/cited/configured contract) and the model tried to edit without first calling
`declare_verification`. `nudge`/`max_nudges` track the bounded-nudge budget: at the cap the
runner stops refusing and falls back to the smoke floor.

```python theme={null}
DeclarationRequired(*, schema_version: Literal[1] = 1, event_id: int = 0, session_id: str = '', task_id: str | None = None, turn: int | None = None, ts: datetime = <factory>, type: Literal['declaration_required'] = 'declaration_required', nudge: int = 0, max_nudges: int = 0) -> None
```

**Fields**

| Field            | Type                              | Required |    |
| ---------------- | --------------------------------- | -------- | -- |
| `schema_version` | `Literal[1]`                      | no       |    |
| `event_id`       | `int`                             | no       |    |
| `session_id`     | `str`                             | no       |    |
| `task_id`        | \`str                             | None\`   | no |
| `turn`           | \`int                             | None\`   | no |
| `ts`             | `datetime`                        | no       |    |
| `type`           | `Literal['declaration_required']` | no       |    |
| `nudge`          | `int`                             | no       |    |
| `max_nudges`     | `int`                             | no       |    |

### `EventBase`

Fields common to every lifecycle event — the journal's ordering/versioning keys.

The `type` discriminator is declared on each concrete event (not here): it is
per-event by nature, and a shared mutable base field can't be narrowed to a
`Literal` soundly. `HarnessEvent` is the discriminated union over the concretes.

```python theme={null}
EventBase(*, schema_version: Literal[1] = 1, event_id: int = 0, session_id: str = '', task_id: str | None = None, turn: int | None = None, ts: datetime = <factory>) -> None
```

**Fields**

| Field            | Type         | Required |    |
| ---------------- | ------------ | -------- | -- |
| `schema_version` | `Literal[1]` | no       |    |
| `event_id`       | `int`        | no       |    |
| `session_id`     | `str`        | no       |    |
| `task_id`        | \`str        | None\`   | no |
| `turn`           | \`int        | None\`   | no |
| `ts`             | `datetime`   | no       |    |

### `EventSink`

Where the runner publishes typed events (the bus stamps `event_id`/`session_id`/`ts`).

Foundation publishing is fire-and-forget via `publish_nowait` onto an unbounded
queue; the awaited `emit` is the frozen async interface lane 1 fills in with
bounded, backpressured fan-out. Both must keep `event_id` monotonic.

```python theme={null}
EventSink(*args, **kwargs)
```

#### `EventSink.emit(self, draft: 'HarnessEvent') -> 'HarnessEvent'`

Awaitable publish — the interface lane 1 fills in with backpressure.

Args:
draft: The event to publish.

Returns:
The stamped event.

#### `EventSink.publish_nowait(self, draft: 'HarnessEvent') -> 'HarnessEvent'`

Stamp and enqueue `draft` without blocking.

Args:
draft: The event to publish.

Returns:
The stamped event.

### `ModelDecisionEvent`

The model chose an action this turn (thought + a one-line brief).

```python theme={null}
ModelDecisionEvent(*, schema_version: Literal[1] = 1, event_id: int = 0, session_id: str = '', task_id: str | None = None, turn: int | None = None, ts: datetime = <factory>, type: Literal['model_decision'] = 'model_decision', thought: str = '', action_type: str = '', action: str = '', transport: str = '') -> None
```

**Fields**

| Field            | Type                        | Required |    |
| ---------------- | --------------------------- | -------- | -- |
| `schema_version` | `Literal[1]`                | no       |    |
| `event_id`       | `int`                       | no       |    |
| `session_id`     | `str`                       | no       |    |
| `task_id`        | \`str                       | None\`   | no |
| `turn`           | \`int                       | None\`   | no |
| `ts`             | `datetime`                  | no       |    |
| `type`           | `Literal['model_decision']` | no       |    |
| `thought`        | `str`                       | no       |    |
| `action_type`    | `str`                       | no       |    |
| `action`         | `str`                       | no       |    |
| `transport`      | `str`                       | no       |    |

### `ModelUpdate`

A streamed model-output delta — display only; never private chain-of-thought (ADR-0001 D6).

```python theme={null}
ModelUpdate(*, schema_version: Literal[1] = 1, event_id: int = 0, session_id: str = '', task_id: str | None = None, turn: int | None = None, ts: datetime = <factory>, type: Literal['model_update'] = 'model_update', delta: str = '', channel: Literal['display'] = 'display') -> None
```

**Fields**

| Field            | Type                      | Required |    |
| ---------------- | ------------------------- | -------- | -- |
| `schema_version` | `Literal[1]`              | no       |    |
| `event_id`       | `int`                     | no       |    |
| `session_id`     | `str`                     | no       |    |
| `task_id`        | \`str                     | None\`   | no |
| `turn`           | \`int                     | None\`   | no |
| `ts`             | `datetime`                | no       |    |
| `type`           | `Literal['model_update']` | no       |    |
| `delta`          | `str`                     | no       |    |
| `channel`        | `Literal['display']`      | no       |    |

### `ModelUsage`

Provider-reported token usage for one turn (in-client retries summed).

The journal's per-turn cost record — the eval harness (ADR-0004) sums these for
tokens/\$ per solved task; without them cost is unmeasurable (invariant #5).

```python theme={null}
ModelUsage(*, schema_version: Literal[1] = 1, event_id: int = 0, session_id: str = '', task_id: str | None = None, turn: int | None = None, ts: datetime = <factory>, type: Literal['model_usage'] = 'model_usage', prompt_tokens: int = 0, completion_tokens: int = 0) -> None
```

**Fields**

| Field               | Type                     | Required |    |
| ------------------- | ------------------------ | -------- | -- |
| `schema_version`    | `Literal[1]`             | no       |    |
| `event_id`          | `int`                    | no       |    |
| `session_id`        | `str`                    | no       |    |
| `task_id`           | \`str                    | None\`   | no |
| `turn`              | \`int                    | None\`   | no |
| `ts`                | `datetime`               | no       |    |
| `type`              | `Literal['model_usage']` | no       |    |
| `prompt_tokens`     | `int`                    | no       |    |
| `completion_tokens` | `int`                    | no       |    |

### `PhaseChanged`

The control phase advanced from `old` to `new` (§7).

```python theme={null}
PhaseChanged(*, schema_version: Literal[1] = 1, event_id: int = 0, session_id: str = '', task_id: str | None = None, turn: int | None = None, ts: datetime = <factory>, type: Literal['phase_changed'] = 'phase_changed', old: str, new: str) -> None
```

**Fields**

| Field            | Type                       | Required |    |
| ---------------- | -------------------------- | -------- | -- |
| `schema_version` | `Literal[1]`               | no       |    |
| `event_id`       | `int`                      | no       |    |
| `session_id`     | `str`                      | no       |    |
| `task_id`        | \`str                      | None\`   | no |
| `turn`           | \`int                      | None\`   | no |
| `ts`             | `datetime`                 | no       |    |
| `type`           | `Literal['phase_changed']` | no       |    |
| `old`            | `str`                      | yes      |    |
| `new`            | `str`                      | yes      |    |

### `TaskEscalated`

The task was escalated `investigate → edit` mid-run (ADR-0048).

Emitted when a consented `switch_to_editing` (model-requested, or a thrash-nudged request)
flips the task **kind only** — deliberately not the phase, and not the frozen plan. The task
becomes a normal edit task still sitting in `investigating`, so the standard edit-intent
bootstrap runs the declaration gate and advances the phase on the next edit: escalation never
*jumps* that gate. `trigger` records what caused it (`model` = the model asked unprompted;
`thrash` = the harness's thrash detector nudged it there). The transition is one-directional
and once-only, so this only ever reads `investigate → edit`.

```python theme={null}
TaskEscalated(*, schema_version: Literal[1] = 1, event_id: int = 0, session_id: str = '', task_id: str | None = None, turn: int | None = None, ts: datetime = <factory>, type: Literal['task_escalated'] = 'task_escalated', from_kind: str = 'investigate', to_kind: str = 'edit', trigger: str = 'model') -> None
```

**Fields**

| Field            | Type                        | Required |    |
| ---------------- | --------------------------- | -------- | -- |
| `schema_version` | `Literal[1]`                | no       |    |
| `event_id`       | `int`                       | no       |    |
| `session_id`     | `str`                       | no       |    |
| `task_id`        | \`str                       | None\`   | no |
| `turn`           | \`int                       | None\`   | no |
| `ts`             | `datetime`                  | no       |    |
| `type`           | `Literal['task_escalated']` | no       |    |
| `from_kind`      | `str`                       | no       |    |
| `to_kind`        | `str`                       | no       |    |
| `trigger`        | `str`                       | no       |    |

### `ToolEnd`

A tool call finished — `success` plus its summary/content (§10).

```python theme={null}
ToolEnd(*, schema_version: Literal[1] = 1, event_id: int = 0, session_id: str = '', task_id: str | None = None, turn: int | None = None, ts: datetime = <factory>, type: Literal['tool_end'] = 'tool_end', call_id: str = '', tool: str, success: bool, summary: str = '', content: str = '') -> None
```

**Fields**

| Field            | Type                  | Required |    |
| ---------------- | --------------------- | -------- | -- |
| `schema_version` | `Literal[1]`          | no       |    |
| `event_id`       | `int`                 | no       |    |
| `session_id`     | `str`                 | no       |    |
| `task_id`        | \`str                 | None\`   | no |
| `turn`           | \`int                 | None\`   | no |
| `ts`             | `datetime`            | no       |    |
| `type`           | `Literal['tool_end']` | no       |    |
| `call_id`        | `str`                 | no       |    |
| `tool`           | `str`                 | yes      |    |
| `success`        | `bool`                | yes      |    |
| `summary`        | `str`                 | no       |    |
| `content`        | `str`                 | no       |    |

### `ToolStart`

A tool call (`call_id`) is about to execute.

```python theme={null}
ToolStart(*, schema_version: Literal[1] = 1, event_id: int = 0, session_id: str = '', task_id: str | None = None, turn: int | None = None, ts: datetime = <factory>, type: Literal['tool_start'] = 'tool_start', call_id: str = '', tool: str, input: dict = <factory>) -> None
```

**Fields**

| Field            | Type                    | Required |    |
| ---------------- | ----------------------- | -------- | -- |
| `schema_version` | `Literal[1]`            | no       |    |
| `event_id`       | `int`                   | no       |    |
| `session_id`     | `str`                   | no       |    |
| `task_id`        | \`str                   | None\`   | no |
| `turn`           | \`int                   | None\`   | no |
| `ts`             | `datetime`              | no       |    |
| `type`           | `Literal['tool_start']` | no       |    |
| `call_id`        | `str`                   | no       |    |
| `tool`           | `str`                   | yes      |    |
| `input`          | `dict`                  | no       |    |

### `TurnEnd`

The current loop iteration has finished.

```python theme={null}
TurnEnd(*, schema_version: Literal[1] = 1, event_id: int = 0, session_id: str = '', task_id: str | None = None, turn: int | None = None, ts: datetime = <factory>, type: Literal['turn_end'] = 'turn_end') -> None
```

**Fields**

| Field            | Type                  | Required |    |
| ---------------- | --------------------- | -------- | -- |
| `schema_version` | `Literal[1]`          | no       |    |
| `event_id`       | `int`                 | no       |    |
| `session_id`     | `str`                 | no       |    |
| `task_id`        | \`str                 | None\`   | no |
| `turn`           | \`int                 | None\`   | no |
| `ts`             | `datetime`            | no       |    |
| `type`           | `Literal['turn_end']` | no       |    |

### `TurnStart`

A new loop iteration (`iteration`) has begun.

```python theme={null}
TurnStart(*, schema_version: Literal[1] = 1, event_id: int = 0, session_id: str = '', task_id: str | None = None, turn: int | None = None, ts: datetime = <factory>, type: Literal['turn_start'] = 'turn_start', iteration: int = 0) -> None
```

**Fields**

| Field            | Type                    | Required |    |
| ---------------- | ----------------------- | -------- | -- |
| `schema_version` | `Literal[1]`            | no       |    |
| `event_id`       | `int`                   | no       |    |
| `session_id`     | `str`                   | no       |    |
| `task_id`        | \`str                   | None\`   | no |
| `turn`           | \`int                   | None\`   | no |
| `ts`             | `datetime`              | no       |    |
| `type`           | `Literal['turn_start']` | no       |    |
| `iteration`      | `int`                   | no       |    |

### `VerificationEnd`

The verifier returned a verdict — `passed` plus its summary (§12).

```python theme={null}
VerificationEnd(*, schema_version: Literal[1] = 1, event_id: int = 0, session_id: str = '', task_id: str | None = None, turn: int | None = None, ts: datetime = <factory>, type: Literal['verification_end'] = 'verification_end', passed: bool, summary: str = '') -> None
```

**Fields**

| Field            | Type                          | Required |    |
| ---------------- | ----------------------------- | -------- | -- |
| `schema_version` | `Literal[1]`                  | no       |    |
| `event_id`       | `int`                         | no       |    |
| `session_id`     | `str`                         | no       |    |
| `task_id`        | \`str                         | None\`   | no |
| `turn`           | \`int                         | None\`   | no |
| `ts`             | `datetime`                    | no       |    |
| `type`           | `Literal['verification_end']` | no       |    |
| `passed`         | `bool`                        | yes      |    |
| `summary`        | `str`                         | no       |    |

### `VerificationPlanFrozen`

The per-session verification plan was resolved and frozen (ADR-0007).

Journaled at the investigating → editing boundary, before any verification:
each check carries its command and provenance, so every run's rubric — and
where each check came from — is auditable. An empty `checks` records that
nothing was discovered (the verifier will fail legibly). `change_kinds`
records the kinds a model-declared contract covers (ADR-0044) — the model's
stated intent, auditable against the diff; `None` = no declaration (tiers 1-3),
including journals written before the field existed.

```python theme={null}
VerificationPlanFrozen(*, schema_version: Literal[1] = 1, event_id: int = 0, session_id: str = '', task_id: str | None = None, turn: int | None = None, ts: datetime = <factory>, type: Literal['verification_plan_frozen'] = 'verification_plan_frozen', checks: list[PlannedCheck] = <factory>, change_kinds: list[str] | None = None) -> None
```

**Fields**

| Field            | Type                                  | Required |    |
| ---------------- | ------------------------------------- | -------- | -- |
| `schema_version` | `Literal[1]`                          | no       |    |
| `event_id`       | `int`                                 | no       |    |
| `session_id`     | `str`                                 | no       |    |
| `task_id`        | \`str                                 | None\`   | no |
| `turn`           | \`int                                 | None\`   | no |
| `ts`             | `datetime`                            | no       |    |
| `type`           | `Literal['verification_plan_frozen']` | no       |    |
| `checks`         | `list[PlannedCheck]`                  | no       |    |
| `change_kinds`   | \`list\[str]                          | None\`   | no |

### `VerificationStart`

The harness-owned verifier has begun (§12).

```python theme={null}
VerificationStart(*, schema_version: Literal[1] = 1, event_id: int = 0, session_id: str = '', task_id: str | None = None, turn: int | None = None, ts: datetime = <factory>, type: Literal['verification_start'] = 'verification_start') -> None
```

**Fields**

| Field            | Type                            | Required |    |
| ---------------- | ------------------------------- | -------- | -- |
| `schema_version` | `Literal[1]`                    | no       |    |
| `event_id`       | `int`                           | no       |    |
| `session_id`     | `str`                           | no       |    |
| `task_id`        | \`str                           | None\`   | no |
| `turn`           | \`int                           | None\`   | no |
| `ts`             | `datetime`                      | no       |    |
| `type`           | `Literal['verification_start']` | no       |    |

## Functions

### `dump_event(event: Annotated[AgentStart | AgentEnd | TurnStart | TurnEnd | PhaseChanged | DeclarationRequired | ModelDecisionEvent | ModelUpdate | ToolStart | ToolEnd | ApprovalRequested | ApprovalResolved | DecisionError | ModelUsage | VerificationPlanFrozen | VerificationStart | VerificationEnd | CancellationObserved | TaskEscalated, FieldInfo(annotation=NoneType, required=True, discriminator='type')]) -> str`

Serialize an event to one JSON line for the journal.

Args:
event: The event to serialize.

Returns:
Its compact JSON representation.

### `load_events(path: Path) -> list[Annotated[AgentStart | AgentEnd | TurnStart | TurnEnd | PhaseChanged | DeclarationRequired | ModelDecisionEvent | ModelUpdate | ToolStart | ToolEnd | ApprovalRequested | ApprovalResolved | DecisionError | ModelUsage | VerificationPlanFrozen | VerificationStart | VerificationEnd | CancellationObserved | TaskEscalated, FieldInfo(annotation=NoneType, required=True, discriminator='type')]]`

Reload a JSONL journal back into typed events, in file order.

Args:
path: The JSONL journal written via `dump_event` / a typed `EventLog`.

Returns:
The events, one per non-blank line, validated through the union.

### `parse_event(data: dict | str | bytes) -> Annotated[AgentStart | AgentEnd | TurnStart | TurnEnd | PhaseChanged | DeclarationRequired | ModelDecisionEvent | ModelUpdate | ToolStart | ToolEnd | ApprovalRequested | ApprovalResolved | DecisionError | ModelUsage | VerificationPlanFrozen | VerificationStart | VerificationEnd | CancellationObserved | TaskEscalated, FieldInfo(annotation=NoneType, required=True, discriminator='type')]`

Validate a dict / JSON string into the right `HarnessEvent` variant.

Raises `pydantic.ValidationError` if `type` is unknown (the union is closed) or
fields are invalid.

Args:
data: A mapping or JSON text carrying a known `type` discriminator.

Returns:
The validated event.
