void-async-safety

Implements idempotent webhook, job, and cron handlers with signature verification, dedup, outbox, and bounded retries.

Updated May 29, 2026
One-click install
npx skills add https://github.com/voidcorp-core/void-harness --skill void-async-safety-voidcorp-core
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: void-async-safety
Source: https://github.com/voidcorp-core/void-harness/tree/main/packages/core/skills/void-async-safety
Command: npx skills add https://github.com/voidcorp-core/void-harness --skill void-async-safety-voidcorp-core

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? Webhooks redeliver, jobs restart mid-run, and crons overlap, so without idempotency by design every re-delivery risks corrupting state or duplicating side effects like payments and notifications. ## Core Features & Use Cases - Webhook safety pattern: Enforces a fixed order of signature verification, atomic idempotency-key claim, event handling, and completion marking, with replay-window enforcement and durable dedup stores (Redis or Postgres adapters). - Outbox pattern: Writes the database change and the domain event in one transaction so external notifications are never lost or sent without the corresponding state change. - Job and cron safety: Defines explicit job state machines, exponential backoff with jitter, dead-letter queues after bounded retries, and overlap protection for scheduled tasks. - Fail-soft outbound HTTP: Requires timeouts, bounded retries for idempotent reads, and an explicit critical-vs-degradable failure decision for third-party calls. - Use Case: When adding a Stripe webhook endpoint, apply this discipline so the handler verifies the HMAC signature, dedups on the Stripe event ID, and processes each event exactly once even under redelivery. ## Quick Start Ask the agent to make my Stripe webhook handler idempotent with signature verification, dedup, and an outbox for the refund notification.

Frequently Asked Questions about void-async-safety

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I make a Stripe webhook handler idempotent?

Verify the HMAC signature first, then atomically claim an idempotency key such as the Stripe event ID before running business logic, and mark it completed afterward. Store claims in Redis or Postgres so process restarts do not lose dedup state, and reject events older than a five-minute replay window.

What is the outbox pattern and when should I use it?

The outbox pattern writes the database change and the event to publish in the same transaction, then a background dispatcher publishes the event with retries. Use it whenever one operation must both update the database and notify an external system, so a failure cannot leave the two inconsistent.

How should I retry failed background jobs?

Use exponential backoff with jitter, starting around one second and doubling per attempt, capped at three to five attempts. After exhaustion, move the job to a dead-letter queue and alert, since further failure is structural and needs human review.

Can I use an in-memory Set for webhook deduplication?

No. In-memory dedup loses all claims on process restart, allowing redelivered events to be processed twice. Use a durable store such as Redis or Postgres with an atomic claim operation like INSERT ... ON CONFLICT DO NOTHING.

How do I prevent cron jobs from overlapping?

Acquire a lock keyed by the cron name, such as a Postgres advisory lock, and skip the run with a structured log entry if the previous execution is still in flight. Without overlap protection, jobs slower than the cron interval stack up and crash workers.

When should an outbound API call fail the request versus degrade gracefully?

Decide up front: critical calls like payment authorization must surface the failure to the caller, while degradable calls like FX rates or recommendations should fall back to a cached or default value with a warning log. Always bound the call with a timeout such as AbortSignal.timeout.