TS-002 — QueuePort & NotificationChannelPort + F1 Adapters
Objective: both ports in packages/core; adapters VercelQueueAdapter, ResendEmailAdapter, FcmPushAdapter, InAppAdapter, WebhookAdapter; per-module composition-root binding.
Archetype: synchronous command · Refs: Amendment A1 (must be APPLIED first), ADR-019, standards/jobs.md, notifications.md
Objective: both ports in packages/core; adapters VercelQueueAdapter, ResendEmailAdapter, FcmPushAdapter, InAppAdapter, WebhookAdapter; per-module composition-root binding.
In: port interfaces + Zod envelopes · consumer harness (processed_jobs gate, retry/backoff/jitter, dead_letters writer, token buckets) · rails wiring notif.{channel}.{rail} · resolveChannels pure function with full unit matrix (levels 0–3 × recipient gates).
Out: SMS adapter (F1b, provider ADR) · fallback between channels (F2).
Acceptance: consumer harness replay test (same job_id twice ⇒ single effect) · marketing yield test under transactional depth · resolveChannels 100% branch coverage · zero direct provider imports outside adapters (lint rule).
⌘I