fix(core): preserve event routing semantics

This commit is contained in:
Kit Langton 2026-06-25 12:41:44 -04:00
commit 603b334b7f
13 changed files with 277 additions and 129 deletions

View file

@ -11,18 +11,21 @@ const fields = {
location: Schema.optional(Location.Ref),
}
const DurableEnvelope = Schema.Struct({ aggregateID: Schema.String, seq: Schema.Int, version: Schema.Int })
const schema = (definitions: ReadonlyArray<Definition>) =>
Schema.Union([
...definitions.map((definition) =>
definition.durable
? Schema.Struct({
...fields,
durable: Event.durableEnvelope(definition.durable.version),
durable: DurableEnvelope,
type: Schema.Literal(definition.type),
data: definition.data,
}).annotate({ identifier: `V2Event.${definition.type}` })
: Schema.Struct({
...fields,
durable: Schema.optional(Schema.Never),
type: Schema.Literal(definition.type),
data: definition.data,
}).annotate({ identifier: `V2Event.${definition.type}` }),
@ -32,6 +35,7 @@ const schema = (definitions: ReadonlyArray<Definition>) =>
: [
Schema.Struct({
...fields,
durable: Schema.optional(Schema.Never),
type: Schema.Literal("server.connected"),
data: Schema.Struct({}),
}).annotate({ identifier: "V2Event.server.connected" }),
@ -62,4 +66,5 @@ export const makeEventGroup = (definitions: ReadonlyArray<Definition>) => make(d
const event = make(EventManifest.ServerDefinitions)
export const EventGroup = event.group
export type Event = typeof event.schema.Type
export const EventSchema = event.schema
export type Event = typeof EventSchema.Type

View file

@ -0,0 +1,27 @@
import { describe, expect, test } from "bun:test"
import { Event } from "@opencode-ai/schema/event"
import { Schema } from "effect"
import { EventSchema } from "../src/groups/event"
describe("EventSchema", () => {
test("requires durable metadata on durable events", () => {
expect(
Schema.is(EventSchema)({
id: Event.ID.create(),
type: "session.created",
data: { sessionID: "session" },
}),
).toBe(false)
})
test("rejects durable metadata on live events", () => {
expect(
Schema.is(EventSchema)({
id: Event.ID.create(),
type: "server.connected",
durable: { aggregateID: "aggregate", seq: 0, version: 1 },
data: {},
}),
).toBe(false)
})
})