Table of Contents

Constructor AuthoredSendGovernor

Namespace
MailFathom.Application.Mail.Delivery.Governance
Assembly
MailFathom.Application.dll

AuthoredSendGovernor(OutgoingRecipientPolicy, AuthoredSendSettings, RecipientVouching, AuthoredSendUsageLedger, IAuthoredSendAuditor, AccessAuthorization, TimeProvider)

Decides what one caller may talk this deployment into sending, and records what it did send.

public AuthoredSendGovernor(OutgoingRecipientPolicy recipientPolicy, AuthoredSendSettings settings, RecipientVouching vouching, AuthoredSendUsageLedger ledger, IAuthoredSendAuditor auditor, AccessAuthorization authorization, TimeProvider timeProvider)

Parameters

recipientPolicy OutgoingRecipientPolicy

Says who this deployment may write to.

settings AuthoredSendSettings

Says what to do about a recipient nothing here vouches for.

vouching RecipientVouching

Counts the addresses the caller wrote down that nothing here vouches for.

ledger AuthoredSendUsageLedger

Weighs the send against what this caller has already been admitted for, and charges it.

auditor IAuthoredSendAuditor

Records the send once it is durable.

authorization AccessAuthorization

Names the caller the work is running for.

timeProvider TimeProvider

Stamps the record with when the send was admitted.

Remarks

OutgoingMailGovernor answers what this deployment may send at all, whoever is asking, and it is asked by the outbox so that nothing reaches a record ungoverned. This answers the other question — what a caller acting on text a stranger wrote may be talked into — and it is therefore asked where a caller exists, which the outbox is deliberately not: work no caller requested has no principal, no grant, and no client to bound.

It is asked by the use cases rather than by the tools, which is what makes it unbypassable on this surface for the reason the outbox's own checks are: a second protocol added later reaches the same use case and meets the same three refusals without re-implementing any of them, and a tool that forgot to ask would be a tool that could not send.

The deployment's recipient policy is asked first, because it is decided in memory and refuses outright. It is re-evaluated here rather than trusted from the outbox beneath — not because the outbox might not ask, but because a caller refused for naming somebody this installation never writes to should learn that before its message is written down, and because a bound with one implementation is a bound with one place to get wrong.

The caller's own ceilings are asked last, after the contact book has answered, and that ordering is the ledger's rather than a preference. Asking it is what charges it: a ceiling read here and charged after the record was written would be a ceiling two concurrent sends from one caller both passed, which is the loop this bound exists to stop. So nothing may refuse a send after the ledger has admitted it, and the read of the book — the one step here that awaits anything — happens in front of it. The cost is one indexed lookup on a send the ceiling then refuses, which is the cheaper half of the trade.

The book is asked even where the posture admits an unvouched recipient, and that is a read this deployment pays for on every send. What it buys is the one thing the admitting posture would otherwise have no record of: that a message went to somebody this installation has never corresponded with. A count of them reaches the audit; nothing reaches the caller.