DashboardopencodeSession 0167D9N66z91

Session 0167D9N66z91

Full ID: 0167D9N66z91MADxH
Messages: 76
Distillations: 0
Time range: 2026-09-16 20:04:38 — 2026-09-16 20:35:23

Conversation (76 messages)

Read-only adversarial correctness review of frozen v13. Base ab9408c81cc9916177641ae8e9f08624fc27b5b9. Patch /tmp/opencode/session-recovery-final-v13.patch SHA-256 3e9b20cb5ec05d1065b6bc78bab00b47e8ca9296bc819689a4f3d889eddcb5bf. SEA /home/byk/Code/opencode/packages/opencode/dist/server/opencode-server SHA-256 c3b8c5d78e473ad4104a5b54617900e28921a283029b8484be7bce4bc3cee85a. Do not mutate/run tests/builds/services. Verify hashes, clean apply, inspect all 33 paths. Primary closures from v12: cancellation and projection-failure quarantine writes now require exact owner plus unexpired lease and stop on zero rows; deterministic tests expire old owner and show successor recovery. Assistant-less ready/unknown/continue supersession is revalidated inside Step.Recovered immediate transaction against captured claim.assistant_seq; concurrent Step.Started must roll back projection and exact claim clear. Direct tests cover acquisition snapshot and Step.Started advancement; equality permits current-boundary continue. Inspect these regressions and mutation sensitivity. Reassess complete identity quarantine, stale ownership, cancellation, tools/providers, replay/reservation/fairness, migration/schema, dependency direction. Accepted residuals: final synchronous check-to-external-call race, process-local interrupts, bounded clock skew. Evidence: recovery 241/0/712; Core 1178/0/3301; Core typecheck after fixes; prior unchanged four package typechecks and Schema manifest; migration checks; v13 smoke. Return findings with exact file:line, PASS/CONCERN/MUST-FIX, end exactly MERGE or DO-NOT-MERGE. Empty invalid; no recall.

gateway · 2026-09-16 20:04:38
result
<path>/home/byk/Code/opencode</path>
<type>directory</type>
<entries>
.dockerignore
.editorconfig
.git/
.gitattributes
.github/
.gitignore
.gitleaksignore
.husky/
.lore.md
.node-cache/
.opencode/
.oxlintrc.json
.prettierignore
.turbo/
.vscode/
.zed/
AGENTS.md
artifacts/
bun.lock
bunfig.toml
CONTEXT.md
CONTRIBUTING.md
flake.lock
flake.nix
github/
infra/
install
LICENSE
nix/
node_modules/
package.json
packages/
patches/
perf.data
perf.data.old
perf/
pnpm-lock.yaml
pnpm-workspace.yaml
README.ar.md
README.bn.md
README.br.md
README.bs.md
README.da.md
README.de.md
README.es.md
README.fr.md
README.gr.md
README.it.md
README.ja.md
README.ko.md
README.md
README.no.md
README.pl.md
README.ru.md
README.th.md
README.tr.md
README.uk.md
README.vi.md
README.zh.md
README.zht.md
screenshot-uk.png
script/
sdks/
SECURITY.md
specs/
sst-env.d.ts
sst.config.ts
STATS.md
tmp/
tsconfig.json
turbo.json

(71 entries)
</entries>
gateway · 2026-09-16 20:05:07
result
3e9b20cb5ec05d1065b6bc78bab00b47e8ca9296bc819689a4f3d889eddcb5bf  /tmp/opencode/session-recovery-final-v13.patch
c3b8c5d78e473ad4104a5b54617900e28921a283029b8484be7bce4bc3cee85a  /home/byk/Code/opencode/packages/opencode/dist/server/opencode-server
dc661f30cb2055ad6248fdc59b14998d834497be
commit
 M .lore.md
 M AGENTS.md
 M packages/core/schema.json
 M packages/core/src/database/migration.gen.ts
 M packages/core/src/database/migration/20260914170650_session-recovery.ts
 D packages/core/src/database/migration/20260914214636_session-execution.ts
 D packages/core/src/database/migration/20260914222526_session-execution-phase.ts
 M packages/core/src/database/schema.gen.ts
 M packages/core/src/session.ts
 M packages/core/src/session/compaction.ts
 M packages/core/src/session/context-epoch.ts
 M packages/core/src/session/execution/local.ts
 M packages/core/src/session/input.ts
 M packages/core/src/session/message-updater.ts
 M packages/core/src/session/projector.ts
 M ...
gateway · 2026-09-16 20:05:20
result
<path>/tmp/opencode</path>
<type>directory</type>
<entries>
.oxfmtrc.json
base-pipeline-numbered.txt
base-test-numbered.txt
llm-v5-current.diff
local-v5-current.diff
lore-ui-search-response
oxfmt-opencode.json
projection-parent-pipeline.ts
publisher-v5-current.diff
reference-v2-format/
restore-projector-v5-labeled.patch
restore-projector-v5.patch
restore-runner-v5-labeled.patch
restore-runner-v5.patch
session-recovery-final-v10.patch
session-recovery-final-v10/
session-recovery-final-v11.patch
session-recovery-final-v11/
session-recovery-final-v12.patch
session-recovery-final-v12/
session-recovery-final-v13.patch
session-recovery-final-v13/
session-recovery-final-v4-diag/
session-recovery-final-v4.index
session-recovery-final-v4.patch
session-recovery-final-v4/
session-recovery-final-v5.index
session-recovery-final-v5.patch
session-recovery-final-v5/
session-recovery-final-v6.patch
session-recovery-final-v6/
session-recovery-final-v7.patch
session-recovery-final-v7/
session-recovery-fi...
gateway · 2026-09-16 20:05:35
result
<path>/tmp/opencode/session-recovery-final-v13</path>
<type>directory</type>
<entries>
cache/
config/
data/
home/
opencode.db
state/
workspace/

(7 entries)
</entries>
gateway · 2026-09-16 20:05:49
result
<path>/tmp/opencode/session-recovery-final-v13.patch</path>
<type>file</type>
<content>
1: diff --git a/packages/core/schema.json b/packages/core/schema.json
2: index d0eeeebd5c..dedf0cc600 100644
3: --- a/packages/core/schema.json
4: +++ b/packages/core/schema.json
5: @@ -1,8 +1,10 @@
6:  {
7:    "version": "7",
8:    "dialect": "sqlite",
9: -  "id": "f14a9b18-8207-487e-a3d3-227e629ba9ad",
10: -  "prevIds": ["169a0f0f-d58f-479f-b024-fa1c7b9a09db"],
11: +  "id": "3a5ec6d4-a60d-47da-a347-3c72396a13c1",
12: +  "prevIds": [
13: +    "f14a9b18-8207-487e-a3d3-227e629ba9ad"
14: +  ],
15:    "ddl": [
16:      {
17:        "name": "workspace",
18: @@ -60,6 +62,10 @@
19:        "name": "session_context_epoch",
20:        "entityType": "tables"
21:      },
22: +    {
23: +      "name": "session_execution",
24: +      "entityType": "tables"
25: +    },
26:      {
27:        "name": "session_input",
28:        "entityType": "tables"
29: @@ -68,6 +74,10 @@
30:        "name": "session_message",
31: ...
gateway · 2026-09-16 20:06:07
result
paths=33 unique=33
worktree_diff_sha256=2f1b5ee3b250604baa6f809b664776c5889266390d24b65b4a0ddae8f2374c8f
patch_sha256=3e9b20cb5ec05d1065b6bc78bab00b47e8ca9296bc819689a4f3d889eddcb5bf
byte_equal=False
gateway · 2026-09-16 20:06:25
result
patch_lines=10147 diff_lines=10061
common_prefix_all_shorter; extra=86
gateway · 2026-09-16 20:06:34
result
<path>/tmp/opencode/session-recovery-final-v13.patch</path>
<type>file</type>
<content>
10045: +++ b/packages/server/src/routes.ts
10046: @@ -10,6 +10,7 @@ import { SessionV2 } from "@opencode-ai/core/session"
10047:  import { SessionExecution } from "@opencode-ai/core/session/execution"
10048:  import { LocationServiceMap } from "@opencode-ai/core/location-service-map"
10049:  import { SessionExecutionLocal } from "@opencode-ai/core/session/execution/local"
10050: +import { SessionRecovery } from "@opencode-ai/core/session/recovery"
10051:  import { ToolOutputStore } from "@opencode-ai/core/tool-output-store"
10052:  import { HttpRouter, HttpServer } from "effect/unstable/http"
10053:  import { HttpApiBuilder } from "effect/unstable/httpapi"
10054: @@ -29,6 +30,7 @@ const applicationServices = LayerNode.group([
10055:    httpClient,
10056:    ToolOutputStore.cleanupNode,
10057:    SessionV2.node,
10058: +  SessionRecovery.node,
10059:    PermissionSaved.node,
10060:    ...
gateway · 2026-09-16 20:06:52
result
tracked_patch_exact=False
packages/core/src/database/migration/20260914170650_session-recovery.ts_exact=True
packages/core/src/session/recovery.ts_exact=True
packages/core/test/session-execution-local.test.ts_exact=True
packages/core/src/session/execution/claim.ts_exact=True
packages/core/src/session/recovery-id.ts_exact=True
tracked=28 new=5 total=33
gateway · 2026-09-16 20:07:06
result
Found 100 matches (more matches available)
/tmp/opencode/session-recovery-final-v13.patch:
  Line 1: diff --git a/packages/core/schema.json b/packages/core/schema.json

  Line 5: @@ -1,8 +1,10 @@

  Line 18: @@ -60,6 +62,10 @@

  Line 29: @@ -68,6 +74,10 @@

  Line 40: @@ -920,6 +930,96 @@

  Line 137: @@ -980,6 +1080,16 @@

  Line 154: @@ -1060,6 +1170,96 @@

  Line 251: @@ -1350,6 +1550,16 @@

  Line 268: @@ -1481,9 +1691,13 @@

  Line 284: @@ -1492,9 +1706,13 @@

  Line 300: @@ -1503,9 +1721,13 @@

  Line 316: @@ -1514,9 +1736,13 @@

  Line 332: @@ -1525,9 +1751,13 @@

  Line 348: @@ -1536,9 +1766,13 @@

  Line 364: @@ -1547,9 +1781,13 @@

  Line 380: @@ -1558,9 +1796,13 @@

  Line 396: @@ -1569,9 +1811,28 @@

  Line 427: @@ -1580,9 +1841,13 @@

  Line 443: @@ -1591,9 +1856,58 @@

  Line 504: @@ -1602,9 +1916,13 @@

  Line 520: @@ -1613,9 +1931,13 @@

  Line 536: @@ -1624,133 +1946,192 @@

  Line 748: @@ -1872,6 +2253,34 @@

  Line 783: @@ -1934,6 +2343,28 @@

  Line 812: @@ ...
gateway · 2026-09-16 20:07:31
result
1: packages/core/schema.json
888: packages/core/src/database/migration.gen.ts
899: packages/core/src/database/migration/20260914170650_session-recovery.ts
964: packages/core/src/database/schema.gen.ts
1067: packages/core/src/session.ts
1099: packages/core/src/session/compaction.ts
1188: packages/core/src/session/context-epoch.ts
1364: packages/core/src/session/execution/local.ts
1573: packages/core/src/session/input.ts
2119: packages/core/src/session/message-updater.ts
2213: packages/core/src/session/projector.ts
2332: packages/core/src/session/recovery.ts
2842: packages/core/src/session/run-coordinator.ts
2911: packages/core/src/session/runner/index.ts
2933: packages/core/src/session/runner/llm.ts
3490: packages/core/src/session/runner/publish-llm-event.ts
3810: packages/core/src/session/sql.ts
3934: packages/core/test/database-migration.test.ts
4026: packages/core/test/session-execution-local.test.ts
4347: packages/core/test/session-projector.test.ts
6835: ...
gateway · 2026-09-16 20:07:43
result
<path>/home/byk/Code/opencode/packages/core/src/session/execution/claim.ts</path>
<type>file</type>
<content>
1: export * as SessionExecutionClaim from "./claim"
2: 
3: import { and, eq, gt } from "drizzle-orm"
4: import { Clock, Effect } from "effect"
5: import type { Database } from "../../database/database"
6: import type { SessionSchema } from "../schema"
7: import { SESSION_EXECUTION_LEASE_MS, SessionExecutionTable } from "../sql"
8: 
9: type DatabaseService = Database.Interface["db"]
10: 
11: export type Claim = {
12:   readonly sessionID: SessionSchema.ID
13:   readonly executionID: string
14:   readonly ownerID: string
15: }
16: 
17: export type Values = Partial<
18:   Pick<typeof SessionExecutionTable.$inferInsert, "assistant_message_id" | "assistant_seq" | "phase">
19: >
20: 
21: export class Lost extends Error {
22:   constructor(readonly claim: Claim) {
23:     super(`Session execution claim lost: ${claim.executionID}`)
24:   }
25: }
26: 
27: const where = (claim: Claim, ...
gateway · 2026-09-16 20:07:48
result
<path>/home/byk/Code/opencode/packages/core/src/session/execution/local.ts</path>
<type>file</type>
<content>
1: import { and, asc, desc, eq, isNull } from "drizzle-orm"
2: import { Cause, Clock, Duration, Effect, Exit, Layer, Schedule } from "effect"
3: import { Database } from "../../database/database"
4: import { LocationServiceMap } from "../../location-service-map"
5: import { makeGlobalNode } from "../../effect/app-node"
6: import { SessionRunCoordinator } from "../run-coordinator"
7: import { SessionRunner } from "../runner"
8: import { SessionMessage } from "../message"
9: import { SessionSchema } from "../schema"
10: import { SessionStore } from "../store"
11: import { SessionExecution } from "../execution"
12: import { SessionExecutionClaim } from "./claim"
13: import {
14:   SESSION_EXECUTION_LEASE_MS,
15:   SessionExecutionTable,
16:   SessionMessageTable,
17:   SessionRecoveryTable,
18: } from "../sql"
19: 
20: /** Current-process routing for implicit-local Locations. ...
gateway · 2026-09-16 20:07:58
result
<path>/home/byk/Code/opencode/packages/core/src/session/recovery.ts</path>
<type>file</type>
<content>
1: export * as SessionRecovery from "./recovery"
2: 
3: import { and, asc, desc, eq, exists, gt, isNull, lte, or, sql } from "drizzle-orm"
4: import { Clock, DateTime, Effect, Layer, Option, Schedule, Schema } from "effect"
5: import { Database } from "../database/database"
6: import { makeGlobalNode } from "../effect/app-node"
7: import { EventV2 } from "../event"
8: import { SessionEvent } from "./event"
9: import { SessionExecution } from "./execution"
10: import { SessionProjector } from "./projector"
11: import { SessionExecutionClaim } from "./execution/claim"
12: import { SessionInput } from "./input"
13: import { continuation } from "./recovery-id"
14: import { SessionSchema } from "./schema"
15: import {
16:   MAX_WAKE_ATTEMPTS,
17:   SESSION_EXECUTION_LEASE_MS,
18:   SessionExecutionTable,
19:   SessionInputTable,
20:   SessionRecoveryTable,
21:   SessionMessageTable,
22:   ...
gateway · 2026-09-16 20:08:38
result
<path>/home/byk/Code/opencode/packages/core/src/session/input.ts</path>
<type>file</type>
<content>
1: export * as SessionInput from "./input"
2: 
3: import { and, asc, desc, eq, isNull, lte } from "drizzle-orm"
4: import { DateTime, Effect, Option, Schema } from "effect"
5: import { Admitted, Delivery } from "@opencode-ai/schema/session-input"
6: import type { Database } from "../database/database"
7: import { EventV2 } from "../event"
8: import { SessionEvent } from "./event"
9: import { SessionMessage } from "./message"
10: import { Prompt } from "./prompt"
11: import { continuation, message } from "./recovery-id"
12: import { SessionSchema } from "./schema"
13: import { SessionInputTable, SessionMessageTable, SessionRecoveryTable } from "./sql"
14: 
15: type DatabaseService = Database.Interface["db"]
16: 
17: export { Admitted, Delivery }
18: 
19: const decodePrompt = Schema.decodeUnknownSync(Prompt)
20: const encodePrompt = Schema.encodeSync(Prompt)
21: const continuePrompt = ...
gateway · 2026-09-16 20:09:06
result
<path>/home/byk/Code/opencode/packages/core/src/session/projector.ts</path>
<type>file</type>
<content>
1: export * as SessionProjector from "./projector"
2: 
3: import { and, desc, eq, gt, or, sql } from "drizzle-orm"
4: import { DateTime, Effect, Layer, Schema } from "effect"
5: import { Database } from "../database/database"
6: import { EventV2 } from "../event"
7: import { makeGlobalNode } from "../effect/app-node"
8: import { SessionEvent } from "./event"
9: import { SessionV1 } from "../v1/session"
10: import { WorkspaceTable } from "../control-plane/workspace.sql"
11: import { SessionMessage } from "./message"
12: import { SessionMessageUpdater } from "./message-updater"
13: import { SessionInput } from "./input"
14: import { Prompt } from "./prompt"
15: import { continuation } from "./recovery-id"
16: import { WorkspaceV2 } from "../workspace"
17: import {
18:   MessageTable,
19:   PartTable,
20:   SessionInputTable,
21:   SessionMessageTable,
22:   SessionRecoveryTable,
23:   ...
gateway · 2026-09-16 20:09:17
result
No files found
gateway · 2026-09-16 20:09:24
result
/home/byk/Code/opencode/packages/core/src/event.ts
/home/byk/Code/opencode/packages/core/src/session/event.ts
gateway · 2026-09-16 20:10:16
result
Found 23 matches
/home/byk/Code/opencode/packages/core/src/event.ts:
  Line 122:   /** Local operational projection committed atomically with a new durable event. Not replayed or serialized. */

  Line 123:   readonly commit?: (seq: number) => Effect.Effect<void>

  Line 205:       function commitDurableEvent(

  Line 214:         commit?: (seq: number) => Effect.Effect<void>,

  Line 239:                   const committed = yield* db

  Line 316:                           const committed = {

  Line 321:                             yield* projector(committed)

  Line 323:                           if (commit) yield* commit(seq)

  Line 354:                   if (committed) {

  Line 356:                       pubsub.durable.get(committed.aggregateID) ?? [],

  Line 361:                   return committed

  Line 369:       function publishEvent<D extends Definition>(definition: D, event: Payload<D>, commit?: PublishOptions["commit"]) {

  Line 371:           if (!definition?.durable ...
gateway · 2026-09-16 20:11:06
result
<path>/home/byk/Code/opencode/packages/core/src/event.ts</path>
<type>file</type>
<content>
195:           yield* PubSub.shutdown(pubsub.all)
196:           yield* Effect.forEach(
197:             pubsub.durable.values(),
198:             (pubsubs) => Effect.forEach(pubsubs, PubSub.shutdown, { discard: true }),
199:             { discard: true },
200:           )
201:           yield* Effect.forEach(pubsub.typed.values(), PubSub.shutdown, { discard: true })
202:         }),
203:       )
204: 
205:       function commitDurableEvent(
206:         definition: Definition,
207:         event: Payload,
208:         input?: {
209:           readonly seq: number
210:           readonly aggregateID: string
211:           readonly ownerID?: string
212:           readonly strictOwner?: boolean
213:         },
214:         commit?: (seq: number) => Effect.Effect<void>,
215:       ) {
216:         return Effect.gen(function* () {
217:           const durable = definition?.durable
218:           if ...
gateway · 2026-09-16 20:11:18
result
<path>/home/byk/Code/opencode/packages/core/src/session/message-updater.ts</path>
<type>file</type>
<content>
200:               id: event.data.assistantMessageID,
201:               type: "assistant",
202:               agent: event.data.agent,
203:               model: event.data.model,
204:               time: { created: event.data.timestamp },
205:               content: [],
206:               snapshot: event.data.snapshot ? { start: event.data.snapshot } : undefined,
207:             }),
208:           )
209:         })
210:       },
211:       "session.next.step.ended": (event) => {
212:         return updateOwnedAssistant(event.data.assistantMessageID, (draft) => {
213:           draft.time.completed = event.data.timestamp
214:           draft.finish = event.data.finish
215:           draft.cost = event.data.cost
216:           draft.tokens = event.data.tokens
217:           if (event.data.snapshot || event.data.files)
218:             draft.snapshot = {
219:               ...
gateway · 2026-09-16 20:11:27
result
<path>/home/byk/Code/opencode/packages/core/src/session/runner/llm.ts</path>
<type>file</type>
<content>
1: import {
2:   LLM,
3:   LLMClient,
4:   LLMError,
5:   LLMEvent,
6:   Message,
7:   SystemPart,
8:   isContextOverflowFailure,
9:   type ProviderErrorEvent,
10: } from "@opencode-ai/llm"
11: import { Cause, DateTime, Effect, Exit, Fiber, Layer, Option, Semaphore, Stream } from "effect"
12: import { and, eq } from "drizzle-orm"
13: import { AgentV2 } from "../../agent"
14: import { Config } from "../../config"
15: import { Database } from "../../database/database"
16: import { EventV2 } from "../../event"
17: import { Location } from "../../location"
18: import { ModelV2 } from "../../model"
19: import { PermissionV2 } from "../../permission"
20: import { ProviderV2 } from "../../provider"
21: import { QuestionV2 } from "../../question"
22: import { SystemContext } from "../../system-context/index"
23: import { SystemContextRegistry } from "../../system-context/registry"
24: ...
gateway · 2026-09-16 20:11:56
result
<path>/home/byk/Code/opencode/packages/core/src/session/runner/publish-llm-event.ts</path>
<type>file</type>
<content>
1: import { ToolOutput, type LLMEvent, type ProviderMetadata, type ToolResultValue, type Usage } from "@opencode-ai/llm"
2: import { DateTime, Effect } from "effect"
3: import { EventV2 } from "../../event"
4: import { ModelV2 } from "../../model"
5: import { SessionEvent } from "../event"
6: import { SessionMessage } from "../message"
7: import { SessionSchema } from "../schema"
8: 
9: type Input = {
10:   readonly sessionID: SessionSchema.ID
11:   readonly agent: string
12:   readonly model: ModelV2.Ref
13:   readonly snapshot?: string
14:   readonly startCommit: (assistantMessageID: SessionMessage.ID, seq: number) => Effect.Effect<void>
15:   readonly eventCommit: () => Effect.Effect<void>
16: }
17: 
18: const safe = (value: number | undefined) => Math.max(0, Number.isFinite(value) ? (value ?? ...
gateway · 2026-09-16 20:12:40
result
<path>/home/byk/Code/opencode/packages/core/src/session/context-epoch.ts</path>
<type>file</type>
<content>
1: export * as SessionContextEpoch from "./context-epoch"
2: 
3: import { eq } from "drizzle-orm"
4: import { DateTime, Effect, Schema } from "effect"
5: import type { Database } from "../database/database"
6: import { EventV2 } from "../event"
7: import { SystemContext } from "../system-context/index"
8: import { ContextSnapshotDecodeError } from "./error"
9: import { SessionEvent } from "./event"
10: import { SessionHistory } from "./history"
11: import { SessionInput } from "./input"
12: import { SessionMessage } from "./message"
13: import { SessionSchema } from "./schema"
14: import { SessionContextEpochTable } from "./sql"
15: import { SessionExecutionClaim } from "./execution/claim"
16: 
17: type DatabaseService = Database.Interface["db"]
18: 
19: interface Prepared {
20:   readonly baseline: string
21:   readonly baselineSeq: number
22: }
23: 
24: export function ...
gateway · 2026-09-16 20:13:13
result
<path>/home/byk/Code/opencode/packages/core/src/session/compaction.ts</path>
<type>file</type>
<content>
1: export * as SessionCompaction from "./compaction"
2: 
3: import { LLM, LLMError, LLMEvent, Message, type LLMRequest, type Model } from "@opencode-ai/llm"
4: import { DateTime, Effect, Stream } from "effect"
5: import type { Config } from "../config"
6: import type { EventV2 } from "../event"
7: import { SessionEvent } from "./event"
8: import { SessionMessage } from "./message"
9: import { SessionSchema } from "./schema"
10: import { Token } from "../util/token"
11: 
12: const DEFAULT_BUFFER = 20_000
13: const DEFAULT_KEEP_TOKENS = 8_000
14: const TOOL_OUTPUT_MAX_CHARS = 2_000
15: const SUMMARY_OUTPUT_TOKENS = 4_096
16: const SUMMARY_TEMPLATE = `Output exactly the Markdown structure shown inside <template> and keep the section order unchanged. Do not include the <template> tags in your response. ...
gateway · 2026-09-16 20:13:31
result
<path>/home/byk/Code/opencode/packages/core/src/session.ts</path>
<type>file</type>
<content>
340:         return stored?.sessionID === input.sessionID ? stored.message : undefined
341:       }),
342:       context: Effect.fn("V2Session.context")(function* (sessionID) {
343:         yield* result.get(sessionID)
344:         return yield* store.context(sessionID)
345:       }),
346:       events: (input) =>
347:         Stream.unwrap(
348:           result
349:             .get(input.sessionID)
350:             .pipe(Effect.as(events.durable({ aggregateID: input.sessionID, after: input.after }))),
351:         ).pipe(Stream.filter((event): event is SessionEvent.DurableEvent => isDurableSessionEvent(event))),
352:       history: Effect.fn("V2Session.history")(function* (input) {
353:         yield* result.get(input.sessionID)
354:         return yield* EventV2.readAggregate(db, {
355:           ...input,
356:           aggregateID: input.sessionID,
357:           manifest: ...
gateway · 2026-09-16 20:14:17
result
<path>/home/byk/Code/opencode/packages/core/src/session/run-coordinator.ts</path>
<type>file</type>
<content>
1: export * as SessionRunCoordinator from "./run-coordinator"
2: 
3: import { Deferred, Effect, Exit, Fiber, FiberSet, Scope } from "effect"
4: 
5: /** Serializes execution for each key while allowing different keys to run concurrently. */
6: export interface Coordinator<Key, E> {
7:   /** Snapshots keys with an execution owned by this coordinator. */
8:   readonly active: Effect.Effect<ReadonlySet<Key>>
9:   /** Starts execution while idle or joins the active execution. */
10:   readonly run: (key: Key) => Effect.Effect<void, E>
11:   /** Registers one coalesced follow-up after newly recorded work. */
12:   readonly wake: (key: Key) => Effect.Effect<void>
13:   /** Stops active execution, runs cleanup, then starts work that arrived while stopping. */
14:   readonly interrupt: (key: Key, cleanup?: Effect.Effect<void>) => Effect.Effect<void>
15: }
16: 
17: type Entry<E> = {
18: ...
gateway · 2026-09-16 20:14:56
result
<path>/home/byk/Code/opencode/packages/core/src/session/sql.ts</path>
<type>file</type>
<content>
1: import { sql } from "drizzle-orm"
2: import { check, sqliteTable, text, integer, index, primaryKey, real, uniqueIndex } from "drizzle-orm/sqlite-core"
3: import * as DatabasePath from "../database/path"
4: import { ProjectTable } from "../project/sql"
5: import type { SessionMessage } from "./message"
6: import type { Prompt } from "./prompt"
7: import type { SessionInput } from "./input"
8: import type { Snapshot } from "../snapshot"
9: import { PermissionV1 } from "../v1/permission"
10: import { ProjectV2 } from "../project"
11: import type { SessionSchema } from "./schema"
12: import type { MessageID, PartID, SessionV1 } from "../v1/session"
13: import { WorkspaceV2 } from "../workspace"
14: import { Timestamps } from "../database/schema.sql"
15: import type { SystemContext } from "../system-context/index"
16: import { AgentV2 } from "../agent"
17: import type { Revert } from ...
gateway · 2026-09-16 20:15:56
result
<path>/home/byk/Code/opencode/packages/core/src/database/migration/20260914170650_session-recovery.ts</path>
<type>file</type>
<content>
1: import { Effect } from "effect"
2: import type { DatabaseMigration } from "../migration"
3: 
4: export default {
5:   id: "20260914170650_session-recovery",
6:   up(tx) {
7:     return Effect.gen(function* () {
8:       yield* tx.run(`ALTER TABLE \`session_input\` ADD \`wake_pending\` integer DEFAULT false NOT NULL;`)
9:       yield* tx.run(
10:         `ALTER TABLE \`session\` ADD \`wake_attempts\` integer DEFAULT 0 NOT NULL CONSTRAINT \`session_wake_attempts_check\` CHECK(\`wake_attempts\` >= 0 AND \`wake_attempts\` <= 9007199254740991);`,
11:       )
12:       yield* tx.run(`
13:         CREATE TABLE \`session_execution\` (
14:           \`id\` text NOT NULL,
15:           \`session_id\` text NOT NULL,
16:           \`owner_id\` text NOT NULL,
17:           \`assistant_message_id\` text,
18:            \`phase\` text NOT NULL,
19:            ...
gateway · 2026-09-16 20:16:11
result
<path>/home/byk/Code/opencode/packages/core/src/database/migration.gen.ts</path>
<type>file</type>
<content>
1: import type { DatabaseMigration } from "./migration"
2: 
3: export const migrations = (
4:   await Promise.all([
5:     import("./migration/20260127222353_familiar_lady_ursula"),
6:     import("./migration/20260211171708_add_project_commands"),
7:     import("./migration/20260213144116_wakeful_the_professor"),
8:     import("./migration/20260225215848_workspace"),
9:     import("./migration/20260227213759_add_session_workspace_id"),
10:     import("./migration/20260228203230_blue_harpoon"),
11:     import("./migration/20260303231226_add_workspace_fields"),
12:     import("./migration/20260309230000_move_org_to_state"),
13:     import("./migration/20260312043431_session_message_cursor"),
14:     import("./migration/20260323234822_events"),
15:     import("./migration/20260410174513_workspace-name"),
16:     import("./migration/20260413175956_chief_energizer"),
17:     ...
gateway · 2026-09-16 20:16:42
result
<path>/home/byk/Code/opencode/packages/core/src/database/schema.gen.ts</path>
<type>file</type>
<content>
140:           \`message_id\` text NOT NULL,
141:           \`session_id\` text NOT NULL,
142:           \`time_created\` integer NOT NULL,
143:           \`time_updated\` integer NOT NULL,
144:           \`data\` text NOT NULL,
145:           CONSTRAINT \`fk_part_message_id_message_id_fk\` FOREIGN KEY (\`message_id\`) REFERENCES \`message\`(\`id\`) ON DELETE CASCADE
146:         );
147:       `)
148:       yield* tx.run(`
149:         CREATE TABLE \`session_context_epoch\` (
150:           \`session_id\` text PRIMARY KEY,
151:           \`baseline\` text NOT NULL,
152:           \`snapshot\` text NOT NULL,
153:           \`baseline_seq\` integer NOT NULL,
154:           CONSTRAINT \`fk_session_context_epoch_session_id_session_id_fk\` FOREIGN KEY (\`session_id\`) REFERENCES \`session\`(\`id\`) ON DELETE CASCADE
155:         );
156:       `)
157:       yield* tx.run(`
158:         ...
gateway · 2026-09-16 20:16:54
result
<path>/home/byk/Code/opencode/packages/schema/src/session-event.ts</path>
<type>file</type>
<content>
1: export * as SessionEvent from "./session-event"
2: 
3: import { Schema } from "effect"
4: import { optional } from "./schema"
5: import { Event } from "./event"
6: import { ProviderMetadata, ToolContent } from "./llm"
7: import { Delivery } from "./session-delivery"
8: import { Model } from "./model"
9: import { DateTimeUtcFromMillis, NonNegativeInt, RelativePath } from "./schema"
10: import { FileAttachment, Prompt } from "./prompt"
11: import { SessionID } from "./session-id"
12: import { Location } from "./location"
13: import { SessionMessage } from "./session-message"
14: import { Revert } from "./revert"
15: 
16: export { FileAttachment }
17: 
18: export const Source = Schema.Struct({
19:   start: NonNegativeInt,
20:   end: NonNegativeInt,
21:   text: Schema.String,
22: }).annotate({
23:   identifier: "session.next.event.source",
24: })
25: export interface Source extends ...
gateway · 2026-09-16 20:17:14
result
<path>/home/byk/Code/opencode/packages/core/src/session/runner/index.ts</path>
<type>file</type>
<content>
1: export * as SessionRunner from "./index"
2: 
3: import type { LLMError } from "@opencode-ai/llm"
4: import { Context, Effect } from "effect"
5: import { SessionSchema } from "../schema"
6: import type { SessionMessage } from "../message"
7: import type { ContextSnapshotDecodeError, MessageDecodeError } from "../error"
8: import { SessionRunnerModel } from "./model"
9: import type { SystemContext } from "../../system-context/index"
10: import type { ToolOutputStore } from "../../tool-output-store"
11: 
12: export type RunError =
13:   | LLMError
14:   | SessionRunnerModel.Error
15:   | MessageDecodeError
16:   | ContextSnapshotDecodeError
17:   | SystemContext.InitializationBlocked
18:   | ToolOutputStore.Error
19: 
20: /** Runs one local continuation from already-recorded Session history. */
21: export interface Interface {
22:   /** Drains eligible durable work. ...
gateway · 2026-09-16 20:17:21
result
<path>/home/byk/Code/opencode/packages/server/src/routes.ts</path>
<type>file</type>
<content>
1: import { Database } from "@opencode-ai/core/database/database"
2: import { LayerNode } from "@opencode-ai/core/effect/layer-node"
3: import { httpClient } from "@opencode-ai/core/effect/app-node-platform"
4: import { AppNodeBuilder } from "@opencode-ai/core/effect/app-node-builder"
5: import { EventV2 } from "@opencode-ai/core/event"
6: import { Credential } from "@opencode-ai/core/credential"
7: import { PermissionSaved } from "@opencode-ai/core/permission/saved"
8: import { PtyTicket } from "@opencode-ai/core/pty/ticket"
9: import { SessionV2 } from "@opencode-ai/core/session"
10: import { SessionExecution } from "@opencode-ai/core/session/execution"
11: import { LocationServiceMap } from "@opencode-ai/core/location-service-map"
12: import { SessionExecutionLocal } from "@opencode-ai/core/session/execution/local"
13: import { SessionRecovery } from ...
gateway · 2026-09-16 20:17:32
result
<path>/home/byk/Code/opencode/packages/opencode/src/server/routes/instance/httpapi/server.ts</path>
<type>file</type>
<content>
1: import { Config as EffectConfig, Context, Effect, Layer } from "effect"
2: import { HttpApiBuilder, OpenApi } from "effect/unstable/httpapi"
3: import { HttpClient, HttpMiddleware, HttpRouter, HttpServer, HttpServerResponse } from "effect/unstable/http"
4: import * as Socket from "effect/unstable/socket/Socket"
5: import { FSUtil } from "@opencode-ai/core/fs-util"
6: import * as Observability from "@opencode-ai/core/observability"
7: import { Account } from "@/account/account"
8: import { Agent } from "@/agent/agent"
9: import { Auth } from "@/auth"
10: import { BackgroundJob } from "@/background/job"
11: import { Command } from "@/command"
12: import { Config } from "@/config/config"
13: import { Workspace } from "@/control-plane/workspace"
14: import { Env } from "@/env"
15: import { EventV2Bridge } from "@/event-v2-bridge"
16: import { Format } from ...
gateway · 2026-09-16 20:17:47
result
Found 3 matches
/home/byk/Code/opencode/packages/opencode/src/server/routes/instance/httpapi/server.ts:
  Line 69: import { SessionRecovery } from "@opencode-ai/core/session/recovery"

  Line 237:   SessionProjector.node,

  Line 300:       AppNodeBuilderV1.build(LayerNode.group([SessionV2.node, SessionRecovery.node]), [
gateway · 2026-09-16 20:17:56
result
<path>/home/byk/Code/opencode/packages/opencode/src/server/routes/instance/httpapi/server.ts</path>
<type>file</type>
<content>
215:   FSUtil.node,
216:   Database.node,
217:   Auth.node,
218:   Account.node,
219:   Config.node,
220:   Env.node,
221:   Git.node,
222:   Ripgrep.node,
223:   Storage.node,
224:   Snapshot.node,
225:   Plugin.node,
226:   ModelsDev.node,
227:   Provider.node,
228:   ProviderAuth.node,
229:   Agent.node,
230:   Skill.node,
231:   Discovery.node,
232:   Question.node,
233:   Permission.node,
234:   PermissionSaved.node,
235:   Todo.node,
236:   Session.node,
237:   SessionProjector.node,
238:   SessionStatus.node,
239:   BackgroundJob.node,
240:   RuntimeFlags.node,
241:   EventV2Bridge.node,
242:   SessionRunState.node,
243:   SessionProcessor.node,
244:   SessionCompaction.node,
245:   SessionRevert.node,
246:   SessionSummary.node,
247:   SessionPrompt.node,
248:   Instruction.node,
249:   LLM.node,
250:   LSP.node,
251:   MCP.node,
252:   ...
gateway · 2026-09-16 20:18:04
result
Found 77 matches
/home/byk/Code/opencode/packages/core/test/session-runner.test.ts:
  Line 26: import { Snapshot } from "@opencode-ai/core/snapshot"

  Line 767:         .set({ id: "provider-successor", owner_id: "successor", expires_at: 60_000 })

  Line 793:         .set({ id: "publication-successor", owner_id: "successor", expires_at: 60_000 })

  Line 823:               .set({ id: "tool-successor", owner_id: "successor", expires_at: 60_000 })

  Line 852:       yield* events.publish(SessionEvent.Step.Started, {

  Line 885:         .set({ id: "interrupted-tool-successor", owner_id: "successor" })

  Line 1060:   it.effect("fails gracefully when a stored context snapshot cannot be decoded", () =>

  Line 1070:         .set({ snapshot: { invalid: { value: "bad" } } })

  Line 1516:             .set({ id: "compaction-successor", owner_id: "successor", expires_at: 60_000 })

  Line 1538:       ).toEqual({ id: "compaction-successor", phase: "unknown" })

  Line 2016:       ...
gateway · 2026-09-16 20:18:29
result
<path>/home/byk/Code/opencode/packages/core/test/session-projector.test.ts</path>
<type>file</type>
<content>
300:       expect(messages[0]?.type).toBe("synthetic")
301:     }),
302:   )
303: 
304:   it.effect("never recovers a live execution lease", () =>
305:     Effect.gen(function* () {
306:       const { db } = yield* Database.Service
307:       yield* db
308:         .insert(ProjectTable)
309:         .values({ id: Project.ID.global, worktree: AbsolutePath.make("/project"), sandboxes: [] })
310:         .run()
311:       yield* db
312:         .insert(SessionTable)
313:         .values({
314:           id: sessionID,
315:           project_id: Project.ID.global,
316:           slug: "test",
317:           directory: "/project",
318:           title: "test",
319:           version: "test",
320:         })
321:         .run()
322:       yield* db
323:         .insert(SessionExecutionTable)
324:         .values({
325:           id: "execution",
326:           session_id: ...
gateway · 2026-09-16 20:18:57
result
<path>/home/byk/Code/opencode/packages/core/test/session-projector.test.ts</path>
<type>file</type>
<content>
1370:       yield* db
1371:         .insert(ProjectTable)
1372:         .values({ id: Project.ID.global, worktree: AbsolutePath.make("/project"), sandboxes: [] })
1373:         .run()
1374:       yield* db
1375:         .insert(SessionTable)
1376:         .values(
1377:           [sessionID, other].map((id) => ({
1378:             id,
1379:             project_id: Project.ID.global,
1380:             slug: id,
1381:             directory: "/project",
1382:             title: "test",
1383:             version: "test",
1384:           })),
1385:         )
1386:         .run()
1387:       yield* events.publish(SessionEvent.Step.Recovered, {
1388:         sessionID: other,
1389:         timestamp: created,
1390:         executionID: "shared-recovery-identity",
1391:         phase: "ready",
1392:       })
1393: 
1394:       const recovered = yield* events
1395:         ...
gateway · 2026-09-16 20:19:20
result
<path>/home/byk/Code/opencode/packages/core/test/session-execution-local.test.ts</path>
<type>file</type>
<content>
1: import { describe, expect } from "bun:test"
2: import { Deferred, Effect, Exit, Fiber, Scope } from "effect"
3: import { TestClock } from "effect/testing"
4: import { eq, sql } from "drizzle-orm"
5: import { Database } from "@opencode-ai/core/database/database"
6: import { Project } from "@opencode-ai/core/project"
7: import { ProjectTable } from "@opencode-ai/core/project/sql"
8: import { AbsolutePath } from "@opencode-ai/core/schema"
9: import { SessionExecutionLocal } from "@opencode-ai/core/session/execution/local"
10: import { SessionSchema } from "@opencode-ai/core/session/schema"
11: import { SessionExecutionTable, SessionTable } from "@opencode-ai/core/session/sql"
12: import { testEffect } from "./lib/effect"
13: 
14: const sessionID = SessionSchema.ID.make("ses_execution_local")
15: const it = testEffect(Database.layerFromPath(":memory:"))
16: 
17: const ...
gateway · 2026-09-16 20:19:56
result
<path>/home/byk/Code/opencode/packages/core/test/session-projector.test.ts</path>
<type>file</type>
<content>
2750:         text: "partial",
2751:       })
2752:       expect(
2753:         yield* db
2754:           .select({ id: EventTable.id })
2755:           .from(EventTable)
2756:           .where(eq(EventTable.type, SessionEvent.Compaction.Delta.type))
2757:           .all()
2758:           .pipe(Effect.orDie),
2759:       ).toEqual([])
2760:       expect(
2761:         yield* db
2762:           .select({ id: SessionMessageTable.id })
2763:           .from(SessionMessageTable)
2764:           .where(eq(SessionMessageTable.type, "compaction"))
2765:           .all()
2766:           .pipe(Effect.orDie),
2767:       ).toEqual([])
2768:       yield* events.publish(SessionEvent.Compaction.Ended, {
2769:         sessionID,
2770:         messageID: compactionID,
2771:         timestamp: DateTime.makeUnsafe(1),
2772:         reason: "manual",
2773:         text: "summary",
2774:         ...
gateway · 2026-09-16 20:20:07
result
Found 10 matches
/home/byk/Code/opencode/packages/core/test/session-projector.test.ts:
  Line 37: import { Snapshot } from "@opencode-ai/core/snapshot"

  Line 419:             assistant_seq: -1,

  Line 461:             assistant_seq: -1,

  Line 533:           assistant_seq: 0,

  Line 2269:         .select({ snapshot: SessionContextEpochTable.snapshot })

  Line 2305:           .select({ snapshot: SessionContextEpochTable.snapshot })

  Line 2362:         .select({ snapshot: SessionContextEpochTable.snapshot })

  Line 2396:           .select({ snapshot: SessionContextEpochTable.snapshot })

  Line 2547:         revert: { messageID: boundary, snapshot: Snapshot.ID.make("tree"), diff: "patch", files: [] },

  Line 2551:         snapshot: "tree",
gateway · 2026-09-16 20:20:29
result
Found 29 matches
/home/byk/Code/opencode/packages/core/test/session-prompt.test.ts:
  Line 140:   it.effect("exposes the execution registry", () =>

  Line 147:   it.effect("delegates execution continuation through SessionExecution", () =>

  Line 159:   it.effect("delegates process-local interruption through SessionExecution", () =>

  Line 171:   it.effect("delegates interruption without requiring a recorded Session", () =>

  Line 181:   it.effect("durably admits one user message before transcript promotion", () =>

  Line 203:   it.effect("resolves attachment MIME before admission", () =>

  Line 224:   it.effect("streams durable Session events after an aggregate sequence", () =>

  Line 254:   it.effect("resumes through a recorded message without appending another prompt", () =>

  Line 275:   it.effect("records distinct messages when the ID is omitted", () =>

  Line 290:   it.effect("returns the original recorded message when the ID is retried", () =>

  Line 310:   ...
gateway · 2026-09-16 20:20:43
result
Found 45 matches
/home/byk/Code/opencode/packages/core/test/session-projector.test.ts:
  Line 68:   it.effect("atomically reconciles one abandoned execution into one continuation", () =>

  Line 222:   it.effect("records a recovery continuation without forging an assistant identity", () =>

  Line 258:   it.effect("recovers each abandoned execution once across repeated startup scans", () =>

  Line 304:   it.effect("never recovers a live execution lease", () =>

  Line 342:   it.effect("never recovers an execution superseded by a newer assistant", () =>

  Line 504:   it.effect("recovers assistant-less continuation at its current assistant boundary", () =>

  Line 555:   it.effect("redrives a durable recovery wake after admission", () =>

  Line 606:   it.effect("quarantines a malformed recovery row without blocking a valid wake", () =>

  Line 660:   it.effect("quarantines a full batch of poison recovery rows before redriving valid work", () =>

  Line 725:   it.effect("fairly ...
gateway · 2026-09-16 20:20:56
result
<path>/home/byk/Code/opencode/packages/core/test/session-projector.test.ts</path>
<type>file</type>
<content>
50: const created = DateTime.makeUnsafe(0)
51: const model = { id: ModelV2.ID.make("model"), providerID: ProviderV2.ID.make("provider") }
52: const encodeMessage = Schema.encodeSync(SessionMessage.Message)
53: 
54: const assistantRow = (
55:   id: SessionMessage.ID,
56:   seq: number,
57:   time: { created: DateTime.Utc; completed?: DateTime.Utc } = { created },
58: ) => {
59:   const {
60:     id: _,
61:     type,
62:     ...data
63:   } = encodeMessage(SessionMessage.Assistant.make({ id, type: "assistant", agent: "build", model, content: [], time }))
64:   return { id, session_id: sessionID, type, seq, time_created: DateTime.toEpochMillis(time.created), data }
65: }
66: 
67: describe("SessionProjector", () => {
68:   it.effect("atomically reconciles one abandoned execution into one continuation", () =>
69:     Effect.gen(function* () {
70:       const { db } = yield* ...
gateway · 2026-09-16 20:21:11
result
<path>/home/byk/Code/opencode/packages/core/test/session-projector.test.ts</path>
<type>file</type>
<content>
600:           wake_pending: true,
601:         }),
602:       ])
603:     }),
604:   )
605: 
606:   it.effect("quarantines a malformed recovery row without blocking a valid wake", () =>
607:     Effect.gen(function* () {
608:       const { db } = yield* Database.Service
609:       const events = yield* EventV2.Service
610:       const valid = SessionV2.ID.make("ses_recovery_row_valid")
611:       yield* db
612:         .insert(ProjectTable)
613:         .values({ id: Project.ID.global, worktree: AbsolutePath.make("/project"), sandboxes: [] })
614:         .run()
615:       yield* db
616:         .insert(SessionTable)
617:         .values(
618:           [sessionID, valid].map((id) => ({
619:             id,
620:             project_id: Project.ID.global,
621:             slug: id,
622:             directory: "/project",
623:             title: "test",
624:             ...
gateway · 2026-09-16 20:21:30
result
<path>/home/byk/Code/opencode/packages/core/test/session-runner.test.ts</path>
<type>file</type>
<content>
680:         LLMEvent.finish({ reason: "stop" }),
681:       ]
682:       yield* session.resume(sessionID)
683:       expect(userTexts(requests[1]!)).toContain("ordinary work after replayed recovery")
684:       requests.length = 0
685:     }),
686:   )
687: 
688:   it.effect("clears durable execution intent when ordinary input is promoted", () =>
689:     Effect.gen(function* () {
690:       yield* setup
691:       const session = yield* SessionV2.Service
692:       const message = yield* session.prompt({
693:         sessionID,
694:         prompt: Prompt.make({ text: "clear durable wake" }),
695:         resume: false,
696:       })
697:       const { db } = yield* Database.Service
698:       yield* db.update(SessionInputTable).set({ wake_pending: true }).where(eq(SessionInputTable.id, message.id)).run()
699:       response = [
700:         LLMEvent.stepStart({ index: 0 ...
gateway · 2026-09-16 20:21:52
result
<path>/home/byk/Code/opencode/packages/core/test/database-migration.test.ts</path>
<type>file</type>
<content>
1: import { describe, expect, test } from "bun:test"
2: import { $ } from "bun"
3: import { fileURLToPath } from "url"
4: import path from "path"
5: import { SqliteClient } from "@effect/sql-sqlite-bun"
6: import { EffectDrizzleSqlite } from "@opencode-ai/effect-drizzle-sqlite"
7: import { Effect, Exit, Layer } from "effect"
8: import { eq, inArray, sql } from "drizzle-orm"
9: import { DatabaseMigration } from "@opencode-ai/core/database/migration"
10: import { migrations } from "@opencode-ai/core/database/migration.gen"
11: import workspaceNameMigration from "@opencode-ai/core/database/migration/20260410174513_workspace-name"
12: import sessionUsageMigration from "@opencode-ai/core/database/migration/20260510033149_session_usage"
13: import normalizeStoragePathsMigration from "@opencode-ai/core/database/migration/20260601010001_normalize_storage_paths"
14: import ...
gateway · 2026-09-16 20:22:00
result
<path>/home/byk/Code/opencode/packages/core/test/database-migration.test.ts</path>
<type>file</type>
<content>
166:   test("adds final recovery ownership tables to a populated predecessor", async () => {
167:     await run(
168:       Effect.gen(function* () {
169:         const db = yield* makeDb
170:         yield* db.run(sql`CREATE TABLE session (id text PRIMARY KEY)`)
171:         yield* db.run(sql`CREATE TABLE session_message (id text PRIMARY KEY)`)
172:         yield* db.run(
173:           sql`CREATE TABLE session_input (id text PRIMARY KEY, session_id text NOT NULL, promoted_seq integer, time_created integer NOT NULL)`,
174:         )
175:         yield* db.run(sql`INSERT INTO session (id) VALUES ('ses_existing')`)
176:         yield* db.run(sql`INSERT INTO session_message (id) VALUES ('msg_existing')`)
177:         yield* db.run(sql`INSERT INTO session_input (id, session_id, time_created) VALUES ('msg_input', 'ses_existing', 0)`)
178: 
179:         yield* ...
gateway · 2026-09-16 20:22:13
result
Found 100 matches (more matches available)
/home/byk/Code/opencode/packages/sdk/openapi.json:
  Line 17899:                       "requestExecution": {

  Line 18110:                       "assistantMessageID": {

  Line 18124:                     "required": ["timestamp", "sessionID", "assistantMessageID", "agent", "model"],

  Line 18152:                       "assistantMessageID": {

  Line 18201:                     "required": ["timestamp", "sessionID", "assistantMessageID", "finish", "cost", "tokens"],

  Line 18229:                       "assistantMessageID": {

  Line 18237:                     "required": ["timestamp", "sessionID", "assistantMessageID", "error"],

  Line 18265:                       "assistantMessageID": {

  Line 18273:                     "required": ["timestamp", "sessionID", "assistantMessageID", "error"],

  Line 18289:                     "enum": ["session.next.step.recovered"]

  Line 18301:                       "executionID": {

  Line 18304:         ...
gateway · 2026-09-16 20:22:23
result
Found 19 matches
/home/byk/Code/opencode/packages/sdk/js/src/v2/gen/types.gen.ts:
  Line 33:   | EventSessionNextStepRecovered

  Line 874:           requestExecution?: boolean

  Line 983:         type: "session.next.step.recovered"

  Line 987:           executionID: string

  Line 1659:     | SyncEventSessionNextStepRecovered

  Line 2794:   | SessionNextStepRecovered

  Line 2924:   | SessionNextStepRecovered

  Line 3430:       requestExecution?: boolean

  Line 3602: export type SyncEventSessionNextStepRecovered = {

  Line 3606:     type: "session.next.step.recovered.1"

  Line 3613:       executionID: string

  Line 4362:     requestExecution?: boolean

  Line 4560: export type SessionNextStepRecovered = {

  Line 4565:   type: "session.next.step.recovered"

  Line 4575:     executionID: string

  Line 6464:     requestExecution?: boolean

  Line 6581: export type EventSessionNextStepRecovered = {

  Line 6583:   type: "session.next.step.recovered"

  Line 6587:     ...
gateway · 2026-09-16 20:22:39
result
<path>/home/byk/Code/opencode/packages/schema/test/event-manifest.test.ts</path>
<type>file</type>
<content>
1: import { describe, expect, test } from "bun:test"
2: import { FileSystem, Integration, Permission, Project, Reference, Session, Workspace } from "../src"
3: import { EventManifest } from "../src/event-manifest"
4: import { IdeEvent } from "../src/ide-event"
5: import { SessionEvent } from "../src/session-event"
6: import { SessionTodo } from "../src/session-todo"
7: import { SessionV1 } from "../src/session-v1"
8: import { WorkspaceEvent } from "../src/workspace-event"
9: 
10: describe("public event manifest", () => {
11:   test("owns the complete public event surface", () => {
12:     expect(EventManifest.ServerDefinitions.length).toBe(61)
13:     expect(EventManifest.Definitions.length).toBe(91)
14:     expect(SessionV1.Event.Definitions).toEqual([
15:       SessionV1.Event.Created,
16:       SessionV1.Event.Updated,
17:       SessionV1.Event.Deleted,
18:       ...
gateway · 2026-09-16 20:22:51
result
<path>/tmp/opencode/session-recovery-final-v13.patch</path>
<type>file</type>
<content>
7160:      }),
7161:    )
7162: diff --git a/packages/core/test/session-run-coordinator.test.ts b/packages/core/test/session-run-coordinator.test.ts
7163: index dfbeda664c..63dfad7a71 100644
7164: --- a/packages/core/test/session-run-coordinator.test.ts
7165: +++ b/packages/core/test/session-run-coordinator.test.ts
7166: @@ -282,6 +282,51 @@ describe("SessionRunCoordinator", () => {
7167:      ),
7168:    )
7169:  
7170: +  it.effect("finalizes interruption when cleanup dies", () =>
7171: +    Effect.scoped(
7172: +      Effect.gen(function* () {
7173: +        const firstStarted = yield* Deferred.make<void>()
7174: +        const cleanupStarted = yield* Deferred.make<void>()
7175: +        const cleanupGate = yield* Deferred.make<void>()
7176: +        const secondStarted = yield* Deferred.make<void>()
7177: +        const defect = new Error("cleanup defect")
7178: +        let runs = 0
7179: +    ...
gateway · 2026-09-16 20:23:06
result
<path>/home/byk/Code/opencode/packages/core/test/session-run-coordinator.test.ts</path>
<type>file</type>
<content>
260:                   ? Deferred.succeed(firstStarted, undefined).pipe(
261:                       Effect.andThen(Effect.never),
262:                       Effect.onInterrupt(() =>
263:                         Deferred.succeed(cleanupStarted, undefined).pipe(Effect.andThen(Deferred.await(cleanupGate))),
264:                       ),
265:                     )
266:                   : Deferred.succeed(secondStarted, undefined),
267:               ),
268:             ),
269:         })
270: 
271:         yield* coordinator.wake("session")
272:         yield* Deferred.await(firstStarted)
273:         const interrupt = yield* coordinator.interrupt("session").pipe(Effect.forkChild)
274:         yield* Deferred.await(cleanupStarted)
275:         yield* coordinator.wake("session")
276:         yield* Deferred.succeed(cleanupGate, undefined)
277:         yield* ...
gateway · 2026-09-16 20:23:35
result
<path>/home/byk/Code/opencode/packages/core/src/session/projector.ts</path>
<type>file</type>
<content>
500:     yield* events.project(SessionEvent.RevertEvent.Committed, (event) =>
501:       Effect.gen(function* () {
502:         const boundary = yield* db
503:           .select({ seq: SessionMessageTable.seq })
504:           .from(SessionMessageTable)
505:           .where(
506:             and(
507:               eq(SessionMessageTable.session_id, event.data.sessionID),
508:               eq(SessionMessageTable.id, event.data.messageID),
509:             ),
510:           )
511:           .get()
512:           .pipe(Effect.orDie)
513:         if (!boundary) return yield* Effect.die(`Revert boundary message not found: ${event.data.messageID}`)
514:         yield* db
515:           .delete(SessionMessageTable)
516:           .where(
517:             and(eq(SessionMessageTable.session_id, event.data.sessionID), gt(SessionMessageTable.seq, boundary.seq)),
518:           )
519:        ...
gateway · 2026-09-16 20:24:11
result
Found 5 matches
/home/byk/Code/opencode/packages/core/test/session-projector.test.ts:
  Line 1862:   it.effect("never quarantines cancellation after recovery ownership expires", () =>

  Line 1914:   it.effect("never quarantines projection failure after recovery ownership expires", () =>

  Line 2199:           owner_id: "successor",

  Line 2296:         .set({ id: "successor-advance", owner_id: "successor-owner", expires_at: 60_000 })

  Line 2469:           owner_id: "successor-owner",
gateway · 2026-09-16 20:24:34
result
<path>/home/byk/Code/opencode/packages/core/src/session/message-updater.ts</path>
<type>file</type>
<content>
1: import { castDraft, produce, type WritableDraft } from "immer"
2: import { Effect } from "effect"
3: import { SessionEvent } from "./event"
4: import { SessionMessage } from "./message"
5: import { message } from "./recovery-id"
6: 
7: export type MemoryState = {
8:   messages: SessionMessage.Message[]
9: }
10: 
11: export interface Adapter {
12:   readonly getCurrentAssistant: () => Effect.Effect<SessionMessage.Assistant | undefined>
13:   readonly getAssistant: (messageID: SessionMessage.ID) => Effect.Effect<SessionMessage.Assistant | undefined>
14:   readonly getCurrentShell: (callID: string) => Effect.Effect<SessionMessage.Shell | undefined>
15:   readonly updateAssistant: (assistant: SessionMessage.Assistant) => Effect.Effect<void>
16:   readonly updateShell: (shell: SessionMessage.Shell) => Effect.Effect<void>
17:   readonly appendMessage: (message: ...
gateway · 2026-09-16 20:24:49
result
...output truncated...

Full output saved to: /home/byk/.local/share/opencode/tool-output/tool_0abe4bc6f001ARGqKQzk1YnJJf

 +                      stored?.sessionID === claim.session_id &&
 +                      stored.assistantMessageID === (assistantMessageID ?? null) &&
 +                      stored.continuationMessageID === continuation(claim.id) &&
 +                      stored.phase === phase.value
 +                    )
 +                      return Effect.void
-+                    return db
-+                      .update(SessionExecutionTable)
-+                      .set({ recovery_error: "Recovery projection failed" })
-+                      .where(
-+                        and(
-+                          eq(SessionExecutionTable.id, recoveryClaim.executionID),
-+                          eq(SessionExecutionTable.session_id, recoveryClaim.sessionID),
-+                          eq(SessionExecutionTable.owner_id, recoveryClaim.ownerID),
-+                          ...
gateway · 2026-09-16 20:25:12
result
<path>/tmp/opencode/session-recovery-final-v13.patch</path>
<type>file</type>
<content>
6835: diff --git a/packages/core/test/session-prompt.test.ts b/packages/core/test/session-prompt.test.ts
6836: index c6bc9430b3..a0d6f26467 100644
6837: --- a/packages/core/test/session-prompt.test.ts
6838: +++ b/packages/core/test/session-prompt.test.ts
6839: @@ -1,6 +1,6 @@
6840:  import { describe, expect } from "bun:test"
6841:  import { DateTime, Effect, Fiber, Layer, Stream } from "effect"
6842: -import { eq } from "drizzle-orm"
6843: +import { asc, eq } from "drizzle-orm"
6844:  import { Database } from "@opencode-ai/core/database/database"
6845:  import { AppNodeBuilder } from "@opencode-ai/core/effect/app-node-builder"
6846:  import { LayerNode } from "@opencode-ai/core/effect/layer-node"
6847: @@ -16,6 +16,7 @@ import { SessionMessage } from "@opencode-ai/core/session/message"
6848:  import { SessionProjector } from "@opencode-ai/core/session/projector"
6849:  import { SessionExecution } ...
gateway · 2026-09-16 20:25:23
result
Found 96 matches
/home/byk/Code/opencode/packages/core/test/session-runner.test.ts:
  Line 619:   it.effect("redrives only the synthetic recovery continuation", () =>

  Line 688:   it.effect("clears durable execution intent when ordinary input is promoted", () =>

  Line 715:   it.effect("redrives an ordinary prompt after its advisory wake is lost", () =>

  Line 752:   it.effect("never dispatches a provider after ownership changes", () =>

  Line 778:   it.effect("never publishes streamed output after ownership changes", () =>

  Line 805:   it.effect("never starts a local tool after ownership changes", () =>

  Line 845:   it.effect("never fails interrupted tools after ownership changes", () =>

  Line 902:   it.effect("advertises and executes a globally attached application tool", () =>

  Line 958:   it.effect("starts a real runner turn after default prompt recording", () =>

  Line 977:   it.effect("streams one request with registry definitions from chronological V2 user ...
gateway · 2026-09-16 20:25:48
result
<path>/home/byk/Code/opencode/packages/core/test/session-runner.test.ts</path>
<type>file</type>
<content>
560:         : fixture.expectedContent
561:     expect(yield* session.context(sessionID)).toMatchObject([
562:       { type: "user", text: prompt },
563:       {
564:         type: "assistant",
565:         finish: "error",
566:         error: { type: "unknown", message: "Provider unavailable" },
567:         content: [expectedContent],
568:       },
569:     ])
570:   })
571: 
572: const verifyPartialFlushOnInterruption = (kind: FragmentKind) =>
573:   Effect.gen(function* () {
574:     yield* setup
575:     const session = yield* SessionV2.Service
576:     const prompt = `Interrupt after ${kind}`
577:     const fixture = fragmentFixture(kind, fragmentID(kind, "interrupted"), ["Partial"])
578:     const streamed = yield* Deferred.make<void>()
579:     yield* session.prompt({ sessionID, prompt: Prompt.make({ text: prompt }), resume: false })
580:     responseStream = ...
gateway · 2026-09-16 20:26:09
result
verified_blob_pairs=33 mismatches=0
gateway · 2026-09-16 20:26:58
result
Found 7 matches
/home/byk/Code/opencode/packages/core/src/tool/registry.ts:
  Line 31:   readonly settle: (input: ExecuteInput) => Effect.Effect<Settlement, ToolOutputStore.Error>

  Line 50:     const settleWith = Effect.fn("ToolRegistry.settle")(function* (input: ExecuteInput, advertised?: object) {

  Line 62:       const pending = yield* settle(registration.tool, input.call, {

  Line 116:           settle: (input) => {


/home/byk/Code/opencode/packages/core/src/tool/tool.ts:
  Line 66:   readonly settle: (call: ToolCall, context: Context) => Effect.Effect<ToolOutput, ToolFailure>

  Line 91:     settle: (call, context) =>

  Line 150: export const settle = (tool: AnyTool, call: ToolCall, context: Context) => runtimeOf(tool).settle(call, context)
gateway · 2026-09-16 20:27:21
result
<path>/home/byk/Code/opencode/packages/core/src/tool/registry.ts</path>
<type>file</type>
<content>
1: export * as ToolRegistry from "./registry"
2: 
3: import { ToolOutput, type ToolCall, type ToolDefinition, type ToolResultValue } from "@opencode-ai/llm"
4: import { Context, Effect, Layer, Scope } from "effect"
5: import { AgentV2 } from "../agent"
6: import { PermissionV2 } from "../permission"
7: import { SessionMessage } from "../session/message"
8: import { SessionSchema } from "../session/schema"
9: import { ToolOutputStore } from "../tool-output-store"
10: import { Wildcard } from "../util/wildcard"
11: import { ApplicationTools } from "./application-tools"
12: import { definition, permission, settle, validateName, type AnyTool, type RegistrationError } from "./tool"
13: import { Tools } from "./tools"
14: import { makeLocationNode } from "../effect/app-node"
15: 
16: export type ExecuteInput = {
17:   readonly sessionID: SessionSchema.ID
18:   readonly agent: AgentV2.ID
19:   ...
gateway · 2026-09-16 20:28:00
result
<path>/home/byk/Code/opencode/packages/core/src/tool/tool.ts</path>
<type>file</type>
<content>
50:     readonly input: Schema.Schema.Type<Input>
51:     readonly output: Output["Encoded"]
52:   }) => Schema.Schema.Type<Structured>
53:   readonly execute: (
54:     input: Schema.Schema.Type<Input>,
55:     context: Context,
56:   ) => Effect.Effect<Schema.Schema.Type<Output>, ToolFailure>
57:   readonly toModelOutput?: (input: {
58:     readonly input: Schema.Schema.Type<Input>
59:     readonly output: Output["Encoded"]
60:   }) => ReadonlyArray<Content>
61: }
62: 
63: type Runtime = {
64:   readonly permission?: string
65:   readonly definition: (name: string) => ToolDefinition
66:   readonly settle: (call: ToolCall, context: Context) => Effect.Effect<ToolOutput, ToolFailure>
67: }
68: 
69: const runtimes = new WeakMap<AnyTool, Runtime>()
70: 
71: export function make<
72:   Input extends SchemaType<any>,
73:   Output extends SchemaType<any>,
74:   Structured extends SchemaType<any> ...
gateway · 2026-09-16 20:28:21
result
Found 66 matches
/home/byk/Code/opencode/packages/core/src/tool/write.ts:
  Line 14: import { PermissionV2 } from "../permission"

  Line 52:     const permission = yield* PermissionV2.Service

  Line 56:         [name]: Tool.withPermission(

  Line 73:                   yield* permission.assert({

  Line 74:                     ...LocationMutation.externalDirectoryPermission(external),

  Line 79:                 yield* permission.assert({

  Line 100:   deps: [ToolRegistry.node, LocationMutation.node, FileMutation.node, PermissionV2.node],


/home/byk/Code/opencode/packages/core/src/tool/glob.ts:
  Line 11: import { PermissionV2 } from "../permission"

  Line 43:     const permission = yield* PermissionV2.Service

  Line 62:               yield* permission.assert({

  Line 104:   deps: [ToolRegistry.node, Ripgrep.node, Location.node, PermissionV2.node],


/home/byk/Code/opencode/packages/core/src/tool/edit.ts:
  Line 17: import { PermissionV2 } from "../permission"

  Line 96:     ...
gateway · 2026-09-16 20:28:49
result
<path>/home/byk/Code/opencode/packages/core/src/tool/bash.ts</path>
<type>file</type>
<content>
100:     const mutation = yield* LocationMutation.Service
101:     const fs = yield* FSUtil.Service
102:     const appProcess = yield* AppProcess.Service
103:     const config = yield* Config.Service
104:     const permission = yield* PermissionV2.Service
105: 
106:     yield* tools
107:       .register({
108:         [name]: Tool.make({
109:           description: `Execute one shell command string with the host user's filesystem, process, and network authority. The active Location is the default working directory. Relative workdir values resolve from that Location. External workdir values require external_directory approval; best-effort command-argument path warnings are advisory only. Timeout values are milliseconds (default: ${DEFAULT_TIMEOUT_MS}; maximum: ${MAX_TIMEOUT_MS}). Uses the configured shell when set; otherwise uses /bin/sh on POSIX and COMSPEC or cmd.exe on Windows.`,
110:     ...
gateway · 2026-09-16 20:29:37
result
<path>/home/byk/Code/opencode/packages/core/src/session.ts</path>
<type>file</type>
<content>
280:             order === "asc"
281:               ? or(
282:                   gt(sortColumn, input.anchor.time),
283:                   and(eq(sortColumn, input.anchor.time), gt(SessionTable.id, input.anchor.id)),
284:                 )!
285:               : or(
286:                   lt(sortColumn, input.anchor.time),
287:                   and(eq(sortColumn, input.anchor.time), lt(SessionTable.id, input.anchor.id)),
288:                 )!,
289:           )
290:         }
291:         const query = db
292:           .select()
293:           .from(SessionTable)
294:           .where(conditions.length > 0 ? and(...conditions) : undefined)
295:           .orderBy(
296:             order === "asc" ? asc(sortColumn) : desc(sortColumn),
297:             order === "asc" ? asc(SessionTable.id) : desc(SessionTable.id),
298:           )
299:         const rows = yield* (input.limit === undefined ? ...
gateway · 2026-09-16 20:29:47
result
<path>/home/byk/Code/opencode/packages/core/test/session-prompt.test.ts</path>
<type>file</type>
<content>
630:       const events = yield* EventV2.Service
631:       const first = yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Before cutoff" }), resume: false })
632:       const cutoff = first.admittedSeq
633:       const second = yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "After cutoff" }), resume: false })
634: 
635:       yield* SessionInput.promoteSteers(db, events, sessionID, cutoff)
636: 
637:       expect(yield* admitted(first.id)).toHaveProperty("promotedSeq")
638:       expect(yield* admitted(second.id)).not.toHaveProperty("promotedSeq")
639:     }),
640:   )
641: 
642:   it.effect("reprojects pending inbox input without scheduling execution", () =>
643:     Effect.gen(function* () {
644:       yield* setup
645:       const { db } = yield* Database.Service
646:       const session = yield* SessionV2.Service
647:       wakeCalls.length = ...
gateway · 2026-09-16 20:31:06
result
Found 57 matches
/home/byk/Code/opencode/packages/core/schema.json:
  Line 66:       "name": "session_execution",

  Line 78:       "name": "session_recovery",

  Line 941:       "table": "session_execution"

  Line 951:       "table": "session_execution"

  Line 961:       "table": "session_execution"

  Line 971:       "table": "session_execution"

  Line 981:       "table": "session_execution"

  Line 989:       "name": "assistant_seq",

  Line 991:       "table": "session_execution"

  Line 1001:       "table": "session_execution"

  Line 1011:       "table": "session_execution"

  Line 1021:       "table": "session_execution"

  Line 1089:       "name": "wake_pending",

  Line 1181:       "table": "session_recovery"

  Line 1191:       "table": "session_recovery"

  Line 1201:       "table": "session_recovery"

  Line 1211:       "table": "session_recovery"

  Line 1221:       "table": "session_recovery"

  Line 1229:       "name": "wake_pending",

  Line 1231:       "table": ...
gateway · 2026-09-16 20:32:17
result
No files found
gateway · 2026-09-16 20:32:50
result
Found 42 matches
/home/byk/Code/opencode/packages/core/src/database/schema.gen.ts:
  Line 206:           \`wake_attempts\` integer DEFAULT 0 NOT NULL,

  Line 213:           CONSTRAINT "session_recovery_wake_attempts_check" CHECK("wake_attempts" >= 0 AND "wake_attempts" <= 9007199254740991)

  Line 247:           \`wake_attempts\` integer DEFAULT 0 NOT NULL,

  Line 249:           CONSTRAINT "session_wake_attempts_check" CHECK("wake_attempts" >= 0 AND "wake_attempts" <= 9007199254740991)

  Line 314:         `CREATE INDEX \`session_recovery_wake_pending_error_attempts_created_execution_idx\` ON \`session_recovery\` (\`wake_pending\`,\`recovery_error\`,\`wake_attempts\`,\`time_created\`,\`execution_id\`);`,


/home/byk/Code/opencode/packages/core/src/database/migration/20260914170650_session-recovery.ts:
  Line 10:         `ALTER TABLE \`session\` ADD \`wake_attempts\` integer DEFAULT 0 NOT NULL CONSTRAINT \`session_wake_attempts_check\` CHECK(\`wake_attempts\` >= 0 AND ...
gateway · 2026-09-16 20:34:17
result
No files found
gateway · 2026-09-16 20:35:23

Verification

  • PASS Base ab9408c81cc9916177641ae8e9f08624fc27b5b9 exists as a commit.
  • PASS Patch SHA-256 matches 3e9b20cb5ec05d1065b6bc78bab00b47e8ca9296bc819689a4f3d889eddcb5bf.
  • PASS SEA SHA-256 matches c3b8c5d78e473ad4104a5b54617900e28921a283029b8484be7bce4bc3cee85a.
  • PASS The patch contains 33 unique paths. All 33 old blob IDs match the stated base and all 33 new blob IDs match the frozen candidate. Reverse application also checks cleanly.
  • Inspected all 33 paths. I did not mutate files, run tests, build artifacts, or touch services.

Findings

MUST-FIX — ordinary wake retry debt survives settled work and can starve later prompts

session.wake_attempts belongs to the Session and only increases:

  • packages/core/src/session/sql.ts:63
  • packages/core/src/session/recovery.ts:395-445
  • packages/core/src/session/recovery.ts:449-480

Prompt promotion clears the input’s wake state but never resets the Session counter:

  • packages/core/src/session/input.ts:260-301

The scheduler reserves only one ordinary retry slot per scan at packages/core/src/session/recovery.ts:395-410, then ranks retries by their persistent attempt count. This leaks retry debt across independent work episodes.

For example:

  1. Session A accumulates 60,000 attempts during an outage.
  2. Its old input eventually promotes, but A keeps wake_attempts = 60000.
  3. A later prompt loses its advisory wake.
  4. One permanently failing Session B starts at attempt 1.
  5. B monopolizes the retry slot until its count catches A. Continuous lower-count retry work can starve A indefinitely.

The MAX_WAKE_ATTEMPTS rotation at packages/core/src/session/recovery.ts:403-405 does not help in practice because the maximum is Number.MAX_SAFE_INTEGER.

Existing fairness coverage at packages/core/test/session-projector.test.ts:725-857 starts each work set with comparable counters. It does not cover a new work episode on a Session carrying historical retry debt. ...

gpt-5.6-sol · 2026-09-16 20:35:23 · ~1.2K tokens