Dashboard › opencode › Distillation
5508b0d5-db6f-45a5-9bc0-2ba5709c2779["lore_tm_v1_AE03YNwG0ssscAEtRVpE5RbrNEYxaRBTSost7d0w1hY","lore_tm_v1_Q-F6iFIs5hgETjapMXstz9FAamMilZHxuIHoNF-XsBk","lore_tm_v1_lye-VsIxeUXLw2NlXEtf9qZiFd0zugMJcXm2GlYzUyo","lore_tm_v1_Quf5MX4XjGP0dWp6k7USl8MyoX2xPrxbHeLcEaWdxeA","lore_tm_v1_vw9Mf6-zTd3E0qUsSL1SPENMAsWdQb2dbN1UKniw7rA"]
Date: Sep 16, 2026
packages/core/src/session/execution/claim.ts:25-31 defines where(claim, now) to fence operations by exact session_id, id, owner_id, and expires_at > now.packages/core/src/session/execution/claim.ts:33-36 states that lease timestamps use node wall clocks and that the lease interval must exceed the deployment’s maximum clock skew plus one renewal interval; execution IDs immediately fence a node after takeover.SessionExecutionClaim.update reads Clock.currentTimeMillis, sets expires_at to now + SESSION_EXECUTION_LEASE_MS, applies the exact/unexpired where fence, and dies with new Lost(claim) if no row updates.SessionExecutionClaim.clear deletes only through the exact/unexpired where fence and dies with new Lost(claim) if no row is deleted.SessionExecutionClaim.transaction executes an immediate database transaction that renews the claim via update(db, claim) before running the supplied effect.packages/core/src/session/recovery.ts:62-96 scans at most BATCH_SIZE expired, non-quarantined claims ordered by time_created then id; takeover CAS-matches the claim’s id, session_id, previous owner_id, expiration at the current time, and null recovery_error, then assigns a random ownerID and renews the lease.recovery_error to Invalid execution phase: ${String(claim.phase)} under exact Session, execution, replacement-owner, and unexpired-lease fencing; failure to update dies with Recovery execution claim changed: ${claim.id}."ready" claim with no assistant_message_id when hasPendingExecutionIntent(db, claim.session_id) is true; it also clears a "safe" claim or a claim whose recorded assistant message is no longer the latest assistant message.SessionEvent.Step.Recovered with sessionID, timestamp, executionID, optional assistantMessageID, and phase; its commit rechecks pending execution intent for an unassociated "ready" claim, then clears the exact recovery claim.packages/core/src/session/run-coordinator.ts, interrupt(key, cleanup) sets entry.stopping = true, clears entry.pendingWake, interrupts the owner fiber, waits for cleanup, verifies the interrupted entry settled, then either deletes it or starts a successor if a wake arrived; cleanup failure is propagated after coordinator state is settled.interrupts runner continuation when permission approval is declined registers tool declined, whose execute dies with new PermissionV2.DeclinedError(), then expects session.resume(sessionID) to fail with an interrupt-only cause and exactly 1 model request."Call declined"; an assistant message with finish: "error" and error message "Tool execution declined"; and tool call-declined in error state with message "Tool execution interrupted".SessionEvent.Step.Interrupted.type, an empty SessionExecutionTable, no SessionRecoveryTable rows after SessionRecovery.recover(), and no additional model request.returns permission corrections to the model and continues registers tool corrected; its execution fails with PermissionV2.CorrectedError({ feedback: "Use another tool" }) and maps that to new Tool.Failure({ message: "Use another tool" }).FiberSet.join fails when the first tool fiber fails; therefore, racing it against set emptiness can classify provider failure as safe while sibling local-tool fibers remain active.a5c1bace440d1b6acb383c4fcffc52714a9373892e75b4f23bdbbf2dfdad8e16 for /tmp/opencode/session-recovery-final-v6.patch.d09c992a0f4cce15e73dd158fe60413420109c821afed6e121d11cdad9c7b583 for /home/byk/Code/opencode/packages/opencode/dist/server/opencode-server.ab9408c81cc9916177641ae8e9f08624fc27b5b9, parent 2e9407768d1401a25b69febb36657638a779053a, and tree d3323b963b9ef2de41a7ff9884299c74b93886ba.DO-NOT-MERGE.packages/core/src/session/runner/llm.ts:393-397 publishes Step.Interrupted, deletes the exact claim, and returns an interrupt on user decline before outer runner/location scopes finish at packages/core/src/session/execution/local.ts:145-150. A blocked outer finalizer can therefore leave no unique Session claim, allowing another node to acquire and execute the Session while the old ownership chain remains active. Exact fencing prevents deletion of a replacement owner but does not prevent surrendering current ownership too early. Existing coverage at packages/core/test/session-runner.test.ts:3405-3457 checks only eventual deletion and does not block an outer finalizer.awaitToolFibers at packages/core/src/session/runner/llm.ts:154-155 races first failure against set emptiness, but FiberSet.join returns on the first failed tool fiber rather than waiting for siblings. The failure path marks unsettled tools terminal at lines 410-416 and writes phase: "safe" at lines 417-420 without clearing and awaiting remaining fibers, so a blocked sibling may still execute or remain in a finalizer after durable state says failed.wake_attempts lacks non-negative and upper-bound validation in packages/core/src/session/sql.ts:176-205 and the migration. Recovery sorting at packages/core/src/session/recovery.ts:194-208 trusts attacker-controlled counters, while increments at lines 232-245 and 256-278 use JavaScript arithmetic. A full batch of negative counters can defer valid rows for arbitrarily many scans, and values beyond JavaScript’s safe-integer range may stop advancing and monopolize every restart scan; existing fairness tests cover only ordinary increments.packages/core/src/session/execution/claim.ts:33-36 requires a skew bound, but takeover at packages/core/src/session/recovery.ts:67-90 compares independent node wall clocks. A node ahead by more than the lease budget can take a freshly renewed claim; exact fencing blocks later publication but cannot retract an already dispatched provider or local-tool call, expanding the accepted final synchronous pre-dispatch residual unless deployment enforces the bound.a5c1bace440d1b6acb383c4fcffc52714a9373892e75b4f23bdbbf2dfdad8e16; SEA SHA-256 matched d09c992a0f4cce15e73dd158fe60413420109c821afed6e121d11cdad9c7b583.ab9408c81cc9916177641ae8e9f08624fc27b5b9 has parent 2e9407768d1401a25b69febb36657638a779053a, tree d3323b963b9ef2de41a7ff9884299c74b93886ba, and is an ancestor of the current Git head.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/schema.gen.ts; 5. packages/core/src/session.ts; 6. packages/core/src/session/compaction.ts; 7. packages/core/src/session/context-epoch.ts; 8. packages/core/src/session/execution/local.ts; 9. packages/core/src/session/input.ts; 10. packages/core/src/session/message-updater.ts; 11. packages/core/src/session/projector.ts; 12. packages/core/src/session/recovery.ts; 13. packages/core/src/session/run-coordinator.ts; 14. packages/core/src/session/runner/index.ts; 15. packages/core/src/session/runner/llm.ts; 16. packages/core/src/session/runner/publish-llm-event.ts; 17. packages/core/src/session/sql.ts; 18. packages/core/test/database-migration.test.ts; 19. packages/core/test/session-execution-local.test.ts; 20. packages/core/test/session-projector.test.ts; 21. packages/core/test/session-prompt.test.ts; 22. packages/core/test/session-run-coordinator.test.ts; 23. packages/core/test/session-runner-recorded.test.ts; 24. packages/core/test/session-runner-tool-events.test.ts; 25. packages/core/test/session-runner.test.ts; 26. packages/opencode/src/server/routes/instance/httpapi/server.ts; 27. packages/schema/src/session-event.ts; 28. packages/schema/test/event-manifest.test.ts; 29. packages/sdk/js/src/v2/gen/types.gen.ts; 30. packages/sdk/openapi.json; 31. packages/server/src/routes.ts; 32. packages/core/src/session/execution/claim.ts; 33. packages/core/src/session/recovery-id.ts.Fiber.interrupt and cleanup complete at packages/core/src/session/execution/local.ts:105-132 and packages/core/src/session/run-coordinator.ts:99-124.SessionPrompt call.