Skip to main content

Module work_queue

Module work_queue 

Source
Expand description

Muxqueue — the universal agent work queue.

One row = one unit of work that ANY agent may claim, as opposed to jekt, which is addressed push delivery to a named recipient right now. See docs/reports/REPORT_UNIVERSAL_AGENT_WORK_QUEUE_2026_09_01.md for why this is a new primitive rather than a feature of the Drone or Swarm panes.

Shaped deliberately as db_cron_jobs’ sibling: cron is this row with a TIME trigger, this is the same row with a READINESS trigger. not_before makes that relationship literal.

This lives in the always-global identity store, never the per-channel one (db_work_queue in run_identity_store_schema). A per-channel queue would mean “any agent IN THIS CHANNEL can pick it up”, which is close to useless when every local/dev/portable build is its own channel.

§Claiming is a lease, not a lock

A claim carries claim_expires. A claimant that dies without completing loses the row back to the pool when Store::work_queue_reap runs. This is deliberate, and copies db_background_tasks’ last_seen_ms heartbeat pattern rather than a bare claimed boolean — a bare flag reproduces the stuck-running-forever incident class (agentmux issue #2518), where a row whose owner vanished is indistinguishable from one being actively worked.

attempts/max_attempts bound that recycling, so a poison item that crashes every taker is eventually parked in failed instead of cycling forever.

Modules§

work_state
Lifecycle state of a queue item. Stored as TEXT.

Structs§

ClaimFilter
What a caller may filter a claim by. All fields are AND-ed; None means “don’t constrain on this”.
WorkItem

Enums§

HolderMatch
How a holder-only transition (heartbeat, complete, release) matched the item’s holder — identity M4c-2 (spec §6.5.9).

Constants§

COLS 🔒
HOLDER_BY_NAME 🔒
HOLDER_BY_UID 🔒
The holder predicates, tried in order. When the row’s claimed_by_uid and the caller’s UID (?6) are both known, only the UID decides — a name two agents share no longer lets either drive the other’s item. Otherwise the name (?2) decides, as it always has: a tokenless holder keeps working. Each is its own conditional UPDATE, so each is a complete authorization on its own; the second runs only when the first matched nothing.

Functions§

holder_update 🔒
Run a holder-only UPDATE (sql renders it around a holder predicate) with the UID predicate, then the name one. Every holder statement binds ?1 id, ?2 the request’s name, ?3 the fence and ?6 the caller’s UID ('' when Unattributed).
row_to_item 🔒