> ## Documentation Index
> Fetch the complete documentation index at: https://internal.softcrum.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Standard — Jobs, Queues & Workers (v2)

> Interface in packages/core: publish(queue, payload, opts), schedule(queue, payload, runAt). Payloads are Zod-validated envelopes: { job_id: uuidv7, tenant_id, correlation_id, kind, data }.

## QueuePort (constitution category 7)

* Interface in packages/core: `publish(queue, payload, opts)`, `schedule(queue, payload, runAt)`. Payloads are Zod-validated envelopes: `{ job_id: uuidv7, tenant_id, correlation_id, kind, data }`.
* Binding per module composition root (R21). F1 default adapter: Vercel Queues. New vendors (QStash, etc.): ADR before first import.

## Consumers

* Idempotency MANDATORY: check/insert into `core.processed_jobs (job_id, consumer, processed_at)` inside the work transaction; duplicate ⇒ ack and skip. TTL cleanup job.
* Retry policy (industry default, override per queue with rationale in module spec): 5 attempts, exponential backoff with jitter (base 30s, cap 1h).
* Exhausted retries and hard failures MUST persist to `core.dead_letters (job_id, queue, payload, attempts, last_error, status: pending_review|replayed|discarded, correlation_id)` + BetterStack alert. Replay tooling lives in Softcrum Ops. High-volume successes are metrics, not rows.
* Poison messages: schema-invalid payloads go straight to dead\_letters (no retries).

## Notification queues (with standards/notifications.md)

* One queue per channel per rail: `notif.{channel}.transactional` and `notif.{channel}.marketing`.
* Transactional ALWAYS has priority: marketing workers yield (pause/drain) when transactional depth > threshold.
* Rate limiting: token bucket in Upstash per PROVIDER (global — e.g., Resend 10 rps is per team across ALL tenants) and per TENANT (fair use). 429 ⇒ backoff, never drop.
* Email blasts: Resend batch endpoint (100/request) exclusively; NEVER sync contacts to Resend Audiences (our store is the source of truth).

## Cron fan-out

* Per-tenant fan-out pattern (existing) for: partition pre-creation, retention export+purge, nightly reconciliation, data-freshness recomputes (tier per entitlement: nightly/12h/6h/3h/1h), points\_expiring\_soon scans, usage snapshots (30 min).
