One Case per Run
A consumer Agent processes exactly one Case from start to finish, and the platform handles everything around it: picking up the next Case, running several in parallel, and re-dispatching postponed ones. Write the AOP for a single item and let Duvo iterate — a batch loop in the AOP hides per-item failures inside one Run and breaks per-Case tracking. This is the same rule as Writing Effective AOPs, applied to Queues.Split Producers from Consumers
A healthy Queue has two distinct roles, and usually two distinct Agents:- The producer finds work and adds Cases to the Queue. Its job ends when the Cases are added — it never claims or processes them.
- The consumer claims one Case, works it, and settles it.
Close Every Case, Every Time
Every Case a consumer claims must end in exactly one of four ways: completed, failed (with a reason), postponed for a later retry, or handed over to another Agent. If a Run ends without settling its Case, Duvo marks the Case as Failed automatically — with no reason attached. In practice this is the most common failure mode for Queue-driven Agents: the AOP covered the happy path, an odd Case took an uncovered branch, and the Case shows up Failed with nothing to explain why. The fix is in the AOP: give every branch an explicit ending.Postpone or Fail: Choose Deliberately
Postpone and fail look similar in the moment (“I can’t finish this Case now”) but mean opposite things:
Postponing a permanent problem is the trap to avoid: the Case comes back, hits the same wall, gets postponed again, and loops forever without anyone noticing. If retrying won’t change the outcome, fail the Case with a clear reason so a person can step in.
Postpones have a minimum wait — very short postpone times are rounded up to your workspace’s minimum. Don’t design flows that depend on retrying within a few minutes.
The Waiting Pattern
For any step that means “wait N days, then act” — follow-ups, reminders, escalation timers — use postpone with a marker on the Case:- On the first pickup, record a marker in the Case data (for example
reminder_sent: true), then postpone the Case for the waiting period. - On the next pickup, the marker is there, so the AOP skips ahead and does the real work.
Update the Case as You Go
Anything you record on a Case — progress notes, intermediate results, markers — survives postpones and handovers. The next Run picks up where the last one left off, and a teammate looking at the Queue can see where each Case stands. Update the Case at meaningful milestones, not just at the end; a Case that fails halfway through with no notes is as opaque as one that never updated at all.Handing Over Is Its Own Ending
Handover passes the Case to a different Agent after the current Run finishes — use it when a specialist Agent is better placed to continue. It is one of the four endings, not something you combine with the others: a branch that hands the Case over must not also complete, fail, or postpone it, or the receiving Agent never gets the Case.Watch the Throughput, Not Just the Cases
Cases process in parallel up to the consuming Agent’s concurrency limit. When the Agent is at capacity, new Cases simply wait as Pending until a Run finishes — nothing is lost, but a slow AOP quietly turns into a growing backlog. If Pending keeps climbing, make each Case’s work shorter, or split the process into stages with Multi-Agent Process Decomposition. And give each Queue exactly one consuming Agent. If two Agents both have triggers on the same Queue, Duvo won’t pick a winner — conflicted Cases don’t run at all. The trigger setup warns you about this; take the warning seriously.Related
Queue
What Queues and Cases are, statuses, and how to set them up.
Writing Effective AOPs
The principles behind AOPs that close every branch.
Choosing How Your Agent Starts
Schedules, triggers, Queues, and manual Runs — picking the right one.
Multi-Agent Process Decomposition
When one Agent is doing too much, split it into stages.