Dashboard › opencode › Distillation
ca9d16cc-f2e2-4ddf-b2ed-90ec9de5dd71["lore_tm_v1_jKzEqhz30GRjJYoPJ8QEuaLoYQla9DtXpBRQP1rTpOk","lore_tm_v1_Ywdmi48bCO6rAvgBaY8wCPz7zcQlvFLVmgT3TsIqAjE","lore_tm_v1_uq7KT7MC5-OHBylbD9eSdKYPHtSCHeuuWVqs6W8WKrU","lore_tm_v1_-VKdK5NUadZprmAIM5CBpRK0PKj7YeEThUKoqgAPpNs","lore_tm_v1_dSEf_eJaYzCQJKIp2KqojGYVyWzeNhfQkTSr16MEQF0","lore_tm_v1_dByioBH7H0ydW7fLI3rhpwlyAHUIt3nHvT1dS98o5Vg","lore_tm_v1_5h7jEZv1sm512QtfTQAG0IoOoS7cjgZARWba3bdiEJE","lore_tm_v1_sd5kIQR1I3HLbYzLwla_uahCsEHqW_J4JRtkdrJ8ycM","lore_tm_v1_Qm4LXjgQl1naYnRrR0RDQK8wLmBm09QrM-OeO12JieU","lore_tm_v1_-dF5kMpfKA9qh2EoV4VJ082aLzeAqL1CM68tR8L1gUo","lore_tm_v1_b2l0v8Zy-DsO6tMwdnT5PV_Iob6BVvdEOsRFZMbiRoM"]
Date: Sep 17, 2026
/tmp/opencode/session-recovery-v23-review; prohibited editing, running tests/builds/services, mutating VCS/index/refs, and using recall.ab9408c81cc9916177641ae8e9f08624fc27b5b9; patch /tmp/opencode/session-recovery-final-v23.patch SHA-256 14035d7631ba25b820fdc553087469935f447af034d549e2f14f8a141eda59dc; SEA /home/byk/Code/opencode/packages/opencode/dist/server/opencode-server SHA-256 f875987afa4336956b9f33e14eee6de0a4af90e2bc6de899cccb7cbe5a5df998; expected change set: 34 paths.HEAD and base as ab9408c81cc9916177641ae8e9f08624fc27b5b9; final reported count was 0.packages/client/src/generated/types.ts; packages/core/schema.json; packages/core/src/database/migration.gen.ts; packages/core/src/database/migration/20260914170650_session-recovery.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/recovery.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-execution-local.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; packages/server/src/routes.ts; packages/core/src/session/execution/claim.ts; packages/core/src/session/recovery-id.ts.packages/client/src/generated/types.ts +72/-0; packages/core/schema.json +566/-47; packages/core/src/database/migration.gen.ts +1/-0; packages/core/src/database/migration/20260914170650_session-recovery.ts +62/-0; packages/core/src/database/schema.gen.ts +52/-1; packages/core/src/session.ts +6/-4; packages/core/src/session/compaction.ts +31/-16; packages/core/src/session/context-epoch.ts +54/-34; packages/core/src/session/execution/local.ts +291/-19; packages/core/src/session/input.ts +391/-31; packages/core/src/session/message-updater.ts +69/-0; packages/core/src/session/projector.ts +88/-1; packages/core/src/session/recovery.ts +579/-0; packages/core/src/session/run-coordinator.ts +40/-6; packages/core/src/session/runner/index.ts +4/-0; packages/core/src/session/runner/llm.ts +289/-104; packages/core/src/session/runner/publish-llm-event.ts +108/-48; packages/core/src/session/sql.ts +88/-1; packages/core/test/database-migration.test.ts +66/-1; packages/core/test/session-execution-local.test.ts +415/-0; packages/core/test/session-projector.test.ts +2994/-3; packages/core/test/session-prompt.test.ts +247/-25; packages/core/test/session-run-coordinator.test.ts +154/-5; packages/core/test/session-runner-recorded.test.ts +5/-10; packages/core/test/session-runner-tool-events.test.ts +46/-7; packages/core/test/session-runner.test.ts +1220/-70; packages/opencode/src/server/routes/instance/httpapi/server.ts +2/-1; packages/schema/src/session-event.ts +43/-1; packages/schema/test/event-manifest.test.ts +8/-5; packages/sdk/js/src/v2/gen/types.gen.ts +190/-0; packages/sdk/openapi.json +657/-44; packages/server/src/routes.ts +2/-0; packages/core/src/session/execution/claim.ts +112/-0; packages/core/src/session/recovery-id.ts +6/-0.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.file:line and severity MUST-FIX or CONCERN, and required the final review to end exactly with MERGE or DO-NOT-MERGE.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", 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../packages/sdk/js/script/build.ts; after changing public Protocol or Server HttpApi, run bun run generate from packages/client; do not edit src/generated or src/generated-effect directly.dev; local main may not exist, so diffs should use dev or origin/dev.feat/ or fix/; examples are session-recovery, fix-scroll-state, and regenerate-sdk.type(scope): summary; valid types are feat, fix, docs, chore, refactor, and test, with optional affected-package scopes such as core, opencode, tui, app, desktop, sdk, or plugin.SessionV2.prompt(...) durably admits one session_input before advisory SessionExecution.wake(sessionID), except resume: false means admit-only; the serialized runner promotes admitted inputs at safe boundaries; exact prompt-ID retry requires matching Session, prompt, and delivery mode; conflicting reuse fails; historical projected prompts lazily synthesize promoted inbox records.SessionExecution must remain process-global and Session-ID based; its local implementation owns the process-local Session coordinator and discovers placement via SessionStore plus LocationServiceMap.get(session.location) only when a drain begins; no layer should take a Session ID; V2 interruption targets the active process-local ownership chain, while idle or absent interruption is a no-op.SessionRunner, model resolution, tool registry, permissions, and filesystem must remain Location-scoped; omitted Location.workspaceID means implicit-local placement, while explicit workspace identity is reserved for future placement semantics.llm.stream(request) call and reload projected history before durable continuation; orchestration must not bridge through legacy SessionPrompt.loop(...) or delegate to an in-memory tool loop.SessionRunCoordinator joins explicit same-Session resumes, coalesces prompt wakeups, and permits different Sessions to run concurrently. Advisory wakes only drain eligible durable inbox rows; post-crash provider-work continuation requires a separate explicit design. A drain has no durable identity or transcript boundary.queue inputs remain pending until the Session would otherwise idle; promote one queued input at that boundary and reevaluate before another; any new user input resets the selected agentβs provider-turn allowance, with a steer batch resetting it once.packages/core/src/session/execution/claim.ts defines SessionExecutionClaim with claim fields sessionID, executionID, and ownerID; operations update, renew, settleCancellation, clear, and transaction; and Lost extends Error. Claim matching fences on session ID, execution ID, owner ID, and expires_at > now.SessionExecutionClaim.update renews expires_at to now + SESSION_EXECUTION_LEASE_MS; phase transitions enforce: "cancelled" only from "cancelling", "cancelling" from anything except "cancelled", and other updates from neither "cancelling" nor "cancelled". Missing updates die with new Lost(claim).SessionExecutionClaim.transaction uses db.transaction(() => update(db, claim).pipe(Effect.andThen(effect)), { behavior: "immediate" }).pipe(Effect.orDie).packages/core/src/session/recovery-id.ts defines message(executionID, assistantMessageID?) as the supplied assistant ID or SessionMessage.ID.make(\msg_recovery_${executionID}`), and continuation(executionID)asSessionMessage.ID.make(`msg_recovery_continue_${executionID}`)`.