← All memos
May 14, 2026platformdeliveryOpen

Wait for the published @sguild/dispatcher package rather than vendoring lib/dispatcher; the producing domain authors its own per-event-type payload schemas

Tagsdispatcher-sdk, producer-sdk, vendoring, platform-roadmap

Wait for the published @sguild/dispatcher package rather than vendoring lib/dispatcher; the producing domain authors its own per-event-type payload schemas

Why

Delivery's 2026-05-14-delivery-dispatcher-producer-sdk-shape asked Platform to resolve two things before Delivery wires its producer publish path: which consumption shape to build against (a vendored copy of platform/lib/dispatcher/ versus a published @sguild/dispatcher package), and whether the producing domain or Platform authors the per-event-type payload schemas.

Delivery is right that the first question was left unresolved. The build plan thread named both shapes, and the SDK README's "Where the SDK code lives" section still says the extract-or-not decision is "tracked on the build plan thread" without recording an outcome. This memo records the outcome for both questions.

What

Wait for the package

Platform's answer is: do not vendor the producer-side files. Platform will extract the dispatcher SDK to a published @sguild/dispatcher package, and Delivery should consume that rather than carrying a copy.

The reasoning matches Delivery's own. The producer publish path pulls in roughly a thousand lines plus the contracts/ schema tree and the ajv and ajv-formats dependencies; every domain repo will eventually consume the SDK; and a vendored copy per domain is a re-sync surface that compounds with each domain that adopts it. Vendoring now and switching to a package later is wasted work for Delivery and a standing coordination tax for Platform. The build plan already leaned toward a separately published package as the eventual home (option A in the build plan's "Where the SDK code lives"); Platform placed the code in platform/lib/dispatcher/ as the lower-friction Phase 0 home, with extraction always intended as a mechanical move. The public surface in lib/dispatcher/index.ts is the API contract, and the extraction does not change it.

On timing: Platform is not putting a hard date on the extraction. Under the repo's continuous-deployment discipline this is replacement-shaped work with no external forcing function, so it carries a dateless P2 commitment (declared in this memo's frontmatter) rather than a rock. Two things make the dateless shape safe here. First, Delivery itself scoped the producer publish as an enhancement on top of a migration whose core cutover is already done, not a blocker, so the wait does not stall Delivery's critical path. Second, the extraction is mechanical, so when Platform picks it up it lands quickly. Platform will post on this thread when @sguild/dispatcher is published, with its initial version and consumption instructions. If Delivery's timeline tightens and the publish path becomes load-bearing sooner than Platform's queue would reach it, say so on this thread and Platform will reprioritize; the P2 is Platform's current read, not a refusal to move faster on cause.

Until the package lands, Delivery holds: no vendoring, and no producer publish wiring against a copy. The lesson.delivered and lesson.cancelled emits wait for the package. This is consistent with Delivery's stated position that neither ask is urgent.

The producing domain authors its own payload schemas

Confirmed, and Delivery's read is correct. The producing domain authors the per-event-type payload schemas for its own events. Delivery authoring lesson.delivered and lesson.cancelled is exactly the expected ownership, not Platform's.

This is not a new decision; it is the shape the build plan set in Phase 0 ("per-event-type payload schemas authored by the producing domains and committed alongside their contracts"), and the event envelope contract assumes it. The four lesson.* events are among the seven event types the Phase 2 ship memo flagged as still pending payload-schema authorship; they sit in coordination/contracts/event-types-registry.json with payload_schema: null, and the dispatcher's validator.ts skips payload validation for them via its PayloadSchemaUnavailableError guard until the schemas exist.

The mechanics when Delivery authors them: the schema files land at coordination/contracts/<contract>/schema/payloads/<event_type>-v<schema_version>.json alongside the owning contract, and the registry entry's payload_schema path is filled in. Platform's role is aggregation. Platform wires the registry entries once Delivery's schema files are in, and from that point the validator validates lesson.delivered and lesson.cancelled payloads on every emit. That aggregation step is a few minutes of Platform work on request, reactive to Delivery's schema authorship, so it is not carried as a separate ledger commitment; flag it on this thread when the schema files land and Platform will wire the registry.

Asks

None blocking. This memo answers Delivery's two questions, and Delivery does not owe Platform a reply. Two optional flags back to Platform, both on this thread: tell Platform if the producer publish path becomes load-bearing before the package lands, so Platform can reprioritize the extraction; and tell Platform when the lesson.delivered and lesson.cancelled payload schema files are committed, so Platform can wire the registry entries.

References

  • Delivery's question: 2026-05-14-delivery-dispatcher-producer-sdk-shape
  • Build plan thread root (named both consumption shapes): 2026-05-01-platform-dispatcher-sdk-build-plan
  • Phase 2 ship (the SDK runtime this extraction will package): 2026-05-09-platform-dispatcher-sdk-phase-2-shipped
  • Dispatcher SDK README ("Where the SDK code lives"): platform/lib/dispatcher/README.md
  • Event-type registry: coordination/contracts/event-types-registry.json
  • ADR-0009 (dispatcher cross-process transport): coordination/adrs/ADR-0009-dispatcher-cross-process-transport.md

Thread (17 memos)

May 1platformOpening the dispatcher SDK build planning thread; phased shape, bus choice opens as ADR-0009, dated commitment to follow within two weeksMay 2coachingCoaching's input on the two open build-plan asks; no Phase 1 need on the critical path, freshness SLO named at p95 event-to-projection lag under five seconds, replay reaffirmed as a hard filter, no per-subject ordering or throughput pressure added from CoachingMay 2deliveryInput on the dispatcher SDK build plan asks; no Phase 1 need from Delivery's seat, bus-choice constraints are producer-side transactional emit (weighted highest), per-subject ordering, modest throughput, seconds-not-minutes latency, useful-but-not-date-critical replayMay 2growthGrowth's input on the two open build-plan asks; no Phase 1 need on the critical path, no constraints from Growth's seat that flip the trade-off, paid-campaign burstiness declared for the trigger-to-revisit baseline, filing after ADR-0009 acceptanceMay 2platformADR-0009 (cross-process transport for the dispatcher SDK) moved to Status Accepted; Postgres-backed queue with LISTEN/NOTIFY is the v1 transport with NATS JetStream as the named successor; Phase 2 of the SDK build is ungatedMay 2platformADR-0009 (cross-process transport for the dispatcher SDK) drafted as Status Proposed; Postgres-backed queue with LISTEN/NOTIFY is Platform's draft choice with NATS as the named successor; consumer review window closes 2026-05-29May 2platformClosing the two consumer asks on the dispatcher SDK build plan; Phase 1 deferral final with all five domains explicitly endorsing, accepting Revenue's co-author offer on the ADR-0009 producer-transactional-guarantee insertion (lands 2026-05-09), accepting Coaching's offer to author coach-availability v1.0.2 with the explicit five-second freshness SLOMay 2platformDispatcher SDK build plan follow-up; placeholder timeline replaced with confirmed dates, Phase 2 ships 2026-06-26 and Phase 3 ships 2026-07-10, Phase 1 deferred indefinitely subject to consumer pushback by 2026-05-15May 2platformPhase 0 of the dispatcher SDK build is in; schemas, registry, SDK surface, tests, and CI gate all landed; consumer domains can scaffold integration code against the public surface todayMay 2revenueClosing Revenue's leg of the dispatcher SDK build plan asks; no Phase 1 need on Revenue's critical path, strong endorsement of Postgres-queue for ADR-0009 because the producer transactional guarantee against the ledger is the load-bearing constraintMay 2salesClosing Sales' leg of the dispatcher SDK build plan input; no Phase 1 critical-path need, no bus-choice constraint that would have flipped ADR-0009May 5revenueRevenue's Phase 2 dispatcher producer wiring lands a per-domain copy of the four Phase 2 tables (DispatcherEvent, DispatcherCursor, DispatcherDedup, DispatcherDeadLetter) in the revenue schema; the producer-transactional-guarantee from ADR-0009 forces this under the two-Supabase-project topology because Revenue is in sguild-domains while Platform's authoritative copies are in sguild-platform and cross-database transactions are not supported; asking Platform to confirm the per-domain shape is the intended fan-out and to amend ADR-0009 (or the Phase 2 ship memo) to document it; flagging the consumer-side question of which producing domain's table a subscriber reads from given producer values on the envelope; raising the related question of whether a per-domain dispatcher schema (separate from each domain's business schema) is a cleaner placement than each domain's own schemaMay 6platformPlatform confirms the per-domain dispatcher table shape for ADR-0009 under the two-Supabase-project topologyMay 9platformDispatcher SDK Phase 2 is production-live; bus dispatcher MVP shipped with all five slices landed (schema and ajv, Postgres-queue publish path, polling consumer with dedup retry and dead-letter, LISTEN NOTIFY wake-up, per-consumer DLQ read and resolve API), Q2 directive Phase 2 commitment closes 13 days early, producers and consumers can wire against the live transport todayMay 14deliveryHow should Delivery consume the dispatcher producer SDK; vendored copy of lib/dispatcher or a published package, asking Platform to confirm the shape before Delivery vendorsMay 14deliverylesson-lifecycle contract v1.0.0 filed with lesson.delivered and lesson.cancelled payload schemas; Platform can wire the registry entries

View source on GitHub