45. pepsi-stage-block-language

Route a message by the human language(s) detected in its body.

45.1. Role

pepsi-stage-block-language is a language-policy filter. It scores the language(s) recorded under state.language (written upstream by pepsi-stage-detect-language) against a configured whitelist and blacklist and routes the message: above the score THRESHOLD it advances to NEXT_STAGE, otherwise it is rerouted to BOUNCE_STAGE carrying a failure-DSN state. It reads only state — the body is never loaded — and never pauses or fails. Reference: pepsi-stage-block-language(1).

45.2. Scoring

state.language is an HTTP Accept-Language-style string of code;q=quality items, each quality being the detection probability of that language. The stage collapses it to one number:

score = Σ q over languages listed in WHITELIST
      − Σ q over languages listed in BLACKLIST

Languages on neither list contribute nothing. With English whitelisted and French blacklisted, en;q=0.7, fr;q=0.3 scores 0.7 0.3 = 0.4. A message whose score is strictly greater than THRESHOLD advances; otherwise it is bounced.

  • Undetected mail. When no language was detected (state.language absent) the score is computed against the pseudo-distribution none;q=1. The literal none may itself appear in WHITELIST/BLACKLIST, so the operator decides the fate of undetected mail (blacklisting none scores it −1, whitelisting +1, listing it nowhere leaves it at 0).

  • Whitelist bypass. A message carrying an explicit state.spam = false verdict — set by an upstream pepsi-stage-check-whitelist match, or by ingress for the reserved <Postmaster> mailbox (RFC 5321 §4.5.1) — skips the language policy entirely and advances to NEXT_STAGE.

  • Never bounce a bounce. A message that is already a bounce (the null envelope sender) advances to NEXT_STAGE regardless of its score (RFC 5321 §6.1).

On the block path the stage reroutes to BOUNCE_STAGE with a permanent failure-DSN state, so pepsi-stage-bounce emits a bounce only if the sender’s NOTIFY requests FAILURE (the default when absent).

45.3. Fusion

The stage defaults to FUSION = yes: under the unified pepsi binary with [pepsi] ALLOW_FUSION on (the default), a predecessor may run it in its own worker process rather than dispatching it separately. See pepsi-dispatch.

45.4. Configuration

[stage-<name>]: PROGRAM = pepsi-stage-block-language, NEXT_STAGE, BOUNCE_STAGE, the WHITELIST/BLACKLIST language lists and the numeric THRESHOLD. pepsi-setup rejects an invalid language code, an overlap between the two lists, or a configuration that can block with no BOUNCE_STAGE. See pepsi-stage-block-language(1) and Configuration.

45.5. State

  • Inputs: state.language (treated as none;q=1 when absent) and, for a blocked message, state.dsn and the envelope recipient.

  • Outputs: on the pass path state is untouched; on the block path the failure-DSN keys pepsi-stage-bounce consumes (state.bounce) are merged.

  • Transitions: score above THRESHOLD → advance to NEXT_STAGE; score at or below → reroute to BOUNCE_STAGE.

45.6. See also

pepsi-stage-detect-language, pepsi-stage-check-whitelist, pepsi-stage-bounce, Supported Features, pepsi-stage-block-language(1).