Dashboard › opencode › Distillation
2bbda100-3d2c-4922-b451-12ce4f008094["lore_tm_v1_CZ2X6R4WFnPqwjTx7qAZM5TcQ68qyl4-lVNP2dMBVUE","lore_tm_v1__tmft3WHT0kK6WV7k4VmCdO3XIdQUwvha6Hxl1Lkwlg","lore_tm_v1_uGSmF7zvKoH7RugP1UxbB1tq5Tk4BSy-xky7W9pD6yw","lore_tm_v1_nSBx84olIXNv4r6UBPN5p4eFtmE_rXT-v0heEp7RRFg","lore_tm_v1_zU9g0ut5kvJ-gko9DEedf-6Jutmh21lmgNOf2ZeGmsg","lore_tm_v1_A0DaG_yuFzsYig0DZyn8YT2L0oVUclsvDqMMuYcDguo","lore_tm_v1_GkeHYYyGLW-jQA0ltCs7BWAXqMt9gDJpgLsnrYTgn7s","lore_tm_v1_xd7ftM7vGisO22zbcBwbUR2Jc7BZYMM40z6BO8b2lrA","lore_tm_v1_PhyeDSVmk7ffNW8AIg0AlA1b9lq857hvrwsLY0xg2J0","lore_tm_v1_PTttj9Evgb2nzM1YaQLA-dyoQ3Eg4Coa_ldVESUoqeo","lore_tm_v1_2LGAu-jbRa8WMOA95fFMODbs8mZj8YjiYcKKdCfmT8M"]
Date: Sep 17, 2026
/tmp/opencode/session-recovery-v23-review, with findings first, exact file:line, each finding labeled MUST-FIX or CONCERN, and the response ending exactly MERGE or DO-NOT-MERGE.ab9408c81cc9916177641ae8e9f08624fc27b5b9; patch /tmp/opencode/session-recovery-final-v23.patch with SHA-256 14035d7631ba25b820fdc553087469935f447af034d549e2f14f8a141eda59dc; SEA /home/byk/Code/opencode/packages/opencode/dist/server/opencode-server with SHA-256 f875987afa4336956b9f33e14eee6de0a4af90e2bc6de899cccb7cbe5a5df998; 34 changed paths.14035d7631ba25b820fdc553087469935f447af034d549e2f14f8a141eda59dc and SEA SHA-256 f875987afa4336956b9f33e14eee6de0a4af90e2bc6de899cccb7cbe5a5df998.ab9408c81cc9916177641ae8e9f08624fc27b5b9, 2e9407768d1401a25b69febb36657638a779053a, ab9408c81cc9916177641ae8e9f08624fc27b5b9, and ab9408c81cc9916177641ae8e9f08624fc27b5b9 as the queried revision-related values.activeClaims registration/finalizer handoff under a pending interrupt.cancelling, while preserving wakes/resumes already present or arriving during setup.beforeInterrupt failure finalization and concurrent-interrupt single-flight behavior.Tool.Failed/Step.Interrupted event to atomically delete the exact claim, with publication failure rolling back the entire transaction.Step.Failed to preserve the provider error.sdk-next composes Client, Core, and Server.import { foo as bar } from "..." and renamed imports such as resolve as pathResolve.import * as Foo from "..." and import type * as Foo from "...".import { Project } from "@opencode-ai/core/project" and then use Project.ID.bun typecheck from package directories such as packages/opencode; never run tsc directly.do-not-run-tests-from-root guard; tests must run from package directories such as packages/opencode.HttpApi, run bun run generate from packages/client; do not edit src/generated or src/generated-effect directly../packages/sdk/js/script/build.ts.dev; local main may not exist, so diffs should use dev or origin/dev.feat/ or fix/.type(scope): summary; valid types are feat, fix, docs, chore, refactor, and test, with optional scopes such as core, opencode, tui, app, desktop, sdk, or plugin.SessionV2.prompt(...) admits one durable session_input row before advisory SessionExecution.wake(sessionID), unless resume: false requests admit-only behavior; the serialized runner promotes admitted inputs at safe boundaries.SessionExecution must remain process-global and Session-ID based; its local implementation owns the process-local Session coordinator and discovers placement through SessionStore plus LocationServiceMap.get(session.location) only when a drain starts; no layer should take a Session ID; V2 interruption targets the active process-local ownership chain, and idle or missing interruption is a no-op.SessionRunner, model resolution, tool registry, permissions, and filesystem must remain Location-scoped; omitted Location.workspaceID means implicit-local placement.llm.stream(request) call per provider turn and reload projected history before durable continuation; do not bridge through legacy SessionPrompt.loop(...) or delegate orchestration to an in-memory tool loop.SessionRunCoordinator joins explicit same-Session resumes, coalesces prompt wakeups, and allows different Sessions to run concurrently; advisory wakes drain eligible durable inbox rows only; post-crash continuation recovery requires a separate explicit design before retrying provider work; a drain has no durable identity or transcript boundary.queue input stays pending until the Session would otherwise become idle; promote one queued input at that boundary, reevaluate continuation, then consider another; promoting new user input resets the selected agentβs provider-turn allowance, with a steer batch resetting it once.src/system-context; Context Source producers remain with their observed domains; Session History selection and Context Epoch persistence remain Session-owned.packages/client/src/generated/types.ts, 2. packages/core/schema.json, 3. packages/core/src/database/migration.gen.ts, 4. packages/core/src/database/migration/20260914170650_session-recovery.ts, 5. packages/core/src/database/schema.gen.ts, 6. packages/core/src/session.ts, 7. packages/core/src/session/compaction.ts, 8. packages/core/src/session/context-epoch.ts, 9. packages/core/src/session/execution/local.ts, 10. packages/core/src/session/input.ts, 11. packages/core/src/session/message-updater.ts, 12. packages/core/src/session/projector.ts, 13. packages/core/src/session/recovery.ts, 14. packages/core/src/session/run-coordinator.ts, 15. packages/core/src/session/runner/index.ts, 16. packages/core/src/session/runner/llm.ts, 17. packages/core/src/session/runner/publish-llm-event.ts, 18. packages/core/src/session/sql.ts, 19. packages/core/test/database-migration.test.ts, 20. packages/core/test/session-execution-local.test.ts, 21. packages/core/test/session-projector.test.ts, 22. packages/core/test/session-prompt.test.ts, 23. packages/core/test/session-run-coordinator.test.ts, 24. packages/core/test/session-runner-recorded.test.ts, 25. packages/core/test/session-runner-tool-events.test.ts, 26. packages/core/test/session-runner.test.ts, 27. packages/opencode/src/server/routes/instance/httpapi/server.ts, 28. packages/schema/src/session-event.ts, 29. packages/schema/test/event-manifest.test.ts, 30. packages/sdk/js/src/v2/gen/types.gen.ts, 31. packages/sdk/openapi.json, 32. packages/server/src/routes.ts, 33. packages/core/src/session/execution/claim.ts, 34. packages/core/src/session/recovery-id.ts.7,784 insertions and 484 deletions; five additional files were untracked/new: packages/core/src/database/migration/20260914170650_session-recovery.ts, packages/core/src/session/recovery.ts, packages/core/test/session-execution-local.test.ts, packages/core/src/session/execution/claim.ts, and packages/core/src/session/recovery-id.ts.4fc947c76004f9c6a826b8067f97e74e71862523cbb60280911d8896a1af7b2a.packages/core/src/session/run-coordinator.ts defines Coordinator<Key, E> with active, run(key), wake(key), and interrupt(key, cleanup?, beforeInterrupt?); each Entry<E> tracks done, optional interruption, optional owner, optional exit, pendingWake, and stopping.packages/core/src/session/run-coordinator.ts:104-134, interrupt() returns cleanup when no active owner exists, joins an existing entry.interruption for concurrent calls, sets entry.stopping = true, captures beforeInterrupt with Effect.exit, interrupts the owner, runs cleanup only when beforeInterrupt succeeded, finalizes the active entry or starts a successor for pendingWake, completes entry.done, propagates cleanup/before-interrupt failure causes, executes uninterruptibly, and completes the shared interruption deferred on exit.packages/core/src/session/run-coordinator.ts:57-75, settle() stores the owner exit while an entry is stopping; otherwise a successful owner with pendingWake immediately starts a successor on the same entry, while other exits either delete the active key or replace it with a new successor entry before completing entry.done.packages/core/src/session/execution/claim.ts defines exact claims as { sessionID: SessionSchema.ID, executionID: string, ownerID: string } and Lost extends Error with message Session execution claim lost: ${claim.executionID}.packages/core/src/session/execution/claim.ts:27-33, exact live-claim matching requires session_id, execution id, and owner_id equality plus expires_at > now.packages/core/src/session/execution/claim.ts:40-65, SessionExecutionClaim.update() renews expiry to now + SESSION_EXECUTION_LEASE_MS; transition to cancelled requires current phase cancelling, transition to cancelling excludes only cancelled, and ordinary updates exclude both cancelling and cancelled; a missing returned row defects with new Lost(claim).packages/core/src/session/execution/claim.ts:67-82, renew() updates only an exact unexpired claim and defects with Lost if no row is returned.packages/core/src/session/execution/claim.ts:84-98, settleCancellation() updates only an exact unexpired claim currently in phase cancelling, renews its expiry, and defects with Lost if no row is returned.packages/core/src/session/execution/claim.ts:100-109, clear() deletes only an exact unexpired claim and defects with Lost if no row is returned.packages/core/src/session/execution/claim.ts:111-112, transaction(db, claim, effect) uses an immediate database transaction, first runs update(db, claim), then the supplied effect, and converts transaction errors to defects with Effect.orDie.packages/core/src/session/execution/claim.ts:35-39 documents wall-clock lease semantics: the lease interval must exceed maximum deployment clock skew plus one renewal interval; execution IDs fence a node immediately after takeover; an expired claim never renews itself.