Workers
The worker registry — one durable identity for anyone who can take Work, human or agent, with ownership, fenced readiness, and bid eligibility built in.
A Worker is anyone who can take Work — a person,
a team, a queue, an external system, or an AI agent. The worker registry is
where that identity becomes durable: a registration row with a stable
worker_id, an immutable binding to the thing it represents, a settlement
account, and the standing facts — status, readiness, capacity, capabilities —
that decide whether it may bid. This page is the operational guide to the
registry and the WorkerService API behind it
(Worker (WorkerRegistration)).
The registry is deliberately not a copy of anything. A worker is a projection over exactly one upstream subject, and that binding is fixed for the life of the worker:
- recipient
- A routing recipient projects into a worker directly — its live availability and capacity show through at read time, never copied.
- agent_definition
- An AI agent projects only once a caller pins an immutable definition — id, version, and content hash — so an agent worker's identity can never drift under an award.
- work_assignment_candidate
- A case-management candidate, projected with registry-owned readiness.
- human_principal
- A human identity from the auth plane, for workers that are people rather than routing recipients.
- external_system
- An external work system reached through a connector or bridge.
Five kinds of upstream subject, one registration shape, one eligibility answer the market consumes:
One worker per subject, enforced by the database: registering the same subject twice converges when the payload is identical and conflicts loudly when it is not. The subject columns are never touched by any update — immutability is a schema property, not a convention.
The registration record
Everything a worker carries, in one durable row:
Prop
Type
Ownership is server-derived
The registry never trusts a payload to say who owns a worker. The owning principal is captured from the authenticated caller at registration, and every mutation of an owned worker — update, status change, re-pin, readiness report — verifies the caller against it. A mismatch is refused with a uniform permission error that does not reveal whether the foreign worker exists. Ownerless workers (a recipient-backed queue, say) stay tenant-scoped.
This is the same check the market uses: when an agent submits a bid as
worker_id, the bid path verifies the caller owns that worker through the
registry before anything is priced. One ownership model, two enforcement
points, zero payload trust.
Readiness under a fence
Readiness is a moment-to-moment fact, and moment-to-moment facts arrive out of order. Registry-owned readiness is therefore reported under a monotonic fence: every report carries a strictly increasing number, and a report whose fence does not advance is refused with a typed conflict — visibly, never silently absorbed.
The failure this kills: an agent reports not ready (it is out of budget), then a delayed earlier report arrives claiming ready. Without fencing, the stale report wins and a down agent looks biddable. With fencing, the late arrival is refused and the caller knows it.
Recipient-backed workers skip all of this — their readiness is projected from the live recipient at read time. The registry never stores a copy that could go stale, and if the recipient subsystem is briefly unreachable, reads still succeed with the worker degraded to not ready with an explicit reason — fail-closed for bidding, never fabricated-ready.
Bid eligibility
CanBid is one question with a normalized answer. A worker may bid when it is
active, ready, within capacity, and — for an ai_agent — bound
to a pinned definition. Anything else is a refusal with a reason:
Status is the lifecycle gate in front of that question. Removal is reversible by design — there is no hard delete:
statusThe lifecycle gate. Disabled workers are out of the market entirely; paused workers are resumable.
ai_agentAn agent worker with no pinned definition has no stable identity to award against — refused until a definition is pinned.
readinessCarries the reported reason through — budget exhausted, runtime down, off-schedule, enrichment unavailable.
concurrencyCurrent load has reached the declared ceiling. Clears itself as work completes.
Nothing in this list is a silent drop. Every refusal reaches the caller — and the market's rejection records — as a normalized reason string.
The WorkerService API
Every RPC requires authorization, carries the tenant from the authenticated context (never the payload), and maps refusals to typed errors:
Prop
Type
The registry ships enabled by default behind the worker_registry config
gate. Disabling it removes the service cleanly — dependent surfaces fail
closed rather than half-working.
Where to go deeper
Worker
The primitive this registry makes durable.
Agent procurement
How a registered worker bids — typed terms, pinned identity, buyer-side clearing.
Pools & recipients
The recipient substrate recipient-backed workers project over.
Durable agent runtime
Budgets, delegation, and journaled state for ai_agent workers.
Pools & Recipients
Manage routing targets — pools (containers with a strategy and kill-switch) and recipients (concrete endpoints with capacity and state) — over the management API.
Rules
Manage routing rules — CEL expressions attached to a pool, with priority, enable/disable, validation, and the cross-instance cache invalidation that makes edits take effect live.