mirror of
https://github.com/anomalyco/opencode.git
synced 2026-06-02 06:16:48 +02:00
ab31c41fee
Today every sync.run produces TWO GlobalBus events:
1. From bus.publish itself — the projection view:
{ payload: { id, type: "session.created", properties } }
2. From sync/index.ts — the source-of-truth envelope:
{ payload: { type: "sync", syncEvent: { type: "session.created.1", id, seq, aggregateID, data } } }
These two emits live in different files and discriminate via
`payload.type` — either a real event type or the sentinel "sync".
That collision is the source of confusion in the codebase:
consumers have to know which shape they're looking at.
The duality dates back to:
- d88912abf0 (Dec 2025): Dax added GlobalBus.emit inside bus.publish.
- b22add292c (#22347, Apr 2026): James consolidated sync events onto
GlobalBus by ADDING a second emit with the source envelope.
#22347's stated intent was "consolidate events into a single stream".
Two emits with different shapes on one channel isn't quite that. One
emit per event with a unified shape is.
This PR collapses the two emits into one:
{ payload: { id, type: "session.created", properties, sync?: { name, seq, aggregateID, data } } }
- bus.publish accepts an optional `sync?: SyncMetadata` option.
- sync/index.ts passes it; its own GlobalBus.emit is removed.
- BusEvent.effectPayloads() adds an optional `sync` field to every
event schema.
- SyncEvent.effectPayloads() is no longer included in the wire schema
(it's now subsumed by the optional field).
- Consumers migrate from `payload.type === "sync"` filtering to
`payload.sync != null` filtering. control-plane/workspace.ts
reconstructs SerializedEvent from { id, sync.* } for replay.
Note: this is a BREAKING SDK wire-format change. External consumers
that read `payload.type === "sync"` or `payload.syncEvent` need to
migrate. Internal opencode consumers all migrated in this PR.
Side observation: the runtime emit was using `payload.syncEvent`
(nested) while the SDK schema declared the fields at top level under
`type: "sync"` — a silent schema drift. Collapsing to one emit also
fixes that drift by definition.
Verified:
- bun typecheck — clean
- bun run test test/sync/index.test.ts test/bus/bus-effect.test.ts
test/server/httpapi-event.test.ts
test/server/httpapi-event-diagnostics.test.ts — 29/29 green
- bun run test test/server/httpapi-sdk.test.ts -t "streams sync-backed" — green