# OpenSpec Change: enterprise-suppression - **Change ID**: enterprise-suppression - **Package**: `@suaveplan/suppression` - **Category**: universal - **Target path**: `universal/email/suppression` - **Status**: PROPOSED - **Date**: 2026-04-19 - **Reference spec**: `/mnt/s/web/suaveplan/enterprise/suppression.md` ## Summary Email suppression list manager — classifies bounces, records unsubscribes, filters outgoing sends, and generates signed one-click unsubscribe links per RFC 8058. Pluggable store. ## Current-state audit (genesis) Package does not exist yet — fresh build. ## Dependencies - Workspace: `@suaveplan/error`, `@suaveplan/events`, `@suaveplan/types` - External (via catalog): `zod`, `tslib`, `@opentelemetry/api` - Dev (via catalog): `vitest`, `@vitest/coverage-istanbul`, `fast-check`, `mitata` ## Preserved public surface (star-exported from main) - `BounceClassifier`, `classifyBounce`, `BounceType` - `SuppressionFilter` — filters an outgoing send list against the store. - `SuppressionManager` — CRUD over suppressions with reason tagging. - `UnsubscribeLink` — `generateLink`, `verifyLink`, `rotateSecret`. - `SuppressionStore` interface + `MemorySuppressionStore`. - Types: `SuppressionReason`, `SuppressionEntry`, `BounceReport`, `FilterResult`, `LinkOptions`. ## New genesis additions - Codes: `SUPPRESSION.INVALID_ADDRESS`, `SUPPRESSION.STORE_ERROR`, `SUPPRESSION.LINK_EXPIRED`, `SUPPRESSION.LINK_INVALID_SIGNATURE`. - Zod schemas for every type. - OTel counter `suppression.filter.total{outcome}`, `suppression.suppressed.total{reason}`. - Property tests: every classified hard bounce remains suppressed; round-trip of `generateLink → verifyLink`. ## Impact - Adds one new package: `universal/email/suppression` - Adds one new spec capability: `suppression`