Problem/Motivation
Suppression lives in a procedural helper returning an English string, with global service access and up to three database queries. Other mail integrations and operator tools cannot consume a typed, consistent decision without reaching into implementation details.
Evidence and scope
Reviewed 1.0.0-alpha1, source commit 02fd9d36af5237e712cecb7155d79725f7824880. Location: postmark_webhooks.module:86.
Architecture observation, not a current exploit or measured performance failure.
Proposed resolution
Introduce one injectable decision service returning allowed/suppressed, reason code, expiry and evidence reference. Keep presentation outside the decision. Have the existing hook and Drush command delegate to it. Offer a narrow documented extension event only where concrete consumers need it.
Acceptance criteria
Contract tests for all current policies and disabled mode; no behavior regression. Publish examples for consumers without requiring a new framework or a general-purpose email platform.
Comments
Comment #2
jmcerdaThe shared suppression policy is implemented with durable state (#3621121) and provider-time ordering (#3621124). Its immutable decision includes effective suppression, a reason code, expiry, evidence reference, occurrence time and time basis, with no recipient or credential. Core mail and the compatibility helper delegate to the service; disabled mode is explicitly allowed. Contract tests pass on Drupal 10 and 11. Integration and release are still pending.
Comment #3
jmcerdaThe shared suppression policy is now integrated into 1.x at d3c5d94. Integrations can inject postmark_webhooks.suppression_policy and call decide() for the effective enabled-state, reason, expiry and evidence/time basis. Core mail and the legacy helper use this boundary; the every-recipient follow-up is #3621123.
PostgreSQL CI passes on Drupal 10.3/PHP 8.3 and Drupal 11/PHP 8.4 (39 tests, 226 assertions each), including policy reasons, disabled mode and durable-state behavior. No optional Symfony Mailer adapter is claimed. Fixed on the development branch; no release tag or deployment has been made.