feat(session): refuse session logs a build cannot faithfully read

Old runtimes meeting a newer session format now fail loud instead of
misreading: version refusal names the direction (newer: upgrade the
harness; older: no upgrade path) and points at the raw JSONL log, and an
event type outside the generated known vocabulary refuses resume unless
its envelope carries the new ignorable: true marker (default: required,
so a forgotten marker over-refuses instead of silently resuming a gutted
session). gen-persistence-catalog now also emits
KNOWN_SESSION_EVENT_TYPES; SQLite stores the marker in a dedicated
column (SCHEMA_VERSION 15). The versioning design (monotonic integer,
n->n+1 upgrader chain, migrate-on-continue) is recorded in the
session-log-version-mechanism Agent Note.
This commit is contained in:
creatixchu
2026-08-10 15:22:50 +08:00
parent 53c58e3914
commit 9186824e87
40 changed files with 622 additions and 106 deletions

View File

@@ -63,6 +63,17 @@ export type SessionEvent<T extends SessionEventType = SessionEventType> = {
/** Unix epoch milliseconds. */
time: number
data: SessionEventMap[K]
/**
* Marks an event a reader may safely skip when it does not recognize
* `type`. Absent means required: a reader meeting an unrecognized type
* without this marker MUST refuse to reconstruct the session instead of
* silently dropping the event, because an unrecognized required event may
* change how the rest of the log is interpreted. A writer sets `true` only
* on purely informational records whose loss cannot affect reconstruction;
* defaulting to required means a forgotten marker over-refuses (an
* inconvenience) rather than silently resuming a gutted session.
*/
ignorable?: true
} & (K extends SurfaceEventType ? {
/**
* Seq numbers of earlier events that this event cites as sources
@@ -79,7 +90,7 @@ export type SessionEvent<T extends SessionEventType = SessionEventType> = {
}[T]
```
Sources: [`packages/core/session/src/types.ts:316`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:323`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:352`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:384`](../packages/core/session/src/types.ts)
Sources: [`packages/core/session/src/types.ts:331`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:338`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:367`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:399`](../packages/core/session/src/types.ts)
## Events
@@ -192,7 +203,7 @@ Source: [`packages/interaction/user-approval/src/index.ts:67`](../packages/inter
Types: [StreamChunk](subsystems/llm-streaming.md)
Source: [`packages/core/session/src/types.ts:246`](../packages/core/session/src/types.ts)
Source: [`packages/core/session/src/types.ts:261`](../packages/core/session/src/types.ts)
#### `assistant/message` — surface
@@ -208,7 +219,7 @@ Source: [`packages/core/session/src/types.ts:246`](../packages/core/session/src/
Types: [TokenUsage](subsystems/llm-streaming.md)
Source: [`packages/core/session/src/types.ts:253`](../packages/core/session/src/types.ts)
Source: [`packages/core/session/src/types.ts:268`](../packages/core/session/src/types.ts)
### `command/*`
@@ -488,7 +499,7 @@ Source: [`packages/plan/plan-mode/src/index.ts:53`](../packages/plan/plan-mode/s
'request/context': RequestContext
```
Source: [`packages/core/session/src/types.ts:289`](../packages/core/session/src/types.ts)
Source: [`packages/core/session/src/types.ts:304`](../packages/core/session/src/types.ts)
#### `request/header` — log-only
@@ -500,7 +511,7 @@ Source: [`packages/core/session/src/types.ts:289`](../packages/core/session/src/
'request/header': { header: EpochHeader; reason: RequestHeaderReason }
```
Source: [`packages/core/session/src/types.ts:284`](../packages/core/session/src/types.ts)
Source: [`packages/core/session/src/types.ts:299`](../packages/core/session/src/types.ts)
### `sandbox/*`
@@ -553,7 +564,7 @@ Source: [`packages/sandbox/sandbox-policy/src/session-mode.ts:33`](../packages/s
'session/end-seed': Record<string, never>
```
Source: [`packages/core/session/src/types.ts:312`](../packages/core/session/src/types.ts)
Source: [`packages/core/session/src/types.ts:327`](../packages/core/session/src/types.ts)
#### `session/title` — log-only
@@ -589,7 +600,7 @@ Source: [`packages/session/session-title-llm/src/index.ts:43`](../packages/sessi
'step/end': { turn: number; step: number }
```
Source: [`packages/core/session/src/types.ts:236`](../packages/core/session/src/types.ts)
Source: [`packages/core/session/src/types.ts:251`](../packages/core/session/src/types.ts)
#### `step/start` — log-only
@@ -598,7 +609,7 @@ Source: [`packages/core/session/src/types.ts:236`](../packages/core/session/src/
'step/start': { turn: number; step: number }
```
Source: [`packages/core/session/src/types.ts:234`](../packages/core/session/src/types.ts)
Source: [`packages/core/session/src/types.ts:249`](../packages/core/session/src/types.ts)
### `subagent/*`
@@ -628,7 +639,7 @@ Source: [`packages/subagent/subagent/src/descriptor.ts:37`](../packages/subagent
Types: [TodoItem](subsystems/session.md)
Source: [`packages/core/session/src/types.ts:279`](../packages/core/session/src/types.ts)
Source: [`packages/core/session/src/types.ts:294`](../packages/core/session/src/types.ts)
### `tool/*`
@@ -645,7 +656,7 @@ Source: [`packages/core/session/src/types.ts:279`](../packages/core/session/src/
Types: [CallId](subsystems/core.md)
Source: [`packages/core/session/src/types.ts:259`](../packages/core/session/src/types.ts)
Source: [`packages/core/session/src/types.ts:274`](../packages/core/session/src/types.ts)
#### `tool/code-dispatch` — log-only
@@ -714,7 +725,7 @@ Source: [`packages/core/tools/src/types.ts:40`](../packages/core/tools/src/types
}
```
Source: [`packages/core/session/src/types.ts:271`](../packages/core/session/src/types.ts)
Source: [`packages/core/session/src/types.ts:286`](../packages/core/session/src/types.ts)
### `turn/*`
@@ -734,7 +745,7 @@ Source: [`packages/core/session/src/types.ts:271`](../packages/core/session/src/
Types: [TurnEndReason](subsystems/session.md)
Source: [`packages/core/session/src/types.ts:232`](../packages/core/session/src/types.ts)
Source: [`packages/core/session/src/types.ts:247`](../packages/core/session/src/types.ts)
#### `turn/start` — log-only
@@ -748,7 +759,7 @@ Source: [`packages/core/session/src/types.ts:232`](../packages/core/session/src/
'turn/start': { turn: number }
```
Source: [`packages/core/session/src/types.ts:223`](../packages/core/session/src/types.ts)
Source: [`packages/core/session/src/types.ts:238`](../packages/core/session/src/types.ts)
### `user/*`
@@ -765,7 +776,7 @@ Source: [`packages/core/session/src/types.ts:223`](../packages/core/session/src/
'user/message': UserMessage
```
Source: [`packages/core/session/src/types.ts:244`](../packages/core/session/src/types.ts)
Source: [`packages/core/session/src/types.ts:259`](../packages/core/session/src/types.ts)
### `web/*`