Dashboard › opencode › Distillation
724ee5fb-b80c-4cf4-8f96-b16c5a87bb7e["lore_tm_v1_PefaLkLydUv6AyS2lUgN8LtHk7Rd2j6hNTgQ_cOkM_Q","lore_tm_v1_gtBWNZHDrgsFP9t-S-NCOrFXWmVDpRZnhE6OFVRPJpQ","lore_tm_v1_uCXEOU9oLvKQv00ZZ62HdeZcre-q4Ypnt2CLL9guS5Y","lore_tm_v1_mCLBka8uXPvskEwGU1GotWJuFHb8hDGmtk808vZe0Tk","lore_tm_v1_bf3FyNYcFQhGl6cLLgdyYGG26Rsut1FaQfYBmF_45Zo","lore_tm_v1_Mhyf5d1MPPl1oUqZX8YVBTZP7L1f0S31par4cuHkDYo"]
Date: Sep 16, 2026
packages/core/src/session/execution/claim.ts lines 33-37 also require SESSION_EXECUTION_LEASE_MS to remain larger than maximum deployment clock skew plus one renewal interval because lease timestamps use node wall clocks.base-and-application-ok. SHA-256: /tmp/opencode/session-recovery-final-v8.patch = 446412b56ac31b2a60f98765b5f14955a771f6074ebeb9309f603a0ceefad1bc; /home/byk/Code/opencode/packages/opencode/dist/server/opencode-server = f4f0bd585d33bd47114b2d8d54082c2b061380771c808e909223350e62c8c72f.packages/core/schema.json, packages/core/src/database/migration.gen.ts, packages/core/src/database/schema.gen.ts, packages/core/src/session.ts, packages/core/src/session/compaction.ts, packages/core/src/session/context-epoch.ts, packages/core/src/session/execution/local.ts, packages/core/src/session/input.ts, packages/core/src/session/message-updater.ts, packages/core/src/session/projector.ts, packages/core/src/session/run-coordinator.ts, packages/core/src/session/runner/index.ts, packages/core/src/session/runner/llm.ts, packages/core/src/session/runner/publish-llm-event.ts, packages/core/src/session/sql.ts, packages/core/test/database-migration.test.ts, packages/core/test/session-projector.test.ts, packages/core/test/session-prompt.test.ts, packages/core/test/session-run-coordinator.test.ts, packages/core/test/session-runner-recorded.test.ts, packages/core/test/session-runner-tool-events.test.ts, packages/core/test/session-runner.test.ts, packages/opencode/src/server/routes/instance/httpapi/server.ts, packages/schema/src/session-event.ts, packages/schema/test/event-manifest.test.ts, packages/sdk/js/src/v2/gen/types.gen.ts, packages/sdk/openapi.json, and packages/server/src/routes.ts.packages/core/src/database/migration/20260914170650_session-recovery.ts, packages/core/src/session/execution/claim.ts, packages/core/src/session/recovery-id.ts, and packages/core/src/session/recovery.ts.packages/core/test/session-projector.test.ts at 2,010 added lines, packages/core/test/session-runner.test.ts at 974 added lines, packages/sdk/openapi.json at 701 added lines, and packages/core/schema.json at 579 added lines.bun test v1.3.14 (0d9b296a) run did not execute tests because dependencies were unavailable in /tmp/opencode/session-recovery-v7-check: exactly 0 pass, 7 fail, and 7 errors across 7 files in 290.00ms.effect missing from test/session-prompt.test.ts, test/session-run-coordinator.test.ts, test/session-projector.test.ts, test/session-execution-local.test.ts, and test/session-runner-tool-events.test.ts; @effect/sql-sqlite-bun missing from test/database-migration.test.ts; and @opencode-ai/llm missing from test/session-runner.test.ts.packages/core/src/session/execution/claim.ts defines SessionExecutionClaim.Claim with exact fields sessionID: SessionSchema.ID, executionID: string, and ownerID: string; Values optionally carries assistant_message_id and phase; and SessionExecutionClaim.Lost reports Session execution claim lost: ${claim.executionID}.packages/core/src/session/execution/claim.ts, the shared where(claim, now) fence requires matching session_id, execution id, and owner_id, plus expires_at > now. Both update() and clear() die with SessionExecutionClaim.Lost when no row is returned, preventing an expired, replaced, or incorrectly owned claim from mutating the execution row.SessionExecutionClaim.update() in packages/core/src/session/execution/claim.ts renews expires_at to now + SESSION_EXECUTION_LEASE_MS and atomically applies optional assistant_message_id/phase values. SessionExecutionClaim.clear() deletes under the same live-claim fence. SessionExecutionClaim.transaction() uses an "immediate" database transaction, renews the claim first, then runs the supplied effect; database failures are converted with Effect.orDie.packages/core/src/session/execution/local.ts creates one process-local ownerID with crypto.randomUUID(), maintains activeClaims: Map<SessionSchema.ID, SessionExecutionClaim.Claim>, and acquires an execution by inserting a "ready" row into SessionExecutionTable with a fresh execution ID, time_created: now, and expires_at: now + SESSION_EXECUTION_LEASE_MS; .onConflictDoNothing() means an existing execution row prevents acquisition.packages/core/src/session/execution/local.ts selects the oldest eligible recovery by filtering SessionRecoveryTable for the session, wake_pending = true, and recovery_error IS NULL, ordering by time_created then execution_id, and taking one continuation_message_id.input.run(claim, force, recovery?.continuationMessageID) against lease renewal via SessionExecutionClaim.update(db, claim) repeated every leaseDuration / 3. Non-interruption-only failures are logged as "Failed to drain Session" with sessionID.activeClaims. Successful runs clear the claim. Failed/interrupted runs inspect the current phase: an interrupted run leaves the row intact unless phase is "safe"; otherwise the claim is cleared when its phase is neither "unknown" nor "continue".packages/core/src/session/execution/local.ts first renews the active claim, starts a scoped renewal loop every leaseDuration / 3, then invokes coordinator.interrupt() with claim clearing as finalization. A SessionExecutionClaim.Lost during clear is tolerated only when no current SessionExecutionTable row remains for the session; if another row exists, the defect is rethrown.SessionExecutionLocal exposes active: coordinator.active, resume: coordinator.run, and wake: coordinator.wake. Its layer resolves the session from SessionStore, dies with Session not found: ${claim.sessionID} if absent, and calls runner.run({ ...claim, force, recoveryInputID }) under the location-specific service layer from LocationServiceMap.packages/core/test/session-runner.test.ts found 5 matches: SystemContext.empty at lines 212 and 215; { type: "unknown", message: "Provider Step ended without settlement" } at lines 505 and 4249; and test "durably fails a hosted tool left unresolved at normal provider EOF" beginning at line 4225.