Skip to content

Intent on create, outcome on resolve

Resolving from anywhereDashboardHTTPSDKMCPconditionalresolvemetadata patch

The row is created with the facets that route it and resolved with the facets that describe what happened. One row answers both questions.

The situation

Operations wants to know what was asked, what was decided and how long it took. Keeping a separate audit table means two writes and a reconciliation job.

The recipe

workflows/review.ts
const decision = await conditional<{ approved: boolean }>(signalId, {
role: 'order-reviewer',
metadata: { orderId, channel: 'web', amountBand: 'high' },
});
services/review-desk.ts
await lt.escalations.resolve({
id,
resolverPayload: { approved: true },
metadata: { outcome: 'approved', reasonCode: 'verified' },
});
Field Goes where Indexed
resolverPayload Delivered to the waiting workflow, stored as resolver_payload No
metadata Merged into the row’s metadata Yes, GIN

Every resolve surface takes the metadata patch: the HTTP body, the SDK, and the metadata argument on the resolve_escalation and claim_and_resolve MCP tools.

The guarantee

The patch merges in the same atomic update as the resolve, on the winning resolve only. Intent and outcome are then queryable side by side: facets: { outcome: 'approved' } finds every approval. Elapsed time needs no field, since the row carries created_at and resolved_at. See Conditional.