25 September 2025 / Applied AI / 9 chapters

Give each task a durable identity

From Designing an audit trail for tool-using agents

Every event needs to belong to a stable task. A browser session, model response ID or background process ID is too narrow because one task can cross all three.

Create a task_id when work is accepted. Store the requesting actor, authenticated tenant or workspace, task type, bounded objective, creation time, current status and parent task if another workflow delegated it. If the agent starts a subtask, give that subtask its own ID and link it to the parent rather than mixing both sequences.

Each execution attempt also needs a run_id. Keep the task_id stable when work is retried under a different model, resumed after approval or recovered by another worker, then assign a separate run_id to each technical attempt. Include an attempt_number only for display because concurrent or resumed work does not always fit a simple counter.

Use correlation IDs at external boundaries. A tool call has its own tool_call_id, an approval has approval_id, and a destination mutation has an action_id used as an idempotency key where supported. Preserve provider request IDs and destination object references. Those identifiers let an operator compare the local record with source-system logs.

Events should include both event time and recorded time. A delayed queue may write an event after the external action occurred. Use a sequence assigned by the task event store for stable ordering, while retaining destination timestamps as claims from that system.

Task status should be derived from events or updated under the same consistency rules. A task can be running, waiting_for_approval, waiting_for_dependency, completed, completed_with_unresolved_action, cancelled or failed. Avoid marking it completed while an external action is merely queued.

All articles