DashboardopencodeSession 0IiWXRdLX6HX

Session 0IiWXRdLX6HX

Full ID: 0IiWXRdLX6HXB8OJn
Messages: 89
Distillations: 17
Time range: 2026-09-16 15:46:34 — 2026-09-16 16:27:17

Conversation (89 messages)

Independent replacement SECURITY/pentest review. Return substantive evidence; empty/progress-only output is invalid. Read-only only.

Immutable inputs:

  • Base commit: ab9408c81cc9916177641ae8e9f08624fc27b5b9
  • Patch: /tmp/opencode/session-recovery-final-v8.patch
  • Expected patch SHA-256: 446412b56ac31b2a60f98765b5f14955a771f6074ebeb9309f603a0ceefad1bc
  • SEA: /home/byk/Code/opencode/packages/opencode/dist/server/opencode-server
  • Expected SEA SHA-256: f4f0bd585d33bd47114b2d8d54082c2b061380771c808e909223350e62c8c72f
  • Already-applied inspection tree: /tmp/opencode/session-recovery-v7-check. New patch-added files can be untracked because the patch is not committed.

Never modify files, refs, index, services, artifacts, or databases. Never build or run tests. First verify both hashes, the inspection-tree base, and that its exact diff equals the supplied patch. If this cannot be verified, report the exact command/error and end DO-NOT-MERGE.

Inspect all 33 changed files. Threat-model corrupt database rows, forged/cross-Session identities, stale owners, concurrent nodes, public retry of internal continuation IDs, event replay, malformed phases, poisoned batches, starvation/DoS, retry-counter saturation, cancellation finalizers, provider/tool publication defects, and migration constraints.

Explicitly verify:

  1. Recovery never takes a live lease, renews an expired owner, lets ordinary acquisition overwrite an expired claim, or permits same-owner uncertain re-entry.
  2. Every claim mutation fences exact Session ID, execution ID, owner ID, and unexpired lease.
  3. Recovery produces only canonical deterministic same-Session continuations for the newest assistant; internal continuations cannot enter public retry, ordinary queue/steer promotion, or ordinary redrive.
  4. Execution-recovery conversion defects quarantine the exact acquired claim, so 100 poison claims cannot starve claim 101.
  5. ...
gateway · 2026-09-16 15:46:34
result
No files found
gateway · 2026-09-16 15:48:42
result
<path>/home/byk/Code/opencode</path>
<type>directory</type>
<entries>
.dockerignore
.editorconfig
.git/
.gitattributes
.github/
.gitignore
.gitleaksignore
.husky/
.lore.md
.node-cache/
.opencode/
.oxlintrc.json
.prettierignore
.turbo/
.vscode/
.zed/
AGENTS.md
artifacts/
bun.lock
bunfig.toml
CONTEXT.md
CONTRIBUTING.md
flake.lock
flake.nix
github/
infra/
install
LICENSE
nix/
node_modules/
package.json
packages/
patches/
perf.data
perf.data.old
perf/
pnpm-lock.yaml
pnpm-workspace.yaml
README.ar.md
README.bn.md
README.br.md
README.bs.md
README.da.md
README.de.md
README.es.md
README.fr.md
README.gr.md
README.it.md
README.ja.md
README.ko.md
README.md
README.no.md
README.pl.md
README.ru.md
README.th.md
README.tr.md
README.uk.md
README.vi.md
README.zh.md
README.zht.md
screenshot-uk.png
script/
sdks/
SECURITY.md
specs/
sst-env.d.ts
sst.config.ts
STATS.md
tmp/
tsconfig.json
turbo.json

(71 entries)
</entries>
gateway · 2026-09-16 15:49:41
result
446412b56ac31b2a60f98765b5f14955a771f6074ebeb9309f603a0ceefad1bc  /tmp/opencode/session-recovery-final-v8.patch
f4f0bd585d33bd47114b2d8d54082c2b061380771c808e909223350e62c8c72f  /home/byk/Code/opencode/packages/opencode/dist/server/opencode-server
gateway · 2026-09-16 15:50:43
result
<path>/tmp/opencode/session-recovery-v7-check</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-16 15:51:47
result
ab9408c81cc9916177641ae8e9f08624fc27b5b9
 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 packages/core/test/session-runner-tool-events.test.ts
 M ...
gateway · 2026-09-16 15:52:40
result
<path>/tmp/opencode/session-recovery-final-v8.patch</path>
<type>file</type>
<content>
1: diff --git a/packages/core/schema.json b/packages/core/schema.json
2: index d0eeeebd5c..7e176bd78b 100644
3: --- a/packages/core/schema.json
4: +++ b/packages/core/schema.json
5: @@ -1,8 +1,10 @@
6:  {
7:    "version": "7",
8:    "dialect": "sqlite",
9: -  "id": "f14a9b18-8207-487e-a3d3-227e629ba9ad",
10: -  "prevIds": ["169a0f0f-d58f-479f-b024-fa1c7b9a09db"],
11: +  "id": "682548a8-b895-4f9b-a6af-fdd4b14a5fc9",
12: +  "prevIds": [
13: +    "d6936168-4f91-42dc-ad64-130da940b0f8"
14: +  ],
15:    "ddl": [
16:      {
17:        "name": "workspace",
18: @@ -60,6 +62,10 @@
19:        "name": "session_context_epoch",
20:        "entityType": "tables"
21:      },
22: +    {
23: +      "name": "session_execution",
24: +      "entityType": "tables"
25: +    },
26:      {
27:        "name": "session_input",
28:        "entityType": "tables"
29: @@ -68,6 +74,10 @@
30:        "name": "session_message",
31:  ...
gateway · 2026-09-16 15:53:11
result
Found 20 matches
/tmp/opencode/session-recovery-final-v7.patch:
  Line 892: diff --git a/packages/core/src/database/migration/20260914170650_session-recovery.ts b/packages/core/src/database/migration/20260914170650_session-recovery.ts

  Line 2289: diff --git a/packages/core/src/session/recovery.ts b/packages/core/src/session/recovery.ts

  Line 9075: diff --git a/packages/core/src/session/execution/claim.ts b/packages/core/src/session/execution/claim.ts

  Line 9147: diff --git a/packages/core/src/session/recovery-id.ts b/packages/core/src/session/recovery-id.ts


/tmp/opencode/session-recovery-final-v6.patch:
  Line 877: diff --git a/packages/core/src/database/migration/20260914170650_session-recovery.ts b/packages/core/src/database/migration/20260914170650_session-recovery.ts

  Line 2267: diff --git a/packages/core/src/session/recovery.ts b/packages/core/src/session/recovery.ts

  Line 8698: diff --git a/packages/core/src/session/execution/claim.ts ...
gateway · 2026-09-16 15:54:08
result
EXACT_DELTA_OK base=HEAD changed_paths=33
gateway · 2026-09-16 15:54:17
result
/tmp/opencode/session-recovery-v7-check/packages/stats/AGENTS.md
/tmp/opencode/session-recovery-v7-check/packages/schema/AGENTS.md
/tmp/opencode/session-recovery-v7-check/packages/app/AGENTS.md
/tmp/opencode/session-recovery-v7-check/packages/core/src/tool/AGENTS.md
/tmp/opencode/session-recovery-v7-check/packages/desktop/AGENTS.md
/tmp/opencode/session-recovery-v7-check/packages/session-ui/AGENTS.md
/tmp/opencode/session-recovery-v7-check/packages/app/e2e/AGENTS.md
/tmp/opencode/session-recovery-v7-check/packages/app/e2e/performance/AGENTS.md
/tmp/opencode/session-recovery-v7-check/packages/ui/AGENTS.md
/tmp/opencode/session-recovery-v7-check/packages/effect-drizzle-sqlite/AGENTS.md
/tmp/opencode/session-recovery-v7-check/packages/llm/AGENTS.md
/tmp/opencode/session-recovery-v7-check/packages/codemode/AGENTS.md
/tmp/opencode/session-recovery-v7-check/packages/opencode/AGENTS.md
/tmp/opencode/session-recovery-v7-check/packages/opencode/src/server/routes/instance/httpapi/AGENTS.md
/tmp/...
gateway · 2026-09-16 15:54:24
result
<path>/tmp/opencode/session-recovery-v7-check/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-16 15:54:34
result
<path>/tmp/opencode/session-recovery-v7-check/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-16 15:54:40
result
<path>/tmp/opencode/session-recovery-v7-check/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-16 15:54:46
result
<path>/tmp/opencode/session-recovery-v7-check/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-16 15:54:51
result
<path>/tmp/opencode/session-recovery-v7-check/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-16 15:55:00
result
<path>/tmp/opencode/session-recovery-v7-check/packages/core/package.json</path>
<type>file</type>
<content>
1: {
2:   "$schema": "https://json.schemastore.org/package.json",
3:   "version": "1.18.30",
4:   "name": "@opencode-ai/core",
5:   "type": "module",
6:   "license": "MIT",
7:   "private": true,
8:   "scripts": {
9:     "db": "bun drizzle-kit",
10:     "migration": "bun run script/migration.ts",
11:     "fix-node-pty": "bun run script/fix-node-pty.ts",
12:     "test": "bun test --only-failures",
13:     "typecheck": "tsgo --noEmit"
14:   },
15:   "bin": {
16:     "opencode": "./bin/opencode"
17:   },
18:   "exports": {
19:     "./effect/layer-node": "./src/effect/layer-node.ts",
20:     "./effect/app-node": "./src/effect/app-node.ts",
21:     "./session/runner": "./src/session/runner/index.ts",
22:     "./system-context": "./src/system-context/index.ts",
23:     "./*": "./src/*.ts"
24:   },
25:   "imports": {
26:     "#sqlite": {
27:       "bun": ...
gateway · 2026-09-16 15:55:06
result
<path>/tmp/opencode/session-recovery-v7-check/packages/schema/package.json</path>
<type>file</type>
<content>
1: {
2:   "$schema": "https://json.schemastore.org/package.json",
3:   "name": "@opencode-ai/schema",
4:   "private": true,
5:   "type": "module",
6:   "license": "MIT",
7:   "exports": {
8:     ".": "./src/index.ts",
9:     "./*": "./src/*.ts"
10:   },
11:   "scripts": {
12:     "typecheck": "tsgo --noEmit"
13:   },
14:   "dependencies": {
15:     "effect": "catalog:"
16:   },
17:   "devDependencies": {
18:     "@tsconfig/bun": "catalog:",
19:     "@types/bun": "catalog:",
20:     "@typescript/native-preview": "catalog:"
21:   }
22: }

(End of file - total 22 lines)
</content>
gateway · 2026-09-16 15:55:17
result
<path>/tmp/opencode/session-recovery-v7-check/packages/server/package.json</path>
<type>file</type>
<content>
1: {
2:   "$schema": "https://json.schemastore.org/package.json",
3:   "name": "@opencode-ai/server",
4:   "version": "1.18.30",
5:   "private": true,
6:   "type": "module",
7:   "license": "MIT",
8:   "exports": {
9:     "./*": "./src/*.ts"
10:   },
11:   "scripts": {
12:     "typecheck": "tsgo --noEmit"
13:   },
14:   "dependencies": {
15:     "@opencode-ai/core": "workspace:*",
16:     "@opencode-ai/protocol": "workspace:*",
17:     "drizzle-orm": "catalog:",
18:     "effect": "catalog:"
19:   },
20:   "devDependencies": {
21:     "@tsconfig/bun": "catalog:",
22:     "@types/bun": "catalog:",
23:     "@typescript/native-preview": "catalog:"
24:   }
25: }

(End of file - total 25 lines)
</content>
gateway · 2026-09-16 15:55:24
result
<path>/tmp/opencode/session-recovery-v7-check/packages/opencode/package.json</path>
<type>file</type>
<content>
1: {
2:   "$schema": "https://json.schemastore.org/package.json",
3:   "version": "1.18.30",
4:   "name": "opencode",
5:   "type": "module",
6:   "license": "MIT",
7:   "private": true,
8:   "scripts": {
9:     "typecheck": "tsgo --noEmit",
10:     "test": "bun test --timeout 30000 --only-failures",
11:     "test:httpapi": "bun run script/httpapi-exercise.ts --mode coverage --fail-on-missing --fail-on-skip && bun run script/httpapi-exercise.ts --mode auth --fail-on-missing --fail-on-skip && bun run script/httpapi-exercise.ts --mode effect --fail-on-missing --fail-on-skip",
12:     "bench:test": "bun run script/bench-test-suite.ts",
13:     "profile:test": "bun run script/profile-test-files.ts",
14:     "build": "bun run script/build.ts",
15:     "build:server": "node script/build-server.mjs",
16:     "dev": "bun run ./src/index.ts",
17:     "dev:temporary": "bun run ...
gateway · 2026-09-16 15:55:31
result
<path>/tmp/opencode/session-recovery-v7-check/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-16 15:55:38
result
<path>/tmp/opencode/session-recovery-v7-check/packages/core/src/session/execution/claim.ts</path>
<type>file</type>
<content>
1: export * as SessionExecutionClaim from "./claim"
2: 
3: import { and, eq, gt } from "drizzle-orm"
4: import { Clock, Effect } from "effect"
5: import type { Database } from "../../database/database"
6: import type { SessionSchema } from "../schema"
7: import { SESSION_EXECUTION_LEASE_MS, SessionExecutionTable } from "../sql"
8: 
9: type DatabaseService = Database.Interface["db"]
10: 
11: export type Claim = {
12:   readonly sessionID: SessionSchema.ID
13:   readonly executionID: string
14:   readonly ownerID: string
15: }
16: 
17: export type Values = Partial<Pick<typeof SessionExecutionTable.$inferInsert, "assistant_message_id" | "phase">>
18: 
19: export class Lost extends Error {
20:   constructor(readonly claim: Claim) {
21:     super(`Session execution claim lost: ${claim.executionID}`)
22:   }
23: }
24: 
25: const where = (claim: Claim, now: number) ...
gateway · 2026-09-16 15:55:43
result
<path>/tmp/opencode/session-recovery-v7-check/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-16 15:55:48
result
<path>/tmp/opencode/session-recovery-v7-check/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 { SessionSchema } from "./schema"
14: import {
15:   MAX_WAKE_ATTEMPTS,
16:   SESSION_EXECUTION_LEASE_MS,
17:   SessionExecutionTable,
18:   SessionInputTable,
19:   SessionRecoveryTable,
20:   SessionMessageTable,
21:   SessionTable,
22: } from ...
gateway · 2026-09-16 15:55:53
result
<path>/tmp/opencode/session-recovery-v7-check/packages/core/src/session/execution/local.ts</path>
<type>file</type>
<content>
1: import { and, asc, eq, isNull } from "drizzle-orm"
2: import { Cause, Clock, Duration, Effect, Exit, Layer, Schedule } from "effect"
3: import { Database } from "../../database/database"
4: import { LocationServiceMap } from "../../location-service-map"
5: import { makeGlobalNode } from "../../effect/app-node"
6: import { SessionRunCoordinator } from "../run-coordinator"
7: import { SessionRunner } from "../runner"
8: import { SessionMessage } from "../message"
9: import { SessionSchema } from "../schema"
10: import { SessionStore } from "../store"
11: import { SessionExecution } from "../execution"
12: import { SessionExecutionClaim } from "./claim"
13: import { SESSION_EXECUTION_LEASE_MS, SessionExecutionTable, SessionRecoveryTable } from "../sql"
14: 
15: /** Current-process routing for implicit-local Locations. Future remote placement belongs here. ...
gateway · 2026-09-16 15:56:01
result
<path>/tmp/opencode/session-recovery-v7-check/packages/core/src/session/input.ts</path>
<type>file</type>
<content>
1: export * as SessionInput from "./input"
2: 
3: import { and, asc, desc, eq, isNull, lte } from "drizzle-orm"
4: import { DateTime, Effect, Option, Schema } from "effect"
5: import { Admitted, Delivery } from "@opencode-ai/schema/session-input"
6: import type { Database } from "../database/database"
7: import { EventV2 } from "../event"
8: import { SessionEvent } from "./event"
9: import { SessionMessage } from "./message"
10: import { Prompt } from "./prompt"
11: import { continuation, message } from "./recovery-id"
12: import { SessionSchema } from "./schema"
13: import { SessionInputTable, SessionMessageTable, SessionRecoveryTable } from "./sql"
14: 
15: type DatabaseService = Database.Interface["db"]
16: 
17: export { Admitted, Delivery }
18: 
19: const decodePrompt = Schema.decodeUnknownSync(Prompt)
20: const encodePrompt = Schema.encodeSync(Prompt)
21: const ...
gateway · 2026-09-16 15:56:10
result
<path>/tmp/opencode/session-recovery-v7-check/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-16 15:56:26
result
<path>/tmp/opencode/session-recovery-v7-check/packages/core/src/session/projector.ts</path>
<type>file</type>
<content>
501:           .pipe(Effect.orDie)
502:         if (!boundary) return yield* Effect.die(`Revert boundary message not found: ${event.data.messageID}`)
503:         yield* db
504:           .delete(SessionMessageTable)
505:           .where(
506:             and(eq(SessionMessageTable.session_id, event.data.sessionID), gt(SessionMessageTable.seq, boundary.seq)),
507:           )
508:           .run()
509:           .pipe(Effect.orDie)
510:         yield* db
511:           .delete(SessionInputTable)
512:           .where(
513:             and(
514:               eq(SessionInputTable.session_id, event.data.sessionID),
515:               or(gt(SessionInputTable.admitted_seq, boundary.seq), gt(SessionInputTable.promoted_seq, boundary.seq)),
516:             ),
517:           )
518:           .run()
519:           .pipe(Effect.orDie)
520:         yield* db
521:           ...
gateway · 2026-09-16 15:56:38
result
<path>/tmp/opencode/session-recovery-v7-check/packages/core/src/session/message-updater.ts</path>
<type>file</type>
<content>
1: import { castDraft, produce, type WritableDraft } from "immer"
2: import { Effect } from "effect"
3: import { SessionEvent } from "./event"
4: import { SessionMessage } from "./message"
5: import { message } from "./recovery-id"
6: 
7: export type MemoryState = {
8:   messages: SessionMessage.Message[]
9: }
10: 
11: export interface Adapter {
12:   readonly getCurrentAssistant: () => Effect.Effect<SessionMessage.Assistant | undefined>
13:   readonly getAssistant: (messageID: SessionMessage.ID) => Effect.Effect<SessionMessage.Assistant | undefined>
14:   readonly getCurrentShell: (callID: string) => Effect.Effect<SessionMessage.Shell | undefined>
15:   readonly updateAssistant: (assistant: SessionMessage.Assistant) => Effect.Effect<void>
16:   readonly updateShell: (shell: SessionMessage.Shell) => Effect.Effect<void>
17:   readonly appendMessage: (message: ...
gateway · 2026-09-16 15:57:00
result
<path>/tmp/opencode/session-recovery-v7-check/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-16 15:57:13
result
Found 33 matches
/tmp/opencode/session-recovery-v7-check/packages/core/src/database/migration/20260914170650_session-recovery.ts:
  Line 10:         `ALTER TABLE \`session\` ADD \`wake_attempts\` integer DEFAULT 0 NOT NULL CONSTRAINT \`session_wake_attempts_check\` CHECK(\`wake_attempts\` >= 0 AND \`wake_attempts\` <= 9007199254740991);`,

  Line 13:         CREATE TABLE \`session_execution\` (

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

  Line 23:           CONSTRAINT \`session_execution_phase_check\` CHECK(\`phase\` IN ('ready', 'safe', 'unknown', 'continue')),

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

  Line 28:         CREATE TABLE \`session_recovery\` (

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

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

  Line 39:          ...
gateway · 2026-09-16 15:57:19
result
<path>/tmp/opencode/session-recovery-v7-check/packages/core/src/database/schema.gen.ts</path>
<type>file</type>
<content>
140:           \`message_id\` text NOT NULL,
141:           \`session_id\` text NOT NULL,
142:           \`time_created\` integer NOT NULL,
143:           \`time_updated\` integer NOT NULL,
144:           \`data\` text NOT NULL,
145:           CONSTRAINT \`fk_part_message_id_message_id_fk\` FOREIGN KEY (\`message_id\`) REFERENCES \`message\`(\`id\`) ON DELETE CASCADE
146:         );
147:       `)
148:       yield* tx.run(`
149:         CREATE TABLE \`session_context_epoch\` (
150:           \`session_id\` text PRIMARY KEY,
151:           \`baseline\` text NOT NULL,
152:           \`snapshot\` text NOT NULL,
153:           \`baseline_seq\` integer NOT NULL,
154:           CONSTRAINT \`fk_session_context_epoch_session_id_session_id_fk\` FOREIGN KEY (\`session_id\`) REFERENCES \`session\`(\`id\`) ON DELETE CASCADE
155:         );
156:       `)
157:       yield* ...
gateway · 2026-09-16 15:57:38
result
<path>/tmp/opencode/session-recovery-v7-check/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-16 15:57:48
result
<path>/tmp/opencode/session-recovery-v7-check/packages/core/src/session.ts</path>
<type>file</type>
<content>
421:       }),
422:       wait: Effect.fn("V2Session.wait")(function* (sessionID) {
423:         yield* result.get(sessionID)
424:         return yield* new OperationUnavailableError({ operation: "wait" })
425:       }),
426:       active: execution.active,
427:       resume: Effect.fn("V2Session.resume")(function* (sessionID) {
428:         yield* result.get(sessionID)
429:         yield* execution.resume(sessionID)
430:       }),
431:       interrupt: Effect.fn("V2Session.interrupt")((sessionID) =>
432:         Effect.uninterruptible(execution.interrupt(sessionID)),
433:       ),
434:       revert: {
435:         stage: Effect.fn("V2Session.revert.stage")(function* (input) {
436:           const session = yield* result.get(input.sessionID)
437:           return yield* SessionRevert.stage({ session, messageID: input.messageID, files: input.files }).pipe(
438:             ...
gateway · 2026-09-16 15:58:08
result
<path>/tmp/opencode/session-recovery-v7-check/packages/core/src/session/compaction.ts</path>
<type>file</type>
<content>
1: export * as SessionCompaction from "./compaction"
2: 
3: import { LLM, LLMError, LLMEvent, Message, type LLMRequest, type Model } from "@opencode-ai/llm"
4: import { DateTime, Effect, Stream } from "effect"
5: import type { Config } from "../config"
6: import type { EventV2 } from "../event"
7: import { SessionEvent } from "./event"
8: import { SessionMessage } from "./message"
9: import { SessionSchema } from "./schema"
10: import { Token } from "../util/token"
11: 
12: const DEFAULT_BUFFER = 20_000
13: const DEFAULT_KEEP_TOKENS = 8_000
14: const TOOL_OUTPUT_MAX_CHARS = 2_000
15: const SUMMARY_OUTPUT_TOKENS = 4_096
16: const SUMMARY_TEMPLATE = `Output exactly the Markdown structure shown inside <template> and keep the section order unchanged. Do not include the <template> tags in your response. ...
gateway · 2026-09-16 15:58:22
result
<path>/tmp/opencode/session-recovery-v7-check/packages/core/src/session/context-epoch.ts</path>
<type>file</type>
<content>
1: export * as SessionContextEpoch from "./context-epoch"
2: 
3: import { eq } from "drizzle-orm"
4: import { DateTime, Effect, Schema } from "effect"
5: import type { Database } from "../database/database"
6: import { EventV2 } from "../event"
7: import { SystemContext } from "../system-context/index"
8: import { ContextSnapshotDecodeError } from "./error"
9: import { SessionEvent } from "./event"
10: import { SessionHistory } from "./history"
11: import { SessionInput } from "./input"
12: import { SessionMessage } from "./message"
13: import { SessionSchema } from "./schema"
14: import { SessionContextEpochTable } from "./sql"
15: import { SessionExecutionClaim } from "./execution/claim"
16: 
17: type DatabaseService = Database.Interface["db"]
18: 
19: interface Prepared {
20:   readonly baseline: string
21:   readonly baselineSeq: number
22: }
23: 
24: export ...
gateway · 2026-09-16 15:58:49
result
<path>/tmp/opencode/session-recovery-v7-check/packages/core/src/session/run-coordinator.ts</path>
<type>file</type>
<content>
1: export * as SessionRunCoordinator from "./run-coordinator"
2: 
3: import { Deferred, Effect, Exit, Fiber, FiberSet, Scope } from "effect"
4: 
5: /** Serializes execution for each key while allowing different keys to run concurrently. */
6: export interface Coordinator<Key, E> {
7:   /** Snapshots keys with an execution owned by this coordinator. */
8:   readonly active: Effect.Effect<ReadonlySet<Key>>
9:   /** Starts execution while idle or joins the active execution. */
10:   readonly run: (key: Key) => Effect.Effect<void, E>
11:   /** Registers one coalesced follow-up after newly recorded work. */
12:   readonly wake: (key: Key) => Effect.Effect<void>
13:   /** Stops active execution, runs cleanup, then starts work that arrived while stopping. */
14:   readonly interrupt: (key: Key, cleanup?: Effect.Effect<void>) => Effect.Effect<void>
15: }
16: 
17: type ...
gateway · 2026-09-16 15:59:11
result
<path>/tmp/opencode/session-recovery-v7-check/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-16 15:59:23
result
<path>/tmp/opencode/session-recovery-v7-check/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-16 15:59:45
result
<path>/tmp/opencode/session-recovery-v7-check/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) => Effect.Effect<void>
15:   readonly eventCommit: () => Effect.Effect<void>
16: }
17: 
18: const safe = (value: number | undefined) => Math.max(0, Number.isFinite(value) ? (value ?? ...
gateway · 2026-09-16 16:00:02
result
Found 8 matches
/tmp/opencode/session-recovery-v7-check/packages/core/test/session-runner-tool-events.test.ts:
  Line 136:   expect(published.some((event) => event.type === "session.next.tool.failed.1")).toBe(true)

  Line 140:   const decoded = Schema.decodeUnknownSync(SessionEvent.Tool.Success.data)({


/tmp/opencode/session-recovery-v7-check/packages/core/test/session-runner.test.ts:
  Line 837:             event.type.startsWith(SessionEvent.Tool.Success.type) ||

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

  Line 1737:   it.effect("publishes the original overflow when recovery summarization fails", () =>

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

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

  Line 3124:       yield* events.publish(SessionEvent.Step.Started, {
gateway · 2026-09-16 16:00:42
result
Found 21 matches
/tmp/opencode/session-recovery-v7-check/packages/core/src/event.ts:
  Line 369:       function publishEvent<D extends Definition>(definition: D, event: Payload<D>, commit?: PublishOptions["commit"]) {


/tmp/opencode/session-recovery-v7-check/packages/core/src/project.ts:
  Line 49:   readonly commit: (input: { store: AbsolutePath; id: ID }) => Effect.Effect<void>


/tmp/opencode/session-recovery-v7-check/packages/core/src/session.ts:
  Line 178:     readonly commit: (sessionID: SessionSchema.ID) => Effect.Effect<void, NotFoundError>

  Line 450:         commit: Effect.fn("V2Session.revert.commit")(function* (sessionID) {


/tmp/opencode/session-recovery-v7-check/packages/core/src/session/input.ts:
  Line 483:         commit ? { commit: () => commit(row) } : undefined,

  Line 558:   return row === undefined ? false : yield* publish(db, events, sessionID, [row.input], commit).pipe(Effect.as(true))

  Line 566:   commit: (row: typeof SessionInputTable.$inferSelect) => ...
gateway · 2026-09-16 16:01:14
result
<path>/tmp/opencode/session-recovery-v7-check/packages/core/src/event.ts</path>
<type>file</type>
<content>
330:                                 seq,
331:                                 ...(input?.ownerID && row?.ownerID == null ? { owner_id: input.ownerID } : {}),
332:                               },
333:                             })
334:                             .run()
335:                             .pipe(Effect.orDie)
336:                           yield* db
337:                             .insert(EventTable)
338:                             .values([
339:                               {
340:                                 id: event.id,
341:                                 aggregate_id: aggregateID,
342:                                 seq,
343:                                 type: versionedType(definition.type, durable.version),
344:                                 data: encoded,
345:                               },
346:                             ])
347:             ...
gateway · 2026-09-16 16:01:29
result
<path>/tmp/opencode/session-recovery-v7-check/packages/core/src/event.ts</path>
<type>file</type>
<content>
441:       function replay(
442:         event: SerializedEvent,
443:         options?: { readonly publish?: boolean; readonly ownerID?: string; readonly strictOwner?: boolean },
444:       ) {
445:         return Effect.gen(function* () {
446:           const definition = Durable.get(event.type)
447:           if (!definition?.durable) {
448:             yield* Effect.die(
449:               new InvalidDurableEventError({ type: event.type, message: `Unknown durable event type ${event.type}` }),
450:             )
451:           } else {
452:             const payload = {
453:               id: event.id,
454:               type: definition.type,
455:               data: Schema.decodeUnknownSync(definition.data)(event.data),
456:             } as Payload
457:             const committed = yield* commitDurableEvent(definition, payload, {
458:               seq: event.seq,
459:     ...
gateway · 2026-09-16 16:01:58
result
<path>/tmp/opencode/session-recovery-v7-check/packages/core/src/event.ts</path>
<type>file</type>
<content>
230:                   new InvalidDurableEventError({
231:                     type: event.type,
232:                     message: `Aggregate mismatch: expected ${input.aggregateID}, got ${aggregateID}`,
233:                   }),
234:                 )
235:               }
236:               const list = projectors.get(event.type) ?? []
237:               return yield* Effect.uninterruptible(
238:                 Effect.gen(function* () {
239:                   const committed = yield* db
240:                     .transaction(
241:                       () =>
242:                         Effect.gen(function* () {
243:                           const row = yield* db
244:                             .select({ seq: EventSequenceTable.seq, ownerID: EventSequenceTable.owner_id })
245:                             .from(EventSequenceTable)
246:                             ...
gateway · 2026-09-16 16:02:13
result
<path>/tmp/opencode/session-recovery-v7-check/packages/core/src/event.ts</path>
<type>file</type>
<content>
180:       // TODO: Bind durable projectors to exact type+version before supporting incompatible historical payloads.
181:       const listeners = new Array<Subscriber>()
182:       const { db } = yield* Database.Service
183: 
184:       const getOrCreate = (definition: Definition) =>
185:         Effect.gen(function* () {
186:           const existing = pubsub.typed.get(definition.type)
187:           if (existing) return existing
188:           const created = yield* PubSub.unbounded<Payload>()
189:           pubsub.typed.set(definition.type, created)
190:           return created
191:         })
192: 
193:       yield* Effect.addFinalizer(() =>
194:         Effect.gen(function* () {
195:           yield* PubSub.shutdown(pubsub.all)
196:           yield* Effect.forEach(
197:             pubsub.durable.values(),
198:             (pubsubs) => Effect.forEach(pubsubs, ...
gateway · 2026-09-16 16:03:30
result
<path>/tmp/opencode/session-recovery-v7-check/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-16 16:04:18
result
<path>/tmp/opencode/session-recovery-v7-check/packages/server/src/routes.ts</path>
<type>file</type>
<content>
1: import { Database } from "@opencode-ai/core/database/database"
2: import { LayerNode } from "@opencode-ai/core/effect/layer-node"
3: import { httpClient } from "@opencode-ai/core/effect/app-node-platform"
4: import { AppNodeBuilder } from "@opencode-ai/core/effect/app-node-builder"
5: import { EventV2 } from "@opencode-ai/core/event"
6: import { Credential } from "@opencode-ai/core/credential"
7: import { PermissionSaved } from "@opencode-ai/core/permission/saved"
8: import { PtyTicket } from "@opencode-ai/core/pty/ticket"
9: import { SessionV2 } from "@opencode-ai/core/session"
10: import { SessionExecution } from "@opencode-ai/core/session/execution"
11: import { LocationServiceMap } from "@opencode-ai/core/location-service-map"
12: import { SessionExecutionLocal } from "@opencode-ai/core/session/execution/local"
13: import { SessionRecovery } from ...
gateway · 2026-09-16 16:04:37
result
<path>/tmp/opencode/session-recovery-v7-check/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-16 16:05:03
result
<path>/tmp/opencode/session-recovery-v7-check/packages/opencode/src/server/routes/instance/httpapi/server.ts</path>
<type>file</type>
<content>
221:   Git.node,
222:   Ripgrep.node,
223:   Storage.node,
224:   Snapshot.node,
225:   Plugin.node,
226:   ModelsDev.node,
227:   Provider.node,
228:   ProviderAuth.node,
229:   Agent.node,
230:   Skill.node,
231:   Discovery.node,
232:   Question.node,
233:   Permission.node,
234:   PermissionSaved.node,
235:   Todo.node,
236:   Session.node,
237:   SessionProjector.node,
238:   SessionStatus.node,
239:   BackgroundJob.node,
240:   RuntimeFlags.node,
241:   EventV2Bridge.node,
242:   SessionRunState.node,
243:   SessionProcessor.node,
244:   SessionCompaction.node,
245:   SessionRevert.node,
246:   SessionSummary.node,
247:   SessionPrompt.node,
248:   Instruction.node,
249:   LLM.node,
250:   LSP.node,
251:   MCP.node,
252:   McpAuth.node,
253:   Command.node,
254:   Truncate.node,
255:   ToolRegistry.node,
256:   Format.node,
257:   ...
gateway · 2026-09-16 16:05:18
result
Found 26 matches
/tmp/opencode/session-recovery-v7-check/packages/sdk/js/src/v2/gen/types.gen.ts:
  Line 24:   | EventSessionNextPromptExecutionRequested

  Line 33:   | EventSessionNextStepRecovered

  Line 874:           requestExecution?: boolean

  Line 879:         type: "session.next.prompt.execution_requested"

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

  Line 1650:     | SyncEventSessionNextPromptExecutionRequested

  Line 1659:     | SyncEventSessionNextStepRecovered

  Line 2785:   | SessionNextPromptExecutionRequested

  Line 2794:   | SessionNextStepRecovered

  Line 2915:   | SessionNextPromptExecutionRequested

  Line 2924:   | SessionNextStepRecovered

  Line 3430:       requestExecution?: boolean

  Line 3435: export type SyncEventSessionNextPromptExecutionRequested = {

  Line 3439:     type: "session.next.prompt.execution_requested.1"

  Line 3602: export type SyncEventSessionNextStepRecovered = {

  Line 3606:     type: ...
gateway · 2026-09-16 16:05:55
result
<path>/tmp/opencode/session-recovery-v7-check/packages/sdk/js/src/v2/gen/types.gen.ts</path>
<type>file</type>
<content>
850:           location: LocationRef
851:           subdirectory?: string
852:         }
853:       }
854:     | {
855:         id: string
856:         type: "session.next.prompted"
857:         properties: {
858:           timestamp: number
859:           sessionID: string
860:           messageID: string
861:           prompt: Prompt
862:           delivery: "steer" | "queue"
863:         }
864:       }
865:     | {
866:         id: string
867:         type: "session.next.prompt.admitted"
868:         properties: {
869:           timestamp: number
870:           sessionID: string
871:           messageID: string
872:           prompt: Prompt
873:           delivery: "steer" | "queue"
874:           requestExecution?: boolean
875:         }
876:       }
877:     | {
878:         id: string
879:         type: "session.next.prompt.execution_requested"
880:         ...
gateway · 2026-09-16 16:06:40
result
<path>/tmp/opencode/session-recovery-v7-check/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-16 16:07:19
result
Found 44 matches
/tmp/opencode/session-recovery-v7-check/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 1171:       "table": "session_recovery"

  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 1231:       "table": "session_recovery"

  Line 1241:       "table": "session_recovery"

  Line 1251:       "table": "session_recovery"

  ...
gateway · 2026-09-16 16:07:29
result
<path>/tmp/opencode/session-recovery-v7-check/packages/core/schema.json</path>
<type>file</type>
<content>
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:       "table": "session_execution"
952:     },
953:     {
954:       "type": "text",
955:       "notNull": true,
956:       ...
gateway · 2026-09-16 16:07:41
result
<path>/tmp/opencode/session-recovery-v7-check/packages/core/schema.json</path>
<type>file</type>
<content>
1790:         "session_id"
1791:       ],
1792:       "tableTo": "session",
1793:       "columnsTo": [
1794:         "id"
1795:       ],
1796:       "onUpdate": "NO ACTION",
1797:       "onDelete": "CASCADE",
1798:       "nameExplicit": false,
1799:       "name": "fk_session_context_epoch_session_id_session_id_fk",
1800:       "entityType": "fks",
1801:       "table": "session_context_epoch"
1802:     },
1803:     {
1804:       "columns": [
1805:         "session_id"
1806:       ],
1807:       "tableTo": "session",
1808:       "columnsTo": [
1809:         "id"
1810:       ],
1811:       "onUpdate": "NO ACTION",
1812:       "onDelete": "CASCADE",
1813:       "nameExplicit": false,
1814:       "name": "fk_session_execution_session_id_session_id_fk",
1815:       "entityType": "fks",
1816:       "table": "session_execution"
1817:     },
1818:     {
1819:       "columns": [
1820:      ...
gateway · 2026-09-16 16:08:17
result
<path>/tmp/opencode/session-recovery-v7-check/packages/core/schema.json</path>
<type>file</type>
<content>
1950:         "project_id",
1951:         "directory"
1952:       ],
1953:       "nameExplicit": false,
1954:       "name": "project_directory_pk",
1955:       "entityType": "pks",
1956:       "table": "project_directory"
1957:     },
1958:     {
1959:       "columns": [
1960:         "id"
1961:       ],
1962:       "nameExplicit": true,
1963:       "name": "session_execution_pk",
1964:       "entityType": "pks",
1965:       "table": "session_execution"
1966:     },
1967:     {
1968:       "columns": [
1969:         "execution_id"
1970:       ],
1971:       "nameExplicit": true,
1972:       "name": "session_recovery_pk",
1973:       "entityType": "pks",
1974:       "table": "session_recovery"
1975:     },
1976:     {
1977:       "columns": [
1978:         "session_id",
1979:         "position"
1980:       ],
1981:       "nameExplicit": false,
1982:       "name": "todo_pk",
1983:  ...
gateway · 2026-09-16 16:08:26
result
<path>/tmp/opencode/session-recovery-v7-check/packages/core/schema.json</path>
<type>file</type>
<content>
2520:     {
2521:       "columns": [
2522:         {
2523:           "value": "session_id",
2524:           "isExpression": false
2525:         }
2526:       ],
2527:       "isUnique": false,
2528:       "where": null,
2529:       "origin": "manual",
2530:       "name": "todo_session_idx",
2531:       "entityType": "indexes",
2532:       "table": "todo"
2533:     },
2534:     {
2535:       "value": "\"phase\" IN ('ready', 'safe', 'unknown', 'continue')",
2536:       "name": "session_execution_phase_check",
2537:       "entityType": "checks",
2538:       "table": "session_execution"
2539:     },
2540:     {
2541:       "value": "\"wake_attempts\" >= 0 AND \"wake_attempts\" <= 9007199254740991",
2542:       "name": "session_recovery_wake_attempts_check",
2543:       "entityType": "checks",
2544:       "table": "session_recovery"
2545:     },
2546:     {
2547:       "value": ...
gateway · 2026-09-16 16:08:43
result
Found 33 matches
/tmp/opencode/session-recovery-final-v8.patch:
  Line 1: diff --git a/packages/core/schema.json b/packages/core/schema.json

  Line 881: diff --git a/packages/core/src/database/migration.gen.ts b/packages/core/src/database/migration.gen.ts

  Line 892: diff --git a/packages/core/src/database/migration/20260914170650_session-recovery.ts b/packages/core/src/database/migration/20260914170650_session-recovery.ts

  Line 956: diff --git a/packages/core/src/database/schema.gen.ts b/packages/core/src/database/schema.gen.ts

  Line 1058: diff --git a/packages/core/src/session.ts b/packages/core/src/session.ts

  Line 1090: diff --git a/packages/core/src/session/compaction.ts b/packages/core/src/session/compaction.ts

  Line 1179: diff --git a/packages/core/src/session/context-epoch.ts b/packages/core/src/session/context-epoch.ts

  Line 1355: diff --git a/packages/core/src/session/execution/local.ts b/packages/core/src/session/execution/local.ts

  Line 1541: diff --git ...
gateway · 2026-09-16 16:08:54
result
Found 100 matches (more matches available)
/tmp/opencode/session-recovery-v7-check/packages/core/test/tool-output-store.test.ts:
  Line 45: const it = testEffect(Layer.empty)

  Line 48:   it.live("bounds the provider-facing text channel with one managed file", () =>

  Line 73:   it.live("uses bounded text for oversized structured-only output", () =>

  Line 86:   it.live("preserves native media and structured metadata without applying a settlement media limit", () =>

  Line 111:   it.live("preserves structured metadata and native media when bounding text", () =>

  Line 134:   it.live("does not double-count structured data duplicated in projected text", () =>

  Line 147:   it.live("fails oversized settlement when complete retention cannot be written", () =>

  Line 165:   it.live("does not encode ignored structured metadata when projected content exists", () =>

  Line 177:   it.live("preserves interruption while retaining complete output", () =>

  Line 212:   it.live("honors ...
gateway · 2026-09-16 16:09:00
result
<path>/tmp/opencode/session-recovery-v7-check/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 } from "drizzle-orm"
5: import { Database } from "@opencode-ai/core/database/database"
6: import { Project } from "@opencode-ai/core/project"
7: import { ProjectTable } from "@opencode-ai/core/project/sql"
8: import { AbsolutePath } from "@opencode-ai/core/schema"
9: import { SessionExecutionLocal } from "@opencode-ai/core/session/execution/local"
10: import { SessionSchema } from "@opencode-ai/core/session/schema"
11: import { SessionExecutionTable, SessionTable } from "@opencode-ai/core/session/sql"
12: import { testEffect } from "./lib/effect"
13: 
14: const sessionID = SessionSchema.ID.make("ses_execution_local")
15: const it = testEffect(Database.layerFromPath(":memory:"))
16: ...
gateway · 2026-09-16 16:09:09
result
<path>/tmp/opencode/session-recovery-v7-check/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-16 16:09:37
result
Found 29 matches
/tmp/opencode/session-recovery-v7-check/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 259:   it.effect("recovers each abandoned execution once across repeated startup scans", () =>

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

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

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

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

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

  Line 560:   it.effect("fairly redrives recovery and ordinary work beyond a full bounded batch", () =>

  Line 696:   ...
gateway · 2026-09-16 16:10:01
result
<path>/tmp/opencode/session-recovery-v7-check/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-16 16:10:26
result
<path>/tmp/opencode/session-recovery-v7-check/packages/core/test/session-projector.test.ts</path>
<type>file</type>
<content>
1051:         sessionID,
1052:         timestamp: created,
1053:         executionID: "existing-recovery",
1054:         phase: "ready",
1055:       })
1056:       yield* db
1057:         .insert(SessionExecutionTable)
1058:         .values({
1059:           id: "ready-before-recovery-promotion",
1060:           session_id: sessionID,
1061:           owner_id: "dead",
1062:           phase: "ready",
1063:           time_created: 0,
1064:           expires_at: 0,
1065:         })
1066:         .run()
1067:       const wakes: string[] = []
1068: 
1069:       yield* SessionRecovery.recover().pipe(
1070:         Effect.provideService(
1071:           SessionExecution.Service,
1072:           SessionExecution.Service.of({
1073:             ...recoveryExecution,
1074:             wake: (id) => Effect.sync(() => wakes.push(id)).pipe(Effect.asVoid),
1075:           ...
gateway · 2026-09-16 16:11:05
result
Found 21 matches
/tmp/opencode/session-recovery-v7-check/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 254:   it.effect("resumes through a recorded message without appending another prompt", () =>

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

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

  Line 310:   it.effect("wakes execution when an exact prompt retry recovers a committed message", () =>

  Line 330:   it.effect("never wakes execution when retrying an already promoted prompt", () =>

  Line 374:   it.effect("durably records execution intent before advisory wake", () =>

  Line 408:   it.effect("replays historical prompt admission without execution intent as admit-only", () =>

  Line 440:   it.effect("turns an admit-only exact retry into ...
gateway · 2026-09-16 16:11:21
result
<path>/tmp/opencode/session-recovery-v7-check/packages/core/test/session-prompt.test.ts</path>
<type>file</type>
<content>
240:         [1, "session.next.prompt.admitted"],
241:         [2, "session.next.prompted"],
242:         [3, "session.next.prompted"],
243:       ])
244:       expect(
245:         Array.from(
246:           yield* session
247:             .events({ sessionID, after: streamed[0]!.durable?.seq })
248:             .pipe(Stream.take(1), Stream.runCollect),
249:         ).map((event) => [event.durable?.seq, event.type]),
250:       ).toEqual([[1, "session.next.prompt.admitted"]])
251:     }),
252:   )
253: 
254:   it.effect("resumes through a recorded message without appending another prompt", () =>
255:     Effect.gen(function* () {
256:       yield* setup
257:       const session = yield* SessionV2.Service
258:       const message = yield* session.prompt({
259:         sessionID,
260:         prompt: Prompt.make({ text: "Fix the failing tests" }),
261:         ...
gateway · 2026-09-16 16:11:53
result
<path>/tmp/opencode/session-recovery-v7-check/packages/core/test/session-prompt.test.ts</path>
<type>file</type>
<content>
600: 
601:   it.effect("promotes one message once under concurrent promotion attempts", () =>
602:     Effect.gen(function* () {
603:       yield* setup
604:       const { db } = yield* Database.Service
605:       const session = yield* SessionV2.Service
606:       const events = yield* EventV2.Service
607:       yield* session.prompt({ id: messageID, sessionID, prompt: Prompt.make({ text: "Promote once" }), resume: false })
608: 
609:       yield* Effect.all(
610:         [
611:           SessionInput.promoteSteers(db, events, sessionID, Number.MAX_SAFE_INTEGER),
612:           SessionInput.promoteSteers(db, events, sessionID, Number.MAX_SAFE_INTEGER),
613:         ],
614:         { concurrency: "unbounded" },
615:       )
616: 
617:       expect(yield* eventCount(EventV2.versionedType(SessionEvent.Prompted.type, 1))).toBe(1)
618:       expect(yield* ...
gateway · 2026-09-16 16:12:20
result
<path>/tmp/opencode/session-recovery-v7-check/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 second ...
gateway · 2026-09-16 16:12:24
result
<path>/tmp/opencode/session-recovery-v7-check/packages/core/test/session-run-coordinator.test.ts</path>
<type>file</type>
<content>
341:             return forces.length === 1
342:               ? Deferred.succeed(firstStarted, undefined).pipe(
343:                   Effect.andThen(Effect.never),
344:                   Effect.onInterrupt(() =>
345:                     Deferred.succeed(cleanupStarted, undefined).pipe(Effect.andThen(Deferred.await(cleanupGate))),
346:                   ),
347:                 )
348:               : Deferred.succeed(secondStarted, undefined)
349:           },
350:         })
351: 
352:         yield* coordinator.wake("session")
353:         yield* Deferred.await(firstStarted)
354:         const interrupt = yield* coordinator.interrupt("session").pipe(Effect.forkChild)
355:         yield* Deferred.await(cleanupStarted)
356:         const resumed = yield* coordinator.run("session").pipe(Effect.forkChild)
357:         yield* Deferred.succeed(cleanupGate, ...
gateway · 2026-09-16 16:12:33
result
<path>/tmp/opencode/session-recovery-v7-check/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-16 16:12:49
result
<path>/tmp/opencode/session-recovery-v7-check/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-16 16:13:00
result
Found 64 matches
/tmp/opencode/session-recovery-v7-check/packages/core/test/session-runner.test.ts:
  Line 619:   it.effect("redrives only the synthetic recovery continuation", () =>

  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 977:   it.effect("streams one request with registry definitions from chronological V2 user history", () =>

  Line 1002:   it.effect("retries the first provider turn after system context becomes available", () =>

  Line 1034:   it.effect("interrupts a source Location runner after a Session moves", () =>

  Line 1542:   it.effect("recovers the continuation ...
gateway · 2026-09-16 16:13:19
result
<path>/tmp/opencode/session-recovery-v7-check/packages/core/test/session-runner.test.ts</path>
<type>file</type>
<content>
560:         : fixture.expectedContent
561:     expect(yield* session.context(sessionID)).toMatchObject([
562:       { type: "user", text: prompt },
563:       {
564:         type: "assistant",
565:         finish: "error",
566:         error: { type: "unknown", message: "Provider unavailable" },
567:         content: [expectedContent],
568:       },
569:     ])
570:   })
571: 
572: const verifyPartialFlushOnInterruption = (kind: FragmentKind) =>
573:   Effect.gen(function* () {
574:     yield* setup
575:     const session = yield* SessionV2.Service
576:     const prompt = `Interrupt after ${kind}`
577:     const fixture = fragmentFixture(kind, fragmentID(kind, "interrupted"), ["Partial"])
578:     const streamed = yield* Deferred.make<void>()
579:     yield* session.prompt({ sessionID, prompt: Prompt.make({ text: prompt }), resume: false })
580:     ...
gateway · 2026-09-16 16:13:25
result
<path>/tmp/opencode/session-recovery-v7-check/packages/core/test/session-runner.test.ts</path>
<type>file</type>
<content>
1460:       expect(userTexts(requests[1])[0]).toContain("<summary>\n## Objective\n- Preserve the task\n</summary>")
1461:       expect(userTexts(requests[1])[0]).toContain(`[User]: ${"Recent exact request ".repeat(180)}`)
1462: 
1463:       const context = yield* (yield* SessionStore.Service).context(sessionID)
1464:       expect(context.map((message) => message.type)).toEqual(["compaction", "assistant"])
1465:       expect(context[0]).toMatchObject({
1466:         type: "compaction",
1467:         summary: "## Objective\n- Preserve the task",
1468:       })
1469: 
1470:       requests.length = 0
1471:       executions.length = 0
1472:       responses = [
1473:         fragmentFixture("text", "text-summary-2", ["## Objective\n- Preserve the updated task"]).completeEvents,
1474:         fragmentFixture("text", "text-final-2", ["Continued ...
gateway · 2026-09-16 16:13:40
result
<path>/tmp/opencode/session-recovery-v7-check/packages/core/test/session-runner.test.ts</path>
<type>file</type>
<content>
3680:         [],
3681:       ]
3682: 
3683:       const run = yield* session.resume(sessionID).pipe(Effect.exit, Effect.forkChild)
3684:       let pending = yield* questions.list()
3685:       while (pending.length === 0) {
3686:         yield* Effect.yieldNow
3687:         pending = yield* questions.list()
3688:       }
3689:       yield* questions.reject(pending[0]!.id)
3690:       const exit = yield* Fiber.join(run)
3691: 
3692:       expect(exit._tag).toBe("Failure")
3693:       if (exit._tag === "Failure") expect(Cause.hasInterruptsOnly(exit.cause)).toBe(true)
3694:       expect(requests).toHaveLength(1)
3695:       expect(yield* session.context(sessionID)).toMatchObject([
3696:         { type: "user", text: "Ask then stop" },
3697:         {
3698:           type: "assistant",
3699:           content: [
3700:             {
3701:               type: ...
gateway · 2026-09-16 16:13:55
result
<path>/tmp/opencode/session-recovery-v7-check/packages/schema/test/event-manifest.test.ts</path>
<type>file</type>
<content>
1: import { describe, expect, test } from "bun:test"
2: import { FileSystem, Integration, Permission, Project, Reference, Session, Workspace } from "../src"
3: import { EventManifest } from "../src/event-manifest"
4: import { IdeEvent } from "../src/ide-event"
5: import { SessionEvent } from "../src/session-event"
6: import { SessionTodo } from "../src/session-todo"
7: import { SessionV1 } from "../src/session-v1"
8: import { WorkspaceEvent } from "../src/workspace-event"
9: 
10: describe("public event manifest", () => {
11:   test("owns the complete public event surface", () => {
12:     expect(EventManifest.ServerDefinitions.length).toBe(61)
13:     expect(EventManifest.Definitions.length).toBe(91)
14:     expect(SessionV1.Event.Definitions).toEqual([
15:       SessionV1.Event.Created,
16:       SessionV1.Event.Updated,
17:       SessionV1.Event.Deleted,
18:   ...
gateway · 2026-09-16 16:14:02
result
<path>/tmp/opencode/session-recovery-v7-check/packages/schema/src/session-event.ts</path>
<type>file</type>
<content>
450:       messageID: SessionMessage.ID,
451:       text: Schema.String,
452:     },
453:   })
454:   export type Delta = typeof Delta.Type
455: 
456:   export const Ended = Event.define({
457:     type: "session.next.compaction.ended",
458:     ...options,
459:     schema: {
460:       ...Base,
461:       messageID: SessionMessage.ID,
462:       reason: Started.data.fields.reason,
463:       text: Schema.String,
464:       recent: Schema.String,
465:     },
466:   })
467:   export type Ended = typeof Ended.Type
468: }
469: 
470: export namespace RevertEvent {
471:   export const Staged = Event.define({
472:     type: "session.next.revert.staged",
473:     ...options,
474:     schema: { ...Base, revert: Revert.State },
475:   })
476:   export const Cleared = Event.define({ type: "session.next.revert.cleared", ...options, schema: Base })
477:   export const Committed = ...
gateway · 2026-09-16 16:14:20
result
Found 12 matches
/tmp/opencode/session-recovery-v7-check/packages/sdk/openapi.json:
  Line 17899:                       "requestExecution": {

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

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

  Line 25709:                   "requestExecution": {

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

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

  Line 28599:               "requestExecution": {

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

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

  Line 34811:               "requestExecution": {

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

  Line 35201:             "enum": ["session.next.step.recovered"]
gateway · 2026-09-16 16:14:26
result
<path>/tmp/opencode/session-recovery-v7-check/packages/sdk/openapi.json</path>
<type>file</type>
<content>
17850:                         "pattern": "^msg_"
17851:                       },
17852:                       "prompt": {
17853:                         "$ref": "#/components/schemas/Prompt"
17854:                       },
17855:                       "delivery": {
17856:                         "type": "string",
17857:                         "enum": ["steer", "queue"]
17858:                       }
17859:                     },
17860:                     "required": ["timestamp", "sessionID", "messageID", "prompt", "delivery"],
17861:                     "additionalProperties": false
17862:                   }
17863:                 },
17864:                 "required": ["id", "type", "properties"],
17865:                 "additionalProperties": false
17866:               },
17867:               {
17868:                 "type": "object",
17869:                 "properties": ...
gateway · 2026-09-16 16:14:45
result
<path>/tmp/opencode/session-recovery-v7-check/packages/sdk/openapi.json</path>
<type>file</type>
<content>
18255:                   "properties": {
18256:                     "type": "object",
18257:                     "properties": {
18258:                       "timestamp": {
18259:                         "type": "number"
18260:                       },
18261:                       "sessionID": {
18262:                         "type": "string",
18263:                         "pattern": "^ses"
18264:                       },
18265:                       "assistantMessageID": {
18266:                         "type": "string",
18267:                         "pattern": "^msg_"
18268:                       },
18269:                       "error": {
18270:                         "$ref": "#/components/schemas/SessionErrorUnknown"
18271:                       }
18272:                     },
18273:                     "required": ["timestamp", "sessionID", "assistantMessageID", ...
gateway · 2026-09-16 16:15:08
result
Found 6 matches
/tmp/opencode/session-recovery-v7-check/packages/core/src/session/execution/claim.ts:
  Line 45:     .update(SessionExecutionTable)

  Line 57:     .delete(SessionExecutionTable)


/tmp/opencode/session-recovery-v7-check/packages/core/src/session/execution/local.ts:
  Line 32:         .insert(SessionExecutionTable)


/tmp/opencode/session-recovery-v7-check/packages/core/src/session/recovery.ts:
  Line 83:           .update(SessionExecutionTable)

  Line 103:             .update(SessionExecutionTable)

  Line 186:                           .update(SessionExecutionTable)
gateway · 2026-09-16 16:15:35
result
No files found
gateway · 2026-09-16 16:16:30
result
<path>/tmp/opencode/session-recovery-final-v8.patch</path>
<type>file</type>
<content>
6786: diff --git a/packages/core/test/session-runner.test.ts b/packages/core/test/session-runner.test.ts
6787: index cc58b43b29..d5c5707506 100644
6788: --- a/packages/core/test/session-runner.test.ts
6789: +++ b/packages/core/test/session-runner.test.ts
6790: @@ -31,7 +31,8 @@ import { SessionMessage } from "@opencode-ai/core/session/message"
6791:  import { Prompt } from "@opencode-ai/core/session/prompt"
6792:  import { SessionProjector } from "@opencode-ai/core/session/projector"
6793:  import { SessionExecution } from "@opencode-ai/core/session/execution"
6794: -import { SessionRunCoordinator } from "@opencode-ai/core/session/run-coordinator"
6795: +import { SessionExecutionLocal } from "@opencode-ai/core/session/execution/local"
6796: +import { SessionRecovery } from "@opencode-ai/core/session/recovery"
6797:  import { SessionRunner } from "@opencode-ai/core/session/runner"
6798:  import * as ...
gateway · 2026-09-16 16:18:40
result
Found 1 matches
/home/byk/.local/share/opencode/repos/github.com/Effect-TS/effect-smol/packages/effect/src/Effect.ts:
  Line 2066: export const andThen: {
gateway · 2026-09-16 16:18:49
result
<path>/home/byk/.local/share/opencode/repos/github.com/Effect-TS/effect-smol/packages/effect/src/Effect.ts</path>
<type>file</type>
<content>
2040:  * const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
2041:  *
2042:  * // Using Effect.map and Effect.flatMap
2043:  * const result1 = pipe(
2044:  *   fetchTransactionAmount,
2045:  *   Effect.map((amount) => amount * 2),
2046:  *   Effect.flatMap((amount) => applyDiscount(amount, 5))
2047:  * )
2048:  *
2049:  * Effect.runPromise(result1).then(console.log)
2050:  * // Output: 190
2051:  *
2052:  * // Using Effect.andThen
2053:  * const result2 = pipe(
2054:  *   fetchTransactionAmount,
2055:  *   Effect.andThen((amount) => Effect.succeed(amount * 2)),
2056:  *   Effect.andThen((amount) => applyDiscount(amount, 5))
2057:  * )
2058:  *
2059:  * Effect.runPromise(result2).then(console.log)
2060:  * // Output: 190
2061:  * ```
2062:  *
2063:  * @category sequencing
2064:  * @since 2.0.0
2065:  */
2066: export const ...
gateway · 2026-09-16 16:21:52
result
446412b56ac31b2a60f98765b5f14955a771f6074ebeb9309f603a0ceefad1bc  /tmp/opencode/session-recovery-final-v8.patch
f4f0bd585d33bd47114b2d8d54082c2b061380771c808e909223350e62c8c72f  /home/byk/Code/opencode/packages/opencode/dist/server/opencode-server
ab9408c81cc9916177641ae8e9f08624fc27b5b9
 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 ...
gateway · 2026-09-16 16:24:00
result
Found 1 matches
/tmp/opencode/session-recovery-v7-check/packages/core/test/session-projector.test.ts:
  Line 366:           assistantRow(SessionMessage.ID.make("msg_recovery_newer"), 1, { created, completed: created }),
gateway · 2026-09-16 16:25:18
result
Found 25 matches
/tmp/opencode/session-recovery-v7-check/packages/core/src/session/input.ts:
  Line 373:     recovery.recovery_error ??

  Line 587:         .set({ recovery_error: defect.reason })

  Line 592:             isNull(SessionRecoveryTable.recovery_error),


/tmp/opencode/session-recovery-v7-check/packages/core/src/session/sql.ts:
  Line 200:     recovery_error: text(),

  Line 208:       table.recovery_error,

  Line 233:     recovery_error: text(),


/tmp/opencode/session-recovery-v7-check/packages/core/src/session/execution/local.ts:
  Line 57:             isNull(SessionRecoveryTable.recovery_error),


/tmp/opencode/session-recovery-v7-check/packages/core/src/session/recovery.ts:
  Line 49:             isNull(SessionRecoveryTable.recovery_error),

  Line 72:     .where(and(lte(SessionExecutionTable.expires_at, scanTime), isNull(SessionExecutionTable.recovery_error)))

  Line 91:               isNull(SessionExecutionTable.recovery_error),

  Line 104:             .set({ ...
gateway · 2026-09-16 16:27:17

MUST-FIX

1. Cross-Session recovery collision can expose an internal continuation as ordinary public input

session_recovery.execution_id is globally unique (packages/core/src/session/sql.ts:204, migration line 38), but the projector checks for an existing recovery using both execution and Session IDs:

  • packages/core/src/session/projector.ts:403-414

A corrupt row may therefore hold execution ID E for Session B with a noncanonical continuation. When recovery for Session A also uses E, the projector:

  1. Creates A’s deterministic continuation at projector.ts:433-441.
  2. Attempts to insert A’s recovery row.
  3. Silently ignores the global primary-key conflict through .onConflictDoNothing() at projector.ts:442-455.
  4. Commits the event and clears A’s claim.

A’s continuation now has no session_recovery row. Consequently:

  • isRecoveryInput returns false (input.ts:434-445).
  • Public exact retry may arm it (input.ts:62-67, 112-161).
  • Ordinary queue promotion includes it because the left join finds no recovery (input.ts:539-558).

This violates the same-Session, internal-only continuation boundary under the requested corrupt-row and forged-identity threat model.

The projector must query execution IDs globally and reject mismatched existing identity. It must also require the recovery insert to affect exactly one row rather than silently accepting conflicts. Add a regression with a malformed Session-B recovery sharing Session A’s execution ID.

2. Cancellation renewal failure permits recovery while stale finalizers remain active

Explicit interruption starts a heartbeat but discards its fiber:

  • packages/core/src/session/execution/local.ts:110-114

It then waits for the runner and all finalizers before clearing ownership:

  • packages/core/src/session/execution/local.ts:115-131
  • packages/core/src/session/run-coordinator.ts:107-108

If the heartbeat loses ownership or dies during a slow finalizer, nothing observes that ...

gpt-5.6-sol · 2026-09-16 16:27:17 · ~1.6K tokens

Distillations (17)

Gen 0 2026-09-16 20:31:51 · 2424 tokens

Date: Sep 16, 2026 * 🟡 (16:21) Inspected `/home/byk/.local/share/opencode/repos/github.com/Effect-TS/effect-smol/packages/effect/src/Effect.ts:2066-2081`: `Effect.andThen` supports both function and effect arguments in pipeable and uncurried forms; its example doubles `100`, applies a `5` discount, and outputs `190`. * 🟡 (16:24) Review inputs identified patch `/tmp/opencode/session-recovery-fin…

Gen 0 2026-09-16 20:26:18 · 397 tokens

Date: Sep 16, 2026 * 🔴 [specified-regression-test] (16:18) User specified regression invariant/test `"never dispatches a provider after ownership changes"` in `/tmp/opencode/session-recovery-v7-check/packages/core/test/session-runner.test.ts`. * 🔴 [specified-regression-test] (16:18) User specified regression invariant/test `"never publishes streamed output after ownership changes"` in `/tmp/ope…

Gen 0 2026-09-16 20:09:12 · 1342 tokens

Date: Sep 16, 2026 * 🔴 (16:13) User specified the regression invariant/test `"never marks a failed Step safe while a sibling tool finalizer is active"` in `/tmp/opencode/session-recovery-v7-check/packages/core/test/session-runner.test.ts`; the test uses sibling tools including `sibling_defect`, gates execution with `executionStarted` and finalization with `releaseFinalizer`, and prompts with `"R…

Gen 0 2026-09-16 19:54:44 · 800 tokens

Date: Sep 16, 2026 * 🟡 (16:13) `/tmp/opencode/session-recovery-v7-check/packages/core/test/session-runner.test.ts` ownership-fencing test `"never dispatches a provider after ownership changes"` pauses model resolution with `modelResolveHook = Deferred.succeed(resolving, undefined).pipe(Effect.andThen(Deferred.await(resumeResolution)))`, changes ownership in `SessionExecutionTable`, and verifies …

Gen 0 2026-09-16 19:34:08 · 2588 tokens

Date: Sep 16, 2026 * 🟡 (16:12) `/tmp/opencode/session-recovery-v7-check/packages/core/test/session-prompt.test.ts` includes `"promotes one message once under concurrent promotion attempts"`: two concurrent `SessionInput.promoteSteers(db, events, sessionID, Number.MAX_SAFE_INTEGER)` calls produce exactly 1 `EventV2.versionedType(SessionEvent.Prompted.type, 1)` event, set `promotedSeq: 1`, and exp…

Gen 0 2026-09-16 19:23:37 · 829 tokens

Date: Sep 16, 2026 * 🔴 (16:11) User requires recovery never to recover a pre-promotion claim when input commits at the recovery boundary. * 🔴 (16:11) User requires recovery never to promote a recovery superseded before scanner validation. * 🔴 (16:11) User requires recovery never to promote a quarantined recovery continuation as an ordinary steer. * 🔴 (16:11) User requires the Context Epoch ne…

Gen 0 2026-09-16 19:08:06 · 82 tokens

Date: Sep 16, 2026 * 🔴 (16:10) User requires recovery never to recover a live execution lease. * 🔴 (16:10) User requires recovery never to recover an execution superseded by a newer assistant. * 🔴 (16:10) User requires redrive never to wake work settled between selection and the redrive compare-and-swap (CAS).

Gen 0 2026-09-16 18:44:39 · 1243 tokens

Date: Sep 16, 2026 * 🟡 (16:08) In `packages/core/schema.json`, `session_execution_pk` is an explicit primary key on `session_execution.id`; `session_recovery_pk` is an explicit primary key on `session_recovery.execution_id`. * 🟡 (16:08) `packages/core/schema.json` defines `session_execution_phase_check` as `"phase" IN ('ready', 'safe', 'unknown', 'continue')`. * 🟡 (16:08) `packages/core/schema…

Gen 0 2026-09-16 18:21:14 · 2382 tokens

Date: Sep 16, 2026 * 🟡 (16:03) In `packages/core/src/event.ts:205-237`, `commitDurableEvent(definition, event, input?, commit?)` reads the aggregate value from `event.data[durable.aggregate]`; a non-string value dies with `InvalidDurableEventError`, `type: event.type`, and exact message `Expected string aggregate field ${durable.aggregate}`. * 🟡 (16:03) `commitDurableEvent(...)` rejects a suppl…

Gen 0 2026-09-16 18:05:44 · 1660 tokens

Date: Sep 16, 2026 * 🟡 (16:00) Search found 8 session-runner event references: `packages/core/test/session-runner-tool-events.test.ts` lines 136 and 140; `packages/core/test/session-runner.test.ts` lines 837, 852, 1737, 3000, 3064, and 3124. Notable checks include `session.next.tool.failed.1`, decoding with `Schema.decodeUnknownSync(SessionEvent.Tool.Success.data)`, matching `SessionEvent.Tool.S…

Gen 0 2026-09-16 18:01:22 · 766 tokens

Date: Sep 16, 2026 * 🔴 (15:59) User directed that local execution ownership be replaced with durable multi-node ownership when clustered. * 🟡 (15:59) Session runner implementation documentation designates `specs/v2/session.md` as the canonical location for tracking V1 runtime-context parity. * 🟡 (15:59) Session runner checklist marks authorization and execution of recorded local calls through …

Gen 0 2026-09-16 17:41:30 · 2158 tokens

Date: Sep 16, 2026 * 🟡 (15:57) Generated schema in `packages/core/src/database/schema.gen.ts` defines recovery wake-selection index `session_recovery_wake_pending_error_attempts_created_execution_idx` on `(wake_pending, recovery_error, wake_attempts, time_created, execution_id)`. * 🟡 (15:58) `packages/core/src/session.ts:422-433` implements `wait` by validating the session with `result.get(sess…

Gen 0 2026-09-16 17:12:49 · 1064 tokens

Date: Sep 16, 2026 * 🔴 (15:56) User established the recovery invariant: a newer turn supersedes stale incomplete rows; never resume an older assistant projection. * 🟡 (15:56) `packages/core/src/session/projector.ts` rejects a recovery target unless it is the latest assistant message, dying with exact error `Recovery target is not the latest assistant: ${event.data.assistantMessageID}`; recovery…

Gen 0 2026-09-16 16:50:18 · 1168 tokens

Date: Sep 16, 2026 * 🟡 (15:55) `packages/core/src/session/recovery.ts` defines `BATCH_SIZE = 100` and contains separate recovery handling for claimed executions, pending recovery wakes, and ordinary session wakes; recovery work is ordered by `SessionRecoveryTable.time_created` then `SessionRecoveryTable.execution_id`. * 🟡 (15:55) `packages/core/src/session/recovery.ts` checks ownership against …

Gen 0 2026-09-16 16:32:48 · 3627 tokens

Date: Sep 16, 2026 * 🟡 (15:54) Patch search found the same 4 added files in 5 patch versions: `/tmp/opencode/session-recovery-final-v7.patch` at lines 892, 2289, 9075, 9147; `/tmp/opencode/session-recovery-final-v6.patch` at lines 877, 2267, 8698, 8770; `/tmp/opencode/session-recovery-final-v8.patch` at lines 892, 2289, 9451, 9523; `/tmp/opencode/session-recovery-final-v5.patch` at lines 878, 13…

Gen 0 2026-09-16 16:27:24 · 1538 tokens

Date: Sep 16, 2026 * 🟡 (15:51) Tool listed `/tmp/opencode/session-recovery-v7-check` as a directory with 65 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…

Gen 0 2026-09-16 16:19:22 · 528 tokens

Date: Sep 16, 2026 * 🟢 (15:48) Tool search returned “No files found.” * 🟡 (15:49) Tool listed `/home/byk/Code/opencode` as a directory with 71 entries: `.dockerignore`, `.editorconfig`, `.git/`, `.gitattributes`, `.github/`, `.gitignore`, `.gitleaksignore`, `.husky/`, `.lore.md`, `.node-cache/`, `.opencode/`, `.oxlintrc.json`, `.prettierignore`, `.turbo/`, `.vscode/`, `.zed/`, `AGENTS.md`, `art…