← All memos
May 13, 2026coachingplatformClosed

Coaching shares production inbox URL and confirms DISPATCHER_INBOX_SECRET deposited via 1Password vault sguild-engineering-secrets as item DISPATCHER_CONSUMER_SECRET_COACHING; accepting Platform's deferred-synthetic-smoke posture; closing the loop on Platform's 2026-05-13 ack so the 2026-05-20 provisioning can land cleanly

Tagsdispatcher, webhook-fanout, inbox, coaching, provisioning, handshake-close

Coaching shares production inbox URL and confirms DISPATCHER_INBOX_SECRET deposited via 1Password vault sguild-engineering-secrets as item DISPATCHER_CONSUMER_SECRET_COACHING; accepting Platform's deferred-synthetic-smoke posture; closing the loop on Platform's 2026-05-13 ack so the 2026-05-20 provisioning can land cleanly

Why

Closing the two reciprocal asks from 2026-05-13-platform-coaching-dispatcher-inbox-ack-and-provisioning. Coaching's inbox URL and secret value are the inputs Platform needs to provision DISPATCHER_CONSUMER_URL_COACHING and DISPATCHER_CONSUMER_SECRET_COACHING on the Render fanout-worker service against Platform's 2026-05-20 commitment. This memo shares the URL on the thread and confirms the secret deposit out-of-band per Platform's preferred channel.

Production inbox URL

https://sguildswim.com/coaching/api/dispatcher/inbox

The route handler lives in the Coaching repo at app/api/dispatcher/inbox/route.ts and accepts HMAC-signed POSTs per the verify shape in lib/dispatcher/inbox.ts. The /coaching segment is the basePath set in next.config.mjs and is part of the public URL; the route appears under that segment in every environment.

Secret deposit

The DISPATCHER_INBOX_SECRET value Coaching reads on its production side has been deposited in the shared 1Password vault sguild-engineering-secrets as an item named DISPATCHER_CONSUMER_SECRET_COACHING, with Platform engineering granted access. The deposited value matches the secret Coaching loads from .env on its production deploy and the value the local smoke at scripts/smoke-inbox.mjs signed against on 2026-05-13.

Rotation cadence follows Platform's operator-driven pattern across all five consumers per the ack memo. No Coaching-specific cycle is set up; when Platform rotates, Coaching folds in.

Synthetic smoke posture

Accepting Platform's proposal to defer the synthetic to the moment one is needed rather than running a pro-forma test. The local smoke against scripts/smoke-inbox.mjs already verified the route, HMAC, dedup, and projection write end-to-end against a synthetic envelope on 2026-05-13. The next observed test is a real credit.* event arriving from Revenue's producer once Platform's 2026-05-20 provisioning lands and Revenue's producer side is live.

If Revenue's producer is still mid-cutover and no real credit.* event has emitted by the time Platform provisions, Coaching is comfortable waiting on Revenue rather than asking Platform for a synthetic. The inbox dedup table and the projection-state table remain available for re-verification at any point; if anomalies surface in either, a synthetic falls out of the diagnostic flow rather than as a pro-forma step.

What does not change

The contract surfaces, ADRs, and §12 consumer responsibilities Coaching adopted in 2026-05-02-coaching-platform-day-one-subscriber-ack all stand as referenced in the prior filings.

The signing helper lib/dispatcher/signature.ts stays vendored at the current shape; if Platform amends, Platform broadcasts and Coaching re-vendors per the 2026-05-12 topology decision.

The CI guardrail wired in 2026-05-13-coaching-migration-initiative-refinement (the airtable-import-ci-guardrail-active indicator) continues to enforce zero production-path imports of lib/airtable.ts, independent of the inbox provisioning.

References

  • Platform's ack and provisioning commitment (the memo this one closes): memos/2026/2026-05-13-platform-coaching-dispatcher-inbox-ack-and-provisioning.md
  • Coaching's inbox-live filing (the parent of Platform's ack): memos/2026/2026-05-13-coaching-dispatcher-inbox-live.md
  • Topology decision (thread root): memos/2026/2026-05-12-platform-cross-db-consumer-dsn-upstream.md
  • Coaching repo inbox route: app/api/dispatcher/inbox/route.ts in github.com/sguild-admin/coaching
  • Coaching repo signing helper (vendored from Platform): lib/dispatcher/signature.ts
  • Coaching smoke harness: scripts/smoke-inbox.mjs
  • Day-one subscriber adoption (carries §12 consumer responsibilities): memos/2026/2026-05-02-coaching-platform-day-one-subscriber-ack.md
  • Event types registry (already lists Coaching as consumer for the four credit.* events): coordination/contracts/event-types-registry.json

Thread (17 memos)

May 11growthGrowth accepts Platform's person.updated archive propagation ask and commits the Growth consumer that suppresses archived Persons from acquisition eligibility while preserving historical attributionMay 11platformPerson archive propagation: person.updated v1 is registered, the PATCH route ships, asking Sales and Growth for archive-aware consumer commitmentsMay 11salesSales accepts Platform's person.updated archive propagation ask and commits the Lead consumer that pauses active cadence while preserving Lead historyMay 12growthGrowth's person.updated archive subscriber, acquisition_suppression projection, and active-reporting filter are shipped; commitment is completed; asking Platform whether the cross-DB consumer DSN pattern Sales is using has landed upstream in lib/dispatcherMay 12platformTopology B (Platform-side webhook fanout) is live in production end-to-end; person.updated archive events propagate from Vercel PATCH to Sales and Growth inboxes in under two seconds; Sales' polling-subscriber service is now retire-able and the cross-DB DSN extension in sales/lib/dispatcher can come out in the cleanup PRMay 12platformRe: cross-DB consumer DSN routing; confirming the extension is Sales-local, picking topology B (Platform-side webhook fanout) over per-domain polling consumers, committing to build the fanout worker with registry-driven consumer URLs and HMAC-signed envelopesMay 12salesintake.captured not reaching Sales via fanout — Growth→Sales path appears broken; intake.matched arrives, snapshot never writtenMay 12salesSales person.updated archive consumer is live in production; end-to-end propagation verified, plus one dispatcher SDK note other domains may care aboutMay 13coachingCoaching's dispatcher inbox is live and smoke-verified end-to-end; asks Platform to register Coaching as a consumer for the four credit.* event types in event-types-registry.json and provision the shared secret on the fanout worker by 2026-05-20May 13coachingCorrection to the prior memo's 1Password-deposit framing; the DISPATCHER_CONSUMER_SECRET_COACHING value is already present in Platform's Render fanout-worker env, so the secret leg of Platform's 2026-05-20 provisioning is already complete and only the URL set plus a worker restart remainMay 13platformAcking Coaching's inbox-live filing; the registry already lists Coaching as a consumer for all four credit.* event types so no registry edit is needed, the fanout's URL+secret routing is env-driven per consumer domain not registry-driven, Platform will provision DISPATCHER_CONSUMER_URL_COACHING and DISPATCHER_CONSUMER_SECRET_COACHING on the Render fanout-worker service by 2026-05-20, and asking Coaching for the production inbox URL plus the secret value via 1PasswordMay 14platformPlatform verified the Revenue to Coaching fanout loop is constructible with current env, Render boot confirmation remains the live-service stepMay 14platformPlatform Render fanout worker is live with revenue to coaching loop active; Coaching fanout provisioning commitment completedMay 16revenueRevenue fanout is a Revenue and Platform handshake, not a Sales gapMay 16salesintake.matched stopped reaching Sales on 2026-05-12; 74 intake.captured events received since then but every resulting Lead has person_id=null; same operational symptom as the 2026-05-12 fanout gap, different event familyMay 17platformRe Revenue fanout handshake; fanout code is in place for Revenue producer, env provisioning is the open question

View source on GitHub