Repository navigation
Description
Feature request: atomic replication API for existing sessions
Feature hasn't been suggested before.
- I verified that no existing issue requests this mutation contract. [FEATURE]: continue a session on another opencode instance when the server is unreachable, and bring the continuation back as a fork #52801
proposes returning offline work as a new fork; this request instead preserves the
existing session identity and requires conflict-safe fast-forward semantics.
Describe the enhancement you want to request
Problem
The public session transfer API can import a session only when its ID is absent on
the target. Importing an existing ID returns 409 Conflict. There is no supported
append, upsert, fast-forward or conditional replacement operation.
This prevents safe offline/multi-host continuity for an existing session. A client
cannot use export → delete → import: another prompt or tool result may be committed
between the export and delete, causing an unrecoverable lost update. Prompt and
synthetic-message endpoints are not substitutes because they may execute the model
or tools and cannot ingest an already completed transcript faithfully.
Requested API contract
Provide one atomic, idempotent mutation for an existing session, either as durable
event ingestion or conditional snapshot import. The operation should:
- preserve the session ID and project association;
- ingest completed user, assistant, tool and terminal events without executing the
model or tools; - transfer all state needed to resume faithfully, including instruction entries,
instruction state/blobs and terminaloutcome/time.idle; - accept an optimistic-concurrency precondition such as
expectedLastSeq, revision
orIf-Match; - return
412 Precondition Failedor409 Conflictwithout mutation when the
target advanced concurrently; - be idempotent when the same event range or snapshot is retried;
- commit data and publish the corresponding event-stream updates atomically;
- reject malformed or incomplete state without creating a partial session.
Possible shapes:
POST /api/session/:id/events
If-Match: <target-revision>
Idempotency-Key: <transfer-id>or:
POST /api/experimental/session/import
{
"mode": "fast-forward",
"expectedLastSeq": 123,
"data": { "...": "full session transfer payload" }
}Why current alternatives are insufficient
- Import on an existing ID returns
409with no safe update mode. - Delete then import has a time-of-check/time-of-use race and can lose writes.
- Forking changes the visible session identity and creates duplicate conversations.
- Replaying prompts changes outputs and can repeat tool side effects.
- Database copying is unsafe while either engine is active and is not an API.
Use case
Two autonomous OpenCode installations should be able to continue the same session
while either host may be offline. On reconnection, a strict fast-forward should be
applied automatically; divergent heads should remain unchanged and be reported as
a conflict for explicit resolution.
Related issues
- [FEATURE]: continue a session on another opencode instance when the server is unreachable, and bring the continuation back as a fork #52801 requests offline continuation returned as a fork. Forking is a safe
fallback, but it changes the visible identity and does not provide transparent
continuity for a non-divergent session. - [FEATURE]: Add a transcript revision token for incremental consumers #43766 requests a transcript revision token. Such a token is a natural
precondition for this mutation API but does not itself provide a write path. - [FEATURE]: Durable event export / replay surface for external integrations #19567 requested durable event export/replay. This request complements it with a
validated, idempotent ingestion path.
Activity
opencode-agent commentedon Oct 8, 2026
Thanks for the detailed write-up! You're asking for an atomic, idempotent way to fast-forward an existing session. It would keep the same session ID, ingest completed events without running the model or tools, and include an optimistic-concurrency precondition (
expectedLastSeq/ revision /If-Match), so that a session that diverged is rejected with a conflict and nothing is changed.This isn't something a plugin can do today: it needs a server-side check and a transactional write to the session log, and the plugin API doesn't expose that. Maintainers will consider it.
Related issues: