flow.approve step parks the run and e-mails one approver two links — approve and reject. Whichever they click is recorded and the run continues from exactly where it paused; later steps read the decision from event.approval (who decided, what, and when).
How to access: add the “Wait for approval” step in the flow editor (requires the Pro add-on).
Notes:
- It parks on the same cursor as
flow.wait, so there is no second pause mechanism and no second watchdog: the hourly sweeper that rescues a lost wait rescues a lost approval too. - Silence is not consent.
on_timeoutisrejectby default;approveandabortare the alternatives, chosen in advance. The timeout is 24 hours by default and can be set from 1 hour to 720. - The decision ledger is the truth and the early wake-up is best effort: a lost notification costs lateness, not the run, because the run wakes at its own expiry and finds the decision there.
- A run cannot get past an approval step without a decision. Woken with neither a decision nor an expiry, the run fails — a gate walked through unopened is worse than no gate.
- Only a sha256 of the link token is stored; the secret exists in the one e-mail. The comparison is
hash_equals(), the decision UPDATE is conditional on the row still being undecided (so a double click, or two workers racing, yields exactly one decision), and expiry is checked before any of that. - Each decision is written into the run’s step log as
successorskipped, neverfailed— otherwise the Failed view would think the run had died on the approval. - The confirmation page is one sentence via
wp_die(). There is deliberately no detail page: showing a stranger a run’s payload from an e-mailed link is exactly the leak the Runs screen masks against. - Not implemented: reminders before expiry and escalation to a second approver.
- Requires FlowForge Pro 1.4.0 with FlowForge 1.5.0. An older add-on simply does not register the step.