Dashboard › opencode › Distillation
c3628ac6-476d-4950-b4b3-3c5391e3ae6e["lore_tm_v1_Lp2UKQk0YqS3l-Ac-ZZJDfVi8sLSGx6GRMXvvDYUDis","lore_tm_v1_5UcjS1pjYu0ARFEaoct5OSjZQFGnGiMaxCSIFOF2p9w","lore_tm_v1_3vec6y8ei2oAKTtV0DhRXBl0MEAVryklNFESnJqQyFg","lore_tm_v1_AQsvRlH5uSKtZEfDgHO63sFzlGHDWFvZbM3hleOMDww","lore_tm_v1_J1_BWREjaovnKlkS56F2Oro3HdkKT0_nLkmIKmrzabI","lore_tm_v1_znVaXDBki6XhEWSqOdJs0TrGWlOSW15ItLcmKu6zkg8","lore_tm_v1_GWsY7NYAEA0z6VOGRLr2D8-WJfGT9D1KG0rIq7kpDhA","lore_tm_v1_yFnwCpy9kq7f3Ty9WAoOHZCyC3rk7uzbnBYjGsCi67A","lore_tm_v1_kbY9C0eQl7arXZGB0mooQalBF4f4GebI9s1ZCfnobYs","lore_tm_v1_WIDjfwbPBaB6CwGeNoi5L5MKGJ9h3rqzd8cxsRQjf6s"]
Date: Sep 15, 2026
packages/core/src/session/recovery.ts queries only expired execution claims with lt(SessionExecutionTable.expires_at, Date.now()), rather than scanning all session_execution rows.SessionRecovery.recover() loads the latest assistant message for claim.session_id, ordered by SessionMessageTable.seq descending with limit(1).claim.phase === "safe" or when claim.assistant_message_id !== null but no longer matches the latest assistant; deletion rechecks both execution id and expires_at < Date.now().recoveryMessageID uses the target assistant ID when present or a new SessionMessage.ID; continuationMessageID is always a new SessionMessage.ID.SessionEvent.Step.Recovered carries sessionID, timestamp, executionID, recoveryMessageID, optional assistantMessageID, continuationMessageID, and the recorded execution phase.SessionEvent.Step.Recovered commit hook atomically deletes the exact stale claim only when id, session_id, phase, assistant_message_id null/value state, and expires_at < Date.now() still match; a changed claim defects with Recovery execution claim changed: ${claim.id}.SessionRecoveryTable for the pair session_id/execution_id: an existing row converts the attempt to false, while absence rethrows the defect. execution.wake(claim.session_id) runs only when a new recovery event was published.session-recovery layer runs recover(), logs failures as "Failed to recover Sessions", repeats with Schedule.spaced("10 seconds"), and forks the loop scoped; dependencies are [Database.node, EventV2.node, SessionProjector.node, SessionExecution.node].packages/core/src/session/run-coordinator.ts defines a per-key Coordinator<Key, E> with active, run, wake, and interrupt; each entry tracks done, optional owner fiber, pendingWake, and stopping.SessionRunCoordinator.run(key) serializes execution per key: it joins an active execution, waits and retries if that execution is stopping, or creates a new entry and calls drain(key, true) when idle.SessionRunCoordinator.wake(key) coalesces repeated follow-up requests by setting pendingWake = true on an existing entry; when idle, it creates an entry and starts drain(key, false).pendingWake and no stop request, the same coordinator entry starts one successor drain after Effect.yieldNow; otherwise settlement either deletes the key or installs a fresh successor entry before completing the prior entryβs Deferred.SessionRunCoordinator.interrupt(key) sets stopping = true, clears pendingWake, and interrupts the owner fiber; it is a no-op if no owner exists.packages/core/src/session/compaction.ts invokes optional input.beforeStream() immediately before the summarization LLM stream and optional input.afterStream() immediately afterward.compactAfterOverflow() streams a tool-free summarization request with generation: { maxTokens: summaryOutput }, collects textDelta chunks, marks provider errors, catches LLM.Error as unsuccessful, and publishes SessionEvent.Compaction.Ended only when streaming succeeded and the joined summary is nonblank.summaryOutput = Math.min(output || SUMMARY_OUTPUT_TOKENS, SUMMARY_OUTPUT_TOKENS) and refuses compaction when Token.estimate(summaryPrompt) > context - summaryOutput; compactIfNeeded() triggers only when estimated system/messages/tools usage exceeds context - Math.max(output, config.buffer).packages/core/src/session/execution/local.ts implementation inserted executions with a random id, owner_id, phase: "safe", and time_created, but had no expires_at, renewal loop, execution-ID claim validation, or conditional takeover.session_id and current ownerID; normal completion and non-interruption failures cleared the row, while interrupted failures left it for recovery.SessionExecutionTable row, embedded Prompt.make({ text: "continue" }), delivery: "queue", and an error directly in SessionEvent.Step.Recovered, and ran only once via Layer.effectDiscard(recover())."Provider Step outcome unknown after server restart" for "unknown", otherwise "Session execution interrupted by server restart".packages/core/src/session/projector.ts projects SessionEvent.Step.Interrupted through the standard run(db, event) path.SessionEvent.Step.Recovered projector requires event.durable.seq; absence defects with "Durable Session event is missing aggregate sequence"."assistant"; failures defect with Recovery target is not the latest assistant: ${event.data.assistantMessageID} or Recovery target is not an assistant: ${event.data.assistantMessageID}.SessionInput.projectAdmitted() using event.durable.seq, event.data.continuationMessageID, Prompt.make({ text: "continue" }), and the recovery timestamp; it then applies run(db, event) and inserts a SessionRecoveryTable row containing session, execution, recovery assistant, continuation message, and epoch-millisecond creation time.20260914170650_session-recovery, 20260914214636_session-execution, and 20260914222526_session-execution-phase, but did not yet list 20260914235657_session-execution-lease.packages/core/src/event.ts is: execute registered projectors, execute the optional local commit(seq) hook, upsert EventSequenceTable, then insert EventTable; all occur inside the immediate transaction.EventV2.publishEvent() rejects commit hooks for non-durable events with InvalidDurableEventError and message "Local commit hooks require a durable event".EventV2 adds durable aggregate metadata and notifies listeners in isolated mode; listener failures excluding interruptions are logged as "Event listener failed" with eventID, eventType, and cause.packages/core/src/session/runner/llm.ts still had failInterruptedTools() converting pending or running tools into SessionEvent.Tool.Failed with unknown error message "Tool execution interrupted"; provider state preserves executed and optional metadata.awaitToolFibers() races FiberSet.join(fibers) against FiberSet.awaitEmpty(fibers), and user-declined detection treats PermissionV2.DeclinedError and QuestionV2.RejectedError defects as loop-halting declines.packages/core/src/database/migration/20260914235657_session-execution-lease.ts has ID 20260914235657_session-execution-lease and applies ALTER TABLE \session_execution` ADD `expires_at` integer NOT NULL;`.