# Dispatch converts demand; it never invents it

> worklists.dev — 2026-08-20
> Written for ED-3 — the in-house supply-chain platform team — the platform engineer deciding where tasks come from, who has seen a task app become a second, disconnected backlog.

One thesis: **Worklists never invents demand; it converts it.** `dispatch` is the verb that turns
something that already exists — a purchase order, a fired exception, a plan, a schedule — into the
tasks it implies. It is the one way tasks come into being, and it is the only reason a work door
belongs in the same family as an event spine rather than next to any to-do app.

## The fourth group

A work door has four groups of verbs, and a to-do app has three of them:

- **Assign** — work reaches a performer
- **Perform** — the lifecycle: start, block, escalate, complete, timeout
- **Read** — query the work, trace its lineage
- **Dispatch** — demand becomes work

Without the fourth, a task system is a place where people type what they intend to do. Its backlog
is a second, disconnected record of the business, maintained by hand, drifting from the documents
and events that actually drive the floor. With it, a document *is* the backlog.

## The compile-down

Four kinds of demand, each with a concrete example from one bag of lettuce:

**A document.** A purchase order for forty cases arrives at
[transactions.dev](https://transactions.dev). `dispatch` reads it and emits the receiving tasks it
implies: one receiving count at dock 12, inside the delivery window, closable by a scan of the
pallet's SSCC. When the ASN arrives, the task gains the expected SSCC as its subject. Nobody typed
a task.

**An exception.** A watch on the spine fires because a lot was received but never put away in the
window. That exception becomes an investigation task through `dispatch` — and this is the only verb
that joins *what happened* to *what needs doing*, ruled one-way. Exceptions become work; work does
not become exceptions.

**A plan.** A one-off, non-repeatable ordering that ends — a relabeling of a recalled lot, a
physical inventory — is a Plan upstream, and `dispatch` emits its tasks. A Project is not a
primitive here; it is a Plan, and both a Plan and a standing Process emit tasks the same way.

**A schedule.** A daily temperature check on the cold room is a `dispatch` whose demand is a
calendar. `schedule` is a parameter, not a verb, because it is the same act with a different
source.

## Every task can name its parent

The surface spec renders this as a field: `dispatchedBy`, present on every task, sourced from
`trace`. A task with no dispatching demand does not exist on this door. That is what lets an
auditor walk from a closed receiving task back through the event hash that closed it and further
back to the PO that asked for it, without an application in the loop asserting any link.

It also bounds the system. There is no `create` on the Task noun. Client surface is the domain
verbs plus the universal verbs over nouns, and the matrix is sparse on purpose: Task has no
`create`, no `update`, no `delete`. Every task arrives through `dispatch` and every change is a
verb that leaves a record.

## Cancel is dispatch's inverse, and it survives the act

The PO is amended and the fourth pallet is no longer coming. `cancel` marks the receiving task as
canceled, with the reason and whatever partial record exists — a claim, a block, a half-done
count — preserved. It is not a delete. A canceled task keeps its lineage, and `trace` still shows
what dispatched it and what happened to it before it was withdrawn.

The fold reads a `cancel` act like any other. The record is append-only, so the cancellation is one
more act, not a row removed.

## What is built, and what is declared

Being plain about the line: `dispatch` and `cancel` are declared in the verb portfolio and are
**not implemented** in the package `worklists.dev`. The package's fold reads their acts, because a
task's history has to be readable whole, and no verb in the package writes one. The five that answer
today are `query`, `trace`, `claim`, `complete`, `timeout`.

The design is fixed, though, and it is the design this post describes. Worklists never invents
demand; it converts it. If you are wiring this door into a WMS or an order system, the integration
point is the demand — the document you already receive, the exception you already raise, the
schedule you already keep — not a form where somebody types a task.

Get started by reading the fold over an `ActionRecord` that begins with a dispatch act citing a
PO. The first act on every task is the answer to *why does this exist*.

---
Get started: https://worklists.dev/get-access/ · All posts: https://worklists.dev/blog/ · Machine face: https://worklists.dev/llms.txt
