Basset is a framework for antispam modules.

It consists of two components: a frontend that runs as a mod_wsgi script within
httpd, and a worker that runs as a separate service.
They communicate with eachother using an AMQP broker (tested with RabbitMQ).


The frontend is a very small, single script whose only job is to get "messages"
from external systems and put these messages into the broker.

Each message is a notification that a user has done something that could possibly
be spam, and asks Basset to decide whether or not this is (likely) spam.

Its output is a JSON dictionary, where the key "result" has one of the following
- "accepted": the checks resulted in acceptance of the submitted query.
- "denied": the checks determined that this request should be denied.
- "manual": the checks could not come to a conclusion, and a human should look
at the request and make a decision. This most likely means that some parameters
in the Basset configuration needs to be tweaked more specific to the setup.
- "checking": the checks are taking a bit longer, which means that the worker
will later on connect to the service via an application-specific API to enact
its decisions

In the current version, it will always return "checking", but applications should
support the "accepted", "denied" and "manual" results as well, and act accordingly.
If a result is provided as part of this API, the worker will NOT also enact the decision


The worker is the part of Basset that does the real work of checking for spam.
It retrieves messages from the message broker, and for each message determines a
spam probability score, based on the enabled Score plugins.

If the spam probability score exceeds the configured threshold for denial, it will
decide to deny the request and enact its decision.
If the spam probability score does not exceed the threshold for denial, but it does
exceed the threshold for manual checks, it will tell the application that it should
ask for an administrator to check the request.
If neither of these thresholds are exceeded, it will decide to accept the request.

Each message may result in 0 or more decisions: a decision is an action that Basset
will take as a direct consequence of the message it just processed.

The processing of decisions is done by Decision Plugins, and only after every decision
has been processed correctly will the original message be acknowledged to the message
broker, which means that the worker becomes available for the next message.