DashboardopencodeSession 0nfk7PGYQ93s

Session 0nfk7PGYQ93s

Full ID: 0nfk7PGYQ93s1uCW2
Messages: 95
Distillations: 16
Time range: 2026-09-17 08:33:19 — 2026-09-17 08:55:50

Conversation (95 messages)

Perform a strict READ-ONLY security/pentest review of frozen v20 in /tmp/opencode/session-recovery-v20-review. Do not edit, run tests/builds/services, mutate VCS/index/refs, or use recall. Read applicable guidance and inspect all changed files plus necessary context. Immutable inputs: base ab9408c81cc9916177641ae8e9f08624fc27b5b9; patch /tmp/opencode/session-recovery-final-v20.patch SHA-256 24352107c74d8245fcba7f8571ba0be4b7fc514e6c73cfbf0498f0c25f29f9ba; SEA /home/byk/Code/opencode/packages/opencode/dist/server/opencode-server SHA-256 d0c78e881892d4f894fab7f6be00643c133ca21f9d2c88ae0d5ff31215393021; 34 paths. Verify provenance/hashes/applicability first. Adversarially inspect stale-owner takeover, cancellation/finalizer order, corrupt rows, cross-Session identity, replay, duplicate wake, starvation/DoS, provider/tool/snapshot side effects, transactions, authorization, schema and generated contracts. Focus on prior v19 blockers: cancellation remains phase cancelling and publishes no Step.Interrupted until owner plus outer finalizers join; cleanup owns live exact claim, reconciles unresolved tools/Step, atomically sets cancelled, then clears before successor; publication failure retains cancelling; expired cancelled is safely cleared and cannot wedge; expired cancelling quarantines; snapshot writes have immediate claim checks. Also verify explicit resume of resume:false arms exact ordinary input before acquisition without arming conflicts/recovery continuations. Treat final synchronous check-to-external-call, process-local interruption, and bounded clock skew as disclosed residuals. Findings first with MUST-FIX/CONCERN and exact file:line evidence; if none, explicitly say so. End exactly MERGE or DO-NOT-MERGE.

gateway · 2026-09-17 08:33:19

I’ll verify the frozen inputs and repository state first, then inspect all 34 changed paths and the relevant call chains without running or modifying anything. The required repo-setup skill is not available in this session, so I’ll follow the checked-in guidance directly.

gpt-5.6-sol · 2026-09-17 08:33:19 · ~53 tokens
result
<path>/tmp/opencode/session-recovery-v20-review</path>
<type>directory</type>
<entries>
.dockerignore
.editorconfig
.git
.gitattributes
.github/
.gitignore
.gitleaksignore
.husky/
.lore.md
.opencode/
.oxlintrc.json
.prettierignore
.vscode/
.zed/
AGENTS.md
artifacts/
bun.lock
bunfig.toml
CONTEXT.md
CONTRIBUTING.md
flake.lock
flake.nix
github/
infra/
install
LICENSE
nix/
package.json
packages/
patches/
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
tsconfig.json
turbo.json

(65 entries)
</entries>
gateway · 2026-09-17 08:33:48
result
<path>/tmp/opencode/session-recovery-v20-review/AGENTS.md</path>
<type>file</type>
<content>
1: - To regenerate the legacy JavaScript SDK, run `./packages/sdk/js/script/build.ts`.
2: - After changing the public Protocol or Server `HttpApi`, run `bun run generate` from `packages/client`. Do not edit `src/generated` or `src/generated-effect` directly.
3: - Keep runtime dependencies directed from Schema to Core and Protocol, then from Core and Protocol to Server. Client runtime code may depend on Schema and Protocol but never Core or Server; `sdk-next` composes Client, Core, and Server.
4: - The default branch in this repo is `dev`.
5: - Local `main` ref may not exist; use `dev` or `origin/dev` for diffs.
6: 
7: ## Branch Names
8: 
9: Use a short branch name of at most three words, separated by hyphens. Do not use slashes or type prefixes such as `feat/` or `fix/`.
10: 
11: Examples: `session-recovery`, `fix-scroll-state`, `regenerate-sdk`. ...
gateway · 2026-09-17 08:33:53
result
<path>/tmp/opencode/session-recovery-v20-review/CONTRIBUTING.md</path>
<type>file</type>
<content>
1: # Contributing to OpenCode
2: 
3: We want to make it easy for you to contribute to OpenCode. Here are the most common type of changes that get merged:
4: 
5: - Bug fixes
6: - Additional LSPs / Formatters
7: - Improvements to LLM performance
8: - Support for new providers
9: - Fixes for environment-specific quirks
10: - Missing standard behavior
11: - Documentation improvements
12: 
13: However, any UI or core product feature must go through a design review with the core team before implementation.
14: 
15: If you are unsure if a PR would be accepted, feel free to ask a maintainer or look for issues with any of the following labels:
16: 
17: - [`help wanted`](https://github.com/anomalyco/opencode/issues?q=is%3Aissue%20state%3Aopen%20label%3Ahelp-wanted)
18: - [`good first ...
gateway · 2026-09-17 08:33:58
result
<path>/tmp/opencode/session-recovery-v20-review/package.json</path>
<type>file</type>
<content>
1: {
2:   "$schema": "https://json.schemastore.org/package.json",
3:   "name": "opencode",
4:   "description": "AI-powered development tool",
5:   "private": true,
6:   "type": "module",
7:   "packageManager": "bun@1.3.14",
8:   "scripts": {
9:     "dev": "bun run --cwd packages/opencode src/index.ts",
10:     "dev:desktop": "bun --cwd packages/desktop dev",
11:     "dev:web": "bun --cwd packages/app dev",
12:     "dev:console": "ulimit -n 10240 2>/dev/null; bun run --cwd packages/console/app dev",
13:     "dev:stats": "bun sst shell --stage=production -- bun run --cwd packages/stats/app dev",
14:     "dev:storybook": "bun --cwd packages/storybook storybook",
15:     "lint": "oxlint",
16:     "typecheck": "bun turbo typecheck",
17:     "upgrade-opentui": "bun run script/upgrade-opentui.ts",
18:     "postinstall": "bun run --cwd packages/core fix-node-pty",
19:     "prepare": "husky",
20:    ...
gateway · 2026-09-17 08:34:01
result
<path>/tmp/opencode/session-recovery-v20-review/.git</path>
<type>file</type>
<content>
1: gitdir: /home/byk/Code/opencode/.git/worktrees/session-recovery-v20-review

(End of file - total 1 lines)
</content>
gateway · 2026-09-17 08:34:14
result
24352107c74d8245fcba7f8571ba0be4b7fc514e6c73cfbf0498f0c25f29f9ba  /tmp/opencode/session-recovery-final-v20.patch
d0c78e881892d4f894fab7f6be00643c133ca21f9d2c88ae0d5ff31215393021  /home/byk/Code/opencode/packages/opencode/dist/server/opencode-server
/tmp/opencode/session-recovery-final-v20.patch 419965 bytes
/home/byk/Code/opencode/packages/opencode/dist/server/opencode-server 157879104 bytes
gateway · 2026-09-17 08:34:20
result
/tmp/opencode/session-recovery-v20-review
ab9408c81cc9916177641ae8e9f08624fc27b5b9
d3323b963b9ef2de41a7ff9884299c74b93886ba
ab9408c81cc9916177641ae8e9f08624fc27b5b9
d3323b963b9ef2de41a7ff9884299c74b93886ba
ab9408c81cc9916177641ae8e9f08624fc27b5b9
gateway · 2026-09-17 08:34:29
result
## HEAD (no branch)
 M packages/client/src/generated/types.ts
 M packages/core/schema.json
 M packages/core/src/database/migration.gen.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 packages/core/src/session/run-coordinator.ts
 M packages/core/src/session/runner/index.ts
 M packages/core/src/session/runner/llm.ts
 M packages/core/src/session/runner/publish-llm-event.ts
 M packages/core/src/session/sql.ts
 M packages/core/test/database-migration.test.ts
 M packages/core/test/session-projector.test.ts
 M packages/core/test/session-prompt.test.ts
 M packages/core/test/session-run-coordinator.test.ts
 M packages/core/test/session-runner-recorded.test.ts
 M ...
gateway · 2026-09-17 08:34:38
result
72	0	packages/client/src/generated/types.ts
567	48	packages/core/schema.json
1	0	packages/core/src/database/migration.gen.ts
62	0	packages/core/src/database/migration/20260914170650_session-recovery.ts
52	1	packages/core/src/database/schema.gen.ts
6	4	packages/core/src/session.ts
31	16	packages/core/src/session/compaction.ts
54	34	packages/core/src/session/context-epoch.ts
200	19	packages/core/src/session/execution/local.ts
391	31	packages/core/src/session/input.ts
69	0	packages/core/src/session/message-updater.ts
88	1	packages/core/src/session/projector.ts
508	0	packages/core/src/session/recovery.ts
30	5	packages/core/src/session/run-coordinator.ts
4	0	packages/core/src/session/runner/index.ts
289	104	packages/core/src/session/runner/llm.ts
108	48	packages/core/src/session/runner/publish-llm-event.ts
88	1	packages/core/src/session/sql.ts
66	1	packages/core/test/database-migration.test.ts
352	0	packages/core/test/session-execution-local.test.ts
2819	3	packages/core/test/session-project...
gateway · 2026-09-17 08:34:47
result
<path>/tmp/opencode/session-recovery-final-v20.patch</path>
<type>file</type>
<content>
1: diff --git a/packages/client/src/generated/types.ts b/packages/client/src/generated/types.ts
2: index 3b3188c874..5130fa9496 100644
3: --- a/packages/client/src/generated/types.ts
4: +++ b/packages/client/src/generated/types.ts
5: @@ -775,8 +775,17 @@ export type SessionsHistoryOutput = {
6:              }>
7:            }
8:            readonly delivery: "steer" | "queue"
9: +          readonly requestExecution?: boolean
10:          }
11:        }
12: +    | {
13: +        readonly id: string
14: +        readonly metadata?: { readonly [x: string]: JsonValue }
15: +        readonly type: "session.next.prompt.execution_requested"
16: +        readonly durable?: { readonly aggregateID: string; readonly seq: number; readonly version: number }
17: +        readonly location?: { readonly directory: string; readonly workspaceID?: string }
18: +        readonly data: { readonly timestamp: number; ...
gateway · 2026-09-17 08:35:12
result
/usr/bin/bash: line 1: python: command not found
gateway · 2026-09-17 08:35:25
result
patch_paths=34 worktree_paths=34
path_set_match=True
blob_mismatches=0
gateway · 2026-09-17 08:35:34
result
/tmp/opencode/session-recovery-v20-review/packages/app/AGENTS.md
/tmp/opencode/session-recovery-v20-review/packages/core/src/tool/AGENTS.md
/tmp/opencode/session-recovery-v20-review/packages/app/e2e/AGENTS.md
/tmp/opencode/session-recovery-v20-review/packages/app/e2e/performance/AGENTS.md
/tmp/opencode/session-recovery-v20-review/packages/session-ui/AGENTS.md
/tmp/opencode/session-recovery-v20-review/packages/effect-drizzle-sqlite/AGENTS.md
/tmp/opencode/session-recovery-v20-review/packages/llm/AGENTS.md
/tmp/opencode/session-recovery-v20-review/packages/desktop/AGENTS.md
/tmp/opencode/session-recovery-v20-review/packages/codemode/AGENTS.md
/tmp/opencode/session-recovery-v20-review/packages/opencode/AGENTS.md
/tmp/opencode/session-recovery-v20-review/packages/ui/AGENTS.md
/tmp/opencode/session-recovery-v20-review/packages/opencode/src/session/llm/AGENTS.md
/tmp/opencode/session-recovery-v20-review/packages/opencode/src/server/routes/instance/httpapi/AGENTS.md
/tmp/opencode/session-reco...
gateway · 2026-09-17 08:35:40
result
<path>/tmp/opencode/session-recovery-v20-review/packages/opencode/AGENTS.md</path>
<type>file</type>
<content>
1: # opencode database guide
2: 
3: ## Database
4: 
5: - **Schema**: Drizzle schema lives in `packages/core/src/**/*.sql.ts`.
6: - **Migrations**: database migrations live in `packages/core` and are applied by core.
7: 
8: ## Development server
9: 
10: - Running `bun dev` from `packages/opencode` starts the live interactive TUI. Do not run it as a blocking foreground command when you need to inspect the result.
11: - Start it in `tmux` instead: `tmux new-session -d -s opencode-dev 'bun dev'`.
12: - Capture the current TUI output with: `tmux capture-pane -pt opencode-dev`.
13: - Stop the session explicitly when done: `tmux kill-session -t opencode-dev`.
14: 
15: # Module shape
16: 
17: Do not use `export namespace Foo { ... }` for module organization. It is not
18: standard ESM, it prevents tree-shaking, and it breaks Node's native TypeScript
19: runner. ...
gateway · 2026-09-17 08:35:52
result
<path>/tmp/opencode/session-recovery-v20-review/packages/opencode/src/server/routes/instance/httpapi/AGENTS.md</path>
<type>file</type>
<content>
1: # HttpApi Route Patterns
2: 
3: Use `HttpApiBuilder.group(...)` for normal HTTP endpoints, including streaming HTTP responses such as server-sent events. Handlers should yield stable services once while building the handler layer, then close over those services in endpoint implementations.
4: 
5: ```ts
6: export const sessionHandlers = HttpApiBuilder.group(InstanceHttpApi, "session", (handlers) =>
7:   Effect.gen(function* () {
8:     const session = yield* Session.Service
9: 
10:     return handlers.handle("list", () => session.list())
11:   }),
12: )
13: ```
14: 
15: For SSE endpoints, stay in `HttpApiBuilder.group(...)` and return `HttpServerResponse.stream(...)` from the handler. Annotate the endpoint success schema with `HttpApiSchema.asText({ contentType: "text/event-stream" })` so OpenAPI documents the stream content type. ...
gateway · 2026-09-17 08:35:56
result
<path>/tmp/opencode/session-recovery-v20-review/packages/schema/AGENTS.md</path>
<type>file</type>
<content>
1: # Schema Package Guide
2: 
3: `@opencode-ai/schema` owns browser-safe wire and storage contracts shared by protocol, server, core, and generated SDKs. Keep runtime behavior, service layers, side effects, and host-local implementation details in the domain package that owns them.
4: 
5: ## Package Boundary
6: 
7: - Preserve the dependency direction: `@opencode-ai/schema <- @opencode-ai/protocol <- @opencode-ai/server`.
8: - Schema values should be serializable contract definitions, not service implementations or runtime registries.
9: - A domain may keep a minimal public wire contract here when SDK generation needs it, but do not move the broader runtime model into Schema just because an event is public. `plugin.added` is the current example: Schema may own the minimum browser-safe event payload, while plugin runtime behavior stays outside Schema. ...
gateway · 2026-09-17 08:36:05
result
<path>/tmp/opencode/session-recovery-v20-review/packages/core/src/session/execution/claim.ts</path>
<type>file</type>
<content>
1: export * as SessionExecutionClaim from "./claim"
2: 
3: import { and, eq, gt, notInArray } 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: ...
gateway · 2026-09-17 08:36:08
result
<path>/tmp/opencode/session-recovery-v20-review/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, DateTime, Duration, Effect, Exit, Layer, Option, 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 { EventV2 } from "../../event"
13: import { SessionEvent } from "../event"
14: import { SessionExecutionClaim } from "./claim"
15: import {
16:   SESSION_EXECUTION_LEASE_MS,
17:   SessionExecutionTable,
18:   ...
gateway · 2026-09-17 08:36:13
result
<path>/tmp/opencode/session-recovery-v20-review/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:   ...
gateway · 2026-09-17 08:36:27
result
<path>/tmp/opencode/session-recovery-v20-review/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, SessionTable } from "./sql"
14: 
15: type DatabaseService = Database.Interface["db"]
16: 
17: export { Admitted, Delivery }
18: 
19: const decodePrompt = Schema.decodeUnknownSync(Prompt)
20: const encodePrompt = ...
gateway · 2026-09-17 08:36:33
result
<path>/tmp/opencode/session-recovery-v20-review/packages/core/src/session/input.ts</path>
<type>file</type>
<content>
621:             commit(row).pipe(
622:               Effect.andThen(
623:                 db
624:                   .update(SessionRecoveryTable)
625:                   .set({ recovery_error: defect.reason })
626:                   .where(
627:                     and(
628:                       eq(SessionRecoveryTable.execution_id, defect.executionID),
629:                       eq(SessionRecoveryTable.wake_pending, true),
630:                       isNull(SessionRecoveryTable.recovery_error),
631:                     ),
632:                   )
633:                   .returning({ executionID: SessionRecoveryTable.execution_id })
634:                   .get()
635:                   .pipe(Effect.orDie),
636:               ),
637:             ),
638:           { behavior: "immediate" },
639:         )
640:         .pipe(
641:           Effect.orDie,
642:           ...
gateway · 2026-09-17 08:36:38
result
<path>/tmp/opencode/session-recovery-v20-review/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 ...
gateway · 2026-09-17 08:36:47
result
<path>/tmp/opencode/session-recovery-v20-review/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-17 08:36:55
result
<path>/tmp/opencode/session-recovery-v20-review/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-17 08:37:01
result
<path>/tmp/opencode/session-recovery-v20-review/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: ...
gateway · 2026-09-17 08:37:08
result
<path>/tmp/opencode/session-recovery-v20-review/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-17 08:37:17
result
<path>/tmp/opencode/session-recovery-v20-review/packages/core/src/session/message-updater.ts</path>
<type>file</type>
<content>
301:           draft.content.push(
302:             castDraft(SessionMessage.AssistantText.make({ type: "text", id: event.data.textID, text: "" })),
303:           )
304:         })
305:       },
306:       "session.next.text.delta": (event) => {
307:         return updateOwnedAssistant(event.data.assistantMessageID, (draft) => {
308:           const match = latestText(draft, event.data.textID)
309:           if (match) match.text += event.data.delta
310:         })
311:       },
312:       "session.next.text.ended": (event) => {
313:         return updateOwnedAssistant(event.data.assistantMessageID, (draft) => {
314:           const match = latestText(draft, event.data.textID)
315:           if (match) match.text = event.data.text
316:         })
317:       },
318:       "session.next.tool.input.started": (event) => {
319:         return ...
gateway · 2026-09-17 08:37:21
result
<path>/tmp/opencode/session-recovery-v20-review/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:   ...
gateway · 2026-09-17 08:37:25
result
<path>/tmp/opencode/session-recovery-v20-review/packages/core/src/session/projector.ts</path>
<type>file</type>
<content>
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:           .run()
520:           .pipe(Effect.orDie)
521:         ...
gateway · 2026-09-17 08:37:37
result
No files found
gateway · 2026-09-17 08:37:41
result
/tmp/opencode/session-recovery-v20-review/packages/core/src/event.ts
/tmp/opencode/session-recovery-v20-review/packages/core/src/session/event.ts
gateway · 2026-09-17 08:37:48
result
<path>/tmp/opencode/session-recovery-v20-review/packages/core/src/event.ts</path>
<type>file</type>
<content>
1: export * as EventV2 from "./event"
2: 
3: import { Cause, Context, Effect, Layer, Option, PubSub, Queue, Schema, Stream } from "effect"
4: import { Event } from "@opencode-ai/schema/event"
5: import type { Data, Definition, Payload } from "@opencode-ai/schema/event"
6: import { and, asc, eq, gt, inArray } from "drizzle-orm"
7: import { Database } from "./database/database"
8: import { EventSequenceTable, EventTable } from "./event/sql"
9: import { Location } from "./location"
10: import { makeGlobalNode } from "./effect/app-node"
11: import { isDeepStrictEqual } from "node:util"
12: import { Durable } from "@opencode-ai/schema/durable-event-manifest"
13: 
14: export const ID = Event.ID
15: export type ID = import("@opencode-ai/schema/event").ID
16: export type { Data, Definition, Payload } from "@opencode-ai/schema/event"
17: 
18: export type Subscriber<D extends Definition ...
gateway · 2026-09-17 08:37:57
result
<path>/tmp/opencode/session-recovery-v20-review/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 { ...
gateway · 2026-09-17 08:38:03
result
<path>/tmp/opencode/session-recovery-v20-review/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 ...
gateway · 2026-09-17 08:38:10
result
<path>/tmp/opencode/session-recovery-v20-review/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:     ...
gateway · 2026-09-17 08:38:15
result
Found 21 matches
/tmp/opencode/session-recovery-v20-review/packages/core/src/database/schema.gen.ts:
  Line 158:         CREATE TABLE \`session_execution\` (

  Line 168:           CONSTRAINT \`session_execution_pk\` PRIMARY KEY(\`id\`),

  Line 169:           CONSTRAINT \`fk_session_execution_session_id_session_id_fk\` FOREIGN KEY (\`session_id\`) REFERENCES \`session\`(\`id\`) ON DELETE CASCADE,

  Line 170:           CONSTRAINT "session_execution_phase_check" CHECK("phase" IN ('ready', 'safe', 'unknown', 'continue', 'cancelling', 'cancelled'))

  Line 181:           \`wake_pending\` integer DEFAULT false NOT NULL,

  Line 199:         CREATE TABLE \`session_recovery\` (

  Line 205:           \`wake_pending\` integer DEFAULT true NOT NULL,

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

  Line 209:           CONSTRAINT \`session_recovery_pk\` PRIMARY KEY(\`execution_id\`),

  Line 210:           CONSTRAINT \`fk_session_recovery_session_id_session_id_fk\` ...
gateway · 2026-09-17 08:38:22
result
<path>/tmp/opencode/session-recovery-v20-review/packages/core/src/database/schema.gen.ts</path>
<type>file</type>
<content>
135:         );
136:       `)
137:       yield* tx.run(`
138:         CREATE TABLE \`part\` (
139:           \`id\` text PRIMARY KEY,
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 ...
gateway · 2026-09-17 08:38:28
result
<path>/tmp/opencode/session-recovery-v20-review/packages/core/src/session.ts</path>
<type>file</type>
<content>
1: export * as SessionV2 from "./session"
2: export * from "./session/schema"
3: 
4: import { DateTime, Effect, Layer, Schema, Context, Stream } from "effect"
5: import { ListAnchor } from "@opencode-ai/schema/session"
6: import { and, asc, desc, eq, gt, like, lt, or, type SQL } from "drizzle-orm"
7: import { ProjectV2 } from "./project"
8: import { WorkspaceV2 } from "./workspace"
9: import { ModelV2 } from "./model"
10: import { Location } from "./location"
11: import { SessionMessage } from "./session/message"
12: import { Prompt } from "./session/prompt"
13: import { PromptInput } from "@opencode-ai/schema/prompt-input"
14: import { EventV2 } from "./event"
15: import { Database } from "./database/database"
16: import { SessionProjector } from "./session/projector"
17: import { SessionMessageTable, SessionTable } from "./session/sql"
18: import { SessionSchema } from ...
gateway · 2026-09-17 08:38:34
result
<path>/tmp/opencode/session-recovery-v20-review/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: ...
gateway · 2026-09-17 08:38:48
result
<path>/tmp/opencode/session-recovery-v20-review/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. ...
gateway · 2026-09-17 08:38:52
result
<path>/tmp/opencode/session-recovery-v20-review/packages/core/src/session/recovery-id.ts</path>
<type>file</type>
<content>
1: import { SessionMessage } from "./message"
2: 
3: export const message = (executionID: string, assistantMessageID?: SessionMessage.ID) =>
4:   assistantMessageID ?? SessionMessage.ID.make(`msg_recovery_${executionID}`)
5: 
6: export const continuation = (executionID: string) => SessionMessage.ID.make(`msg_recovery_continue_${executionID}`)

(End of file - total 6 lines)
</content>
gateway · 2026-09-17 08:38:57
result
<path>/tmp/opencode/session-recovery-v20-review/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-17 08:39:02
result
<path>/tmp/opencode/session-recovery-v20-review/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 { ...
gateway · 2026-09-17 08:39:07
result
<path>/tmp/opencode/session-recovery-v20-review/packages/opencode/src/server/routes/instance/httpapi/server.ts</path>
<type>file</type>
<content>
261:   Installation.node,
262:   ShareNext.node,
263:   SessionShare.node,
264:   InstanceStore.node,
265:   httpClient,
266:   EventV2.node,
267:   ProjectV2.node,
268:   ProjectCopy.node,
269:   PtyTicket.node,
270: ])
271: 
272: export function createRoutes(
273:   corsOptions?: CorsOptions,
274: ): Layer.Layer<never, EffectConfig.ConfigError, RouteRequirements> {
275:   const locationServiceMapV2 = buildLocationServiceMap()
276: 
277:   return Layer.mergeAll(
278:     rootApiRoutes,
279:     eventApiRoutes,
280:     ptyConnectApiRoutes,
281:     instanceRoutes,
282:     serverRoutes,
283:     docRoute,
284:     uiRoute,
285:   ).pipe(
286:     Layer.provide([
287:       errorLayer,
288:       compressionLayer,
289:       corsVaryFix,
290:       fenceLayer,
291:       cors(corsOptions),
292:       AppNodeBuilderV1.build(MoveSession.node, ...
gateway · 2026-09-17 08:39:14
result
<path>/tmp/opencode/session-recovery-v20-review/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 ...
gateway · 2026-09-17 08:39:19
result
Found 100 matches (more matches available)
/tmp/opencode/session-recovery-v20-review/packages/core/test/session-runner.test.ts:
  Line 96:           Effect.andThen(Deferred.await(streamGate)),

  Line 146:             if (toolExecutionGate) yield* Deferred.await(toolExecutionGate)

  Line 256: const it = testEffect(

  Line 588:     yield* Deferred.await(streamed)

  Line 618: describe("SessionRunnerLLM", () => {

  Line 721:       const { admitted: message } = yield* SessionInput.admit(db, events, {

  Line 759:       modelResolveHook = Deferred.succeed(resolving, undefined).pipe(Effect.andThen(Deferred.await(resumeResolution)))

  Line 763:       yield* Deferred.await(resolving)

  Line 771:       yield* Fiber.await(run)

  Line 789:       yield* Deferred.await(streamStarted)

  Line 797:       yield* Fiber.await(run)

  Line 1775:       expect(yield* Fiber.await(run)).toMatchObject({ _tag: "Failure" })

  Line 2328:       yield* Deferred.await(toolExecutionsStarted)

  Line 2486:   ...
gateway · 2026-09-17 08:39:25
result
Found 12 matches
/tmp/opencode/session-recovery-v20-review/packages/core/test/util/effect-flock.test.ts:
  Line 349:             .split("\n")


/tmp/opencode/session-recovery-v20-review/packages/core/test/util/flock.test.ts:
  Line 143:       .split("\n")


/tmp/opencode/session-recovery-v20-review/packages/core/test/process/process.test.ts:
  Line 288:         const [cwd, stdin] = result.stdout.toString("utf8").split("|")


/tmp/opencode/session-recovery-v20-review/packages/core/test/tool-read.test.ts:
  Line 427:       const resized = photon.PhotonImage.new_from_byteslice(Buffer.from(media.uri.split(",")[1] ?? "", "base64"))


/tmp/opencode/session-recovery-v20-review/packages/core/test/effect/observability.test.ts:
  Line 74:   const lines = (await Bun.file(file).text()).trim().split("\n")


/tmp/opencode/session-recovery-v20-review/packages/core/test/plugin/provider-snowflake-cortex.test.ts:
  Line 176:   bun_it("rewrites max_tokens to max_completion_tokens", async () => {

  Line ...
gateway · 2026-09-17 08:39:30
result
Found 100 matches (more matches available)
/tmp/opencode/session-recovery-v20-review/packages/core/test/session-create.test.ts:
  Line 51:   it.effect("creates a fresh projected session when the ID is omitted", () =>

  Line 63:   it.effect("returns the original session when the ID is retried", () =>

  Line 76:   it.effect("stores supplied immutable create attributes", () =>

  Line 96:   it.effect("returns the existing Session when one ID is reused with different create arguments", () =>

  Line 117:   it.effect("returns one recorded session to concurrent exact retries", () =>

  Line 129:   it.effect("returns the current Session projection after updates", () =>

  Line 142:   it.effect("returns the current Session projection after projected updates", () =>

  Line 167:   it.effect("persists creation through the existing legacy created event", () =>

  Line 179:   it.effect("persists caller-ID creation through the existing created event", () =>

  Line 193:   it.effect("omits legacy ...
gateway · 2026-09-17 08:39:38
result
Found 12 matches
/tmp/opencode/session-recovery-v20-review/packages/core/test/session-execution-local.test.ts:
  Line 45:   it.effect("clears the claim after a successful drain", () =>

  Line 54:   it.effect("snapshots the latest assistant sequence when acquiring a claim", () =>

  Line 86:   it.effect("preserves the claim when its scope closes", () =>

  Line 102:   it.effect("clears the claim after explicit interruption", () =>

  Line 116:   it.effect("never starts a second owner while the lease is live", () =>

  Line 139:   it.effect("never overwrites an expired lease", () =>

  Line 166:   it.effect("never re-enters its own uncertain live lease", () =>

  Line 193:   it.effect("renews heartbeat expiry from the current clock", () =>

  Line 216:   it.effect("never revives an expired claim on heartbeat", () =>

  Line 234:   it.effect("settles cancellation before starting a pending successor", () =>

  Line 278:   it.effect("never lets runner settlement overwrite cancellation", ...
gateway · 2026-09-17 08:39:48
result
Found 53 matches
/tmp/opencode/session-recovery-v20-review/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 390:     it.effect(`never recovers an assistant-less ${phase} execution superseded by a newer assistant`, () =>

  Line 435:     it.effect(`never commits assistant-less ${phase} recovery after concurrent assistant supersession`, () =>

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

  Line 555:   it.effect("redrives a durable recovery wake after ...
gateway · 2026-09-17 08:39:58
result
Found 29 matches
/tmp/opencode/session-recovery-v20-review/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 ...
gateway · 2026-09-17 08:40:03
result
Found 100 matches (more matches available)
/tmp/opencode/session-recovery-v20-review/packages/core/test/session-runner.test.ts:
  Line 244: const execution = Layer.effect(

  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:   ...
gateway · 2026-09-17 08:40:56
result
Found 3 matches
/tmp/opencode/session-recovery-v20-review/packages/server/src/handlers/session.ts:
  Line 149:                 resume: ctx.payload.resume,

  Line 366:         "session.interrupt",

  Line 368:           yield* session.interrupt(ctx.params.sessionID)
gateway · 2026-09-17 08:41:02
result
<path>/tmp/opencode/session-recovery-v20-review/packages/server/src/handlers/session.ts</path>
<type>file</type>
<content>
120:           return HttpApiSchema.NoContent.make()
121:         }),
122:       )
123:       .handle(
124:         "session.switchModel",
125:         Effect.fn(function* (ctx) {
126:           yield* session.switchModel({ sessionID: ctx.params.sessionID, model: ctx.payload.model }).pipe(
127:             Effect.catchTag("Session.NotFoundError", (error) =>
128:               Effect.fail(
129:                 new SessionNotFoundError({
130:                   sessionID: error.sessionID,
131:                   message: `Session not found: ${error.sessionID}`,
132:                 }),
133:               ),
134:             ),
135:           )
136:           return HttpApiSchema.NoContent.make()
137:         }),
138:       )
139:       .handle(
140:         "session.prompt",
141:         Effect.fn(function* (ctx) {
142:           return {
143:             data: yield* ...
gateway · 2026-09-17 08:41:09
result
Found 100 matches (more matches available)
/tmp/opencode/session-recovery-v20-review/packages/sdk/js/src/v2/gen/sdk.gen.ts:
  Line 5641:             { in: "body", key: "resume" },


/tmp/opencode/session-recovery-v20-review/packages/opencode/src/cli/cmd/run/runtime.ts:
  Line 33:   "sdk" | "directory" | "sessionID" | "sessionTitle" | "resume" | "agent" | "model" | "variant"


/tmp/opencode/session-recovery-v20-review/packages/opencode/src/acp/service.ts:
  Line 61:   readonly resumeSession: (input: ResumeSessionRequest) => Effect.Effect<ResumeSessionResponse, Error>

  Line 295:   const resumeSession = Effect.fn("ACP.resumeSession")(function* (params: ResumeSessionRequest) {

  Line 503:     resumeSession,


/tmp/opencode/session-recovery-v20-review/packages/opencode/src/acp/agent.ts:
  Line 55:   resumeSession(params: ResumeSessionRequest) {

  Line 56:     return ...
gateway · 2026-09-17 08:41:21
result
Found 16 matches
/tmp/opencode/session-recovery-v20-review/packages/sdk/openapi.json:
  Line 17899:                       "requestExecution": {

  Line 17919:                     "enum": ["session.next.prompt.execution_requested"]

  Line 18253:                     "enum": ["session.next.step.interrupted"]

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

  Line 25709:                   "requestExecution": {

  Line 25740:                 "enum": ["session.next.prompt.execution_requested.1"]

  Line 26242:                 "enum": ["session.next.step.interrupted.1"]

  Line 26299:                 "enum": ["session.next.step.recovered.1"]

  Line 28599:               "requestExecution": {

  Line 28622:             "enum": ["session.next.prompt.execution_requested"]

  Line 29132:             "enum": ["session.next.step.interrupted"]

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

  Line 34811:               "requestExecution": {

  Line ...
gateway · 2026-09-17 08:41:27
result
<path>/tmp/opencode/session-recovery-v20-review/packages/sdk/openapi.json</path>
<type>file</type>
<content>
17870:                   "id": {
17871:                     "type": "string",
17872:                     "pattern": "^evt_"
17873:                   },
17874:                   "type": {
17875:                     "type": "string",
17876:                     "enum": ["session.next.prompt.admitted"]
17877:                   },
17878:                   "properties": {
17879:                     "type": "object",
17880:                     "properties": {
17881:                       "timestamp": {
17882:                         "type": "number"
17883:                       },
17884:                       "sessionID": {
17885:                         "type": "string",
17886:                         "pattern": "^ses"
17887:                       },
17888:                       "messageID": {
17889:                         "type": "string",
17890:                         "pattern": ...
gateway · 2026-09-17 08:41:41
result
Found 25 matches
/tmp/opencode/session-recovery-v20-review/packages/sdk/js/src/v2/gen/types.gen.ts:
  Line 24:   | EventSessionNextPromptExecutionRequested

  Line 32:   | EventSessionNextStepInterrupted

  Line 33:   | EventSessionNextStepRecovered

  Line 874:           requestExecution?: boolean

  Line 1650:     | SyncEventSessionNextPromptExecutionRequested

  Line 1658:     | SyncEventSessionNextStepInterrupted

  Line 1659:     | SyncEventSessionNextStepRecovered

  Line 2785:   | SessionNextPromptExecutionRequested

  Line 2793:   | SessionNextStepInterrupted

  Line 2794:   | SessionNextStepRecovered

  Line 2915:   | SessionNextPromptExecutionRequested

  Line 2923:   | SessionNextStepInterrupted

  Line 2924:   | SessionNextStepRecovered

  Line 3430:       requestExecution?: boolean

  Line 3435: export type SyncEventSessionNextPromptExecutionRequested = {

  Line 3585: export type SyncEventSessionNextStepInterrupted = {

  Line 3602: export type ...
gateway · 2026-09-17 08:41:47
result
<path>/tmp/opencode/session-recovery-v20-review/packages/sdk/js/src/v2/gen/types.gen.ts</path>
<type>file</type>
<content>
3400:   id: string
3401:   syncEvent: {
3402:     type: "session.next.prompted.1"
3403:     id: string
3404:     seq: number
3405:     aggregateID: string
3406:     data: {
3407:       timestamp: number
3408:       sessionID: string
3409:       messageID: string
3410:       prompt: Prompt
3411:       delivery: "steer" | "queue"
3412:     }
3413:   }
3414: }
3415: 
3416: export type SyncEventSessionNextPromptAdmitted = {
3417:   type: "sync"
3418:   id: string
3419:   syncEvent: {
3420:     type: "session.next.prompt.admitted.1"
3421:     id: string
3422:     seq: number
3423:     aggregateID: string
3424:     data: {
3425:       timestamp: number
3426:       sessionID: string
3427:       messageID: string
3428:       prompt: Prompt
3429:       delivery: "steer" | "queue"
3430:       requestExecution?: boolean
3431:     }
3432:   }
3433: }
3434: 
3435: export type ...
gateway · 2026-09-17 08:41:53
result
Found 57 matches
/tmp/opencode/session-recovery-v20-review/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 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": "session_recovery"

  Line ...
gateway · 2026-09-17 08:42:03
result
<path>/tmp/opencode/session-recovery-v20-review/packages/core/schema.json</path>
<type>file</type>
<content>
45:     {
46:       "name": "project_directory",
47:       "entityType": "tables"
48:     },
49:     {
50:       "name": "project",
51:       "entityType": "tables"
52:     },
53:     {
54:       "name": "message",
55:       "entityType": "tables"
56:     },
57:     {
58:       "name": "part",
59:       "entityType": "tables"
60:     },
61:     {
62:       "name": "session_context_epoch",
63:       "entityType": "tables"
64:     },
65:     {
66:       "name": "session_execution",
67:       "entityType": "tables"
68:     },
69:     {
70:       "name": "session_input",
71:       "entityType": "tables"
72:     },
73:     {
74:       "name": "session_message",
75:       "entityType": "tables"
76:     },
77:     {
78:       "name": "session_recovery",
79:       "entityType": "tables"
80:     },
81:     {
82:       "name": "session",
83:       "entityType": "tables"
84:     },
85:    ...
gateway · 2026-09-17 08:42:12
result
<path>/tmp/opencode/session-recovery-v20-review/packages/core/schema.json</path>
<type>file</type>
<content>
920:       "entityType": "columns",
921:       "table": "session_context_epoch"
922:     },
923:     {
924:       "type": "integer",
925:       "notNull": true,
926:       "autoincrement": false,
927:       "default": null,
928:       "generated": null,
929:       "name": "baseline_seq",
930:       "entityType": "columns",
931:       "table": "session_context_epoch"
932:     },
933:     {
934:       "type": "text",
935:       "notNull": true,
936:       "autoincrement": false,
937:       "default": null,
938:       "generated": null,
939:       "name": "id",
940:       "entityType": "columns",
941:       "table": "session_execution"
942:     },
943:     {
944:       "type": "text",
945:       "notNull": true,
946:       "autoincrement": false,
947:       "default": null,
948:       "generated": null,
949:       "name": "session_id",
950:       "entityType": "columns",
951:      ...
gateway · 2026-09-17 08:42:20
result
<path>/tmp/opencode/session-recovery-v20-review/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: ...
gateway · 2026-09-17 08:42:30
result
<path>/tmp/opencode/session-recovery-v20-review/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 { SessionExecutionClaim } from "@opencode-ai/core/session/execution/claim"
11: import { SessionMessage } from "@opencode-ai/core/session/message"
12: import { SessionSchema } from "@opencode-ai/core/session/schema"
13: import { SessionExecutionTable, SessionTable } from "@opencode-ai/core/session/sql"
14: import { testEffect ...
gateway · 2026-09-17 08:42:42
result
<path>/tmp/opencode/session-recovery-v20-review/packages/core/test/session-runner.test.ts</path>
<type>file</type>
<content>
3750:       ])
3751:     }),
3752:   )
3753: 
3754:   it.effect("awaits started local tools before surfacing provider stream failure", () =>
3755:     Effect.gen(function* () {
3756:       yield* setup
3757:       const session = yield* SessionV2.Service
3758:       yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Settle before failing" }), resume: false })
3759:       const failure = providerUnavailable()
3760:       toolExecutionGate = yield* Deferred.make<void>()
3761:       responseStream = Stream.concat(
3762:         Stream.fromIterable([
3763:           LLMEvent.stepStart({ index: 0 }),
3764:           LLMEvent.toolCall({ id: "call-before-failure", name: "echo", input: { text: "settle" } }),
3765:         ]),
3766:         Stream.fail(failure),
3767:       )
3768: 
3769:       const run = yield* ...
gateway · 2026-09-17 08:42:50
result
Found 3 matches
/tmp/opencode/session-recovery-v20-review/packages/core/test/session-runner.test.ts:
  Line 3911:       yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "Interrupt publication failure" }), resume: false })

  Line 3942:         { type: "user", text: "Interrupt publication failure" },

  Line 4087:         phase: "cancelling",
gateway · 2026-09-17 08:42:58
result
Found 9 matches
/tmp/opencode/session-recovery-v20-review/packages/core/test/session-runner.test.ts:
  Line 3922:         CREATE TRIGGER fail_interrupted_tool_publication

  Line 3934:         Effect.ensuring(db.run(sql`DROP TRIGGER fail_interrupted_tool_publication`).pipe(Effect.orDie)),

  Line 3994:           .where(eq(EventTable.type, "session.next.step.interrupted.1"))

  Line 4048:           .where(eq(EventTable.type, "session.next.step.interrupted.1"))

  Line 4082:           .where(eq(EventTable.type, "session.next.step.interrupted.1"))

  Line 4113:           .where(eq(EventTable.type, "session.next.step.interrupted.1"))


/tmp/opencode/session-recovery-v20-review/packages/core/test/session-projector.test.ts:
  Line 2064:         recovery_error: "Cancellation outcome unknown after owner loss",

  Line 2093:           phase: "cancelled",

  Line 2164:         recovery_error: "Cancellation outcome unknown after owner loss",
gateway · 2026-09-17 08:43:09
result
<path>/tmp/opencode/session-recovery-v20-review/packages/core/test/session-projector.test.ts</path>
<type>file</type>
<content>
1930:         sessionID,
1931:         timestamp: created,
1932:         executionID: "quarantined-steer",
1933:         phase: "ready",
1934:       })
1935:       const continuationID = continuation("quarantined-steer")
1936:       yield* db
1937:         .update(SessionInputTable)
1938:         .set({ delivery: "steer" })
1939:         .where(eq(SessionInputTable.id, continuationID))
1940:         .run()
1941:       yield* SessionRecovery.recover().pipe(Effect.provideService(SessionExecution.Service, recoveryExecution))
1942:       expect(yield* db.select().from(SessionRecoveryTable).get()).toMatchObject({
1943:         recovery_error: "Invalid recovery continuation input",
1944:       })
1945:       expect(yield* SessionInput.hasPending(db, sessionID, "steer")).toBe(false)
1946:       expect(yield* SessionInput.promoteSteers(db, events, sessionID, ...
gateway · 2026-09-17 08:43:23
result
<path>/tmp/opencode/session-recovery-v20-review/packages/core/test/session-projector.test.ts</path>
<type>file</type>
<content>
1: import { describe, expect } from "bun:test"
2: import { DateTime, Deferred, Effect, Exit, Fiber, Schema } from "effect"
3: import { TestClock } from "effect/testing"
4: import { asc, eq, sql } from "drizzle-orm"
5: import { Database } from "@opencode-ai/core/database/database"
6: import { LayerNode } from "@opencode-ai/core/effect/layer-node"
7: import { AppNodeBuilder } from "@opencode-ai/core/effect/app-node-builder"
8: import { EventV2 } from "@opencode-ai/core/event"
9: import { EventTable } from "@opencode-ai/core/event/sql"
10: import { ModelV2 } from "@opencode-ai/core/model"
11: import { Project } from "@opencode-ai/core/project"
12: import { ProjectTable } from "@opencode-ai/core/project/sql"
13: import { ProviderV2 } from "@opencode-ai/core/provider"
14: import { AbsolutePath } from "@opencode-ai/core/schema"
15: import { SessionV2 } from ...
gateway · 2026-09-17 08:43:30
result
<path>/tmp/opencode/session-recovery-v20-review/packages/core/test/session-projector.test.ts</path>
<type>file</type>
<content>
901:         aggregateID: prompted.aggregate_id,
902:         seq: prompted.seq,
903:         type: prompted.type,
904:         data: prompted.data,
905:       })
906:       expect(yield* db.select({ attempts: SessionTable.wake_attempts }).from(SessionTable).get()).toEqual({ attempts: 7 })
907:     }),
908:   )
909: 
910:   it.effect("rejects invalid persisted wake attempt counters", () =>
911:     Effect.gen(function* () {
912:       const { db } = yield* Database.Service
913:       const events = yield* EventV2.Service
914:       yield* db
915:         .insert(ProjectTable)
916:         .values({ id: Project.ID.global, worktree: AbsolutePath.make("/project"), sandboxes: [] })
917:         .run()
918:       yield* db
919:         .insert(SessionTable)
920:         .values({
921:           id: sessionID,
922:           project_id: Project.ID.global,
923:      ...
gateway · 2026-09-17 08:43:35
result
<path>/tmp/opencode/session-recovery-v20-review/packages/core/test/session-projector.test.ts</path>
<type>file</type>
<content>
2399:           SELECT RAISE(ABORT, 'poison recovery projection');
2400:         END
2401:       `)
2402:       yield* SessionRecovery.recover().pipe(
2403:         Effect.provideService(SessionExecution.Service, recoveryExecution),
2404:       )
2405:       expect(
2406:         yield* db
2407:           .select()
2408:           .from(SessionExecutionTable)
2409:           .where(eq(SessionExecutionTable.recovery_error, "Recovery projection failed"))
2410:           .all(),
2411:       ).toHaveLength(SessionRecovery.BATCH_SIZE)
2412: 
2413:       yield* SessionRecovery.recover().pipe(
2414:         Effect.provideService(SessionExecution.Service, recoveryExecution),
2415:         Effect.ensuring(db.run(sql`DROP TRIGGER fail_recovery_projection`).pipe(Effect.orDie)),
2416:       )
2417:       expect(yield* ...
gateway · 2026-09-17 08:43:46
result
<path>/tmp/opencode/session-recovery-v20-review/packages/core/test/session-prompt.test.ts</path>
<type>file</type>
<content>
120:       type: event.type,
121:       data: event.data,
122:     })),
123:   )
124: })
125: 
126: const recover = () =>
127:   SessionRecovery.recover().pipe(
128:     Effect.provideService(
129:       SessionExecution.Service,
130:       SessionExecution.Service.of({
131:         active: Effect.succeed(new Set()),
132:         resume: () => Effect.void,
133:         interrupt: () => Effect.void,
134:         wake: (id) => Effect.sync(() => wakeCalls.push(id)).pipe(Effect.asVoid),
135:       }),
136:     ),
137:   )
138: 
139: describe("SessionV2.prompt", () => {
140:   it.effect("exposes the execution registry", () =>
141:     Effect.gen(function* () {
142:       activeSessions.add(sessionID)
143:       expect(Array.from(yield* (yield* SessionV2.Service).active)).toEqual([sessionID])
144:     }).pipe(Effect.ensuring(Effect.sync(() => ...
gateway · 2026-09-17 08:43:54
result
<path>/tmp/opencode/session-recovery-v20-review/packages/core/test/session-run-coordinator.test.ts</path>
<type>file</type>
<content>
1: import { describe, expect } from "bun:test"
2: import { Cause, Deferred, Effect, Exit, Fiber, Layer } from "effect"
3: import { SessionRunCoordinator } from "@opencode-ai/core/session/run-coordinator"
4: import { testEffect } from "./lib/effect"
5: 
6: const it = testEffect(Layer.empty)
7: 
8: describe("SessionRunCoordinator", () => {
9:   it.effect("joins concurrent resumes for one key", () =>
10:     Effect.scoped(
11:       Effect.gen(function* () {
12:         const gate = yield* Deferred.make<void>()
13:         let runs = 0
14:         const coordinator = yield* SessionRunCoordinator.make({
15:           drain: () => Effect.sync(() => runs++).pipe(Effect.andThen(Deferred.await(gate))),
16:         })
17: 
18:         const first = yield* coordinator.run("session").pipe(Effect.forkChild)
19:         yield* Effect.yieldNow
20:         const ...
gateway · 2026-09-17 08:43:59
result
<path>/tmp/opencode/session-recovery-v20-review/packages/core/test/session-run-coordinator.test.ts</path>
<type>file</type>
<content>
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* Fiber.join(interrupt)
278:         yield* ...
gateway · 2026-09-17 08:44:06
result
<path>/tmp/opencode/session-recovery-v20-review/packages/core/test/session-runner.test.ts</path>
<type>file</type>
<content>
600:         event.type.startsWith(SessionEvent.Step.Interrupted.type),
601:       ),
602:     ).toBe(false)
603:     const context = yield* session.context(sessionID)
604:     expect(context).toHaveLength(2)
605:     expect(context[0]).toMatchObject({ type: "user", text: prompt })
606:     expect(context[1]).not.toHaveProperty("finish")
607:     expect(context[1]).not.toHaveProperty("error")
608:     expect(context[1]).toMatchObject({
609:       type: "assistant",
610:       content: [
611:         kind === "tool input"
612:           ? { type: "tool", id: fragmentID(kind, "interrupted"), state: { status: "pending" } }
613:           : { type: kind, id: fragmentID(kind, "interrupted"), text: "" },
614:       ],
615:     })
616:   })
617: 
618: describe("SessionRunnerLLM", () => {
619:   it.effect("redrives only the synthetic recovery continuation", () =>
620:   ...
gateway · 2026-09-17 08:44:12
result
Found 3 matches
/tmp/opencode/session-recovery-v20-review/packages/core/test/session-runner.test.ts:
  Line 26: import { Snapshot } from "@opencode-ai/core/snapshot"

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

  Line 1070:         .set({ snapshot: { invalid: { value: "bad" } } })
gateway · 2026-09-17 08:44:21
result
Found 4 matches
/tmp/opencode/session-recovery-v20-review/packages/core/src/snapshot.ts:
  Line 43: export interface Interface {

  Line 49:   readonly capture: () => Effect.Effect<ID | undefined>

  Line 84: export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Snapshot") {}

  Line 241:     capture: () => Effect.succeed(undefined),
gateway · 2026-09-17 08:44:32
result
<path>/tmp/opencode/session-recovery-v20-review/packages/core/src/snapshot.ts</path>
<type>file</type>
<content>
35:   /** Paths are relative to the project root. */
36:   readonly files: ReadonlyMap<RelativePath, ID>
37: }
38: 
39: export interface PreviewInput extends RestoreInput {
40:   readonly context?: number
41: }
42: 
43: export interface Interface {
44:   /**
45:    * Capture the current Location-scoped filesystem state as a content-addressed
46:    * tree. Returns `undefined` when snapshots are disabled, unsupported, or the
47:    * best-effort capture fails.
48:    */
49:   readonly capture: () => Effect.Effect<ID | undefined>
50: 
51:   /**
52:    * List project-relative paths changed between two captured trees without
53:    * loading file contents or generating patches.
54:    */
55:   readonly files: (input: CompareInput) => Effect.Effect<readonly RelativePath[], Error>
56: 
57:   /**
58:    * Generate structured per-file diffs between two captured trees. ...
gateway · 2026-09-17 08:44:41
result
<path>/tmp/opencode/session-recovery-v20-review/packages/core/test/session-runner-tool-events.test.ts</path>
<type>file</type>
<content>
1: import { expect, test } from "bun:test"
2: import { Effect, Schema, Stream } from "effect"
3: import { LLMEvent } from "@opencode-ai/llm"
4: import { EventV2 } from "@opencode-ai/core/event"
5: import { SessionEvent } from "@opencode-ai/core/session/event"
6: import { SessionMessage } from "@opencode-ai/core/session/message"
7: import { SessionV2 } from "@opencode-ai/core/session"
8: import { ModelV2 } from "@opencode-ai/core/model"
9: import { ProviderV2 } from "@opencode-ai/core/provider"
10: import { createLLMEventPublisher } from "@opencode-ai/core/session/runner/publish-llm-event"
11: 
12: const sessionID = SessionV2.ID.make("ses_tool_event_test")
13: const base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB"
14: 
15: const capture = () => {
16:   const published: Array<{ readonly type: string; readonly data: unknown }> = []
17:   const events = ...
gateway · 2026-09-17 08:44:53
result
<path>/tmp/opencode/session-recovery-v20-review/packages/core/test/session-runner-recorded.test.ts</path>
<type>file</type>
<content>
1: import { HttpRecorder } from "@opencode-ai/http-recorder"
2: import { HttpRecorderInternal } from "@opencode-ai/http-recorder/internal"
3: import * as OpenAIChat from "@opencode-ai/llm/protocols/openai-chat"
4: import { Auth, LLMClient, RequestExecutor } from "@opencode-ai/llm/route"
5: import { Database } from "@opencode-ai/core/database/database"
6: import { AppNodeBuilder } from "@opencode-ai/core/effect/app-node-builder"
7: import { LayerNodePlatform } from "@opencode-ai/core/effect/app-node-platform"
8: import { LayerNode } from "@opencode-ai/core/effect/layer-node"
9: import { EventV2 } from "@opencode-ai/core/event"
10: import { EventTable } from "@opencode-ai/core/event/sql"
11: import { PermissionV2 } from "@opencode-ai/core/permission"
12: import { AgentV2 } from "@opencode-ai/core/agent"
13: import { Config } from ...
gateway · 2026-09-17 08:45:05
result
<path>/tmp/opencode/session-recovery-v20-review/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-17 08:45:18
result
<path>/tmp/opencode/session-recovery-v20-review/packages/client/src/generated/types.ts</path>
<type>file</type>
<content>
750:           readonly delivery: "steer" | "queue"
751:         }
752:       }
753:     | {
754:         readonly id: string
755:         readonly metadata?: { readonly [x: string]: JsonValue }
756:         readonly type: "session.next.prompt.admitted"
757:         readonly durable?: { readonly aggregateID: string; readonly seq: number; readonly version: number }
758:         readonly location?: { readonly directory: string; readonly workspaceID?: string }
759:         readonly data: {
760:           readonly timestamp: number
761:           readonly sessionID: string
762:           readonly messageID: string
763:           readonly prompt: {
764:             readonly text: string
765:             readonly files?: ReadonlyArray<{
766:               readonly uri: string
767:               readonly mime: string
768:               readonly name?: string
769:          ...
gateway · 2026-09-17 08:46:01
result
<path>/tmp/opencode/session-recovery-v20-review/packages/server/src/middleware/session-location.ts</path>
<type>file</type>
<content>
1: import { Database } from "@opencode-ai/core/database/database"
2: import { LocationServiceMap } from "@opencode-ai/core/location-services"
3: import { Location } from "@opencode-ai/core/location"
4: import { AbsolutePath } from "@opencode-ai/core/schema"
5: import { SessionV2 } from "@opencode-ai/core/session"
6: import { SessionTable } from "@opencode-ai/core/session/sql"
7: import { WorkspaceV2 } from "@opencode-ai/core/workspace"
8: import { eq } from "drizzle-orm"
9: import { Effect, Layer, Schema } from "effect"
10: import { HttpRouter } from "effect/unstable/http"
11: import { HttpApiMiddleware } from "effect/unstable/httpapi"
12: import { InvalidRequestError, SessionNotFoundError } from "@opencode-ai/protocol/errors"
13: import type { LocationServices } from "../location"
14: 
15: export class SessionLocationMiddleware extends ...
gateway · 2026-09-17 08:47:11
result
<path>/tmp/opencode/session-recovery-v20-review/packages/core/src/session/execution.ts</path>
<type>file</type>
<content>
1: export * as SessionExecution from "./execution"
2: 
3: import { Context, Effect, Layer } from "effect"
4: import { LayerNode } from "../effect/layer-node"
5: import { Node } from "../effect/app-node"
6: import { SessionRunner } from "./runner/index"
7: import { SessionSchema } from "./schema"
8: 
9: export interface Interface {
10:   /** Snapshots active execution owned by this process. */
11:   readonly active: Effect.Effect<ReadonlySet<SessionSchema.ID>>
12:   /** Starts execution while idle or joins the active execution. */
13:   readonly resume: (sessionID: SessionSchema.ID) => Effect.Effect<void, SessionRunner.RunError>
14:   /** Registers newly recorded work. Repeated wakeups may coalesce. */
15:   readonly wake: (sessionID: SessionSchema.ID) => Effect.Effect<void>
16:   /** Interrupt active work owned by this process. Idle interruption is a no-op. ...
gateway · 2026-09-17 08:47:35
result
File not found: /tmp/opencode/session-recovery-v20-review/packages/server/src/handlers/sync.ts
gateway · 2026-09-17 08:47:45
result
No files found
gateway · 2026-09-17 08:47:52
result
<path>/tmp/opencode/session-recovery-v20-review/packages/opencode/src/server/routes/instance/httpapi/handlers/sync.ts</path>
<type>file</type>
<content>
1: import { Workspace } from "@/control-plane/workspace"
2: import * as InstanceState from "@/effect/instance-state"
3: import { Session } from "@/session/session"
4: import { Database } from "@opencode-ai/core/database/database"
5: import { EventV2 } from "@opencode-ai/core/event"
6: import { EventV2Bridge } from "@/event-v2-bridge"
7: import { EventTable } from "@opencode-ai/core/event/sql"
8: import { asc } from "drizzle-orm"
9: import { and } from "drizzle-orm"
10: import { eq } from "drizzle-orm"
11: import { lte } from "drizzle-orm"
12: import { not } from "drizzle-orm"
13: import { or } from "drizzle-orm"
14: import { Effect, Scope } from "effect"
15: import { HttpApiBuilder, HttpApiError } from "effect/unstable/httpapi"
16: import { InstanceHttpApi } from "../api"
17: import { HistoryPayload, ReplayPayload, SessionPayload } ...
gateway · 2026-09-17 08:48:00
result
<path>/tmp/opencode/session-recovery-v20-review/packages/opencode/src/server/routes/instance/httpapi/middleware/authorization.ts</path>
<type>file</type>
<content>
1: import { ServerAuth } from "@/server/auth"
2: import { Effect, Encoding, Layer, Redacted } from "effect"
3: import { HttpEffect, HttpRouter, HttpServerRequest, HttpServerResponse } from "effect/unstable/http"
4: import { HttpApiError, HttpApiMiddleware } from "effect/unstable/httpapi"
5: import { hasPtyConnectTicketURL } from "@/server/shared/pty-ticket"
6: import { isPublicUIPath } from "@/server/shared/public-ui"
7: export {
8:   Authorization as ServerAuthorization,
9:   authorizationLayer as serverAuthorizationLayer,
10: } from "@opencode-ai/server/middleware/authorization"
11: 
12: const AUTH_TOKEN_QUERY = "auth_token"
13: const UNAUTHORIZED = 401
14: const WWW_AUTHENTICATE = 'Basic realm="Secure Area"'
15: 
16: // Avoid HttpApiSecurity alternatives here: Effect security middleware wraps the
17: // full handler, so ...
gateway · 2026-09-17 08:48:52
result
Found 3 matches
/tmp/opencode/session-recovery-v20-review/packages/core/src/database/database.ts:
  Line 29:     yield* db.run("PRAGMA busy_timeout = 5000")


/tmp/opencode/session-recovery-v20-review/packages/core/src/database/sqlite.node.ts:
  Line 36:   readonly timeout?: number

  Line 153:         timeout: config.timeout,
gateway · 2026-09-17 08:50:32
result
<path>/tmp/opencode/session-recovery-v20-review/packages/core/src/database/database.ts</path>
<type>file</type>
<content>
1: export * as Database from "./database"
2: 
3: import { EffectDrizzleSqlite } from "@opencode-ai/effect-drizzle-sqlite"
4: import { layer as sqliteLayer } from "#sqlite"
5: import { Context, Effect, Layer } from "effect"
6: import { Global } from "../global"
7: import { Flag } from "../flag/flag"
8: import { isAbsolute, join } from "path"
9: import { DatabaseMigration } from "./migration"
10: import { InstallationChannel } from "../installation/version"
11: import { makeGlobalNode } from "../effect/app-node"
12: 
13: const makeDatabase = EffectDrizzleSqlite.makeWithDefaults()
14: type DatabaseShape = Effect.Success<typeof makeDatabase>
15: 
16: export interface Interface {
17:   db: DatabaseShape
18: }
19: 
20: export class Service extends Context.Service<Service, Interface>()("@opencode/v2/storage/Database") {}
21: 
22: const layer = Layer.effect(
23:   ...
gateway · 2026-09-17 08:52:03
result
Found 7 matches
/tmp/opencode/session-recovery-v20-review/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)


/tmp/opencode/session-recovery-v20-review/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) => {
gateway · 2026-09-17 08:53:25
result
<path>/tmp/opencode/session-recovery-v20-review/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 ...
gateway · 2026-09-17 08:54:26
result
Found 100 matches (more matches available)
/tmp/opencode/session-recovery-v20-review/packages/core/test/session-runner.test.ts:
  Line 386:     resume: false,

  Line 522:     yield* session.prompt({ sessionID, prompt: Prompt.make({ text: prompt }), resume: false })

  Line 553:     yield* session.prompt({ sessionID, prompt: Prompt.make({ text: prompt }), resume: false })

  Line 579:     yield* session.prompt({ sessionID, prompt: Prompt.make({ text: prompt }), resume: false })

  Line 629:         prompt: Prompt.make({ text: "unrelated admit-only" }),

  Line 631:         resume: false,

  Line 675:         resume: false,

  Line 695:         resume: false,

  Line 761:       yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "fence provider" }), resume: false })

  Line 787:       yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "fence publication" }), resume: false })

  Line 829:       yield* session.prompt({ sessionID, prompt: Prompt.make({ text: "fence ...
gateway · 2026-09-17 08:55:50

Distillations (16)

Gen 0 2026-09-17 10:05:16 · 2326 tokens

Date: Sep 17, 2026 * 🟡 (08:46) `packages/client/src/generated/types.ts` generated event union defines `"session.next.prompt.admitted"` data with `timestamp`, `sessionID`, `messageID`, a prompt containing `text` plus optional files (`uri`, `mime`, optional `name`, `description`, `source`) and agents (`name`, optional `source`), `delivery: "steer" | "queue"`, and optional `requestExecution`. * 🟡 …

Gen 0 2026-09-17 10:04:30 · 2298 tokens

Date: Sep 17, 2026 * 🟡 (08:44) Remaining `packages/core/test/session-run-coordinator.test.ts` test ordering: 11. `"runs a wake registered during interruption cleanup"` — a wake issued while the first run’s interrupt cleanup waits on `cleanupGate` starts a second run, with `runs` equal to `2`; 12. `"finalizes interruption when cleanup dies"` — cleanup dies with `new Error("cleanup defect")`, the …

Gen 0 2026-09-17 09:54:54 · 884 tokens

Date: Sep 17, 2026 * 🔴 (08:43) User asserted the Context Epoch must “never advance after ownership changes”; the invariant is covered by `it.effect("never advances the Context Epoch after ownership changes", ...)` at line 2603. * 🔴 (08:43) User asserted execution must “never wake when retrying an already promoted prompt”; the invariant is covered by `it.effect("never wakes execution when retryi…

Gen 0 2026-09-17 09:47:21 · 449 tokens

Date: Sep 17, 2026 * 🔴 (08:43) User asserted recovery/redrive must “never wake work settled between selection and redrive CAS”; the invariant is covered by `it.effect("never wakes work settled between selection and redrive CAS", ...)` at line 1011. * 🔴 (08:43) User asserted recovery must “never recover a pre-promotion claim when input commits at the recovery boundary”; the invariant is covered …

Gen 0 2026-09-17 09:40:58 · 341 tokens

Date: Sep 17, 2026 * 🔴 (08:43) User asserted execution recovery must “never recover a live execution lease”; the invariant is covered by `it.effect("never recovers a live execution lease", ...)` at line 304 of the provided test file. * 🔴 (08:43) User asserted execution recovery must “never recover an execution superseded by a newer assistant”; the invariant is covered by `it.effect("never recov…

Gen 0 2026-09-17 09:31:26 · 750 tokens

Date: Sep 17, 2026 * 🔴 (08:42) User asserted the Session runner must “never mark a failed Step safe while a sibling tool finalizer is active”; the invariant is covered by `it.live("never marks a failed Step safe while a sibling tool finalizer is active", ...)` in `packages/core/test/session-runner.test.ts` line 3788. * 🟡 (08:42) The sibling-tool-finalizer race test in `packages/core/test/sessio…

Gen 0 2026-09-17 09:21:31 · 709 tokens

Date: Sep 17, 2026 * 🟡 (08:42) `packages/core/schema.json` defines `session_execution` columns: `id` text required, `session_id` text required, `owner_id` text required, nullable `assistant_message_id`, `phase` text required, `assistant_seq` integer required with default `-1`, `time_created` integer required, `expires_at` integer required, and nullable `recovery_error` (lines 933–1022). * 🟡 (08…

Gen 0 2026-09-17 09:13:34 · 2258 tokens

Date: Sep 17, 2026 * 🔴 (08:40) User asserted the session runner must never dispatch a provider after ownership changes; coverage is in `packages/core/test/session-runner.test.ts` line 752. * 🔴 (08:40) User asserted the session runner must never publish streamed output after ownership changes; coverage is in `packages/core/test/session-runner.test.ts` line 778. * 🔴 (08:40) User asserted the ses…

Gen 0 2026-09-17 09:06:08 · 1726 tokens

Date: Sep 17, 2026 * 🔴 (08:39) User asserted the session runner must never dispatch a provider after ownership changes; coverage is in `packages/core/test/session-runner.test.ts` line 752. * 🔴 (08:39) User asserted the session runner must never publish streamed output after ownership changes; coverage is in `packages/core/test/session-runner.test.ts` line 778. * 🔴 (08:39) User asserted the ses…

Gen 0 2026-09-17 09:05:31 · 1264 tokens

Date: Sep 17, 2026 * 🟡 (08:38) `packages/core/src/session/run-coordinator.ts` defines `SessionRunCoordinator.Coordinator<Key, E>` to serialize execution per key while allowing different keys to run concurrently. Its API is `active`, `run(key)`, `wake(key)`, and `interrupt(key, cleanup?)`; `drain(key, force)` supplies the underlying execution. * 🟡 (08:38) `packages/core/src/session/run-coordinat…

Gen 0 2026-09-17 09:02:38 · 925 tokens

Date: Sep 17, 2026 * 🟡 (08:38) `packages/core/src/session/sql.ts` sets `MAX_WAKE_ATTEMPTS = Number.MAX_SAFE_INTEGER` and enforces `session_wake_attempts_check` and `session_recovery_wake_attempts_check` bounds of `0..9007199254740991`. * 🟡 (08:38) `SessionTable` in `packages/core/src/session/sql.ts` includes `wake_attempts` as a non-null integer defaulting to `0`, alongside execution-related se…

Gen 0 2026-09-17 08:54:30 · 1330 tokens

Date: Sep 17, 2026 * 🔴 (08:37) User directed that a newer turn supersede stale incomplete rows and that the system “never resume an older assistant projection.” * 🟡 (08:37) `packages/core/src/session/context-epoch.ts` defines `SessionContextEpoch.initialize(...)` and `SessionContextEpoch.prepare(...)`; both require a `SessionExecutionClaim.Claim`, and return a baseline plus `baselineSeq` when p…

Gen 0 2026-09-17 08:45:09 · 1160 tokens

Date: Sep 17, 2026 * 🔴 (08:36) User directed that local ownership be replaced with durable multi-node ownership when clustered. * 🟡 (08:37) `packages/core/src/session/compaction.ts` implements automatic Session context compaction with defaults `DEFAULT_BUFFER = 20_000`, `DEFAULT_KEEP_TOKENS = 8_000`, `TOOL_OUTPUT_MAX_CHARS = 2_000`, and `SUMMARY_OUTPUT_TOKENS = 4_096`. * 🟡 (08:37) `SUMMARY_TEM…

Gen 0 2026-09-17 08:41:29 · 974 tokens

Date: Sep 17, 2026 * 🔴 (08:36) User stated that an expired Session execution claim never renews itself. * 🔴 (08:36) User’s lease guidance says timestamps use node wall clocks and `SESSION_EXECUTION_LEASE_MS` must exceed the deployment’s maximum clock skew plus one renewal interval; execution IDs immediately fence a node after takeover. * 🟡 (08:36) `packages/core/src/session/execution/claim.ts`…

Gen 0 2026-09-17 08:36:57 · 1759 tokens

Date: Sep 17, 2026 * 🔴 (08:33) User requires runtime dependencies to flow Schema → Core and Protocol → Server; Client runtime may depend on Schema and Protocol but never Core or Server; `sdk-next` composes Client, Core, and Server. * 🔴 (08:33) User requires imports never be aliased, including forms such as `import { foo as bar } from "..."` and `resolve as pathResolve`. * 🔴 (08:33) User requir…

Gen 0 2026-09-17 08:36:22 · 649 tokens

Date: Sep 17, 2026 * 🔴 [requested-security-review] (08:33) User requested a strict READ-ONLY security/pentest review of frozen v20 in `/tmp/opencode/session-recovery-v20-review`, covering all 34 changed paths plus necessary context. * 🔴 [enforced-workflow] (08:33) User prohibited editing, running tests/builds/services, mutating VCS/index/refs, and using recall; required reading applicable guida…