Make Long-Running Agent Events Monotonic Before Making Them Real-Time
Make Long-Running Agent Events Monotonic Before Making Them Real-Time
Real-time delivery does not guarantee a correct timeline. WebSockets reconnect. Brokers redeliver. Workers race with cancellation. A client may receive event 42, then 40, then a snapshot generated after 45. For long-running agent tasks, define convergence before optimizing animation latency.
Give each operation an ordered log type:
type OperationEvent = {
operationId: string;
sequence: number;
eventId: string;
type: "accepted" | "started" | "progress" | "needs_input" | "completed" | "failed" | "cancelled";
occurredAt: string;
payload: unknown;
};
The producer allocates a strictly increasing sequence per operation in the same durable transaction that appends the event. eventId deduplicates delivery; sequence detects order and gaps. Wall-clock timestamps are for display and diagnosis, not ordering.
Consumer Rules
sequence <= applied_sequenceโ ignore duplicate or stale eventsequence == applied_sequence + 1โ apply and advancesequence > applied_sequence + 1โ buffer briefly and request replay
Terminal State Invariant
After completed, failed, or cancelled, later non-audit state transitions are rejected. Cancellation is a request until the authoritative terminal event is committed.
Reconnect with Snapshots Plus Replay
Return a snapshot containing operationId, materialized state, and throughSequence. Then replay events beginning at throughSequence + 1. The server must create the snapshot from a consistent log position; otherwise the client can miss the gap between two independent reads.
Compact old progress events only after a snapshot is durable and consumers no longer need them for audit. Retain terminal and authority-changing events according to policy.
Test Scenarios
Inject:
- Duplicate delivery
- Reordering
- A missing sequence
- Reconnect during snapshot
- Worker death after a side effect but before event commit
- Cancellation racing with completion
- Two clients reconnecting at different offsets
Validation Properties
- Every client eventually reaches the authoritative terminal state
- Each side effect has an idempotency key independent of delivery attempts
- No client applies the same event twice
- Gaps become observable rather than silently skipped
- Late progress cannot reopen a terminal task
The public MonkeyCode repository describes long-running AI tasks, managed environments, and synchronized PC/mobile workflows. Those capabilities make ordered recovery a relevant evaluation question, but this article does not claim that MonkeyCode uses this schema or report a reliability test.
Disclosure: I contribute to the MonkeyCode project. Product context is based on public documentation; the protocol is an independent reference design.
Real-time is a transport property. Correct recovery is a system property. Build the second one first.
Comments
No comments yet. Start the discussion.