Tasks: offered, never assigned

The running jobjob_7Hq2 · waiting · on approval · $49.00 held

A role step posts a Task at a fee fixed when it posts. Members claim it, it holds for one of them on a clock, and it counts as done only when the gate accepts their act.

A Task answers one question: what does a person claim, and what becomes of it?

When a job reaches a step a role does, the step posts a Task to the role's Pool and the job waits on: 'claim'. No one is assigned. The Task is offered by its dispatch, and the member who wants it claims it.

The fee a Task posts at is the same whatever the member decides: attest, send back or decline, each paid, or, in a work register, the completed Task. It is never lowered. Only the fill ladder moves it, and only up. A pass is free, and so is giving a held Task back.

StatusWhat it means
openOffered to eligible members by its dispatch, as a teaser.
claimedOne member holds it until held_until and is clearing it. Every other feed has lost it.
clearedThe member attested the sheet's statements, and the packet is open to them alone.
cleared, waiting on the clientThe member asked the client a question. The hold and the step's clock pause until the reply comes through the thread.
on_siteIn a work register, the member checked in at the site, inside the window.
doneThe gate accepted the member's act: attested, sent back or declined, or in a work register completed, party_absent or party_silent.
done, withdrawnThe job ended before the act. A member who cleared the Task keeps the kill share; one who only claimed it keeps nothing, and nothing is scored.
open, againThe hold ran out, or the member gave it back or stepped aside for a conflict. reopened counts up by one, and the dispatch runs on.

A status is never a column. It is read off the Task's own appended acts, each named for the worklists.dev verb it writes, so any client that speaks those verbs reads a Task the same way: Task verbs maps every act. Each state is the same object on the wire, a Task, here as the claim answered it:

Call
→ POST /reviews/tsk_7Hq2/claim {}   # as mbr_eligible
200 · tsk_7Hq2 · claimed · magic values: applicant.email = signs@example.test, member = mbr_eligible
{
  "id": "tsk_7Hq2",
  "object": "task",
  "livemode": false,
  "pool": "attorneys",
  "role": "practitioner",
  "status": "claimed",
  "fields": {
    "act": "sign",
    "region": "*",
    "fee_usd": 150,
    "signals": []
  },
  "est": {

A member's act counts only once the gate accepts it. A refused act keeps the Task claimed, showing the refusal, so the member can fix and resend it. The gate holds AI and people to the same checks.

A claim is a person's own act: in the member CLI or the delivery portal, in their own session. MCP and the SDK carry no member act at all:

SERVICES_DEV_SESSION=ms_psNemolonFiaQz8kWxgxgQ npx services.dev reviews claim tsk_7Hq2
tsk_7Hq2 · claimed · attorney · advise · US-CA · $50.00 · 45 min · $66.67 an hour · due 2026-10-27 14:02
→ POST /reviews/tsk_7Hq2/claim   # as mbr_eligible, in their own session
← 200 tsk_7Hq2 · claimed · attorney · advise · US-CA · $50.00 · 45 min · $66.67 an hour · due 2026-10-27 14:02
→ tools/list
← 13 tools · none claims, clears or attests a review

→ tools/call claim_review {"id":"tsk_7Hq2"}
← {"code":-32602,"message":"No tool claim_review. tools/list names them."}
await legal.reviews?.claim?.("tsk_7Hq2")
← undefined · the client has no member act: task.claim's SDK column is never, and its caller a member session

A claim holds for the longer of a day and three times the step's estimate, and never past the Task's due date. At three-quarters of the hold the member is warned, and they may extend it once, by as long again and still never past the due date:

Call
→ POST /matters {"service":"contract-review","contract":"lease.pdf","client":{"name":"Ada Lovelace","email":"signs@example.test"},"client_region":"US-CA","max_usd":99,"key":"hold-extend"}
magic values: client.email = signs@example.test, member = mbr_eligible
← job_7Hq2 · waiting · on claim · $99.00 held · advise · tsk_7Hq2

→ POST /reviews/tsk_7Hq2/claim   # as mbr_eligible
← 200 tsk_7Hq2 · claimed · attorney · advise · US-CA · $50.00 · 45 min · $66.67 an hour · due 2026-10-27 14:02
  held_until 2026-10-26T14:02:11.000Z
→ POST /test_clocks/default/advance {"to":"18h"}
← 2026-10-26T08:02:11.000Z
→ POST /reviews/tsk_7Hq2/extend   # as mbr_eligible
← 200 tsk_7Hq2 · claimed · attorney · advise · US-CA · $50.00 · 45 min · $66.67 an hour · due 2026-10-27 14:02
  held_until 2026-10-27T14:02:11.000Z
→ POST /reviews/tsk_7Hq2/extend   # as mbr_eligible
← 422 input_invalid: tsk_7Hq2's hold was extended once already: it holds until 2026-10-27T14:02:11.000Z.

# the record's hold lines · tsk_7Hq2 claimed · reopened 0
  2026-10-25 14:02 · task.claimed
  2026-10-26 08:02 · task.hold_expiring · held until 2026-10-26 14:02
  2026-10-26 08:02 · task.extended · held until 2026-10-27 14:02

Work that lasts as long as the member works it, such as a sales cycle, holds by touches instead: hold: { claim: '48h', then: 'touch' } holds the claim 48 hours to a first touch with the party, and each touch on the thread renews it for as long again.

A hold that runs out opens the Task again, and the dispatch runs on:

Call
→ POST /matters {"service":"contract-review","contract":"lease.pdf","client":{"name":"Ada Lovelace","email":"signs@example.test"},"client_region":"US-CA","max_usd":99,"key":"hold-expire"}
magic values: client.email = signs@example.test, member = mbr_eligible
← job_7Hq2 · waiting · on claim · $99.00 held · advise · tsk_7Hq2

→ POST /reviews/tsk_7Hq2/claim   # as mbr_eligible
← 200 tsk_7Hq2 · claimed · attorney · advise · US-CA · $50.00 · 45 min · $66.67 an hour · due 2026-10-27 14:02
  held_until 2026-10-26T14:02:11.000Z
→ POST /test_clocks/default/advance {"to":"18h"}
← 2026-10-26T08:02:11.000Z
→ POST /test_clocks/default/advance {"to":"6h"}
← 2026-10-26T14:02:11.000Z

# the record's hold lines · tsk_7Hq2 open · reopened 1
  2026-10-25 14:02 · task.claimed
  2026-10-26 08:02 · task.hold_expiring · held until 2026-10-26 14:02
  2026-10-26 14:02 · job.paused · on claim · reopened 1 · expired

A cascade gives each member a window to themselves, and a sheet is one member's at a time. If the job ends after a member cleared their Task, they keep the kill share of its fee. In a work register, a claimed Task the client cancels inside notice accrues the kill share too, because the member held the window:

KeyWrittenLeft outDoes
holdWithin | { claim: Within; then: 'touch' }max(24h, 3 × est)How long a claim holds before it reopens: one span, or the default, three times the step's estimate and at least a day, never past its due. A member may extend it once. With then: 'touch', each touch renews it.
windowShortSpan'1h'How long one member has a cascade's offer, or a first refusal, to themselves.
sheetShortSpan'10min'How long one member has a sheet to themselves.
killPct'50%'What a member accrues when a Task they cleared is withdrawn because the job ended, or, in a work register, a claimed Task the client cancels inside notice: a share of its fee. Pay has every line a member earns.

A member who has cleared a Task reaches the job's party only through the job's thread: a question, a note, or a flag the owner sees. A question pauses the step's clock and the member's hold until the party answers, and contact details never cross. Talk explains the thread:

Call
→ POST /reviews/tsk_7Hq2/messages {"kind":"question","text":"Is the lease you sent the signed copy? Write me at grace@firm.example."}   # as mbr_7Hq2
magic values: none
← 200 msg_7Hq2 · the attorney · question · open: Is the lease you sent the signed copy? Write me at [email withheld: reply in this thread].
  14:02 · job.paused · on the client's reply · advise · tsk_7Hq2
EventAudienceSays
task.postedmember, ownerA role step posted a Task at its fee, fixed now and never lowered, to its dispatch: or to the one member a client's direct named. Its reach says who it can be offered to.
task.offeredmember, ownerA Task was offered to a member, by its dispatch (feed or cascade), first refusal or the owner: its teaser, with its minutes, rate and due date, and never a party name.
task.claimedmember, ownerA member claimed a Task: it is held for them, gone from every other feed, until they clear it or the hold runs out.
task.hold_expiringmember, ownerThree-quarters of a member's hold on a Task has run: it reopens at held_until unless they finish, or extend it once.
task.extendedmember, ownerThe member extended their hold, once: by as long again as it first held, never past the due date.
pay.accruedmember, ownerA member's pay for a paid act accrued, at the Task's fee as it stood, with the raise the brand funds; or a kill share. Pay says when it is theirs.