Dashboard › opencode › Distillation
7b3ff770-d8b9-4165-86fd-fddfc0408cdf["lore_tm_v1_-pf-2EceDSeYIOceWDXER1JNKkwC6hoywkxd4e9kfNs","lore_tm_v1_LLx9fWuMvwHvYbZVXRJEVMZsvGxxlLkKGyTxlulQFSg","lore_tm_v1_JwEYcYQ4NbpvAh4Jc5vi4OlxFe-AngTaI4hU6QrcAfs","lore_tm_v1_HDTizyHX_LaGLgjtikl3SDeNIVOZm-aiqc-EChJmoRA","lore_tm_v1_jMbdfOQ0Bs7bg6iceH2hXimA3mKYpq8XqD_8617odmg"]
Date: Sep 16, 2026
packages/core/src/session/projector.ts rejects a recovery target unless it is the latest assistant message, dying with exact error Recovery target is not the latest assistant: ${event.data.assistantMessageID}; recovery creates a continuation prompt with Prompt.make({ text: "continue" }).packages/core/src/session/projector.ts:501-525 dies with Revert boundary message not found: ${event.data.messageID} when the boundary is absent, deletes later SessionMessageTable rows where seq > boundary.seq, deletes SessionInputTable rows where either admitted_seq > boundary.seq or promoted_seq > boundary.seq, then clears SessionTable.revert and updates time_updated.packages/core/src/session/projector.ts exports node = makeGlobalNode({ name: "session-projector", layer, deps: [EventV2.node, Database.node] }).updateOwnedAssistant(...) and includes handlers for "session.next.prompted", "session.next.step.started", "session.next.text.started", and "session.next.tool.input.started".packages/core/src/session/sql.ts defines MAX_WAKE_ATTEMPTS = Number.MAX_SAFE_INTEGER, represented in SQLite checks as exactly 9007199254740991; both session.wake_attempts and session_recovery.wake_attempts must remain between 0 and MAX_WAKE_ATTEMPTS.SessionMessageTable in packages/core/src/session/sql.ts stores id, session_id, type, seq, timestamps, and JSON data; it enforces unique (session_id, seq) and indexes (session_id, type, seq), (session_id, time_created, id), and time_created.SessionInputTable stores id, session_id, JSON prompt, delivery, admitted_seq, nullable promoted_seq, wake_pending defaulting to false, and time_created defaulting to Date.now(); it enforces unique (session_id, admitted_seq) and unique (session_id, promoted_seq).SessionInputTable indexes pending delivery selection on (session_id, promoted_seq, delivery, admitted_seq) and wake selection on (wake_pending, promoted_seq, session_id).SessionRecoveryTable in packages/core/src/session/sql.ts uses execution_id as primary key, makes continuation_message_id unique, allows nullable assistant_message_id, restricts phase to TypeScript values "ready" | "unknown" | "continue", defaults wake_pending to true and wake_attempts to 0, and stores nullable recovery_error plus time_created.SessionRecoveryTable.assistant_message_id references SessionMessageTable.id with cascade deletion, while continuation_message_id is non-null and references SessionInputTable.id with cascade deletion.SessionExecutionTable in packages/core/src/session/sql.ts stores id, unique session_id, owner_id, nullable assistant_message_id, phase, time_created, expires_at, and nullable recovery_error; allowed phases are exactly "ready", "safe", "unknown", and "continue".SessionExecutionTable uses primary key session_execution_pk on id, unique index session_execution_session_idx on session_id, index session_execution_owner_idx on owner_id, and check session_execution_phase_check; SESSION_EXECUTION_LEASE_MS = 30_000.SessionContextEpochTable stores one row per session_id with required baseline, JSON snapshot typed as SystemContext.Snapshot, and required baseline_seq; deleting the associated session cascades to this row.packages/core/src/database/migration/20260914170650_session-recovery.ts adds session.wake_attempts, creates session_execution and session_recovery, and creates their primary keys, foreign keys, checks, and indexes; corresponding generated definitions are present in packages/core/src/database/schema.gen.ts.