Skip to content

Steps

A step calls one Verb as one Role; it names its id, what it waits for, and what happens when it fails, and the Verb decides the rest.

A step is one Verb called as one Role, inside a Workflow. It declares its id, its wait and its failure rule; the Verb decides its Permission, its Event and its approval.

Fields

FieldHoldsDefault
idA stable slug, so an Action resumes on the right step after a deployRequired
textThe one sentence the Process page printsRequired
doesThe Verb it calls, such as Invoice.collectNone: a read or a branch
byThe Role whose Permissions and Limits the call runs underThe accountable Role
approvalWho says yes first: none, ask or mandateComputed from the Verb
waitsForAn Event to wait for before the step runs, with an optional whereNone
timeoutHow long it waits before its failure rule applies: 30m, 4h, 7d, 2wNone
onFailretry, escalate, compensate or failretry
compensateThe Verb that undoes or remedies it; required by onFail: compensateNone
exceptionsNamed outcomes that leave the happy path, each with when and an optional continueAtNone
whyWhy the step exists, for the runbookNone

What a step can do

Every step is a Verb call, so the closed set of step kinds is the set of Verbs.

ToCallIt waits as
Write a recordAny Verb, such as Invoice.collectNothing, or its delay window when one-way
Ask a person and wait for the answerAction.ask, answered by Action.answer in any Interfacepending, awaitingInput
Get a yes past a LimitApproval.createpending, awaitingInput
Hand work to another RoleTask.delegatepending, awaitingWorker
Hand a problem upTask.escalatepending, awaitingWorker
Send a messageMessage.createIts delay window
Wait for something to happenwaitsFor an Event, capped by timeoutpending, awaitingAction

A waiting step costs nothing, survives deploys, and shows its reason on the Action. In a Workflow file, $.step, $.sleep and $.waitForEvent write the same steps in code.

Branches and failure

A step leaves the happy path in two ways. An exception is a known outcome: it names when it applies and the step to continue at, or ends the Action when it names none. A failure is anything else: the step retries with backoff, then follows its onFail.

Dunning shows both. When the card on file has expired, the retry step's cardExpired exception skips ahead to telling the Customer. When a retry fails for any other reason, the step tries again on the next day of the schedule.

onFailWhen retries run out
retryKeeps retrying with backoff until timeout, then goes to the accountable Role
escalateBecomes a Task for the accountable Role, with the step's inputs
compensateCalls the compensate Verb, such as Order.refund after a failed redo
failEnds the Action failed, with the reason on record

Three steps, one wait

A Workflow on Quote.sent waits a week for the buyer to accept, then wins the Deal and starts onboarding. If the week passes, the Sales Lead gets the Deal as a Task.

TypeScript
import { $ } from 'startup-builder'

await $.Workflow.create({
  steps: [
    { id: 'accepted', text: 'Wait up to seven days for the buyer to accept.', waitsFor: { event: 'Quote.accepted' }, timeout: '7d', onFail: 'escalate', by: 'sales-lead' },
    { id: 'win', text: 'Mark the Deal won.', does: 'Deal.win', by: 'sales-lead' },
    { id: 'welcome', text: 'Send the buyer the onboarding link.', does: 'Message.create', by: 'onboarding-specialist' },
  ],
})

How a Workflow runs covers approvals, service levels and turning a Process on or off. A Trigger starts the first step, and Triggers lists every kind.