From eb52a1d1355e0cc51622b592191a0efbe5681eab Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sat, 13 Jun 2026 17:27:58 +0900 Subject: [PATCH 1/2] spamassassin: disable EMPTY_MESSAGE penalty for test compatibility --- docker/spamassassin/local.cf | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docker/spamassassin/local.cf b/docker/spamassassin/local.cf index ce9a31c..2bab1f8 100644 --- a/docker/spamassassin/local.cf +++ b/docker/spamassassin/local.cf @@ -58,4 +58,7 @@ score RCVD_IN_VALIDITY_RPBL_BLOCKED 0 score RCVD_IN_VALIDITY_SAFE_BLOCKED 0 score RCVD_IN_VALIDITY_CERTIFIED 0 score RCVD_IN_VALIDITY_RPBL 0 -score RCVD_IN_VALIDITY_SAFE 0 \ No newline at end of file +score RCVD_IN_VALIDITY_SAFE 0 + +# emails with no text are common for tests, don't penalize them +score EMPTY_MESSAGE 0 \ No newline at end of file From 9c3109c0877e4fca1c79860a358f2248037b9f34 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sat, 13 Jun 2026 17:54:37 +0900 Subject: [PATCH 2/2] rbl: apply flat 10% penalty for informational list hits Informational lists previously didn't count toward the score at all. Now any informational listing applies a flat 10% penalty regardless of how many of them fire, with the final score clamped at 0. --- pkg/analyzer/rbl.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/pkg/analyzer/rbl.go b/pkg/analyzer/rbl.go index bd3c9da..1c91180 100644 --- a/pkg/analyzer/rbl.go +++ b/pkg/analyzer/rbl.go @@ -302,7 +302,9 @@ func (r *DNSListChecker) reverseIP(ipStr string) string { } // CalculateScore calculates the list contribution to deliverability. -// Informational lists are not counted in the score. +// Informational lists don't count proportionally; instead, if any +// informational list triggers, a flat 10% penalty is applied regardless +// of how many of them fire. func (r *DNSListChecker) CalculateScore(results *DNSListResults, forWhitelist bool) (int, string) { scoringListCount := len(r.Lists) - len(r.informationalSet) @@ -324,7 +326,13 @@ func (r *DNSListChecker) CalculateScore(results *DNSListResults, forWhitelist bo return 100, "A+" } - percentage := 100 - results.RelevantListedCount*100/scoringListCount + // A listing on any informational list applies a flat 10% penalty. + informationalPenalty := 0 + if results.ListedCount > results.RelevantListedCount { + informationalPenalty = 10 + } + + percentage := max(0, 100-results.RelevantListedCount*100/scoringListCount-informationalPenalty) return percentage, ScoreToGrade(percentage) }