Duroxide Provider Implementation Skill

February 22, 2026 · View on GitHub

Summary

This skill enables AI assistants to help implement custom storage providers for Duroxide, a durable execution runtime for Rust. Providers are storage backends that persist orchestration state, manage work queues, and ensure atomic operations.

Key Concepts

Provider Role

  • Providers are "dumb storage" — they store and retrieve data exactly as instructed
  • Runtime owns all logic — providers never interpret events or make orchestration decisions
  • ID generation is runtime's job — providers MUST NOT generate execution_id or event_id

Architecture

  • Two work queues: Orchestrator queue (completions, timers) and Worker queue (activities)
  • Event history: Append-only log per instance/execution
  • Peek-lock semantics: Items locked during processing, deleted on ack

Core Trait Methods

MethodPurposeComplexity
read()Load history for latest executionEasy
append_with_execution()Append events to historyEasy
fetch_work_item()Fetch and lock from worker queueMedium
ack_work_item()Delete from queue, enqueue completionMedium
fetch_orchestration_item()Fetch turn with instance lockComplex
ack_orchestration_item()Atomic commit of turnComplex

Critical Requirements

  1. Atomicity: ack_orchestration_item() must be a single transaction
  2. Lock validation: Always check lock is still valid before commit
  3. Instance-level locking: All messages for one instance processed together
  4. Ordering: Enqueue worker items BEFORE cancelling (for same-turn schedule+cancel)
  5. Error classification: Use ProviderError::retryable() vs permanent()

Activity Cancellation

Implemented via lock stealing:

  1. Runtime calls ack_orchestration_item() with cancelled_activities list
  2. Provider deletes those entries from worker queue (same transaction)
  3. Worker's next lock renewal fails → triggers cancellation

Implementation Guidance

When implementing a provider:

  1. Start with historyread() and append_with_execution() are simplest
  2. Add worker queueenqueue_for_worker(), fetch_work_item(), ack_work_item()
  3. Add orchestrator queue — Similar pattern but with instance-level locking
  4. Handle advanced features — Lock renewal, cancellation, ProviderAdmin

Common Pitfalls

  • ❌ Generating IDs in the provider (runtime's job)
  • ❌ Non-atomic ack operations (use transactions)
  • ❌ Creating instances in enqueue_orchestrator_work() (only in ack)
  • ❌ DELETE before INSERT for cancelled activities (wrong order)
  • ❌ Silently succeeding on lock renewal failure (must return error)

References

Usage

When asked to implement a Duroxide provider:

  1. Review the implementation guide for detailed method semantics
  2. Use SQLite or PostgreSQL implementations as reference
  3. Follow the "simplest path" — history → worker queue → orchestrator queue
  4. Run validation tests to verify correctness
  5. Consider implementing ProviderAdmin for production use