async-safetylisted
Install: claude install-skill voidcorp-core/void-harness
# async-safety — voidcorp craftsman edition
The network is unreliable. Webhooks redeliver. Jobs restart mid-run. Crons stack when one runs slow. Without idempotency by design, every re-delivery becomes a corruption risk. This skill codifies the patterns so handlers are safe by construction.
**Attribution**: see `.source`. Foundation: Stripe webhook patterns + Outbox pattern (Microservices.io) + Pat Helland "Life Beyond Distributed Transactions" + Bryan Cantrill on distributed failure modes.
---
## At-least-once is the default
Assume every message can be delivered N times. The consumer handles dedup.
Exactly-once delivery requires two-phase commits across systems — extreme effort, rarely worth it. At-least-once + consumer dedup covers > 99% of real cases at a fraction of the cost.
---
## Webhook safety — the canonical pattern
Every webhook handler does FOUR things, IN THIS ORDER:
1. **Verify signature** (HMAC + timestamp window)
2. **Check idempotency key** (claim atomically; if already processed, return success without re-processing)
3. **Handle the event** (business logic)
4. **Mark idempotency key as completed** (or release on failure for retry)
The `pack-nextjs` provides a `withWebhookSafety()` wrapper:
```typescript
import { withWebhookSafety } from '@repo/async';
export const POST = withWebhookSafety({
verify: (req) => verifyStripeSignature(req, env.STRIPE_WEBHOOK_SECRET),
dedupKey: (event) => event.id, // Stripe event ID
replayWindowM