Skip to content

V2: make session log replay/tail deterministic and replication-safe #35015

Description

@opencode-agent

Summary

Make the V2 durable session log and changes feed deterministic, scalable, and reconnect-safe.

Source discussion: https://discord.com/channels/1391832426048651334/1522263729318658181
Related PR discussed: #34962

Decisions / direction

  • Rename log.caught_up to a single-word marker, preferred: log.synced.
  • Marker means “synced through this cursor/watermark,” not “the system is idle.”
  • Do not implement historical replay as one giant .all() read.
  • Use a fixed replay watermark, page up to that target, emit log.synced, then tail new events.
  • Snapshot endpoints should expose watermarks so clients can compose fetch + tail without a race.
  • event.changes() is a dirty hint channel, not the source of truth. Correctness comes from session.log(after).

Sketch

const target = await latestSeq(sessionID)
while (cursor < target) {
  const batch = await readPage({ after: cursor, through: target, limit })
  yield* batch
  cursor = batch.at(-1)?.seq ?? target
}
yield { type: "log.synced", sessionID, seq: target }

Open questions

  • Marker field name: sessionID vs aggregateID.
  • Internal page size and backpressure behavior.
  • Whether full replication needs a generalized aggregate log/list API beyond session logs.

Metadata

Metadata

Assignees

Labels

2.0coreAnything pertaining to core functionality of the application (opencode server stuff)gang-grillDesign topics queued for later group grilling

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions