Post

Been bitten by exactly the "reliable job lifecycle" line before - looks solid right up until two retries land on the same task and the handler turns out not to be idempotent. How are you handling dedup in the workers when a retry doubles up?

THanks for asking ! The workers don't dedup. They're stateless and never touch the DB : they just fire HTTP callbacks to a single writer (the Rust API) that owns idempotency via guarded state transitions + replace/upsert, not a dedup table.

Makes sense money's the one thing you left non-idempotent. A retry really did spend the tokens again, so guarding it just hides real cost. Workers staying dumb while one writer owns every transition is the part I'd steal. For the at-least-once webhooks, do consumers get an event id to dedup on?

Yes dedup on job_id (a run emits one digest => redeliveries carry the same id). And thanks to your comment, I just closed the authenticity gap: added a signing secret, optional HMAC-SHA256 signing.

So when a task redelivers and re runs : results are written DELETE then INSERT, agent-journal steps upsert ON CONFLICT (job_id, seq) DO NOTHING, and status transitions are guarded (started only from pending, a late failure never clobbers a completed).

the hard part of an agent boilerplate isn't the loop, it's the guardrails and retries, the boring tool-schema plumbing everyone rebuilds from scratch. nail that and it saves real hours.