A checklist computed at runtime
The workflow decides which steps a person must confirm. The form renders them from the row, so one schema serves every variation.
The situation
A release check depends on the order: a fragile item adds a packing step, an export order adds a customs step. The list changes per run, and maintaining a form per combination is not an option.
The recipe
import { Durable } from '@hotmeshio/hotmesh';import { conditional, type LTEnvelope } from '@hotmeshio/long-tail';
export async function releaseCheck(envelope: LTEnvelope) { const { orderId, fragile, international } = envelope.data; const { workflowId } = Durable.workflow.workflowInfo();
const steps = [ { id: 'count', label: 'Item count matches the order' }, ...(fragile ? [{ id: 'wrap', label: 'Fragile items are wrapped' }] : []), ...(international ? [{ id: 'customs', label: 'Customs form is attached' }] : []), ];
const result = await conditional<{ checks: Record<string, boolean> }>(`release-check-${workflowId}`, { role: 'packing', description: `Release checks for ${orderId}`, envelope: { checklist_items: steps }, metadata: { orderId, form_schema: { title: 'Release check', required: ['checks'], properties: { checks: { type: 'object', 'x-lt-widget': 'checklist', 'x-lt-source': 'envelope.checklist_items' }, }, }, }, });
if (!result) return { data: { orderId, released: false } }; const missed = steps.filter((s) => !result.checks[s.id]).map((s) => s.label); return { data: { orderId, released: missed.length === 0, missed } };}x-lt-source points the checklist widget at the items the workflow wrote onto the row’s envelope. The count and wording vary per escalation; the schema stays the same.
The guarantee
The person sees exactly the steps this run computed, and the answer comes back keyed by the step ids the workflow chose. See Forms.
Related patterns
Forms and configuration
The form is data
A role's form is a versioned JSON Schema; each row pins the edition it renders, so editing the form never breaks work in flight.
The physical world
Fill a checklist by scan
A batch row lists the codes an order expects; each scan checks one off, and the last fill completes the row and wakes the workflow.
The escalation boundary
Batch: N contributions, one wake
One row collects a named set of submissions and wakes the workflow once, when the last one lands, with the whole collection.
