# Assign is the push, claim is the pull

> worklists.dev — 2026-08-20
> Written for ED-3 — the in-house supply-chain platform team — the platform engineer modeling a station pool and deciding which verb the picker's device calls.

One thesis: **assign is the push, claim is the pull — a pull is not management, and that difference
is what puts the two verbs on opposite sides of the free/paid line.** They look like one operation
from the outside. They are two acts by two different parties, and an append-only record has to
know which one happened.

## Two ways a task reaches a hand

A pallet of lettuce lands at dock 12, and a receiving task exists for it. There are two ways that
task ends up with a receiver.

**Somebody pushes it.** A dispatcher, a routing rule, a supervisor's queue projection decides that
this task goes to this person or this role. That is `assign`: task plus performer, human or agent,
the door does not care which. It is a management act — somebody maintained the queue, somebody
made the routing decision, and the decision is recorded with the task.

**Somebody pulls it.** The receiver finishes the previous pallet, looks at the station pool, and
takes the next one. That is `claim`: a pooled task plus the caller, held by the caller. Nobody
routed anything. A performer reached for work.

The record shows both as appended acts. `assign` writes an assignment; `claim` writes a hold. The
fold treats them differently, and it has to.

## The fold distinguishes them

An `assigned` act folds to **`pending`** — *waiting, available to claim* — not to `claimed`. That is
not a quirk. If a push folded to `claimed`, a task anyone had assigned would vanish from the
worklist predicate `status = pending`, and every assigned task would be invisible to the person it
was assigned to. A `claimed` act folds to `claimed`: locked by the holder, unavailable to others.

Reassignment is not a third verb. Assigning an already-assigned task *is* reassignment, and the
record shows both assignments in order. A separate verb for it would add nothing and hide the history.
Likewise `unassign` returns the task to the pool with the prior assignment retained — the
resource survives the act, so it is a transition, not a delete.

## What claim refuses

Two refusals define the verb as much as what it does.

**There is no claim-on-behalf-of.** `claim` takes the task and the caller. A `claim` that could name
another performer would be `assign` at the free price, and the line would be a fiction. The caller
is resolved by the auth rail; it is not a parameter.

**A failed claim does not name the holder.** When a task is already held, the refusal says *held*.
It does not say by whom. Answering *who has it* for the price of a failed claim is
performer-to-objects disclosure, one task at a time, and it is refused for the same reason any
per-person query is refused on this door.

A double claim is one of the poison fixtures in the package's test suite, alongside the second
settle and the early alarm.

## Why the line is where it is

The free/paid line on this door does not come from a task being state or not. It comes from a
simpler question: **are you recording what you did, or paying to have work organized for you?**

- `complete`, `block`, `escalate` emit. Emitting is never paywalled; witness is never behind a
  paywall. Free, permanently.
- `query` and `trace` are stateless reads. Free.
- `claim` is a performer taking the next thing. **A pull is not management.** Free.
- `dispatch`, `assign`, `unassign`, `start` are the management of work — queues, routing,
  projections, scheduling at org scale. Paid.

Without `claim` on the free side, the free tier could say *you always can record what you did* and
could not say *you can take the next thing*. That is not a tier; it is a defect, and it is why the
verb was added when the model was ruled rather than left for later.

## For the station pool

If you are modeling a dock with six receivers and a pool of receiving tasks, the device calls
`claim`, not `assign`. The station-pool view renders `ref`, `do`, `at` — and has no assignee
column, because a pooled item has no assignee, which is exactly what makes that view safe to render
and a per-person queue unsafe.

`claim` is one of the five verbs that answer in the package today, with `query`, `trace`,
`complete` and `timeout`. `assign` is declared in the portfolio and the fold reads its acts; no
verb in the package writes one. Get started by writing a pool, claiming from it twice with two
callers, and reading the second refusal. It tells you the task is held, and nothing else.

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