Dashboard › opencode › Distillation
41ae2186-0372-4005-9ed9-526976bfec4e["lore_tm_v1_QcsGVFlXYYIM3e4XGD8tskKC7eQhUuOOMZt_SsCFqOY","lore_tm_v1_G7rmE5HHzur28bsyfNnRSBHUBZwp21fK9Jm9imSBtNY","lore_tm_v1_UvVu6AOTNL-85hehqf6nCqmI-nLn0dJm_e0CTqGbbT4","lore_tm_v1_QgDsRxyvppi-FLdKV4o3G_ZvseyZ4idqu5PgO4uANAg","lore_tm_v1_MubykerCw8faZ04iJWE16UR_81b-G04nCnoS-QnT3gc","lore_tm_v1_pOmRyfr0atTm389gPBI6F4qhTV5csXPzAcenz6cxWxU","lore_tm_v1_gJoqTXwtXeimrsErpPVisfkmSmXIYjIsfe3doFtKka4"]
Date: Sep 15, 2026
/tmp/opencode/session-recovery-full.patch has 24 diff matches affecting: 1. packages/core/schema.json, 2. packages/core/src/database/migration.gen.ts, 3. packages/core/src/database/migration/20260914170650_session-recovery.ts, 4. packages/core/src/database/migration/20260914214636_session-execution.ts, 5. packages/core/src/database/migration/20260914222526_session-execution-phase.ts, 6. packages/core/src/database/schema.gen.ts, 7. packages/core/src/session/compaction.ts, 8. packages/core/src/session/execution/local.ts, 9. packages/core/src/session/message-updater.ts, 10. packages/core/src/session/projector.ts, 11. packages/core/src/session/recovery.ts, 12. packages/core/src/session/runner/index.ts, 13. packages/core/src/session/runner/llm.ts, 14. packages/core/src/session/runner/publish-llm-event.ts, 15. packages/core/src/session/sql.ts, 16. packages/core/test/session-execution-local.test.ts, 17. packages/core/test/session-projector.test.ts, 18. packages/core/test/session-runner-recorded.test.ts, 19. packages/core/test/session-runner-tool-events.test.ts, 20. packages/core/test/session-runner.test.ts, 21. packages/opencode/src/server/routes/instance/httpapi/server.ts, 22. packages/schema/src/session-event.ts, 23. packages/server/src/routes.ts, 24. packages/core/src/database/migration/20260914235657_session-execution-lease.ts.packages/core/src/session/execution/local.ts, make() creates one process-local ownerID using crypto.randomUUID() and derives leaseDuration with Duration.toMillis(SESSION_EXECUTION_LEASE_MS).packages/core/src/session/execution/local.ts, clear(sessionID, executionID?) deletes only rows matching session_id and the current owner_id, additionally matching id when executionID is provided.packages/core/src/session/execution/local.ts, renew(executionID) updates expires_at to Date.now() + leaseDuration only when both id === executionID and owner_id === ownerID; if no row is returned, it dies with Session execution claim lost: ${executionID}.packages/core/src/session/execution/local.ts, each coordinator drain generates a new executionID and attempts an insert with phase: "ready", assistant_message_id initially absent, time_created: Date.now(), and expires_at: Date.now() + leaseDuration.packages/core/src/session/execution/local.ts, conflict replacement is permitted only when either the existing row belongs to the same ownerID and has phase "ready" or "safe", or its expires_at is earlier than Date.now(); replacement resets id, owner_id, phase: "ready", assistant_message_id: null, time_created, and expires_at.packages/core/src/session/execution/local.ts, a failed claim returns without starting input.run; a successful claim races input.run(sessionID, force, executionID) against lease renewal repeated every "10 seconds".packages/core/src/session/execution/local.ts, non-interruption drain failures are logged as "Failed to drain Session" with sessionID; the claim is cleared on successful exit but retained on failure or interruption.packages/core/src/session/execution/local.ts, SessionExecution.Service.interrupt(sessionID) runs coordinator.interrupt(sessionID) and then clear(sessionID); resume maps to coordinator.run and wake maps to coordinator.wake.packages/core/src/session/execution/local.ts, the layer loads the session through SessionStore.Service, dies with Session not found: ${sessionID} if absent, and invokes runner.run({ sessionID, force, executionID }) under the location service selected by locations.get(session.location).packages/core/src/session/recovery.ts, SessionRecovery.recover selects only SessionExecutionTable claims whose expires_at is earlier than Date.now().packages/core/src/session/recovery.ts, recovery queries the latest assistant message for each claimed session by filtering session_id and type: "assistant", ordering SessionMessageTable.seq descending, and limiting to 1 row.packages/core/src/session/recovery.ts, an expired claim is deleted without publishing recovery when its phase is "safe" or when its non-null assistant_message_id differs from the latest assistant message ID; this deletion rechecks both the claim id and expiry.packages/core/src/session/recovery.ts, a recoverable claim uses the existing assistant message ID as recoveryMessageID when present; otherwise it creates a new SessionMessage.ID. It always creates a new continuationMessageID and publishes SessionEvent.Step.Recovered with sessionID, timestamp, executionID, recoveryMessageID, optional assistantMessageID, continuationMessageID, and phase.packages/core/src/session/recovery.ts, the recovery event commit fences concurrent claim changes by deleting only a row matching id, session_id, phase, expired expires_at, and the original nullable/non-null assistant_message_id; failure to delete dies with Recovery execution claim changed: ${claim.id}.packages/core/src/session/recovery.ts, a publish defect is treated as an already-completed recovery only if SessionRecoveryTable contains the same session_id and execution_id; otherwise the defect is rethrown. execution.wake(claim.session_id) runs only for a newly published recovery.session-recovery node repeats recovery every "10 seconds", logs failures as "Failed to recover Sessions", forks the loop scoped, and depends on Database.node, EventV2.node, SessionProjector.node, and SessionExecution.node.terminalCommit to updateExecution({ phase: "safe", assistant_message_id: null }), clears tool fibers when an interrupted stream fails, reports unsettled tools as "Tool execution outcome unknown after interruption", and reports other tool failures as Tool execution failed: ${message}.packages/core/src/session/runner/publish-llm-event.ts implementation rejects malformed tool-stream sequences with exact defects including ${name} delta before start: ${id}, Tool input delta after end: ${event.id}, and Tool call name changed for ${event.id}: ${tool.name} -> ${event.name}./home/byk/Code/opencode/packages/core/src/event/sql.ts and /home/byk/Code/opencode/packages/core/src/event.ts.