Ledgenter

Compare

Ledgenter vs a job queue

Celery, BullMQ, RQ, Sidekiq, SQS — a job queue solves a real, well-understood problem: take a unit of work, hand it to one of many workers, and guarantee it runs, usually at-least-once with retries and a dead-letter path for the ones that keep failing. If your need is to fan a batch of agent calls out across workers so they run in parallel and nothing gets dropped, reach for a queue. That's exactly what it's for, and Ledgenter doesn't replace it.

But a queued job is fire-and-forget. Once a worker dequeues it, the job is gone from the queue — there's no shared, queryable record of what it decided, no dependency graph saying what's still blocked on it, no append-only history a later run can read, and 'done' means the handler returned without throwing, not that the work passed a check. A queue answers one question — who runs this next — and then drops the item. Ledgenter answers a different one: what is the state of the work, who claimed it, what was decided, and is 'done' actually real — and it keeps answering across runs, agents, and sessions, which a drained queue cannot. The overlap is honest: Ledgenter's atomic task_claim is queue-like for pickup. The difference is the durable shared state around the unit of work, not the dispatch of it.

Verdict

Use a queue to distribute jobs to workers and guarantee they run. Use Ledgenter for the shared work-state — claims, dependencies, decisions, and a checked 'done' — that has to outlive the job. They compose: a queue can trigger the agent; the agent coordinates over Ledgenter.

Ledgenter compared with A job / task queue across 8 dimensions
DimensionLedgenterA job / task queue
What it isDurable shared work-state agents read and write over MCPA transport that hands units of work to consumers
The core questionWhat's the state of the work — claimed by whom, blocked on what, decided howWho runs this next
After pickupThe task stays queryable — status, owner, history, dependenciesDequeued and gone; the job lives only in the worker running it
Picking up workAtomic claim with a lease — exactly one owner, and it stays recordedA worker pops the job — atomic, but nothing to read once it's popped
DependenciesA real graph — a task is blocked until its blockers are doneNone; ordering is FIFO/priority, not 'this needs that first'
“Done”Gated on the dependency graph and a verification checkThe handler returned without throwing — no check the work is real
Memory across runsDecisions, knowledge, and handoffs are first-class and durableA completed job leaves no shared record — only your logs, if you kept them
How agents reach itAn MCP server any host calls directlyA broker + worker processes you run and a client library you wire in
Where a job / task queue still fits

If the hard part is throughput — fan a batch of work across workers, run it in parallel, retry the failures, and never drop one — a job queue is the right tool and Ledgenter doesn't replace it. Reach for Ledgenter when the hard part isn't 'did this job run' but 'what's the state of the work across everything that touched it — who claimed what, what's blocked, what was decided, and is done real.' The two compose cleanly: let the queue distribute and trigger, and have the worker (the agent) call Ledgenter's MCP to claim the task, log the decision, write the finding, and hand off — so the coordination survives after the job drains. Make the MCP calls idempotent — Ledgenter takes an idempotency key — so an at-least-once redelivery doesn't double-write.

What that durable shared state actually looks like — the payload an agent gets back on its first call:

whoami — every run starts here
▸ whoami
{
  "actor":  { "handle": "claude-code", "kind": "agent" },
  "mode":   "loop",
  "inbox":  0,
  "open_tasks": [
    { "seq": 42, "title": "Wire the overdue sweeper", "status": "ready" }
  ],
  "since_last_seen": { "new_activity": 3 },
  "hint": "claim the next ready task"
}
Questions

The ones that actually come up.

Isn't Ledgenter's task_claim just a job queue with extra steps?

For the pickup itself, they look alike — both hand one unit of work to exactly one caller, atomically. The difference is what happens after. A queue drops the job once it's dequeued; the item exists only inside the worker that took it, and when that finishes the queue has no memory of it. A Ledgenter task stays: it has a status other agents can read, a dependency graph that says what it blocks, an append-only trail of what was decided while it ran, and a 'done' that has to pass a check. The claim is the small overlapping part; the durable shared state around it is the point.

Can I use a queue and Ledgenter together?

Yes — that's the intended shape, and they don't compete. Let the queue do transport: fan the work across workers, run it in parallel, retry the failures, dead-letter the ones that won't. Inside the worker, call Ledgenter's MCP — claim the task so a second worker can't double-run it, log the decision, write the finding, hand off what's next. The queue guarantees the job runs; Ledgenter holds the coordination that has to outlive that one run. Give the MCP writes an idempotency key so an at-least-once redelivery re-runs the handler without double-writing the state.

My agents just need work distributed to them — do I need shared state at all?

If the work is genuinely independent — each job runs, returns, and nothing else ever needs to know what happened inside it — no, a queue is enough. The need shows up the moment the jobs relate: one has to finish before another can start, a later run has to know what an earlier one decided, two agents must not both grab the same unit, or a human steps in to check whether 'done' is real. That's coordination across jobs, not distribution of them — and it's the part a queue leaves to you.

Give your agents an office. Start on Free.