Skip to content

An event is a notification

Agents and MCPSDKHTTPCallbackEventAdaptereventRegistrysystem.escalation.{role}.{id}.{verb}lt.escalations.get

Escalation events carry routing fields and facets only; a subscriber that needs the payload reads the row by id through the scoped API.

The situation

A subscriber wants to react when a packing row resolves. The event bus is not authenticated, and a resolver payload may hold data the subscriber’s account should not see. The event must say what happened without becoming a side channel.

The recipe

subscriber.ts
import { eventRegistry, CallbackEventAdapter, createClient } from '@hotmeshio/long-tail';
const lt = createClient({ auth: { userId: 'shipping-bot' } });
const adapter = new CallbackEventAdapter();
eventRegistry.register(adapter);
await adapter.connect();
adapter.on('escalation.resolved', async (event) => {
if (event.role !== 'packing') return;
const row = await lt.escalations.get({ id: event.escalationId });
if (row.status === 200) await bookPickup(row.data.metadata.orderId);
});

Escalation subjects carry the role as the organizing token: system.escalation.{role}.{id}.{verb}. Subscribe to one queue (system.escalation.packing.>), one verb across queues (system.escalation.*.*.created), or one item across role hops (system.escalation.*.{id}.>).

In data Left out
Routing scalars (id, status, role, assigned_to, …) and every metadata facet envelope, escalation_payload, resolver_payload, metadata.form_schema

The guarantee

Both publisher paths build data through one definition, so the shape is identical whoever moved the row. A subscriber that needs the heavy or sensitive columns fetches the row by id through the authenticated read API, where its own RBAC applies. Browsers that are not builders receive escalation events with routing fields only. See Agents and events.