Dashboard › opencode › Distillation
2b8f5e51-aa73-41ef-9ba1-ed2f064e35b3["lore_tm_v1_mpQCfezA110xD1As1YoDDTctJscEiO3VV6WT1YyqiBE","lore_tm_v1__DCJXtLmFFxT3jdjzh8xE4W3_P1sGoKNx1YhSCQLWD0","lore_tm_v1_zdKUWnP3ZdUp6J8sLRE6JBYF1xbEbP3GILth1VmqTZQ","lore_tm_v1_vfBAHITIOOzQPUMxJzQqYBgGI9CgMbOJGmu7GDdShEA","lore_tm_v1_EHIsR64X1vyWwrO6DZSAMag_fwOCrpX6Dw-jHnki-PU","lore_tm_v1_BDFdz04JQwsS72PzuHDXAJaKQfvMfFn3VdHjuIdO_YI","lore_tm_v1_1fDlWxo8dPqN0I7EzB2zjcV7_g6AOxS1lC5vWTygQRI","lore_tm_v1_qRcJ3FKRiB3N0bWtfIrhLAk32RTXZWbAiilDHwlcdwc","lore_tm_v1_cO2D_vzKc3IAzXdNP6brxd3YXxOukFMb76OFEcTg1eg","lore_tm_v1_b8cy3SEn0mJjTljiXKvz-Dt3IVAg2_O0kDpiKdn1aCk"]
Date: Sep 16, 2026
packages/core/src/event.ts, publishEvent<D extends Definition>(definition, event, commit?) dies with InvalidDurableEventError and message "Local commit hooks require a durable event" when a commit hook is supplied for a non-durable definition.publishEvent() calls commitDurableEvent(definition, event as Payload, undefined, commit); when committed, it adds durable: { aggregateID, seq, version: definition.durable.version }, calls notify(event, true), and returns the enriched event. Otherwise it calls notify(event, false).observe(event, observer) invokes listeners via Effect.suspend(() => observer(event)); non-interruption failures are caught with Effect.catchCauseIf((cause) => !Cause.hasInterrupts(cause), ...) and logged as "Event listener failed" with eventID, eventType, and cause.notify(event, isolateListeners) runs every listener with Effect.forEach(..., { discard: true }), using isolated observe(event, listener) only when isolateListeners is true; it then publishes to the type-specific pubsub, if present, and finally to pubsub.all.publish() resolves event location in this precedence order: options?.location, then Location.Service mapped to { directory, workspaceID }, then no location. It uses options?.id ?? ID.create(), conditionally includes options.metadata, sets type: definition.type, and passes options?.commit to publishEvent().replay() accepts options?: { readonly publish?: boolean; readonly ownerID?: string; readonly strictOwner?: boolean }; unknown or non-durable event types die with InvalidDurableEventError and message Unknown durable event type ${event.type}.replay() rebuilds a payload from serialized id, the durable definitionβs type, and Schema.decodeUnknownSync(definition.data)(event.data), then calls commitDurableEvent() with serialized seq and aggregateID plus ownerID and strictOwner.replay() commits and options?.publish is true, it calls notify(..., true) with durable metadata { aggregateID: committed.aggregateID, seq: committed.seq, version: definition.durable.version }.replayAll() returns undefined for an empty event array; otherwise it requires every event to share the first eventβs aggregateID, dying with InvalidDurableEventError and message "Replay events must belong to the same aggregate" if not.replayAll() requires contiguous sequence numbers beginning at events[0]?.seq ?? 0; a mismatch dies with message Replay sequence mismatch at index ${index}: expected ${seq}, got ${event.seq}. It then replays events in order and returns the source aggregate ID.remove(aggregateID) runs a database transaction that deletes the matching row from EventSequenceTable and then matching rows from EventTable, with failures converted through Effect.orDie.claim(aggregateID, ownerID) updates EventSequenceTable.owner_id where aggregate_id equals aggregateID, then applies Effect.orDie.subscribe<D extends Definition>(definition) obtains or creates a typed pubsub, wraps it with Stream.fromPubSub, and casts each event to Payload<D>; streamAll() returns Stream.fromPubSub(pubsub.all).readAfter(aggregateID, after) first runs options?.beforeAggregateRead?.(aggregateID) ?? Effect.void, then selects EventTable rows where aggregate_id = aggregateID and seq > after, ordered ascending by seq, and maps rows through decodeSerializedEvent().packages/core/src/event.ts selects { seq: EventSequenceTable.seq, ownerID: EventSequenceTable.owner_id }; with strictOwner, an existing differing owner causes an error message Replay owner mismatch for aggregate ${aggregateID}: expected ${row.ownerID}, got ${input.ownerID ?? "none"}.owner_id when input.ownerID is present and the existing rowβs owner is null; sequence updates likewise conditionally include { owner_id: input.ownerID }.packages/opencode/src/control-plane/workspace.ts, history synchronization POSTs state to /sync/history; non-2xx responses produce SyncHttpError with message Workspace history HTTP failure: ${response.status} ${body}, plus status and body.syncHistory() replays each returned history event with { publish: true, ownerID: space.id }, converts event.id using EventV2.ID.make(event.id), and provides WorkspaceRef as space.id.Workspace.syncWorkspaceLoop skips local targets, sets status to "connecting", invokes syncHistory() after connectSSE(), and on connection failure sets status to "error" and logs "failed to connect to global sync" with workspace name and normalized error data.Workspace.syncWorkspaceLoop resets attempt = 0, sets status to "connected", ignores "server.heartbeat" payloads, and replays "sync" payload events with { publish: true, ownerID: space.id }."failed to replay global event" with workspaceID: space.id; successfully handled events are emitted through GlobalBus.emit("event", { directory, project, workspace: space.id, payload }).packages/opencode/src/server/routes/instance/httpapi/handlers/sync.ts, SyncHttpApi.replay maps request events into EventV2.SerializedEvent[], logs "sync replay requested" with sessionID, event count, first/last sequence, and directory, then calls events.replayAll(payload, { ownerID, strictOwner: true }), where ownerID comes from InstanceState.workspaceID.SyncHttpApi.replay logs "sync replay complete" with sessionID, event count, and first/last sequence, then returns { sessionID: source }.SyncHttpApi.steal returns HttpApiError.BadRequest when no workspace ID exists; otherwise it calls session.setWorkspace({ sessionID: ctx.payload.sessionID, workspaceID }), logs "sync session stolen", and returns the session ID.SyncHttpApi.history selects from EventTable, excluding each supplied aggregate/sequence pair via not(or(...and(eq(EventTable.aggregate_id, id), lte(EventTable.seq, seq)))), orders by ascending EventTable.seq, and applies Effect.orDie.packages/core/src/session/projector.ts, the SessionEvent.RevertEvent.Committed projector finds the boundary sequence in SessionMessageTable by session ID and message ID; absence dies with Revert boundary message not found: ${event.data.messageID}.seq is greater than the boundary, deletes session inputs whose admitted_seq or promoted_seq exceeds the boundary, then clears SessionTable.revert and updates time_updated using DateTime.toEpochMillis(event.data.timestamp).packages/core/schema.json 518/47, packages/core/src/session/input.ts 342/31, packages/core/src/session/recovery.ts 331/0, packages/core/src/session/runner/llm.ts 244/95, packages/core/test/session-projector.test.ts 1780/3, packages/core/test/session-runner.test.ts 742/17, and packages/sdk/openapi.json 657/44.packages/core/src/database/migration/20260914170650_session-recovery.ts, packages/core/src/session/recovery.ts, packages/core/test/session-execution-local.test.ts, packages/core/src/session/execution/claim.ts, and packages/core/src/session/recovery-id.ts./tmp/opencode/session-recovery-final-v6.patch contains four runnerFinalizer references: line 6324 initializes let runnerFinalizer = Effect.void; line 6343 uses Effect.ensuring(Effect.suspend(() => runnerFinalizer)); line 6391 resets it to Effect.void; line 7130 assigns Deferred.succeed(finalizerStarted, undefined).pipe(Effect.andThen(Deferred.await(releaseFinalizer))).